Solidity中“未檢查”的目的是什麼?
根據 Solidity 文件:
在 Solidity 0.8.0 之前,算術運算總是會在出現不足或溢出的情況下進行換行,從而導致廣泛使用引入額外檢查的庫。
從 Solidity 0.8.0 開始,預設情況下所有算術運算都會在上溢和下溢時恢復,因此無需使用這些庫。
要獲得先前的行為,可以使用未經檢查的塊:
來源:https ://docs.soliditylang.org/en/v0.8.0/control-structures.html#checked-or-unchecked-arithmetic
我的問題是雙重的:
- 為什麼我想要有可能導致上溢/下溢的行為?
- 我們一直在使用 SafeMath 來避免上溢/下溢問題:現在不需要了嗎?
答案 1) 我們從不希望導致上溢/下溢的行為*。“unchecked”關鍵字存在的原因是為了讓 Solidity 開發人員編寫更高效的程序。預設的“檢查”行為在添加/潛水/乘法時會消耗更多的氣體,因為在引擎蓋下,這些檢查是作為一系列操作碼實現的,在執行實際算術之前,檢查下溢/溢出並恢復如果它是檢測到。因此,如果您是 Solidity 開發人員,需要在 0.8.0 或更高版本中進行一些數學運算,並且您可以靜態確定您的算術不可能出現下溢/溢出(可能是因為您有自己的“if”語句檢查要添加的數字永遠不會大於 100),然後您可以將算術包圍在“未檢查”塊中。
tl; dr:為了節省氣體而存在“未選中”
答案 2) 正確。您不需要在使用 0.8.0 及更高版本編譯的任何合約中包含 SafeMath,因為現在編譯器實現了 SafeMath 的功能。
*我想要這種行為的唯一原因是出於教育原因:如果我正在寫一本 Solidity 介紹書並且我想展示模運算的工作原理,我希望發生下溢/溢出,這樣我就可以向學生展示它是如何工作的。
- 您可能會使用的一個原因
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++; } }
- 這是正確的。對於 pragma >= 0.8.0,SafeMath 不是必需的。