Blockchain 可解性:遍历地址映射
我正在寻找一种方法,在Solidity中遍历映射。例如,我有以下映射:Blockchain 可解性:遍历地址映射,blockchain,ethereum,solidity,smartcontracts,ether,Blockchain,Ethereum,Solidity,Smartcontracts,Ether,我正在寻找一种方法,在Solidity中遍历映射。例如,我有以下映射: 映射(地址=>uint)私人股份 我想在一个函数中迭代所有的地址,并根据它们的份额发送它们 比如: function giveOutEth() onlyOwner returns (bool success){ for(uint i=0; i < shares.length ; i++){ //get the address and send a value } 函数giveoutth()onlyOwner返回(bo
映射(地址=>uint)私人股份代码>
我想在一个函数中迭代所有的地址,并根据它们的份额发送它们
比如:
function giveOutEth() onlyOwner returns (bool success){
for(uint i=0; i < shares.length ; i++){
//get the address and send a value
}
函数giveoutth()onlyOwner返回(bool success){
对于(uint i=0;i
}
我怎样才能做到这一点
谢谢我收到了莱克斯博士的答复:
contract Holders{
uint _totalHolders; // you should initialize this to 0 in the constructor
mapping (uint=> address ) private holders;
mapping (address => uint) private shares;
function GetShares(uint shares) public {
...
holders[_totalHolders] = msg.sender;
shares[msg.sender] = shares;
_totalHolders++;
...
}
function PayOut() public {
...
uint shares;
for(uint i = 0 ; i<_totalHolders; i++) {
shares = shares[holders[i]];
...
}
...
}
合同持有人{
uint _totalHolders;//应该在构造函数中将其初始化为0
映射(uint=>地址)私人持有者;
映射(地址=>uint)私人股份;
功能GetShares(uint shares)public{
...
持有者[_totalHolders]=消息发送者;
股份[msg.sender]=股份;
_totalHolders++;
...
}
函数PayOut()公共{
...
uint股份;
对于(uint i=0;i如果您想要更一般的东西,您可以使用一个库。我在下面使用了一个库。它可能需要一些改进(即,元素
应该更改为一个接口),而且可能有点过分(另外,TBH我还没有做任何气体消耗比较).来自一个更面向对象的背景,我更喜欢使用这样的可重用库,但鉴于Solidity的局限性,这是我能想到的最好的方法
请随意使用和/或改进它
pragma solidity ^0.4.19;
pragma experimental "ABIEncoderV2";
// experimental encoder needed due to https://github.com/ethereum/solidity/issues/3069
library SetLib {
using SetLib for Set;
struct Set {
mapping(address => IndexData) _dataMap;
uint16 _size;
IndexData[] _dataIndex;
}
struct IndexData {
uint16 _index;
bool _isDeleted;
Element _element;
}
struct Element {
address _value;
uint8 _status;
}
function add(Set storage self, Element element) internal returns (bool) {
if (element._value == 0x0 || self.contains(element)) {
return false;
}
IndexData memory data;
data._index = uint16(self._dataIndex.length);
data._element = element;
self._dataMap[element._value] = data;
self._dataIndex.push(data);
self._size++;
return true;
}
function update(Set storage self, Element element) internal {
if (element._value != 0x0) {
IndexData storage data = self._dataMap[element._value];
if (data._element._value == element._value && !data._isDeleted && element._status != data._element._status)
data._element._status = element._status;
}
}
function getByIndex(Set storage self, uint16 index) internal constant returns (Element) {
IndexData storage data = self._dataIndex[index];
if (!data._isDeleted) {
return data._element;
}
}
function get(Set storage self, address addr) internal constant returns (Element) {
IndexData storage data = self._dataMap[addr];
if (!data._isDeleted) {
return data._element;
}
}
function contains(Set storage self, Element element) internal constant returns (bool) {
return self.contains(element._value);
}
function contains(Set storage self, address addr) internal constant returns (bool) {
if (addr != 0x0) {
IndexData storage data = self._dataMap[addr];
return data._index > 0 && !data._isDeleted;
}
return false;
}
function remove(Set storage self, uint16 index) internal returns (Element) {
IndexData storage data = self._dataIndex[index];
if (data._element._value != 0x0 && !data._isDeleted) {
data._isDeleted = true;
self._size--;
return data._element;
}
}
function remove(Set storage self, address addr) internal returns (Element) {
if (addr != 0x0) {
IndexData storage data = self._dataMap[addr];
if (data._element._value != 0x0 && !data._isDeleted) {
data._isDeleted = true;
self._size--;
return data._element;
}
}
}
function size(Set storage self) internal constant returns (uint16) {
return self._size;
}
}
library IteratorLib {
using SetLib for SetLib.Set;
struct Iterator {
bool _started; // using bool instead of making _curIndex int32 for initial state.
uint16 _curIndex;
uint16 _size;
}
function iterator(SetLib.Set storage set) internal constant returns (IteratorLib.Iterator) {
return IteratorLib.Iterator(false, 0, set.size());
}
function hasNext(Iterator self, SetLib.Set storage set) internal constant returns (bool) {
uint16 testIndex = self._curIndex;
while (testIndex < self._size) {
if (set._dataIndex[testIndex]._element._value != 0x0 && !set._dataIndex[testIndex]._isDeleted)
return true;
testIndex++;
}
return false;
}
function next(Iterator self, SetLib.Set storage set) internal constant returns (SetLib.Element) {
SetLib.Element memory element;
do {
if (self._started) {
self._curIndex++;
}
else {
self._started = true;
}
element = set.getByIndex(self._curIndex);
}
while (element._value != 0x0 && self._curIndex < self._size);
return element;
}
}
pragma-solidity^0.4.19;
布拉格实验“ABIRV2”;
//由于https://github.com/ethereum/solidity/issues/3069
库SetLib{
使用SetLib进行Set;
结构集{
映射(地址=>IndexData)\数据映射;
uint16_尺寸;
IndexData[]\u数据索引;
}
结构索引数据{
uint16指数;
布卢被删除;
元素_元素;
}
结构元素{
地址_值;
uint8_状态;
}
函数添加(设置存储自身、元素)内部返回(bool){
if(元素._值==0x0 | | self.contains(元素)){
返回false;
}
索引数据存储数据;
data.\u index=uint16(self.\u dataIndex.length);
数据。_元素=元素;
self.\u dataMap[元素.\u值]=数据;
self.\u dataIndex.push(数据);
自身尺寸++;
返回true;
}
功能更新(设置存储器自身、元件)内部{
if(元素值!=0x0){
IndexData存储数据=self.\u数据映射[元素.\u值];
if(数据元素值==元素值数据元素状态!=数据元素状态)
数据。_元素。_状态=元素。_状态;
}
}
函数getByIndex(设置存储自身,uint16索引)内部常量返回(元素){
IndexData存储数据=self.\u数据索引[索引];
如果(!data.\u被删除){
返回数据。\u元素;
}
}
函数get(设置存储器自身,地址addr)内部常量返回(元素){
IndexData存储数据=self.\u数据映射[addr];
如果(!data.\u被删除){
返回数据。\u元素;
}
}
函数包含(设置存储自身、元素)内部常量返回(bool){
返回self.contains(元素值);
}
函数包含(设置存储器自身、地址addr)内部常量返回(bool){
如果(地址!=0x0){
IndexData存储数据=self.\u数据映射[addr];
返回数据。_索引>0&!数据。_被删除;
}
返回false;
}
函数删除(设置存储自身,uint16索引)内部返回(元素){
IndexData存储数据=self.\u数据索引[索引];
if(数据元素值!=0x0&&!数据已删除){
数据。_isDeleted=true;
自身大小--;
返回数据。\u元素;
}
}
函数删除(设置存储器自身、地址地址)内部返回(元素){
如果(地址!=0x0){
IndexData存储数据=self.\u数据映射[addr];
if(数据元素值!=0x0&&!数据已删除){
数据。_isDeleted=true;
自身大小--;
返回数据。\u元素;
}
}
}
函数大小(设置存储自身)内部常量返回(uint16){
返回自身大小;
}
}
库迭代器lib{
对SetLib.Set使用SetLib;
结构迭代器{
bool _start;//使用bool而不是将_curindexint32作为初始状态。
uint16_curIndex;
uint16_尺寸;
}
函数迭代器(SetLib.Set存储集)内部常量返回(IteratorLib.iterator){
返回IteratorLib.Iterator(false,0,set.size());
}
函数hasNext(迭代器self,SetLib.Set存储集)内部常量返回(bool){
uint16 testIndex=自身.\u curIndex;
而(测试索引<自身大小){
如果(设置数据索引[testIndex]。\u元素值!=0x0&&!设置数据索引[testIndex]。\u已删除)
返回true;
testIndex++;
}
返回false;
}
函数next(迭代器self,SetLib.Set存储集)内部常量返回(SetLib.Element){
元素记忆元素;
做{
如果(自启动){
self._curIndex++;
}
否则{
self.\u start=true;
}
元素=set.getByIndex(self.\u curIndex);
}
while(element.\u value!=0x0&&self.\u curIndex