# 透明可升级合约在hardhat中实现 **Published by:** [web3zoom](https://paragraph.com/@web3zoom/) **Published on:** 2025-08-05 **URL:** https://paragraph.com/@web3zoom/hardhat ## Content 1、首先安装npm包 yarn add @openzeppelin/hardhat-upgrades 2、hardhat.config.ts文件中添加配置:import "@openzeppelin/hardhat-upgrades"; 2、两个基本合约如下:// BoxV1 // SPDX-License-Identifier: MIT pragma solidity ^0.8.28; import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; contract BoxV1 is Initializable { uint public x; function initialize(uint _val) external initializer { x = _val; } function cal() external { x = x + 1; } } // BoxV2 // SPDX-License-Identifier: MIT pragma solidity ^0.8.28; import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; contract BoxV2 is Initializable { uint public x; function initialize(uint _val) external initializer { x = _val; } function cal() external { x = x * 2; } } 目标:需要将原有合约(BoxV1)升级到合约(BoxV2)。 下面则是测试脚本内容:import { time, loadFixture, } from "@nomicfoundation/hardhat-toolbox/network-helpers"; import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { expect } from "chai"; import hre from "hardhat"; describe("TPUProxy", function () { it("test_TPUProxy_Boxv1", async function () { // 分配EOA账户 const [admin] = await hre.ethers.getSigners(); console.log("admin address: " + admin.address); // 部署box1、boxv2合约 const boxv1 = await hre.ethers.getContractFactory("BoxV1"); const boxv1Instance = await hre.upgrades.deployProxy(boxv1, [1], { initializer: "initialize" }); await boxv1Instance.waitForDeployment(); // 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 console.log("proxy address: " + await boxv1Instance.getAddress()); // 获取字节码 // const creationcode = await boxv1Instance.interface.encodeFunctionData("initialize", [1]); }); it("test_TPUPProxy_Boxv2", async function () { const boxv2 = await hre.ethers.getContractFactory("BoxV2"); const boxv2Instance = await hre.upgrades.upgradeProxy( // 部署的BoxV1地址 "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", boxv2 ); await boxv2Instance.waitForDeployment(); console.log(await boxv2Instance.getAddress()); console.log(await boxv2Instance.x()); await boxv2Instance.cal(); console.log(await boxv2Instance.x()); }); }); 总结: 1、透明可升级合约的基本原理还是基于delegatecall方法进行扩展的; 2、升级合约(BoxV2)中的变量x还保留了BoxV1的状态,并且在此基础上进行方法调用和计算。 3、特点就是使用下面的方法代理合约:const boxv2Instance = await hre.upgrades.upgradeProxy( // 逻辑合约(Boxv1) "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", // 代理合约 boxv2 ); ## Publication Information - [web3zoom](https://paragraph.com/@web3zoom/): Publication homepage - [All Posts](https://paragraph.com/@web3zoom/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@web3zoom): Subscribe to updates - [Twitter](https://twitter.com/primer2011): Follow on Twitter