Solidity
為什麼編譯的solidity程式碼會對呼叫它的參數進行檢查?
我已經編譯了以下 Solidity 程式碼:
pragma solidity ^0.4.9; import "./Callee.sol"; contract Caller{ function call(address callee_address){ Callee callee = Callee(callee_address); callee.callee_function(); } }
這將成為以下 EVM: http: //pastebin.com/BeUPghsT
我不明白下面的程式碼片段。只有地址 0x1c 之後的程式碼在執行時被複製到合約的字節數組中。所以所有地址都應該比這裡所說的低 0x1c。
Address 0x1c PUSH1 0x60 PUSH1 0x40 MSTORE PUSH1 0x00 CALLDATALOAD Address 0x24 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 Address 0x42 SWAP1 DIV PUSH4 0xf55332ab EQ PUSH1 0x3a JUMPI JUMPDEST UNKNOWN OPCODE "0xFE"
CALLDATALOAD 是否將地址參數 (callee_address) 放入堆棧?
0xf55332ab
如果是這樣,如果地址的前四個字節沒有,則似乎呼叫了未知的操作碼 FE(一種停止所有執行的方法?) 。這理解正確嗎?為什麼地址要以 開頭
0xf55332ab
?乙太坊地址中沒有校驗和,對吧?我是否正確理解這是呼叫函式的地方還是這個死程式碼?
EVM 中的程式碼執行總是從 PC=0 開始。因此,您呼叫的方法將跳轉到 EVM 字節碼開頭的類似 switch 的程式碼段中。
CALLDATALOAD 不是函式“呼叫”的參數。CALLDATALOAD 是函式簽名,計算方式為
web3.sha3('call(address)').substr(0,10)
其中“call”是本例中的函式名稱,“address”是函式採用的參數類型(或參數類型,如果您願意的話)。你瞧!web3.sha3('initNumbers()').substr(0,10)=0xf55332ab
.因此,如果您在此部署的契約上使用正確的參數集呼叫“呼叫”方法以外的任何方法,則會呼叫 0xFE(停止)。換句話說:合約 EVM 的開始充當一個 switch 語句,將您發送到合約中的正確方法。這種結構稱為跳轉表。