在 Remix 和 Ropsten 中,合约的字节码是不同的
In Remix and Ropsten, the bytecode of a contract is different
我在Remix中编译并在Ropsten上部署的合约。
pragma solidity ^0.5.11;
contract Deployer {
constructor() public {
bytes memory bytecode = hex'61000061000061000061000061006161000301610000619789f100';
assembly {
return (add(bytecode, 0x20), mload(bytecode))
}
}
}
它在 Remix 中的字节码是
{
"linkReferences": {},
"object": "6080604052348015600f57600080fd5b5060606040518060400160405280601b81526020017f61000061000061000061000061006161000301610000619789f10000000000008152509050805160208201f3fe",
"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x60 PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x1B DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x61000061000061000061000061006161000301610000619789F1000000000000 DUP2 MSTORE POP SWAP1 POP DUP1 MLOAD PUSH1 0x20 DUP3 ADD RETURN INVALID ",
"sourceMap": "28:241:0:-;;;53:213;8:9:-1;5:2;;;30:1;27;20:12;5:2;53:213:0;85:21;:83;;;;;;;;;;;;;;;;;;;238:8;232:15;225:4;215:8;211:19;203:45"
}
它的运行时字节码是
{
"linkReferences": {},
"object": "6080604052600080fdfea265627a7a7231582046db7afc80e31555b0d8a4dd3357ac5c36930b00fef8a32c2746b725244550ae64736f6c63430005110032",
"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 CHAINID 0xDB PUSH27 0xFC80E31555B0D8A4DD3357AC5C36930B00FEF8A32C2746B7252445 POP 0xAE PUSH5 0x736F6C6343 STOP SDIV GT STOP ORIGIN ",
"sourceMap": "28:241:0:-;;;;;"
}
但是当我将它部署到 Ropsten 时:https://ropsten.etherscan.io/address/0xCE1e482Bb5600f7DE9d316bcd30fb53cBAd4DcBe#code
它的字节码是
0x61000061000061000061000061006161000301610000619789f100
我想知道造成这种情况的原因是什么
Remix 字节码导出包含 bytecode
变量定义和 assembly
块 ,但未执行 constructor
- 只是编译的实际定义到字节码。
构造函数通常return是合约实例(包括其父合约和导入的库)。但在这种情况下,assembly
块强制 EVM 不是 return 合约实例,而是 return bytecode
变量的值 来自构造函数。
然后部署过程照常继续 - EVM 将构造函数 return 值(通常是合约实例,现在是 bytecode
)存储到合约存储中。
我在Remix中编译并在Ropsten上部署的合约。
pragma solidity ^0.5.11;
contract Deployer {
constructor() public {
bytes memory bytecode = hex'61000061000061000061000061006161000301610000619789f100';
assembly {
return (add(bytecode, 0x20), mload(bytecode))
}
}
}
它在 Remix 中的字节码是
{
"linkReferences": {},
"object": "6080604052348015600f57600080fd5b5060606040518060400160405280601b81526020017f61000061000061000061000061006161000301610000619789f10000000000008152509050805160208201f3fe",
"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x60 PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x1B DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x61000061000061000061000061006161000301610000619789F1000000000000 DUP2 MSTORE POP SWAP1 POP DUP1 MLOAD PUSH1 0x20 DUP3 ADD RETURN INVALID ",
"sourceMap": "28:241:0:-;;;53:213;8:9:-1;5:2;;;30:1;27;20:12;5:2;53:213:0;85:21;:83;;;;;;;;;;;;;;;;;;;238:8;232:15;225:4;215:8;211:19;203:45"
}
它的运行时字节码是
{
"linkReferences": {},
"object": "6080604052600080fdfea265627a7a7231582046db7afc80e31555b0d8a4dd3357ac5c36930b00fef8a32c2746b725244550ae64736f6c63430005110032",
"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 CHAINID 0xDB PUSH27 0xFC80E31555B0D8A4DD3357AC5C36930B00FEF8A32C2746B7252445 POP 0xAE PUSH5 0x736F6C6343 STOP SDIV GT STOP ORIGIN ",
"sourceMap": "28:241:0:-;;;;;"
}
但是当我将它部署到 Ropsten 时:https://ropsten.etherscan.io/address/0xCE1e482Bb5600f7DE9d316bcd30fb53cBAd4DcBe#code
它的字节码是
0x61000061000061000061000061006161000301610000619789f100
我想知道造成这种情况的原因是什么
Remix 字节码导出包含 bytecode
变量定义和 assembly
块 ,但未执行 constructor
- 只是编译的实际定义到字节码。
构造函数通常return是合约实例(包括其父合约和导入的库)。但在这种情况下,assembly
块强制 EVM 不是 return 合约实例,而是 return bytecode
变量的值 来自构造函数。
然后部署过程照常继续 - EVM 将构造函数 return 值(通常是合约实例,现在是 bytecode
)存储到合约存储中。