為什麼 Openzeppelin 的 CountersUpgradeable 庫將算術包裝在未經檢查的塊中?
我正在閱讀 Openzeppelin 的CountersUpgradeable 庫 v4.3.0的原始碼,並意識到遞增/遞減函式中的算術運算是由一個未經檢查的塊包裝的。據我了解,未經檢查的塊將允許上溢/下溢的情況,所以這不是一個壞主意嗎?
tl; dr,(
uint256 - 1
最大的 uint256,因此您必須達到溢出的數字)的大小是如此之大,以至於如果我們設計一個從 0 開始並且必須每次增加 1 的 uint區塊鏈,即使你編寫一個由超新星以最高效率執行的無限循環,你也無法到達那裡。因此,對 +1 遞增 uint256 值的溢出檢查實際上是浪費氣體。
更多詳情:
如果您查看添加此特定未檢查塊的歷史記錄,這是為了使 0.8 程式碼與 0.7 程式碼保持一致。我們可以在 0.7 版本的程式碼中看到這條註釋,解釋了為什麼當時他們沒有使用 safemath 進行遞增:
/** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath} * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */
在那裡使用未檢查的塊匹配之前沒有使用安全數學的程式碼。uint256 上的溢出不是問題,基本上是這樣,而且做未經檢查的數學更便宜。
(可悲的是,他們刪除了這個解釋性說明,這是一個自然而然會看到這個文件的合理問題。)
為什麼加一就不能溢出?更多 OZ:https ://forum.openzeppelin.com/t/counters-sol-increment-does-not-need-overflow-protection/1375
由於以下原因,不可能以 1 的增量溢出 256 位整數:釋義 > https://security.stackexchange.com/a/82412:在電腦由某種東西建構之前,15 個溢出的 256 位計數器是不可能的除了物質,佔據空間以外的東西。
(我強烈建議點擊該連結,順便說一句,它既有趣又具有教育意義。)