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

如何在ethers.js ABI中定义结构体数组类型的返回值

解决方案

Ethers的人类可读ABI格式默认无法识别自定义结构体名称,需要把结构体显式声明为tuple类型,有两种常用修改方案:

方案1:使用人类可读ABI(无需修改为JSON格式)

直接将返回值中的Stake[]替换为对应结构的tuple数组声明,字段顺序和类型完全和你定义的Stake结构体对齐即可,修改后的ABI如下:

const stakingAbi = [
    'function getStakes(address user) external view returns (tuple(uint16 bonusPercentage, uint40 unlockTimestamp, uint128 amount, bool withdrawn)[])',
    'function stake7Days(uint128 _amount) external whenNotPaused',
    'function stake14Days(uint128 _amount) external whenNotPaused',
    'function stake30Days(uint128 _amount) external whenNotPaused',
    'function stake90Days(uint128 _amount) external whenNotPaused'
]

调用getStakes后返回的数组每一项都会自动解析为对应字段的对象,可以直接按属性名访问。

方案2:使用标准JSON格式ABI(兼容性更强)

如果后续还有更多自定义结构体,更推荐用标准JSON ABI,getStakes对应的ABI片段如下,完整ABI可以直接从合约编译产物的abi字段复制:

{
  "inputs": [{"internalType": "address", "name": "user", "type": "address"}],
  "name": "getStakes",
  "outputs": [
    {
      "internalType": "struct Stake[]",
      "name": "",
      "type": "tuple[]",
      "components": [
        {"internalType": "uint16", "name": "bonusPercentage", "type": "uint16"},
        {"internalType": "uint40", "name": "unlockTimestamp", "type": "uint40"},
        {"internalType": "uint128", "name": "amount", "type": "uint128"},
        {"internalType": "bool", "name": "withdrawn", "type": "bool"}
      ]
    }
  ],
  "stateMutability": "view",
  "type": "function"
}

注意事项

tuple内的字段顺序必须和合约中定义的Stake结构体顺序完全一致,否则会出现数据解码错乱的问题。

内容的提问来源于stack exchange,提问作者Thimma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:24:05