我正在使用 Remix 编译我的智能合约并将其部署到 Rinkeby 和 RSK 测试网络。 我不明白为什么我的合约在 Rinkeby explorer 上的字节码与 Remix 工件中的
metadata.data.deployedBytecode.object
不同,也与来自 solcjs编译器的
evm.deployedBytecode.object
不同。我也在 RSK 上尝试过,也遇到了同样的问题。
这就是我在 Remix 中所做的:
我在
MegaHonk.sol
文件夹中创建了一个 contracts
文件
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.7;
contract MegaHonk {
uint256 public count;
event LoudSound(address indexed source);
function honk() external {
require(tx.origin != msg.sender, 'EOA not allowed');
count += 1;
emit LoudSound(tx.origin);
}
}
我选择合适的编译器版本
0.8.7
,选择环境:Injected provider - Metamask
,编译并部署到Rinkeby。合约部署成功。然后我转到 Rinkeby 资源管理器,找到 我的合约字节码,并将其与 remix-file-explorer/contracts/artifacts/MegaHonk.js
属性中 metadata.data.deployedBytecode.object
中的字节码进行比较。
Rinkeby 的字节码长度为 1348 个符号 并且 Remix 中的字节码长度为 1350 个符号。
当我使用
solcjs
编译器编译相同的智能合约时,会发生完全相同的事情。我使用正确的版本 0.8.7
和这些输入参数:
const input = {
language: 'Solidity',
settings: {
outputSelection: {
'*': {
'*': ['evm.deployedBytecode', 'evm.bytecode'],
},
},
optimizer: {
enabled: false,
},
},
sources: {
'MegaHonk.sol': {
content: MegaHonk,
},
},
};
为什么会出现这种情况?我应该使用哪些编译器参数来使 Remix 工件、solcjs 编译器和区块链浏览器(以太坊或 RSK 测试网)中的字节码相同?
有几个因素会影响使用 solc 的智能合约生成的字节码,其中一个关键因素是“编译器版本”,在字节码生成过程中必须准确指定该版本。您可以使用 solc.loadRemoteVersion(solc_version, function()) 方法设置编译器版本,确保 solc 生成的字节码与网络之间的对齐。最后几个字节的细微变化归因于 CBOR。
Solc字节码:0x6080604052348015600e575f80fd5b50600436106026575f3560e01c806326121ff014602a575b5f80fd5b60306032565b005b56fea26 46970667358221220bde8b5c7708b94a5c8c09a58b47f4eaf1973f8ea7e005691d33c38191cccb1cb64736f6c63430008160033
测试网字节码:0x6080604052348015600e575f80fd5b50600436106026575f3560e01c806326121ff014602a575b5f80fd5b60306032565b005b56fea26 46970667358221220cf4e4cecb17edf7af6200f922faa4d15253849d96c544f0cc8e2525055a1995064736f6c63430008160033
字节码的最后一个字节代表 CBOR,由存储在 IPFS 上的元数据的哈希生成。即使是很小的变化也会影响元数据并随后改变 IPFS 哈希,从而影响 CBOR。此 CBOR 包括有关 solc 版本、IPFS 哈希等的信息。全面的了解可以参考下面的验证博客 使用 solc 进行智能合约验证