气体减少循环
gas reduce on loops
我有一个功能需要向很多账户发送代币。
我知道对商店的写操作非常昂贵。
我读过在存储上进行计算时,最好在内存变量上进行计算,然后将此内存变量设置到存储中,从而保存对存储的写操作。
所以我想做的是这样的事情
mapping (address => uint256) private _balances;
function addToBalance(address[] memory accounts,uint[] memory amounts) public{
mapping (address => uint256) memory balances = _balances;
for(uint i=0;i<accounts.length;i++){
balances[accounts[i]]+=amounts[i];
}
_balances = balances;
}
_balances 映射会变得相当大。那么它真的是降低成本的更好方法吗?
没有映射。
映射(和动态大小数组)值都“分散”在不同的存储槽中。插槽位置是可确定的,但是因为它们是基于哈希计算的,所以键 1
的值可以在存储槽 123456789
中,键 2
的值可以在存储槽中5
。 (这些数字只是为了展示一个简单的例子。)
这意味着,当您将 N
值保存到映射中时(在 N
键下),您始终需要写入(相同数量)N
存储槽.写入一个(256 位)插槽需要 5,000 gas,并且可以快速加起来。
所以除了将这些值移动到一个固定大小的数组中(当你存储未知数量的地址余额时,这在这个用例中没有多大意义),我会考虑转移交易您的用户的成本(有一个符合条件的用户列表和另一个已经使用的空投列表,让他们自己领取)。
我有一个功能需要向很多账户发送代币。 我知道对商店的写操作非常昂贵。 我读过在存储上进行计算时,最好在内存变量上进行计算,然后将此内存变量设置到存储中,从而保存对存储的写操作。
所以我想做的是这样的事情
mapping (address => uint256) private _balances;
function addToBalance(address[] memory accounts,uint[] memory amounts) public{
mapping (address => uint256) memory balances = _balances;
for(uint i=0;i<accounts.length;i++){
balances[accounts[i]]+=amounts[i];
}
_balances = balances;
}
_balances 映射会变得相当大。那么它真的是降低成本的更好方法吗?
没有映射。
映射(和动态大小数组)值都“分散”在不同的存储槽中。插槽位置是可确定的,但是因为它们是基于哈希计算的,所以键 1
的值可以在存储槽 123456789
中,键 2
的值可以在存储槽中5
。 (这些数字只是为了展示一个简单的例子。)
这意味着,当您将 N
值保存到映射中时(在 N
键下),您始终需要写入(相同数量)N
存储槽.写入一个(256 位)插槽需要 5,000 gas,并且可以快速加起来。
所以除了将这些值移动到一个固定大小的数组中(当你存储未知数量的地址余额时,这在这个用例中没有多大意义),我会考虑转移交易您的用户的成本(有一个符合条件的用户列表和另一个已经使用的空投列表,让他们自己领取)。