本文探讨了Etherscan上已部署和验证的智能合约显示的字节码内容。通过实验对比,发现Etherscan显示的并非仅是运行时字节码,而是完整的字节码(创建代码+运行时代码),并附加构造函数参数(如果存在)。此外,未验证的合约在Etherscan上仅显示运行时字节码。
这将是一篇关于 Etherscan 如何显示已部署和验证的智能合约字节码的一些发现的简短文章。
在以太坊区块链上部署合约之后,我们确切地知道创建代码(初始化代码)会被执行,并返回运行时字节码,然后将其存储在链上。
必须注意的是,只有智能合约的运行时字节码才会被存储在链上,以便进一步执行智能合约。
但是,这里有一个快速的问题:
当我们在以太坊上部署一个智能合约并在 Etherscan 上验证它时,附加到已验证合约上的字节码到底是什么?
这个问题的非常直观的答案是 运行时字节码,因为这是存储在链上的字节码部分。因此,很容易假设 Etherscan 仅显示运行时字节码。
好吧,情况似乎并非如此。
所以问题仍然存在 - 我们在 Etherscan 上看到的字节码到底是什么?
让我们做一个快速实验来弄清楚。
我们将要部署 2 个不同的合约:
我们使用以下测试合约 👇
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
/**
* @title Test
* @dev Sets and Gets a uint variable called Pointer
*/
contract Test{
uint256 public pointery;
constructor() {
pointery = 100;
}
function setPointer(uint256 _num) public {
pointery = _num;
}
/**
* @dev Return owner address
* @return address of owner
*/
function getPointer() external view returns (uint256) {
return pointery;
}
}
没有构造函数参数的测试合约
实际创建代码
创建代码
608060405234801561001057600080fd5b50606460008190555061017f806100286000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea264697066735822122095cb79f37fbcae031f3faea184aa57e0c8cd49ed26e7a6d17a48cf3858e56d9f64736f6c63430008110033
实际运行时代码
运行时字节码
608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea264697066735822122095cb79f37fbcae031f3faea184aa57e0c8cd49ed26e7a6d17a48cf3858e56d9f64736f6c6343000811003300
合约验证后 Etherscan 的字节码
608060405234801561001057600080fd5b50606460008190555061017f806100286000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea264697066735822122095cb79f37fbcae031f3faea184aa57e0c8cd49ed26e7a6d17a48cf3858e56d9f64736f6c63430008110033
我们使用以下测试合约 👇 并传递 1000 作为参数。
/**
*Submitted for verification at Etherscan.io on 2023-02-15
*/
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
/**
* @title Test
* @dev Sets and Gets a uint variable called Pointer
*/
contract Test{
uint256 public pointer;
constructor(uint256 _num) {
pointer = _num;
}
function setPointer(uint256 _num) public {
pointer = _num;
}
/**
* @dev Return owner address
* @return address of owner
*/
function getPointer() external view returns (uint256) {
return pointer;
}
}
带有 1 个构造函数参数的测试合约
实际创建代码
0x608060405234801561001057600080fd5b506040516102353803806102358339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b61017f806100b66000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea2646970667358221220e258c2c50f60615be13c1352bb92ad8365dcb6b971ca21882a504f1beb4167fc64736f6c6343000811003300000000000000000000000000000000000000000000000000000000000003e8
实际运行时代码
608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea2646970667358221220e258c2c50f60615be13c1352bb92ad8365dcb6b971ca21882a504f1beb4167fc64736f6c6343000811003300
合约验证后 Etherscan 的字节码
608060405234801561001057600080fd5b506040516102353803806102358339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b61017f806100b66000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea2646970667358221220e258c2c50f60615be13c1352bb92ad8365dcb6b971ca21882a504f1beb4167fc64736f6c6343000811003300000000000000000000000000000000000000000000000000000000000003e8
在上述部署和实际字节码与 Etherscan 字节码的字节码比较之后,以下是我遇到的发现:
因此,从技术上讲,Etherscan 显示:
初始化代码(在合约部署期间执行)+ 运行时代码(存储在链上的部分)+ 构造函数参数
一个额外的细节:尚未在 Etherscan 上验证的智能合约的字节码只是运行时字节码。
- 原文链接: decipherclub.com/does-et...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!