一次性获取数组或结构体的所有数据 / 学习智能合约#52

Words
233
Reading
2 min
Listen
Play
5y

我们在获取合约中数组时一般是采用的遍历的方法,这个好像没什么太大问题。但是如果提供节点服务的供应商对访问有限速,那这种遍历的方法就挺蛋疼的。现在我看很多前端是采用的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]];
        }
    }
}

如上所示,用一个数组返回所有的数据即可。在写法上直接转换数据类型,或是用遍历的方法获取数据后一次性返回都可以实现目标。