Solidity

Solidity中“未檢查”的目的是什麼?

  • March 14, 2022

根據 Solidity 文件:

在 Solidity 0.8.0 之前,算術運算總是會在出現不足或溢出的情況下進行換行,從而導致廣泛使用引入額外檢查的庫。

從 Solidity 0.8.0 開始,預設情況下所有算術運算都會在上溢和下溢時恢復,因此無需使用這些庫。

要獲得先前的行為,可以使用未經檢查的塊:

來源https ://docs.soliditylang.org/en/v0.8.0/control-structures.html#checked-or-unchecked-arithmetic

我的問題是雙重的:

  1. 為什麼我想要有可能導致上溢/下溢的行為?
  2. 我們一直在使用 SafeMath 來避免上溢/下溢問題:現在不需要了嗎?

答案 1) 我們從不希望導致上溢/下溢的行為*。“unchecked”關鍵字存在的原因是為了讓 Solidity 開發人員編寫更高效的程序。預設的“檢查”行為在添加/潛水/乘法時會消耗更多的氣體,因為在引擎蓋下,這些檢查是作為一系列操作碼實現的,在執行實際算術之前,檢查下溢/溢出並恢復如果它是檢測到。因此,如果您是 Solidity 開發人員,需要在 0.8.0 或更高版本中進行一些數學運算,並且您可以靜態確定您的算術不可能出現下溢/溢出(可能是因為您有自己的“if”語句檢查要添加的數字永遠不會大於 100),然後您可以將算術包圍在“未檢查”塊中。

tl; dr:為了節省氣體而存在“未選中”

答案 2) 正確。您不需要在使用 0.8.0 及更高版本編譯的任何合約中包含 SafeMath,因為現在編譯器實現了 SafeMath 的功能。

*我想要這種行為的唯一原因是出於教育原因:如果我正在寫一本 Solidity 介紹書並且我想展示模運算的工作原理,我希望發生下溢/溢出,這樣我就可以向學生展示它是如何工作的。

  1. 您可能會使用的一個原因unchecked是在遍歷數組元素時。考慮例如:
uint256 length = array.length;
for(uint256 i = 0; i < length; i++) {
 doSomething(array[i]);
}

每次i++呼叫時都會進行下溢/上溢檢查。但是我們已經i通過length,進行了約束i < length,使得這些下/溢出檢查變得不必要了。因此,我們可以像這樣重寫循環並可能節省大量氣體:

uint256 length = array.length;
for(uint256 i = 0; i < length;) {
 doSomething(array[i]);
 unchecked{ i++; }
}
  1. 這是正確的。對於 pragma >= 0.8.0,SafeMath 不是必需的。

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