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

如何使用For-Loop获取Solidity Iterable Mapping的所有值?

如何遍历Iterable Mapping的所有值

你的IterableMapping合约已经通过keys数组维护了所有存入的地址键,因此可以通过遍历这个数组来获取所有对应的余额值。以下是两种常见的实现方式:

1. 合约内添加遍历函数

直接在合约中实现批量返回所有余额的函数,内部用for循环遍历keys数组:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract IterableMapping {
    mapping(address => uint) public balances;
    mapping(address => bool) public inserted;
    address[] public keys;

    function set(address _addr, uint _bal) external {
        balances[_addr] = _bal;

        if (!inserted[_addr]) {
            inserted[_addr] = true;
            keys.push(_addr);
        }
    }

    function get(uint _index) external view returns (uint) {
        address key = keys[_index];
        return balances[key];
    }

    function first() external view returns (uint) {
        return balances[keys[0]];
    }

    function last() external view returns (uint) {
        return balances[keys[keys.length - 1]];
    }

    // 遍历所有余额并返回
    function getAllBalances() external view returns (uint[] memory) {
        uint[] memory allBalances = new uint[](keys.length);
        for (uint i = 0; i < keys.length; i++) {
            allBalances[i] = balances[keys[i]];
        }
        return allBalances;
    }

    // 可选:同时返回所有地址与对应余额
    function getAllPairs() external view returns (address[] memory, uint[] memory) {
        uint[] memory allBalances = new uint[](keys.length);
        for (uint i = 0; i < keys.length; i++) {
            allBalances[i] = balances[keys[i]];
        }
        return (keys, allBalances);
    }
}

2. 外部(如前端)遍历

如果不需要在合约内批量返回,也可以在外部通过循环调用合约的公开方法获取所有值:

示例伪代码(以ethers.js为例):

async function fetchAllBalances(contractAddress) {
    const contract = await ethers.getContractAt("IterableMapping", contractAddress);
    const totalKeys = await contract.keys.length;
    const result = [];
    
    for (let i = 0; i < totalKeys; i++) {
        const addr = await contract.keys(i);
        const balance = await contract.balances(addr);
        result.push({ address: addr, balance: balance.toString() });
    }
    return result;
}

注意事项

  • 若keys数组长度过大,遍历操作会超出区块gas限制导致失败,建议对大量数据采用分页查询的方式处理。
  • 合约中的inserted映射确保了同一地址不会被重复加入keys数组,避免了无效的重复遍历。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 15:45:57