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

Solidity合约中结构体含数组无法完整返回问题排查

问题分析与解决

问题描述

编写了一个Solidity合约存储WRequest类型的结构体数组,结构体包含address类型的receiver、address[]类型的tokenAddresss、uint256[]类型的amounts以及uint类型的approved。调用submitWithdrawRequest添加数据后,通过自动生成的WRequestList getter获取元素时,仅返回receiver和approved,缺失数组字段。

原因分析

Solidity为public数组自动生成的getter函数,对于包含动态数组的结构体,只会返回其中的非动态字段(值类型)。这是因为动态数组属于引用类型,Solidity的ABI规范限制了自动生成getter的返回逻辑,无法直接将动态数组作为返回值的一部分返回。

解决方案

手动编写自定义getter函数,完整返回结构体的所有字段,或者单独编写函数获取每个动态数组字段。推荐前者,更直观易用。

修改后的合约代码

pragma solidity ^0.8.0;

contract s {
    WRequest[] public WRequestList;

    struct WRequest {
        address receiver;
        address[] tokenAddresss;
        uint256[] amounts;
        uint approved;
    }

    function submitWithdrawRequest(address receiver, address[] memory tokenAddresss, uint256[] memory amounts) public {
        WRequest memory request = WRequest(receiver, tokenAddresss, amounts, 0);
        WRequestList.push(request);
    }

    // 自定义getter函数,返回完整的WRequest结构体
    function getWRequest(uint index) public view returns (WRequest memory) {
        return WRequestList[index];
    }
}

修改后的部署脚本

const hre = require("hardhat");

async function main() {
    const Lock = await hre.ethers.getContractFactory("s");
    const lock = await Lock.deploy();
    const [owner, account1 ,account2] = await ethers.getSigners();

    await lock.deployed();
    console.log("deployed")
    await lock.submitWithdrawRequest(owner.address, [account1.address], [7])
    // 调用自定义getter函数获取完整结构体
    const list = await lock.getWRequest(0);
    console.log(list);
}

main().catch((error) => {
    console.error(error);
    process.exitCode = 1;
});

测试结果

运行修改后的脚本,输出会包含所有字段:

{
  receiver: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
  tokenAddresss: [ '0x70997970C51812dc3A010C7d01b50e0d17dc79C8' ],
  amounts: [ BigNumber { value: "7" } ],
  approved: BigNumber { value: "0" }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 05:05:25