如何在Solidity中有效地替换存储阵列?

时间:2018-02-06 15:53:12

标签: arrays ethereum solidity

我在Solidity中有以下函数,它将参数作为参数2个数组,一个股东地址数组和一系列赌注。我在存储中保留了一系列股东,并附上了他们的股份图。

如果更新的数组大小相同,则很简单,只需用新值覆盖每个位置即可。但是,如果它们的大小不同,我首先遍历整个数组并删除每个元素,然后插入新元素。我觉得这不是很有效,可以做得更好。

PS:我是Solidity的完全初学者,这是我的第一份合同,所以如果我做任何愚蠢或低效的事情,请随时告诉我。

谢谢!

function setShareholders(address[] _shareholders, uint256[] _stakes) public onlyCEO {
    require(_shareholders.length > 0);
    require(_shareholders.length == _stakes.length);
    uint256 accummulator = 0;
    for(uint8 x = 0; x < _stakes.length; x++){
      require(_addressNotNull(_shareholders[x]));
      require(_stakes[x] > 0 && _stakes[x] <= 100);
      accummulator = SafeMath.add(accummulator, _stakes[x]);
    }
    if(accummulator == 100){ // stakes need to add up to 100%
      _setShareholders(_shareholders, _stakes);
    }
  }

function _setShareholders(address[] _shareholders, uint256[] _stakes) private {
    if(_shareholders.length == shareholders.length){
      for(uint8 x = 0; x < shareholders.length; x++) {
        shareholders[x] = _shareholders[x];
        shareholderToStake[_shareholders[x]] = _stakes[x];
      }
    }
    else {
      for(x = 0; x < shareholders.length; x++) {
        delete shareholders[x];
        shareholders.length--;
        delete shareholderToStake[shareholders[x]];
      }
      for(x = 0; x < _shareholders.length; x++) {
        shareholders.push(_shareholders[x]);
        shareholderToStake[_shareholders[x]] = _stakes[x];
      }
    }
  }

1 个答案:

答案 0 :(得分:1)

从理论上讲,这样可行......不幸的是,管理阵列是一项代价高昂的噩梦。不推荐对任何数组进行操作,而不仅仅是一个数组操作,而不是2个数组。

您可以保留一系列股东......但是从那里开始,我建议您创建地址 - &gt;结构的映射。这样,您就可以遍历映射的结构并包含其中的所有必要数据。

对于你的重构来说是这样的:

address[] public shareholders;

struct ShareHolder {
  uint stake;
  // ...other awesome data here
}

mapping (address => ShareHolder) public shareholderData;

这样,您就拥有了shareholders列表。您可以使用shareholderData[<SHAREHOLDER ADDRESS>]直接访问股东。