Solidity

為什麼 throwrevert() 創建不同的字節碼?

  • November 15, 2017

throw並且revert()都在編譯revert操作(操作碼0xfd)。根據文件

throw 關鍵字也可以用作revert() 的替代方法。

那麼為什麼下面的契約

contract test {
   function () {
       throw;
       //revert();
   }
}

revert()如果我使用而不是上面的範例會產生不同的字節碼throw?我正在使用帶有 Solidity 0.4.13+commit.0fb4cb1a.Emscripten.clang 的 Remix。這些是生成的操作碼:

using throw:    PUSH1 0x60 PUSH1 0x40 MSTORE CALLVALUE ISZERO PUSH1 0xE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST JUMPDEST PUSH1 0x47 DUP1 PUSH1 0x1C PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x60 PUSH1 0x40 MSTORE JUMPDEST CALLVALUE ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x19 JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST JUMP JUMPDEST STOP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0x4a PUSH32 0x5473469C00A2379987B5AF61DFF50F8FABE3B71589C4D2BBB53073BEB9D10029 
using revert(): PUSH1 0x60 PUSH1 0x40 MSTORE CALLVALUE ISZERO PUSH1 0xE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST JUMPDEST PUSH1 0x47 DUP1 PUSH1 0x1C PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x60 PUSH1 0x40 MSTORE JUMPDEST CALLVALUE ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x19 JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST JUMP JUMPDEST STOP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0x5f 0xef 0xc4 0xac 0x4c STATICCALL DUP15 TIMESTAMP CODECOPY PUSH10 0x17070269221C62F6F5D4 0xba 0xe1 BALANCE BYTE 0xf7 EQ 0xca SWAP6 SWAP13 0xd0 0x27 0x24 STOP 0x29 

我們看到最後的指令是不同的。而throw結束的版本

0x627A7A723058
KECCAK256
0x4a
PUSH32
0x5473469C00A2379987B5AF61DFF50F8FABE3B71589C4D2BBB53073BEB9D10029

revert()結束的版本

0x627A7A723058
KECCAK256
0x5f
0xef
0xc4
0xac
0x4c
STATICCALL
DUP15
TIMESTAMP
CODECOPY
PUSH10
0x17070269221C62F6F5D4
0xba
0xe1
BALANCE
BYTE
0xf7
EQ
0xca
SWAP6
SWAP13
0xd0
0x27
0x24
STOP
0x29

我會將 OpCode 的精確解釋留給其他人,並指出它們是不同的指令,因此可以預期不同的實現。

據此:http ://solidity.readthedocs.io/en/develop/control-structures.html#error-handling-assert-require-revert-and-exceptions

從 Metropolis 開始,revert;將返回未使用的 gas,而throw將繼續消耗所有可用的 gas。就合約狀態變化而言,它們是相同的——一切都會回滾。

希望能幫助到你。

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