我们在获取合约中数组时一般是采用的遍历的方法,这个好像没什么太大问题。但是如果提供节点服务的供应商对访问有限速,那这种遍历的方法就挺蛋疼的。现在我看很多前端是采用的multicall的方法,就是直接一次到位,获取所有的数据。这个遍历的过程是直接在合约层就完成,节点只需访问一次就可得到所有数据。看了下multicall,然后在合约中也尝试用这种方法来一次获取到所有的数据。如下合约:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract List{
struct Delegator {
uint256 amount;
uint256 rewardDebt;
bool hasDeposited;
string hiveAccount;
}
mapping(address => Delegator) public delegators;
address[] public delegatorList;
function update(string memory _hiveAccount, address _delegator, uint256 _amount) external {
delegators[_delegator].amount = _amount;
delegators[_delegator].rewardDebt = 0;
delegators[_delegator].hasDeposited = true;
delegators[_delegator].hiveAccount = _hiveAccount;
delegatorList.push(_delegator);
}
function setDelegator(address _delegator) external {
delegatorList.push(_delegator);
}
//一次获取所有的代理人
function getDelegators() external view returns(address[] memory){
address[] memory delegatorLists = delegatorList;
return delegatorLists;
}
//一次获取所有代理人的结构体数据
function getDelegatorsInfo() external view returns (Delegator[] memory returnData){
returnData = new Delegator[](delegatorList.length);
for(uint256 i = 0; i < delegatorList.length; i ++){
returnData[i] = delegators[delegatorList[i]];
}
}
}
如上所示,用一个数组返回所有的数据即可。在写法上直接转换数据类型,或是用遍历的方法获取数据后一次性返回都可以实现目标。