You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者Якимов Герман

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:54:03