This is a simple contract that has a function input_data(bytes data) and a simple fallback function that passes msg.data to function input_data.
contract test_input_data{
address owner;
event log_input_data(address result);
constructor() public{
owner = msg.sender;
}
function input_data(bytes data) public payable{
address n = address(keccak256(data));
emit log_input_data(n);
}
function() public payable{
input_data(msg.data);
}}
The contract logs the hashed data converted to an address variable.
Why when I call input_data(data = 1), the log is different than when I do a transaction to the contract (so calling the fallback) attaching data=1 to the transaction?
Here is an example:
input_data(data = 1) log = 0x057beebb9be2ac30c6410aa38d4f3fbe41dcffd2
fallback() = 1 log = 0xdcc703c0e500b653ca82273b7bfad8045d85a470
used:metamask, remix, rinkeby testnet, myetherwallet.
Thanks!
Best Answer
msg.data
is the raw data that's sent in the transaction. It's an encoding of the function selector and then any parameters that you're passing to that function.So, for example, when calling
input_data(bytes)
with a single byte with the value 1, the ABI encoding would be this (with newlines for clarity):The first four bytes are the function selector (hash of
"input_data(bytes)"
). The next 32 bytes are the offset of the start of the bytes argument. The next 32 bytes are the length of the bytes argument. And the last 32 bytes are the actual bytes themselves, padded to a length of 32 bytes.That's
msg.data
. Thebytes
argument being hashed ininput_data
, on the other hand, would just be:So it's expected that the hashes of these two things would be different.
My blog post Anatomy of Transaction Data might help and point you to further reading.