Evm

獨立組裝契約:控制流錯誤

  • December 4, 2017

我試圖理解為什麼以下玩具契約不起作用。我可以部署成功,少於 36 字節數據的事務成功,但包含 36 字節或更多字節的事務失敗。我希望任何輸入大小都不會出現故障。

{
 codecopy(0x0, 0x0, codesize())
 return(0xD, sub(codesize(), 0xD))

 if lt(calldatasize(), 0x24) {
   stop
 }

 if lt(calldatasize(), 0x84) {
   stop
 }

 stop
}

字節碼:386000600039600d3803600df36024361015601657005b6084361015602057005b00

問題是在您部署/執行時的字節碼中,跳轉目的地是錯誤的。我不認為彙程式序期望在那裡找到建構子,因此它不考慮跳轉目標中的 13 字節移位。

這是執行時反彙編。您可以看到跳躍是 0xd 關閉。

0000  PUSH1 0x24
0002  CALLDATASIZE
0003  LT
0004  ISZERO
0005  PUSH1 0x16  <-- should be 0x09
0007  JUMPI

0008  STOP

0009  JUMPDEST
000a  PUSH1 0x84
000c  CALLDATASIZE
000d  LT
000e  ISZERO
000f  PUSH1 0x20  <-- should be 0x13
0011  JUMPI

0012  STOP

0013  JUMPDEST
0014  STOP

如果你想探索這種東西,我推薦 LLL。當您從原始碼建構 Solidity 時,可以使用 LLL 編譯器。您的契約的 LLL 等價物如下:

(returnlll
 (seq
   (when (lt (calldatasize) 0x24) (stop))
   (when (lt (calldatasize) 0x84) (stop))
   (stop)))

上面的returnlll表達式是一個宏,在呼叫編譯器時考慮了建構子/部署程式碼,所以不會出現這個問題。

您可以在此處找到 LLL 文件。

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