有一种可升级代理模式,允许通过将代理合约中的实现地址指向升级合约的新地址来升级智能合约。
有没有办法找到执行合约的地址?当我查看代理代码时,我看到以下内容:
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x64_bytes_string;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x64_bytes_string;
代码中似乎没有任何内容透露执行合约的地址。
_IMPLEMENTATION_SLOT
是代理合约中的内存,保存了实现的地址。要检索当前的实施合约地址,您可以读取该存储:
let proxyContract = "0x_YOUR_PROXY_CONTRACT";
let storagePosition = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
let address = await web3Client.eth.getStorageAt(proxyContract, storagePosition);
我在https://ethereum.stackexchange.com/questions/103143/how-do-i-get-the-implementation-contract-address-from-the-proxy-contract-address上发现了类似的问题 如果没有implementation().call()函数,有一个如何从代理合约获取_IMPLMENTATION_SLOT常量的指南。
一些区块浏览器(例如 Etherscan)现在提供了一种从代理合约的部署地址直接导航到代理合约实现的方法。
你可以通过 etherscan api 来完成。例如:
response = requests.post(f"https://api.etherscan.io/api?module=contract&action=getsourcecode&address={address}&apikey={apiKeyToken}")
response_json = response.json()
implementation = response_json['result'][0]['Implementation']