Solidity Mapping 遍历Keys(代码)

mapping是solidity中常用的数据结构,它可以满足你大部分需要,比如 简单的key->value 的set/get/update/delete. 但是如果你想得到所有的keys或者所有的values,则没有直接API可以使用,不得不借助别的手段。本文介绍一种方法:借助数组和struct。

如果没有struct,也是可以的。

mapping(address=>uint256) balance_;
address[] balanceKeys;

只是代码会比较分散,因为每次你更新balance_都要考虑更新balanceKeys。所以为了将其模块化,应该专门用一个struct管理它。

struct MapUint
{
   mapping(uint256=>uint256)  uintMaps;
   uint256[] keys;
}

对应的,我们添加操作该struct的方法,add,subtract,get,getKeys

function get(MapUint storage self, uint256 itemId) internal view returns(uint256)
	{
		return self.uintMaps[itemId];
	}
function getKeys(MapUint storage self) internal view returns(uint256[] memory)
	{
		return self.keys;
	} 
function add(MapUint storage self, uint256 itemId, uint256 amount) internal returns(bool) {
        uint256 oldv = self.uintMaps[itemId];
        self.uintMaps[itemId] += amount;	
        if (oldv == 0 && amount > 0)       
            {
		self.keys.push(itemId);
	    }
        return true;
    }
function subtract(MapUint storage self, uint256 itemId, uint256 amount) internal returns(bool) {
        uint256 oldv = self.uintMaps[itemId];
       
        if (oldv >= amount && amount > 0) {
            self.uintMaps[itemId] -= amount;
			if(self.uintMaps[itemId] == 0)
			{
				delete self.uintMaps[itemId];
				uint256 kl = self.keys.length;
				if(kl > 1)
				{
					for(uint256 i=0;i<kl;i++)
					{
						if(itemId == self.keys[i])
						{
							self.keys[i] = self.keys[kl-1];
							break;
						}
					}
				}
				self.keys.length -= 1;
			}
			return true;
        }else {
            return false;
        }
    }

本代码片段已经在VOTEIT上使用。

发布于 2021-01-03 17:53