Solidity
Ethereum/Solidity 如何處理合約中的溢出?
假設我有一個類型為變數的智能合約
uint256
。我寫了一個函式來增加這個變數。EVM 如何處理試圖增加變數以儲存超過 256 位的值?
Solidity 文件說以下內容:
數字文字表達式保持任意精度,直到它們被轉換為非文字類型(即通過將它們與非文字表達式一起使用)。這意味著計算不會溢出,除法不會在數字文字表達式中截斷。
顯然它不會溢出,那它有什麼作用呢?
非文字表達式溢出。我認為“文字”表達式類似於 1223424234。我想這不會溢出,因為它甚至不會編譯。如果 a+b 大於最大的 uint256,則非文字表達式(a = 1213232; b = 121231231 – a 和 b 真的很大)將溢出。至少這是我的閱讀。
這取決於您使用的 Solidity 版本。
Solidity v0.8 及以上
預設情況下會檢查上溢和下溢。根據變更日誌:
溢出檢查非常常見,因此我們將它們設為預設值以提高程式碼的可讀性,即使它會稍微增加 gas 成本。
進一步來說:
算術溢出將使用等於函式呼叫的錯誤數據
Panic(uint256)
以及特定於情況的錯誤程式碼。因此,以下程式碼將恢復:
pragma solidity ^0.8.0; function foo() external pure returns (uint256) { uint256 a = type(uint256).max; uint256 b = 1; uint256 c = a + b; // Reverts return c; }
Solidity v0.7 及以下
預設情況下不檢查上溢和下溢。相同的程式碼片段返回 0。
pragma solidity ^0.7.0; function foo() external pure returns (uint256) { uint256 a = type(uint256).max; uint256 b = 1; uint256 c = a + b; // Does NOT revert return c; // Equal to 0 }
為確保您的程序正確執行,您應該使用像SafeMath.sol或CarefulMath.sol這樣的數學庫。