Solidity中address[] calldata参数如何用abi.encodeWithSelector正确编码
问题根因
你代码里的两个类型不匹配问题导致了编码错误:
- 传入的
["0xAddr1Here", "0xAddr2Here"]属于固定长度数组address[2]类型,和目标函数要求的动态长度address[]类型不匹配 - 地址参数加了双引号被识别为字符串,没有转为Solidity原生的
address类型
ABI编码规则只和参数的基础类型有关,和目标函数声明的calldata/memory修饰符无关,你不需要修改目标函数的参数定义,只要传入正确类型的参数即可。
正确写法
方法1:手动构造动态数组后编码
// 先构造动态长度的address数组 address[] memory c = new address[](2); c[0] = 0xAddr1Here; // 直接使用address类型字面量,不要加引号 c[1] = 0xAddr2Here; bytes memory out = abi.encodeWithSelector( bytes4(keccak256("someFunction(uint256,uint256,address[],address,uint256)")), a, b, c, 0xAddr3Here, e ); // 调用 (bool success, ) = addr.call(out); require(success, "call failed");
方法2:用abi.encodeCall简化编码(推荐)
不需要手动计算函数选择器,编译器会自动校验类型匹配度,不容易出错:
// 先定义匹配目标函数的接口,不需要实现 interface ITargetContract { function someFunction(uint a, uint b, address[] calldata c, address d, uint e) external; } // 构造动态数组 address[] memory c = new address[](2); c[0] = 0xAddr1Here; c[1] = 0xAddr2Here; // 直接编码,编译器自动处理类型匹配 bytes memory out = abi.encodeCall(ITargetContract.someFunction, (a, b, c, 0xAddr3Here, e)); (bool success, ) = addr.call(out); require(success, "call failed");
内容的提问来源于stack exchange,提问作者Якимов Герман
相关产品推荐
相关产品推荐

