Steps to reproduce -
- Deploy to Ganache and sepolia the following contract -
contract ABIExample {
event EncodedData(bytes encodedData);
function encodeAndDecode(uint a, uint[] memory b, bytes memory c) public returns (uint, uint[] memory, bytes memory) {
// abi.encode example
bytes memory encodedData = abi.encode(a, b, c);
emit EncodedData(encodedData);
// abi.decode example
(uint decodedA, uint[] memory decodedB, bytes memory decodedC) = abi.decode(encodedData, (uint, uint[], bytes));
return (decodedA, decodedB, decodedC);
//return (a,b,c)
}
function encodePackedExample(uint a, uint b) public returns (bytes memory) {
// abi.encodePacked example types shorter than 32 bytes are concatenated directly, without padding or sign extension
bytes memory packedData = abi.encodePacked(a, b);
emit EncodedData(packedData);
return packedData;
}
function encodeWithSelectorExample(uint a, uint b) public returns (bytes memory) {
// abi.encodeWithSelector example
bytes4 selector = bytes4(keccak256("exampleFunction(uint256,uint256)"));
bytes memory withSelectorData = abi.encodeWithSelector(selector, a, b);
emit EncodedData(withSelectorData);
return withSelectorData;
}
function encodeCallExample() public returns (bytes memory) {
// abi.encodeCall example
bytes memory callData = abi.encodeCall(this.exampleFunction, (42, 123));
emit EncodedData(callData);
return callData;
}
function exampleFunction(uint a, uint b) public pure returns (uint) {
// Example function for abi.encodeCall
return a + b;
}
}
Call
encodeAndDecode(uint a, uint[] memory b, bytes memory c)with following parameters1, [6,8,1,3,5],0xff.Observe the emitted event
Sepolia EncodedData event -
000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001ff00000000000000000000000000000000000000000000000000000000000000
https://sepolia.etherscan.io/address/0x9bf331503430077a1edd0434c8c79d72a2066cf8#events
Ganache EncodedData event -
0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001ff00000000000000000000000000000000000000000000000000000000000000
What it should be if my understanding is correct
<32bytes for uint(1)> <32 bytes representing length of array> <5*32 bytes for array elements> <32bytes for 0xff>
So-
00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005ff00000000000000000000000000000000000000000000000000000000000000
Why am I getting different results for Ganache and Sepolia . Why are they not matching with my results ?
The
Sepoliaresult (you can check here) is the same as yourGanacheresult. The hex version of it (which is similar, but not the same as the one you provided) has some prefixes (for the total length), but still contains the result fromGanache.Here's the breakdown
Since your 2nd input has a dynamic length, it will be represented as an offset. Here,
60in hex equals to 96 bytes. Skip 3 lines (3 x 32 bytes) from the beginning and we got5, which is the length of the array.Same for the 3rd input,
120in hex equals to 288 bytes (9 x 32 bytes). Skip 9 lines and we got the final input.