abi.encode() 在 ganache 和 sepolia 中给出不同的结果,它们都没有意义

问题描述 投票:0回答:1

重现步骤 -

  1. 将以下合约部署到 Ganache 和 sepolia -
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;
    }
}
  1. 使用以下参数调用

    encodeAndDecode(uint a, uint[] memory b, bytes memory c)
    1, [6,8,1,3,5],0xff

  2. 观察发出的事件

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
不同的结果。为什么它们与我的结果不匹配?

ethereum solidity truffle ganache evm
1个回答
0
投票

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 行,我们得到了最终的输入。

© www.soinside.com 2019 - 2024. All rights reserved.