气体减少循环

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,并且可以快速加起来。

所以除了将这些值移动到一个固定大小的数组中(当你存储未知数量的地址余额时,这在这个用例中没有多大意义),我会考虑转移交易您的用户的成本(有一个符合条件的用户列表和另一个已经使用的空投列表,让他们自己领取)。