Obtener la dirección incorrecta de ecrecover

Cuando firmo una cadena con el siguiente código, obtengo una dirección diferente a la que firmé. La dirección devuelta es diferente para diferentes cadenas.

const util = require('ethereumjs-util')
const msg = web3.sha3('hello!');
const sig = web3.eth.sign(web3.eth.accounts[0], msg);
const {v, r, s} = util.fromRpcSig(sig);

const pubKey  = util.ecrecover(util.toBuffer(msg), v, r, s);
const addrBuf = util.pubToAddress(pubKey);
const addr    = util.bufferToHex(addrBuf);

Tomé el código de la respuesta a una pregunta que hice anteriormente aquí Obtener una dirección de ethereumjs-utils erecover .

Hice una pregunta aquí: los enlaces Secp256k1 no están compilados. Se utilizará la implementación JS pura sobre un error posiblemente relevante. Sin embargo, los comentarios sugirieron que debería ser inofensivo.

¿Puede publicar las versiones exactas de los paquetes que utiliza ( npm list). Creo que hubo un error en algunas de las testrpcdependencias.
@maxtaldykin pastebin.com/v2ydwkgy esto es lo que obtuve
@maxtaldykin estoy usando macOS sierra versión 10.12.4 no estoy seguro de dónde encontrar la versión testrpc
@maxtaldykin tengo un error imgur.com/a/JTyU4

Respuestas (1)

Geth agrega un prefijo al mensaje antes de iniciar sesión web3.eth.sign(consulte la especificación JSON-PRC ). Sin esto, es posible engañar al usuario para que firme la transacción (más información aquí ).

Por lo tanto, el código correcto para firmar el mensaje web3.eth.signy recuperar la dirección con ethereumjs-util.ecrecovero (de Solidity ecrecover) debe agregar el prefijo explícitamente.

const util = require('ethereumjs-util')

const msg = new Buffer('hello');
const sig = web3.eth.sign(web3.eth.accounts[0], '0x' + msg.toString('hex'));
const res = util.fromRpcSig(sig);

const prefix = new Buffer("\x19Ethereum Signed Message:\n");
const prefixedMsg = util.sha3(
  Buffer.concat([prefix, new Buffer(String(msg.length)), msg])
);

const pubKey  = util.ecrecover(prefixedMsg, res.v, res.r, res.s);
const addrBuf = util.pubToAddress(pubKey);
const addr    = util.bufferToHex(addrBuf);

console.log(web3.eth.accounts[0],  addr);

Existe una incoherencia engañosa ethereumjs-testrpc, ya que no antepone el mensaje antes de iniciar sesión web3.eth.sign.

Parece que Meteor solo permitirá versiones de nodo de 4.x
¡Funcionó! Muchas gracias, he estado luchando con esto durante años.
lo siento, solo una pequeña cosa ... la dirección de ecrecover está en minúsculas, pero la dirección original tiene algunas mayúsculas. ¿Esto hace una diferencia?
no importa, está respondido aquí ethereum.stackexchange.com/questions/2045/…
¡¿Cómo diablos encontraste esto?! He estado buscando por siempre.