zoukankan      html  css  js  c++  java
  • Solidity遍历

      实际上,映射对于存储地址的标记值非常有用。 我们在许多合约中都看到了它们,它们通常以这种方式定义:

    mapping (address => uint) public users;

      由于映射是公共的,我们得到一个免费的getter,我们可以通过使用简单的方法获取myAddress的值

    users(myAddress);

      Solidity映射看起来可能类似于关联数组,但它不是,它没有索引,因此很难遍历所有地址。但它仍然可以通过其它方法遍历。

      数组更容易管理:

    address[] public addressIndices;
    // start adding address in array
    addressIndices.push(newAddress);
    ...
    // We know the length of the array
    uint arrayLength = addressIndices.length;
    for (uint i=0; i<arrayLength; i++) {
      // do something
    }

      假设我们想要计算所有地址的总值,拥有一组地址确实很有帮助。

    mapping (address => uint) public mappedUsers;
    address[] public addressIndices;
    // start adding address in array
    addressIndices.push(newAddress);
    // define mappedUsers as well
    mappedUsers[newAddress] = someValue;
    ...
    // We know the length of the array
    uint arrayLength = addressIndices.length;
    // totalValue auto init to 0
    uint totalValue;
    for (uint i=0; i<arrayLength; i++) {
      totalValue += mappedUsers[addressIndices[i]];
    }

      如果我们想要有效地删除数组怎么办? 我们必须将数组的最后位置移动到已删除的位置。

    uint indexToBeDeleted;
    mapping (address => uint) public mappedUsers;
    address[] public addressIndices;
    uint arrayLength = addressIndices.length;
    for (uint i=0; i<arrayLength; i++) {
      if (addressIndices[i] == addressToBeDeleted) {
        indexToBeDeleted = i;
        break;
      }
    }
    // if index to be deleted is not the last index, swap position.
    if (indexToBeDeleted < arrayLength-1) {
      mappedUsers[indexToBeDeleted] = mappedUsers[arrayLength-1];
    }
    // we can now reduce the array length by 1
    addressIndices--;

      参考上面的代码,假设我们不希望for循环查找要删除的地址的索引,我们需要在结构中记录项的索引。 如果我们想要做一个合适的CRUD,它会变得有点复杂。

      完整代码的示例参考如下:

    pragma solidity^0.4.17;
    
    contract Test {
        
        struct structUser {
            uint value;
            uint index;
            bool exists;
        }
    
        mapping(address => structUser) public arrayStructs;
        
        address[] public addressIndexes;
        
        function addAddress(uint _val) public returns (bool){
            // if user exists, add _val
            if (arrayStructs[msg.sender].exists > true) {
                arrayStructs[msg.sender].value += _val;
            }
            else {
                // else its new user
                addressIndexes.push(msg.sender);
                arrayStructs[msg.sender].value = _val;
                arrayStructs[msg.sender].index = addressIndexes.length-1;
                arrayStructs[msg.sender].exists = true;
            }
            return true;
        }
        
        function deleteAddress() public returns (bool) {
            // if address exists
            if (arrayStructs[msg.sender].exists) {
                structUser memory deletedUser = arrayStructs[msg.sender];
                // if index is not the last entry
                if (deletedUser.index != addressIndexes.length-1) {
                    // delete addressIndexes[deletedUser.index];
                    // last strucUser
                    address lastAddress = addressIndexes[addressIndexes.length-1];
                    addressIndexes[deletedUser.index] = lastAddress;
                    arrayStructs[lastAddress].index = deletedUser.index; 
                }
                delete arrayStructs[msg.sender];
                addressIndexes.length--;
                return true;
            }
        }
        
        function getAddresses() public view returns (address[]){
            return addressIndexes;    
        }
        
        function getTotalValue() public view returns (uint) {
            uint arrayLength = addressIndexes.length;
            uint total = 0;
            for (uint i=0; i<arrayLength; i++) {
                total += arrayStructs[addressIndexes[i]].value;
            }
            return total;
        }
        
        function getTotalUsers() public view returns (uint) {
            return addressIndexes.length;
        }
    }

      代码来源地址:https://github.com/bernardpeh/solidity-loop-addresses-demo/blob/master/loop-demo.sol

    文章来源:https://medium.com/@blockchain101/looping-in-solidity-32c621e05c22

  • 相关阅读:
    Spring读书笔记
    window.open参数详解
    在spring security3上实现验证码
    Struts2.1 标签详细说明
    总结一下log4j
    【转】hibernate映射oracle自增长
    Java中四舍五入保留七位小数
    求三个整数的最小公倍数
    boxshadow 曲线阴影和翘边阴影
    <div> <p> <span>的用法和区别
  • 原文地址:https://www.cnblogs.com/flyingeagle/p/10140270.html
Copyright © 2011-2022 走看看