i具有以下固体功能,该功能以参数2数组,一系列股东地址和一系列赌注为参数。我将一系列股东保存在存储中,以及他们的股份地图。
如果更新的数组的大小相同,则很简单,只需用新值覆盖每个位置即可。但是,如果它们的尺寸不同,我首先要浏览整个数组并删除每个元素,然后插入新元素。我觉得这不是很有效,而且可以做得更好。
ps:我是固体的完整初学者,这是我的第一份合同,因此请随时让我知道我是否在做任何愚蠢或效率低下的事情。
谢谢!
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];
}
}
}
从理论上讲,这将起作用...不幸的是,在坚固性方面,管理阵列是一场昂贵的噩梦。根本不建议对任何数组操纵,不仅是一个阵列,而且不建议在2个阵列上进行操作。
您可以保留股东的数组...但是从那里开始,我建议创建 address->结构的映射。这样,您可以循环浏览映射的结构并包含其中的所有必要数据。
所以您的重构类似的东西:
address[] public shareholders;
struct ShareHolder {
uint stake;
// ...other awesome data here
}
mapping (address => ShareHolder) public shareholderData;
以这种方式,您有shareholders
列表。您可以直接使用shareholderData[<SHAREHOLDER ADDRESS>]
。