I am trying to pre-compute a keccak
hash in a rust library, to then send it to Ethereum where it must match
the re-computed hash in solidity.
However, I have a strange behavior.
The data to hash:
function testConsumeMessageFromL2(uint256 fromAddress, uint256[] calldata payload)
external
payable
returns (bytes32)
{
bytes memory b = abi.encodePacked(fromAddress, uint256(uint160(msg.sender)), payload.length, payload);
bytes32 msgHash = keccak256(b);
emit TestEvent(fromAddress, uint256(uint160(msg.sender)), msgHash, payload.length, payload, b);
return msgHash;
}
which results in hash 0x52654d122bf06d08b03ee7c6fc4331bb78c93521369b3f8c10f2725316ba59c9
with arguments:
uint256 fromAddress = 03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0;
uint256[] payload = [0x1, 0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266];
On the EVM this is the buffer I have in TestEvent
data, for b
:
03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0
000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000001
000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266
Which is weird.. because based on solidity abi for dynamic sized types it's supposed to have the offset of the array.
Looks like because the array is the last element, the offset is not required? But cast gives a different result.
Doing it with cast
command from foundry and from my rust library (using sha3
), I have the following:
cast abi-encode "e(uint256,uint256,uint256,uint256[])" 0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 2 '[1,1390849295786071768276380950238675083608645509734]'
03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0
000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000080
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000001
000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266
Which generates a hash 0x4728187e41c5f53fb48d5461998c025681e57546967776d74147995716300719
.
So.. I don't know what I am missing, but library and cast tool are giving the same result, but solidity a different one.
If is because the argument is a calldata
?
I am compiling the code with forge
and version solidity pragma solidity ^0.8.0;
.