¿Cómo puedo verificar una firma con la API de javascript web3?

Usando la API javascript web3 puedo crear una firma como esta:

> web3.eth.sign(eth.coinbase, "0xdeadbeef")
"0xd3fe64b6f0920593cc4afb1321d592ae91e25fe1a0216e9002a4a6580fb2698c5ec62491c62557b8cc8f64533a5097b3ffb68208952b30cb27ed0a56ae21682201"

Ahora me gustaría verificar que la firma sea correcta; hacerlo en un contrato ya está documentado en otro lugar , pero estoy buscando una manera de hacerlo usando web3. (¿Cómo) se puede hacer esto?

@ euri10 gracias, pero estoy buscando una respuesta que no requiera un contrato para verificar
(no es una respuesta al comentario) Pero estoy atascado con ethereum.stackexchange.com/questions/15461/… - ¿alguna sugerencia sobre lo que está mal? muchas gracias

Respuestas (2)

web3aún no es compatible con esta característica, pero podría venir con web3 1.0 .

Mientras tanto, puede usar la función ecrecover de ethereumjs- utils . Tenga en cuenta que esta función espera vestar en {27, 28}, y dado que su firma proviene de geth (dado que aún no devuelve firmas en el formato canónico), tendrá que agregar 27a su archivo v.

Dada una firma sgnde un mensaje con hash msg, puede usar la biblioteca ethereumjs-util de esta manera:

r = utils.toBuffer(sgn.slice(0,66))
s = utils.toBuffer('0x' + sgn.slice(66,130))
v = utils.toBuffer('0x' + sgn.slice(130,132))
m = utils.toBuffer(msg)
pub = utils.ecrecover(m, v, r, s)
adr = '0x' + utils.pubToAddress(pub).toString('hex')

Para hacer la verificación en un contrato de solidez, mira esta respuesta .

Si bien esta respuesta puede ser técnicamente correcta, no me pareció muy útil. En particular, comenzando con 0xdeadbeefy 0xd3fe64b6f0920593cc4afb1321d592ae91e25fe1a0216e9002a4a6580fb2698c5ec62491c62557b8cc8f64533a5097b3ffb68208952b30cb27ed0a56ae21682201no está muy claro cómo usar ecrecoveren esa biblioteca para validar realmente la dirección que la firmó.
Actualicé la respuesta con más detalles, con suerte eso será más claro ahora
v = utils.toBuffer(27) //assuming that the given value was 0debe ser 27 + el último valor hexadecimal de la firma (0 o 1).
También vale la pena señalar que en utils, el vparámetro debe ser un número, por lo que la línea v debe leer:v = utils.bufferToInt(utils.toBuffer('0x' + sgn.slice(130,132)))
Propongo cambiar el título agregando especificando que es para web3 0.*
¿Existe ahora esta funcionalidad?

A partir de v1.0 puede usar web3.eth.accounts.recover

// message, signature
web3.eth.accounts.recover('Some data', '0xb91467e570a6466aa9e9876cbcd013baba02900b8979d43fe208a4a4f339f5fd6007e74cd82e037b800186422fc2da167c747ef045e5d18a5f5d4300f8e1a0291c');
> "0x2c7536E3605D9C16a7a3D7b1898e529396a65c23"