Solidity

如何在不爆氣限制的情況下清空大陣?

  • May 16, 2016

正如 redditor ethererik在文章GovernMental 的 1100 ETH 頭獎支付中所發布的那樣,因為它使用了太多的氣體,1,100 個乙太幣被困在了邊緣,因為這個 GovernMental 金字塔計劃的支付需要清除包含債權人地址和金額的數組。隨著每個債權人將他們的乙太幣添加到這個金字塔計劃中,這個數組已經增長。清除相關數組的程式碼如下:

creditorAddresses = new address[](0);
creditorAmounts = new uint[](0);

在不破壞氣體限制的情況下清除大型陣列的最佳方法是什麼?

是 live.ether.camp 上的停滯合約(來自romanmandeleil的連結)。

是智能合約程式碼和網站的連結。

最好的方法就是不清除它們。在許多(大多數?)情況下,數組的大小會隨著時間的推移而變化,並且最終會再次填充清空的插槽。不要縮短數組,而是單獨計算活動元素:

uint numElements = 0;
uint[] array;

function insert(uint value) {
   if(numElements == array.length) {
       array.length += 1;
   }
   array[numElements++] = value;
}

function clear() {
   numElements = 0;
}

這意味著刪除的元素保留在數組中,但被忽略,因為您可以numElements在任何地方使用array.length

這也總體上節省了氣體;刪除和重新插入一個項目到一個數組需要 5k(刪除)- 10k(退款)+ 20k(重新插入)= 10k 淨氣體,再加上另外 10k 來更新數組長度兩次。相比之下,重寫只需要 5k gas,再加上相同的 10k 來更新numElements變數兩次。

如果數組只被擦除一次,並且不會再次增長,一個更明智的選擇可能是在事件的生命週期內生成一個新合約,並讓它在最後殺死自己,這將為所有人返還 gas呼叫者的實時儲存元素。

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