Hago lo siguiente en geth:
var msgHash = web3.sha3("hello")
var signature = eth.sign(eth.accounts[0], msgHash)
var r = signature.slice(0,64)
var s = "0x" +signature.slice(64,128)
var v = signature.slice(128,130)
r = signature.slice(0,64) "0x6d49c891d29b33c292232f690c9972e17e0dbead7d4fc446bb4ce5892f0e55" s = signature.slice(64,128) "a22c9f3c20a7f0bc90666d1d1c6f269658a0ccd56b1db1812671e23331d8ad2c" v = signature.slice(128,130) "52"
Entonces llamo al siguiente código de solidez
function verify(bytes32 msgHash, uint8 v, bytes32 r, bytes32 s) public {
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 prefixedHash = keccak256(prefix, msgHash);
a = ecrecover(prefixedHash, v, r, s);
}
Lo cual devuelve lo siguiente:0x0000000000000000000000000000000000000000
Absolutamente perplejo por esto, he echado un vistazo a los siguientes hilos sin éxito:
Tienes que sacar el 0x antes de hacer el corte; es solo para mostrar que la cadena es hexadecimal, no parte del valor r.
Debe deshacerse del 0x
prefijo antes de cortar.
ethereumjs-util
tiene una función muy útil fromRpcSig
, puedes usarla como
const eutil = require('ethereumjs-util')
const hash = web3.sha3('hello world')
const rpcSig = web3.eth.sign(web3.eth.coinbase, eutil.bufferToHex(hash))
const rsv = eutil.fromRpcSig(rpcSig)
// then call your ecrecover with
// hash, eutil.bufferToHex(rsv.r), eutil.bufferToHex(rsv.s), rsv.v
Tanto flygoing como Liberty tenían razón en que necesitaba eliminar el 0x
prefijo antes de cortar, pero necesitaba volver a agregar el prefijo después del corte, lo que me llevó un poco descifrar. Pude usar web3py para prefijar automáticamente y hacer el segmento, que aún no pudo recuperar la dirección adecuada. No fue hasta que volví a agregar el 0x
prefijo r
y s
funcionó. Como resultado, pude generar el siguiente código web3py:
decryptedPrivateKey = w3.eth.account.decrypt(encrypted, password)
attribDict = w3.eth.account.sign(message_text="testmessage", private_key=decryptedPrivateKey)
msgHash = Web3.toHex(attribDict['messageHash'])
v = attribDict['v']
r = attribDict['r']
s = attribDict['s']
r = Web3.toHex(r)
s = Web3.toHex(s)
vrs = (v,r,s)
contract.functions.testRecovery(msgHash,v,r,s).transact({'from': w3.eth.accounts[0], 'gasPrice': 91000000000})
print("v:\t",v,"\nr:\t",r,"\ns:\t",s,"\nmsgHsh:\t",msgHash)
recoveredAddress = w3.eth.account.recover(msgHash,vrs=vrs)
La testRecovery
función de solidez que utilicé:
function testRecovery(
bytes32 _msgHash,
uint8 _v,
bytes32 _r,
bytes32 _s)
public
returns (bool)
{
returned = ecrecover(_msgHash, _v, _r, _s);
if (returned == expected) {
return true;
} else {
return false;
}
}
hexteto