重现步骤 -
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;
}
}
使用以下参数调用
encodeAndDecode(uint a, uint[] memory b, bytes memory c)
1, [6,8,1,3,5],0xff
。
观察发出的事件
Sepolia
EncodedData
活动-
000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001ff00000000000000000000000000000000000000000000000000000000000000
https://sepolia.etherscan.io/address/0x9bf331503430077a1edd0434c8c79d72a2066cf8#events
甘纳许
EncodedData
活动-
0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001ff00000000000000000000000000000000000000000000000000000000000000
如果我的理解正确的话应该是什么呢
<32bytes for uint(1)> <32 bytes representing length of array> <5*32 bytes for array elements> <32bytes for 0xff>
所以-
00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005ff00000000000000000000000000000000000000000000000000000000000000
为什么我得到
Ganache
和 Sepolia
不同的结果。为什么它们与我的结果不匹配?
Sepolia
结果(您可以在此处查看)与您的Ganache
结果相同。它的十六进制版本(与您提供的相似,但不一样)有一些前缀(总长度),但仍然包含 Ganache
的结果。
这是细分
0000000000000000000000000000000000000000000000000000000000000001 - 1st input
0000000000000000000000000000000000000000000000000000000000000060 - 2nd input
0000000000000000000000000000000000000000000000000000000000000120 - 3rd input
0000000000000000000000000000000000000000000000000000000000000005
0000000000000000000000000000000000000000000000000000000000000006
0000000000000000000000000000000000000000000000000000000000000008
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000003
0000000000000000000000000000000000000000000000000000000000000005
0000000000000000000000000000000000000000000000000000000000000001
ff00000000000000000000000000000000000000000000000000000000000000
由于您的第二个输入具有动态长度,因此它将表示为偏移量。这里,十六进制的
60
等于 96 字节。从开头跳过 3 行(3 x 32 字节),我们得到 5
,这是数组的长度。
与第三个输入相同,十六进制的
120
等于 288 字节(9 x 32 字节)。跳过 9 行,我们得到了最终的输入。