Evm
為什麼 Solidity throw 會消耗所有氣體?
當你
throw
出現異常時,所有的gas都被消耗掉了。這個設計決策的基本原理是什麼?
所有的 gas 都被消耗掉了,因為 EVM 基本上只有一個例外:Out of Gas。
為了更清楚地了解這一點,請查看“純”異常與由於錯誤/錯誤/無效 EVM 程式碼導致的錯誤之間的區別。Out of Gas 是前者。現在有棧下溢、無效的跳轉、無效的操作碼等錯誤:它們可以稱為“異常”,但它們更像是錯誤而不是EVM異常,因為合約的開發者沒有按照規則編寫有效的EVM程式碼的 EVM。例如,無效的操作碼就像在 Javascript 中寫“類”而不是“函式”:原生 Javascript 沒有“類”,這與 Java 等語言不同。對於堆棧下溢,就像開發人員告訴 EVM 添加 2 個數字,但開發人員沒有提供第 2 個數字。
還要注意 EVM 中的“異常”與其他語言有何不同。例如,EVM 中沒有除零異常(儘管 Solidity 0.4+ 會為此生成異常)。假設 EVM 程式碼有效,除了 Out of Gas 沒有例外。
由於只有一個 Out of Gas 異常,因此這些其他錯誤表現為 Out of Gas。這與乙太坊的一些泛化和最小化複雜性的設計原則相對一致。換句話說,在實現堆棧下溢、無效跳轉和無效操作碼的行為時,協議重用 Out of Gas 的實現和行為更加簡單和容易。
其他答案已經解釋了 Solidity 如何編譯
throw
為無效的 JUMP。(Serpent 改為使用無效的操作碼,並呼叫它invalid
而不是throw
.)編輯:拜占庭版本包括EIP 140
REVERT
,一個在 EVM 中命名的新操作碼:提供了一種停止執行和恢復狀態更改的方法,而無需消耗所有提供的氣體並能夠返回原因。