You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单独部署文件中用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 20:05:46