Stellen Sie eine mit JavaScript signierte Nachricht in Python Web3 wieder her

Es treten Probleme beim Entnehmen einer signierten Nachricht von Web3.js und beim Wiederherstellen der Signaturadresse in Web3.py auf.

Hier ist mein Code in JavaScript, um eine signierte Nachricht zu erstellen:

async function sign_message() {
    var message = "hi"
    var message_hash = web3.eth.accounts.hashMessage(message)
    //message_hash == 0x0d52783c4cbad7ebaf7eb943fc648f5282a52070442fc18d8dd16ddb2fcbaf66

    var accounts = await web3.eth.getAccounts()
    var signature = await web3.eth.personal.sign(message, accounts[0])
    //accounts[0] ~ 0x6d31165d5d932d571f3b44695653b46dcc327e84
    console.log(signature)
    //signature == 0x29887fe718fcc6e64b97d681f80e6fd485883a45ec0dbc0e35a3752acf1065655d73c9034cac3df0dc82da015abe42367f5e90fd499d872b19610a3ea9c176921b
}

Dann wird hier versucht, die Adresse in Python wiederherzustellen:

>>> message = "hi"
>>> message_hash = defunct_hash_message(text=message)
>>> message_hash
HexBytes('0x0d52783c4cbad7ebaf7eb943fc648f5282a52070442fc18d8dd16ddb2fcbaf66')
>>> signature = '0x29887fe718fcc6e64b97d681f80e6fd485883a45ec0dbc0e35a3752acf1065655d73c9034cac3df0dc82da015abe42367f5e90fd499d872b19610a3ea9c176921b'
>>> w3.eth.account.recoverHash(message_hash, signature=signature)
'0x6F4630e882c48151D9e4E386F95009b6312717f4'

Beachten Sie, dass die message_hashin beiden Beispielen gleich sind, jedoch recoverHashnicht zur korrekten Ethereum-Adresse führen.

Ich habe diese beiden Quellen verwendet, um zu versuchen, mir beim Debuggen des Problems ohne Erfolg zu helfen:

Wie signiere ich eine Transaktion, die von ecrecover verwendet werden soll?

Überprüfung der personal.sign-Signatur mit Pyethereum

Was ist der Anbieter in web3.js? Verschiedene Anbieter (können) das Verfahren der persönlichen Signatur unterschiedlich implementieren.
Ich habe Metamask (das im Hintergrund Infura verwendet, glaube ich) als meinen Ethereum-Anbieter verwendet. Ich bin davon ausgegangen, dass diese Aufrufe nicht von Ethereum abhängig sind, sondern lediglich vom privaten Schlüssel.
@carver gibt es einen JavaScript-Code, den ich hinzufügen kann, der mir garantiert, dass ich in Python wiederherstellen kann? Oder umgekehrt?

Antworten (1)

Das hat am Ende funktioniert:

async function create_signature(message, accounts) {
    var hex = ''
    for(var i=0;i<message.length;i++) {
        hex += ''+message.charCodeAt(i).toString(16)
    }
    var hexMessage = "0x" + hex
    var signature = web3.eth.personal.sign(hexMessage, accounts[0])
    return signature
}

Und auf der Python-Seite haben wir die Adresse so wiederhergestellt:

def recover_address(message, signature):
    message_hash = defunct_hash_message(text=message)
    address = w3.eth.account.recoverHash(message_hash, signature=signature)
    return address

Wenn jemand einen besseren Weg kennt, um das hexMessageim JavaScript-Code zu berechnen, antworten Sie bitte mit einem Kommentar!