如何编写函数从以太坊区块链获取dapp全部已注册用户列表
实现方案
Solidity 中的 mapping 本身不支持遍历,你现有的合约仅存储了单个地址的注册状态,没有存储全量注册地址的集合,因此无法直接通过现有变量查询到所有已注册用户,需要先调整合约存储结构:
第一步:新增状态变量存储全量注册地址
在合约的状态变量部分新增一个动态数组,用来记录所有注册过的用户地址:
address[] public allRegisteredUsers;
第二步:修改注册逻辑,新增地址入库逻辑
修改checkUser函数,当用户首次完成注册时,将地址写入全量用户数组:
function checkUser(address _address) public{ if(!registerd[_address]){ registerd[_address] = true; allRegisteredUsers.push(_address); } }
第三步:编写查询函数
可以根据你的业务场景选择不同的查询实现:
- 场景1:用户规模较小,直接返回全量用户列表
function getAllRegisteredUsers() public view returns(address[] memory) { return allRegisteredUsers; }
调用该函数即可直接获取所有已注册用户的地址数组,再结合你已有的单个用户查询接口,就能拿到所有用户的详细信息。
- 场景2:用户规模较大,避免gas超限使用分页查询
如果用户量过多时,单次返回全量数组会超出区块gas限制,可实现分页查询接口:
function getRegisteredUsersByPage(uint256 offset, uint256 limit) public view returns(address[] memory) { require(offset + limit <= allRegisteredUsers.length, "查询范围超出总用户数量"); address[] memory pageResult = new address[](limit); for(uint256 i = 0; i < limit; i++) { pageResult[i] = allRegisteredUsers[offset + i]; } return pageResult; }
入参offset为分页起始下标,limit为单次查询的用户数量。
特殊情况说明
如果你的合约已经部署上链无法修改存储结构,可以通过链下扫描合约历史交易/事件日志的方式,统计所有调用过checkUser或sendMail方法的地址,去重后即可得到全量已注册用户列表。
内容的提问来源于stack exchange,提问作者george singh
相关产品推荐
相关产品推荐

