Acabo de descubrir que con b59c839 geth ahora está agregando previamente la cadena:
*\x19Ethereum Signed Message:\n<length of message>*
antes de firmar el mensaje pasado. He leído aquí que para usar ecrecover en el lado de Soldity, debe adjuntarse previamente la misma cadena en el contrato. ¿Tiene algún ejemplo práctico sobre cómo administrar correctamente esta preadjunción en un contrato de Solidity?
Gracias
----- ----- ----- ACTUALIZAR
Estoy tratando de agregar previamente la firma localmente en geth con algo como esto:
test = web3.sha3("hello")
eth.sign(eth.accounts[0], test)
hash_preamble = web3.sha3("\x19Ethereum Signed Message:\n" + test.length + test)
Luego, en el lado del contrato, estoy tratando de probar algo tan simple como esto:
function test(bytes32 r, bytes32 s, uint8 v, bytes32 hash_preamble) constant returns (address) {
address signer = ecrecover(hash_preamble, v, r, s);
return signer;
}
Los bytes32
valores pasados al contrato tienen la forma de "0x1234", mientras que el uint8
es 27 o 28. El hash pasado al contrato es el hash compuesto con el preámbulo, la longitud de mi mensaje (que es un hash) y mi mensaje.
Desafortunadamente, no puedo obtener la misma dirección que el firmante. ¿Puedes ver algunos errores en mi código?
¿Tiene algún ejemplo práctico sobre cómo administrar correctamente esta preadjunción en un contrato de Solidity?
Puede consultar el contrato inteligente de Etherdelta https://github.com/etherdelta/smart_contract/blob/master/etherdelta.sol
function availableVolume(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s) constant returns(uint) {
bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce);
if (!(
(orders[user][hash] || ecrecover(sha3("\x19Ethereum Signed Message:\n32", hash),v,r,s) == user) &&
block.number <= expires
)) return 0;
uint available1 = safeSub(amountGet, orderFills[user][hash]);
uint available2 = safeMul(tokens[tokenGive][user], amountGet) / amountGive;
if (available1<available2) return available1;
return available2;
}
Aquí el mensaje firmado tiene un hash
tamaño de 32. Tenga en cuenta que usan sha256
para crear el mensaje que cuesta más gasolina que sha3
, sospecho que lo hicieron por compatibilidad con el lado del cliente.
ecrecover
se describe en los documentos de Solidity con ejemplos de uso:
ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) devuelve (dirección): recupera la dirección asociada con la clave pública de la firma de curva elíptica o devuelve cero en caso de error ( ejemplo de uso )
Puede ver más ejemplos en diferentes idiomas en Github: https://github.com/search?l=&q=%5Cx19Ethereum+Signed+Message&ref=advsearch&type=Code&utf8=%E2%9C%93
De su nota de recompensa:
proporcionar una forma de recuperar el mensaje original del hash del mensaje firmado de modo que se pueda verificar la integridad de h
No es posible recuperar el mensaje original del hash. Todo lo ecrecover
que puede hacer es "recuperar la dirección asociada con la clave pública de la firma de curva elíptica o devolver cero en caso de error". Básicamente te dice si la firma pertenece a la dirección dada.
tjaden hess
gatb27
hexteto