如何在单独部署文件中用hardhat-upgrades获取已部署代理合约
解决Hardhat Upgrades部署UUPS代理后无法用hardhat-deploy获取合约的问题
你遇到的问题核心是:用@openzeppelin/hardhat-upgrades的deployProxy部署的代理合约,不会自动被hardhat-deploy插件的部署注册表记录,所以在其他脚本里调用get(GOVERNANCE_TOKEN_NAME)时找不到对应的合约记录。
下面是三种可行的解决方法:
方法一:在部署脚本中手动注册代理合约到deployments
在部署GovernanceToken的脚本里,部署完代理合约后,调用deployments.save()将合约信息写入hardhat-deploy的注册表。修改后的部署代码如下:
const { getNamedAccounts, deployments, network } = hre const { deploy, log, get, save } = deployments // 新增save方法 const { deployer } = await getNamedAccounts() log("----------------------------------------------------") log("Deploying GovernanceToken and waiting for confirmations...") const governanceTokenContractFactory = await ethers.getContractFactory(GOVERNANCE_TOKEN_NAME); console.log(`Deploying ${GOVERNANCE_TOKEN_NAME}...`); const deployedProxy = await upgrades.deployProxy(governanceTokenContractFactory, [], { initializer: "initialize", kind: "uups", }); await deployedProxy.deployed(); console.log(`${GOVERNANCE_TOKEN_NAME} proxy deployed to: ${deployedProxy.address}`); // 新增:手动保存代理合约信息到deployments注册表 await save(GOVERNANCE_TOKEN_NAME, { address: deployedProxy.address, abi: governanceTokenContractFactory.interface.format(ethers.utils.FormatTypes.json), }); const governanceToken = await governanceTokenContractFactory.attach( deployedProxy.address );
完成这步后,在Governor部署脚本里就能正常用const governanceToken = await get(GOVERNANCE_TOKEN_NAME)获取合约信息了。
方法二:在Governor部署脚本中直接attach代理合约
如果不想修改原部署脚本,可以在Governor的部署脚本里,通过合约工厂直接attach到代理地址。你可以把代理地址存到环境变量(比如.env文件),或者从hardhat的部署输出文件里读取:
// Governor部署脚本中的代码 const governanceTokenContractFactory = await ethers.getContractFactory(GOVERNANCE_TOKEN_NAME); // 这里替换成你的代理合约地址,或者从环境变量读取 const governanceToken = governanceTokenContractFactory.attach("YOUR_PROXY_CONTRACT_ADDRESS");
如果想自动读取,也可以通过deployments.getOrNull尝试获取,或者直接读取deployments目录下的文件,但手动attach是最直接的方式。
方法三:改用hardhat-deploy自带的deployProxy方法
hardhat-deploy插件本身集成了升级部署功能,如果你改用它的deployProxy方法,部署后的合约会自动注册到deployments注册表,无需额外操作。修改原部署脚本如下:
const { getNamedAccounts, deployments, network } = hre const { deployProxy, log, get } = deployments // 改用deployProxy const { deployer } = await getNamedAccounts() log("----------------------------------------------------") log("Deploying GovernanceToken and waiting for confirmations...") const governanceToken = await deployProxy( GOVERNANCE_TOKEN_NAME, // 直接传合约名称 [], // 初始化参数 { initializer: "initialize", kind: "uups", from: deployer, } ); console.log(`${GOVERNANCE_TOKEN_NAME} proxy deployed to: ${governanceToken.address}`);
这种方式更贴合hardhat-deploy的生态,后续所有脚本都能通过get()正常获取合约。
内容的提问来源于stack exchange,提问作者Ritzy Dev
相关产品推荐
相关产品推荐

