Evm

合約的建構子如何工作並載入輸入值?

  • September 17, 2018

我建立了以下契約:

pragma solidity ^0.4.25;

contract Simplest {
   uint x;

   constructor(bool _lucky) public {
       if (_lucky == true) {
           x = 7;
       } else {
           x = 13;
       }
   }

   function view_x() public view returns (uint) {
       return x;
   }
}

期望根據使用者提供的價值,合約會有兩條不同的路徑lucky_

當我將契約(使用 Remix)編譯為以下內容時:

608060405234801561001057600080fd5b506040516020806101068339810180604052810190808051906020019092919050505060011515811515141561004d576007600081905550610056565b600d6000819055505b5060a1806100656000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a0be66d7146044575b600080fd5b348015604f57600080fd5b506056606c565b6040518082815260200191505060405180910390f35b600080549050905600a165627a7a723058206ff308044f195baf90e204067f39262c537f89c97f293ce31132bfb1d17655c20029

或者

PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP1 PUSH2 0x106 DUP4 CODECOPY DUP2 ADD DUP1 PUSH1 0x40 MSTORE DUP2 ADD SWAP1 DUP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH1 0x1 ISZERO ISZERO DUP2 ISZERO ISZERO EQ ISZERO PUSH2 0x4D JUMPI PUSH1 0x7 PUSH1 0x0 DUP2 SWAP1 SSTORE POP PUSH2 0x56 JUMP JUMPDEST PUSH1 0xD PUSH1 0x0 DUP2 SWAP1 SSTORE POP JUMPDEST POP PUSH1 0xA1 DUP1 PUSH2 0x65 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH1 0x3F JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0xA0BE66D7 EQ PUSH1 0x44 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH1 0x4F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x56 PUSH1 0x6C JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 DUP1 SLOAD SWAP1 POP SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 PUSH16 0xF308044F195BAF90E204067F39262C53 PUSH32 0x89C97F293CE31132BFB1D17655C2002900000000000000000000000000000000 

觀察。如您所見,本契約的第一部分沒有CALLDATA相關的操作碼。

問題。合約如何能夠在_lucky不查看的情況下載入輸入值CALLDATA?建構子接收輸入值的方式與普通合約函式接收輸入值的方式不同嗎?

在 Solidity 中,參數constructor被 ABI 編碼並附加到編譯的字節碼中。使用 CODECOPY將參數複製到 EVM 記憶體

在 Etherscan 中,您可以看到合約“合約創建程式碼”的最後一個字節是 ABI 編碼的“建構子參數”。

在 Remix 的“編譯”選項卡中,“詳細資訊”部分有“字節碼”和“執行時字節碼”。當在 EVM 中執行“字節碼”(包括建構子參數)時,它會返回“執行時字節碼”。“執行時字節碼”是合約地址的區塊鏈上的內容。


請注意,EVM 沒有函式或建構子。函式是ABI的結果,這裡是 EVM 如何找到被呼叫函式的入口的範例

這個答案就是 Solidity 是如何做建構子的,而其他語言可能會以不同的方式實現合約創建。

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