Solidity:将字节数据解码为两个结构

Solidity: decode byte data into two structs

我有一个只接受字节数据的函数调用 (dydx _getCallActions)

_getCallAction(bytes memory data)

在合约执行期间,数据被传递给名为“callFunction”的用户定义函数

当解码为单个结构时,它可以工作,但是我想将数据解码为两个单独的结构。

function callFunction(bytes calldata _data){
// This works, when passed in encoded data matching Struct1Type
Struct1Type memory data1 = abi.decode(_data, (Struct1Type));
}


function callFunction(bytes calldata _data){
// Doesnt work
Struct1Type memory data1, Struct2Type memory data2 = abi.decode(_data, (Struct1Type,Struct2Type));
}

我可以将数据解码为单个结构,然后有选择地将其转换为两个所需的结构,但这似乎效率低下

您可以将数组拆分为第一个结构的总字节长度,四舍五入为乘数 32 - 槽长度 - 然后分别解码每个块。

在下面的例子中,Struct1Type的长度只有8个字节,但是内存和存储槽占用了整个32字节的字。这就是我们在第 32 个索引处拆分的原因。

代码:

pragma solidity ^0.8;

contract MyContract {
    struct Struct1Type {
        uint8 number;
    }

    struct Struct2Type {
        uint16 number;
    }

    function callFunction(bytes calldata _data) external pure returns (Struct1Type memory, Struct2Type memory) {
        // `:32` returns a chunk "from the beginning to the 32nd index"
        Struct1Type memory data1 = abi.decode(_data[:32], (Struct1Type));

        // `32:` returns a chunk "from the 32nd index to the end"
        Struct2Type memory data2 = abi.decode(_data[32:], (Struct2Type));

        return (data1, data2);
    }
}

输入:

# two values: `1` and `2`
0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002

输出:

0: tuple(uint8): 1
1: tuple(uint16): 2