Solidity

什麼是分發代幣的最佳方式

  • April 1, 2018

如果我創建一個代幣,然後想將其分發給 1000 人,我會擔心這些交易的 gas 價格。這就是為什麼我想分析不同的分銷選項及其內在成本。

選項 1: 分發給使用者數組的令牌中的函式

function distributeToken(address[] addresses, uint256 _value) onlyOwner {
    for (uint i = 0; i < addresses.length; i++) {
        balances[owner] -= _value;
        balances[addresses[i]] += _value;
        Transfer(owner, addresses[i], _value);
    }
}

來源:將令牌分發到多個地址

選項一的詳細說明:是否可以使用具有 1000 個不同地址的數組的參數?這將是一個非常大的參數,我很好奇汽油價格會是什麼樣子。

選項2: 使用交易所

但是,此選項非常嚴格。它將允許任何人購買硬幣,我不一定希望它們被購買,而是免費贈送給特定使用者。

問題

  • 人們是否知道其他選擇?
  • 哪個選項最合適並且消耗最少的氣體?

連結的重複問題和這個問題之間的差異:( 如何將代幣轉移給賞金參與者?

問題有明顯差異

  • 正在討論的細節。
  • 我最後還有 2 個具體問題與那個問題不同

而類似的連結問題則詢問:

  • 向賞金參與者發送符合 ERC20 標準的代幣的最佳做法是什麼?

它沒有提供最佳參考的具體標準,而我這樣做了,我還要求其他可用選項進行比較。儘管它們有相似之處,但它們並不相同。

最好的辦法

最好的方法是一個相當客觀的術語。

最具成本效益的方法肯定是在一個循環中執行它們(選項 1),儘管一次可以執行多少個地址會有限制(您可能需要執行 10 批,每批 100 個地址)。

選項 2 可能會間接減少您的 gas 費用,但仍然需要有人支付 gas,並且由於他們(可能)會一一執行,因此總的 gas 成本會更高,但由於您不會支付,也許這對你更好?

一個稍微好一點的實現:

function distributeToken(address[] addresses, uint256 _value) onlyOwner {
    uint total = _value * addresses.length;
    require(total/_value == addresses.length); // Overflow check
    require(balances[owner] >= total); // Underflow check
    balances[owner] -= total;
    for (uint i = 0; i < addresses.length; i++) {
        balances[addresses[i]] += _value;
        require(balances[addresses[i]] >= _value); // Overflow check
        Transfer(owner, addresses[i], _value);
    }
}

氣體估算:

對於典型transfer()函式的單次呼叫,每次呼叫的成本相同,這意味著對於每個地址,您將支付 23,500 天然氣。

但是,當您改為執行批量更新時,您節省了呼叫成本的成本,並且只需要支付循環和儲存等成本。在 27,947 的基本成本之後,每個地址只需要額外的 9,703 天然氣。

┌─────┬────────────┬─────────────────┐
│#│轉賬│distributeToken│
├─────┼────────────┼─────────────────┤
│ 1 │ 23,500 │ 37,650 │
│ 2 │ 47,000 │ 47,353 │
│ 3 │ 70,500 │ 57,056 │
│ 10 │ 235,000 │ 124,977 │
│ 50 │ 1,175,000 │ 513,097 │
│ 500 │ 11,750,000 │ 4,879,447 │
└─────┴────────────┴─────────────────┘

這意味著在 2 個地址之後它更便宜。

對於 8 Mgas(單個呼叫的最大值),您可以處理大約 821 個地址:

27,947 base call gas + 9,703 gas/address * 821 addresses = 7,994,110 gas

引用自:https://ethereum.stackexchange.com/questions/44434