I'm looking at the multisig wallet implementation here and I see the usage of sha3(msg.data,block.number) being used as an identifier.

What exactly is inside the msg.data and why is it unique enough to be used to make the identifier? Doesn't it only contain info on how the contract was called? Meaning will it be same if I call the contract with the same parameters?


msg.data is usually ABI encoded information that indicates to the contract the function and parameters to invoke.

Using standard tools, msg.data will be the same if the contract is called with the same parameters. However, hashing it with the block.number as in sha3(msg.data, block.number) will produce a completely different result, for each block.

Note: msg.data is malleable. For example, extra trailing zeroes can be appended to msg.data without changing the function that will be invoked in a contract. Using standard tools (like web3.js) will not create extra trailing zeroes, but you should examine your use case when using msg.data as an identifier, to ensure that malleability will not cause an issue or vulnerability.

(In the specific wallet case in the question, malleability of msg.data by an owner only seems to cause confusion for themselves or other owners.)

  • To complement on the 2nd part of the question, msg.data will be the same for identical invocation but is also only one of the multiple transactions properties that are used to build its hash (identifier). Crucially, each calling transaction has an account nonce, which is unique and monotonically increased.
    – Matthieu
    Aug 17 '16 at 0:06
  • @Matthieu Sorry are you saying that msg.data also contains the account nonce or that this nonce is being used to make the identifier? The only parameters used by the identifier seem to be msg.data and block.number.
    – plsnoban
    Aug 17 '16 at 9:01
  • The account nonce isn't part of msg.data. I think @Matthieu interpreted identifier as "the transaction hash", instead of the multisig wallet's "operation hash" identifier.
    – eth
    Aug 17 '16 at 11:38
  • It's not necessarily true that "msg.data will be the same if the contract is called with the same parameters." There is lots of room to mess with the msg.data without changing the actual values of the parameters. Apr 10 '17 at 21:20
  • But if the two or more transactions included in the same block, then it will be same, rather than unique. Jan 7 '19 at 8:43

msg.data is simply the data field of the transaction.

From the yellowpaper:

...a message call transaction contains:

data: An unlimited size byte array specifying the input data of the message call, formally Td.

This data field can contain anything the sender wishes, but as @eth said, usually contains the function signature (a 4-bytes identifier which tells Solidity which function to call) and arguments. This will usually be the same when the arguments are the same, but don't rely on this, since the data can be padded at the end with extra zero bytes, which will get stripped off when Solidity decodes the arguments but will change the msg.data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.