是否有来自php的foreach功能?

时间:2018-06-16 11:25:50

标签: foreach solidity

这非常重要,所以当我进行制图时

mapping(address => uint256) balances;

我无法检查列表中的所有地址,例如

foreach(balances as address => balance) log(address + ":" + balance + "\n");

所以,如果我没有将所有地址存储在已排序的数组中,我就不能访问此数组中的任何地址,所以目前我使用这个:

  mapping(address => uint8) joiners;
  address[] members;
...
  if (joiners[_to] >= 1) {
    joiners[_to] = 1;
    members.push(_to);
  }
  balances[_to] += _value;

所以我可以这样做

uint allbalances = 0;
for(uint i; i < members.length; i++) {
allbalances = balances[members[i]];
}
return allbalances;

但这很恶心,任何人都可以找到另一个解决方案,或者像php中的foreach一样的功能

1 个答案:

答案 0 :(得分:1)

此时,您无法从实体mapping中检索所有关键字。

https://solidity.readthedocs.io/en/v0.4.24/types.html?highlight=mapping#mappings

我认为除非我们知道自己在做什么,否则避免合同中的循环是件好事。我无法理解你要从你的问题中实现的内容。如果您的目标是维持每个地址的余额以及总余额,我会做类似的事情。

contract Balance{

    mapping(address => uint) public balances;
    uint public totalBalance;

    function credit() payable public{
        balances[msg.sender] += msg.value;
        totalBalance += msg.value;
    }

    function debit(uint amount) public{
        //conditions
        require(balances[msg.sender] >= amount);

        //effects
        msg.sender.transfer(amount);
        balances[msg.sender] -= amount;
        totalBalance -= amount;
    }

}

即 - 更新单个地址余额时更新totalBalance。

根据评论部分的问题进行更新:

如果我们需要迭代所有帐户,那么我们需要单独维护密钥。我的观点是 - 总余额将比向所有账户分配利润更频繁。所以要避免循环进行总余额计算。

contract Ledger{

    address internal manager;
    mapping(address => uint) public balances;
    address[] public accounts;
    uint public totalBalance;

    constructor() public{
        manager = msg.sender;
    }

    function credit() payable public{
        if(balances[msg.sender] == 0){
            accounts.push(msg.sender);
        }

        balances[msg.sender] += msg.value;
        totalBalance += msg.value;
    }

    function debit(uint amount) public{
        //conditions
        require(balances[msg.sender] > amount);

        //effects
        msg.sender.transfer(amount);
        balances[msg.sender] -= amount;
        totalBalance -= amount;
    }

    function distributeProfit(uint amountToDistribute) public {
        require(manager == msg.sender);
        require(amountToDistribute > 0);

        //if profit might vary depends of balance, then place inside the loop.
        uint profit = amountToDistribute / accounts.length;

        for(uint index=0; index<accounts.length; index++){
            balances[accounts[index]] += profit;
        }
    }

 }