Ecrecover después de la actualización de eth_sign con preámbulo

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 bytes32valores pasados ​​al contrato tienen la forma de "0x1234", mientras que el uint8es 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?

¿Realmente necesita hacer la preparación en el lado de la solidez? Será bastante complicado y costoso. Sería mucho más fácil simplemente pasar el mensaje con el prefijo ya adjunto.
Sí, claro, ¡en realidad se puede hacer así! ¡Gracias! ¿Cuál es la cadena exacta para agregar y cómo si el valor que se firmará es el resumen hash_messages = web3.Sha3 (primer mensaje, segundo mensaje)? :)
¿Alguna vez resolviste esto? Yo también estoy perplejo con esto.

Respuestas (1)

¿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 hashtamaño de 32. Tenga en cuenta que usan sha256para crear el mensaje que cuesta más gasolina que sha3, sospecho que lo hicieron por compatibilidad con el lado del cliente.

ecrecoverse 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 ecrecoverque 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.