如何使用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
相关产品推荐
相关产品推荐

