Solidity

為什麼 Openzeppelin 的 CountersUpgradeable 庫將算術包裝在未經檢查的塊中?

  • November 29, 2021

我正在閱讀 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.
*/

自己查看該文件的舊版本:https ://github.com/OpenZeppelin/openzeppelin-contracts/blob/90ed1af972299070f51bf4665a85da56ac4d355e/contracts/utils/Counters.sol

在那裡使用未檢查的塊匹配之前沒有使用安全數學的程式碼。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 位計數器是不可能的除了物質,佔據空間以外的東西。

(我強烈建議點擊該連結,順便說一句,它既有趣又具有教育意義。)

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