solidity - 如何在 Solidity 中将地址列表或其他函数作为字节传递?
问题描述
在 Uniswap 智能合约中有这个方法:
function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data)
我想将其称为传递地址作为数据或其他函数。
function uniswapV2Call('0x233', 1, 0, ['0x33','0x44'])
或者
function uniswapV2Call('0x233', 1, 0, anotherfunction)
有什么办法吗?
解决方案
来自另一个合约的链上调用
您可以使用abi.encode
和abi.encodePacked
将数据编码为bytes
.
pragma solidity ^0.8.0;
contract MyContract {
function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external {
}
function passArray() external {
bytes memory data = abi.encode([
address(0x33),
address(0x44)
]);
this.uniswapV2Call(address(0x233), 1, 0, data);
}
function passFuncionCall() external {
bytes memory data = abi.encodePacked(
bytes4(keccak256('anotherfunction(uint256,address)')), // function signature
abi.encode(
123, // `anotherfunction()` arguments
address(0x45)
)
);
this.uniswapV2Call(address(0x233), 1, 0, data);
}
}
abi.encode
保留每个参数的前导/尾随(取决于数据类型)零,同时abi.encodePacked
修剪它们。
所以示例中的encodePacked
andencode
的组合passFunctionCall
返回
0x
58de5f3c // function signature
000000000000000000000000000000000000000000000000000000000000007b // 1st argument
0000000000000000000000000000000000000000000000000000000000000045 // 2nd argument
如果您只encode
d 所有参数,它将为bytes4
类型留下尾随零,在这种情况下您不想要,因为接收者将读取 (hex)"64 zeros" 而不是 (hex)"7b" 作为第一个参数,另一个参数也将不正确,并且(十六进制)“45”将被忽略。
0x
58de5f3c00000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000007b
0000000000000000000000000000000000000000000000000000000000000045
// same data, just differently formatted for readability
0x
58de5f3c // function signature
0000000000000000000000000000000000000000000000000000000000000000 // 1st argument
0000000000000000000000000000000000000000000000000000007b00000000 // 2nd argument
00000000000000000000000000000000000000000000000000000045 // ignored
链下生成bytes
论点。
您可以使用web3.eth.abi.encodeParameter()例如对地址数组进行编码
const data = web3.eth.abi.encodeParameter('address[2]', ['0x0000000000000000000000000000000000000033','0x0000000000000000000000000000000000000044']);
返回
0x
0000000000000000000000000000000000000000000000000000000000000033
0000000000000000000000000000000000000000000000000000000000000044
或者您可以使用encodeFunctionCall()来获取bytes
函数调用。
const data = web3.eth.abi.encodeFunctionCall({
name: 'anotherfunction',
type: 'function',
inputs: [{
type: 'uint256',
name: ''
},{
type: 'address',
name: ''
}]
}, ['123', '0x0000000000000000000000000000000000000045']);
返回
0x
58de5f3c // function signature
000000000000000000000000000000000000000000000000000000000000007b // 1st argument
0000000000000000000000000000000000000000000000000000000000000045 // 2nd argument
推荐阅读
- javascript - 将字典转换为保留字典键的数组
- java - 尽管查询在 SQLiteStudio 中正确生成结果,但 ResultSet 返回空
- python-3.x - 即使我声明了“self”,错误“NameError: name 'self' is not defined”
- python - 将两个二维数据集组合成具有共享比例的单二维直方图矩阵
- angular - 基于下拉选择的Angular Form路由
- python - 无法选择列名列表并在 Streamlit 中查看这些列中的数据
- css - Removing a break line from the form text input
- configuration - Filebeat 中央管理替代方案
- laravel - 嵌套的雄辩关系
- dll - Uno WASM 在使用 DLL 时无法解析包