¿Se puede utilizar msg.data como identificador?

Estoy viendo la implementación de la billetera multisig aquí y veo el uso de sha3( msg.data, block.number) como identificador.

¿Qué hay exactamente dentro msg.datay por qué es lo suficientemente único como para ser utilizado para hacer el identificador? ¿No contiene solo información sobre cómo se llamó el contrato? ¿Significa que será lo mismo si llamo al contrato con los mismos parámetros?

Respuestas (2)

msg.datasuele ser información codificada en ABI que indica al contrato la función y los parámetros a invocar.

Usando herramientas estándar, msg.dataserá lo mismo si el contrato se llama con los mismos parámetros. Sin embargo, mezclarlo con el block.numbercomo en sha3(msg.data, block.number)producirá un resultado completamente diferente para cada bloque.

Nota: msg.dataes maleable. Por ejemplo, se pueden agregar ceros finales adicionales msg.datasin cambiar la función que se invocará en un contrato. El uso de herramientas estándar (como web3.js) no creará ceros finales adicionales, pero debe examinar su caso de uso cuando lo use msg.datacomo identificador, para asegurarse de que la maleabilidad no cause un problema o una vulnerabilidad.

(En el caso específico de la billetera en la pregunta, la maleabilidad de msg.dataun propietario solo parece causar confusión para ellos mismos o para otros propietarios).

Para complementar la segunda parte de la pregunta, msg.data será el mismo para una invocación idéntica, pero también es solo una de las múltiples propiedades de transacciones que se utilizan para construir su hash (identificador). Fundamentalmente, cada transacción de llamada tiene un nonce de cuenta, que es único y aumenta de forma monótona.
@Matthieu Disculpe, ¿está diciendo que msg.datatambién contiene el nonce de la cuenta o que este nonce se usa para crear el identificador? Los únicos parámetros utilizados por el identificador parecen ser msg.datay block.number.
La cuenta nonce no es parte de msg.data. Creo que @Matthieu interpretó el identificador como "el hash de transacción", en lugar del identificador de "hash de operación" de la billetera multisig.
No es necesariamente cierto que "msg.data será el mismo si el contrato se llama con los mismos parámetros". Hay mucho espacio para jugar con el msg.datasin cambiar los valores reales de los parámetros.
Pero si las dos o más transacciones se incluyen en el mismo bloque, será igual, en lugar de único.
@TjadenHess Gracias, ediciones realizadas. Luego noté su respuesta, voté a favor y confirma lo que pensaba.
Probablemente debería señalar que la codificación ABI también permite una manipulación más matizada. Por ejemplo, puede intercambiar el orden de dos argumentos de tamaño dinámico o agregar datos arbitrarios entre ellos jugando con los punteros
Los comentarios no son para una discusión extensa; esta conversación se ha movido a chat .

msg.dataes simplemente el datacampo de la transacción.

Del papel amarillo:

...una transacción de llamada de mensaje contiene:

datos: una matriz de bytes de tamaño ilimitado que especifica los datos de entrada de la llamada de mensaje, formalmente T d .

Este campo de datos puede contener cualquier cosa que el remitente desee, pero como dijo @eth, generalmente contiene la firma de la función (un identificador de 4 bytes que le dice a Solidity qué función llamar) y argumentos. Por lo general, será el mismo cuando los argumentos sean los mismos, pero no confíe en esto, ya que los datos se pueden rellenar al final con bytes cero adicionales, que se eliminarán cuando Solidity decodifique los argumentos, pero cambiará el msg.data.