Der*_*awi 3 decode ethereum solidity
我有一个仅接受字节数据的函数调用(dydx _getCallActions)
_getCallAction(bytes memory data)
Run Code Online (Sandbox Code Playgroud)
在合约执行期间,数据被传递到名为“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));
}
Run Code Online (Sandbox Code Playgroud)
我可以将数据解码为单个结构,然后有选择地将其转换为两个所需的结构,但这似乎气体效率低下
您可以将数组除以第一个结构体的总字节长度(四舍五入到乘数 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);
}
}
Run Code Online (Sandbox Code Playgroud)
输入:
# two values: `1` and `2`
0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002
Run Code Online (Sandbox Code Playgroud)
输出:
0: tuple(uint8): 1
1: tuple(uint16): 2
Run Code Online (Sandbox Code Playgroud)