# UUPS在hardhat中的实现 **Published by:** [web3zoom](https://paragraph.com/@web3zoom/) **Published on:** 2025-08-05 **URL:** https://paragraph.com/@web3zoom/uups-hardhat ## Content 1、创建两个文件UUPSV1和UUPSV2// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.28; import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract UUPSV1 is Initializable, UUPSUpgradeable, OwnableUpgradeable { uint public x; function _authorizeUpgrade(address implementation) internal override {} function initialize(uint _var) external initializer { x = _var; __Ownable_init(msg.sender); } function cal() external { x = x + 1; } } // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.28; import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract UUPSV2 is Initializable, UUPSUpgradeable, OwnableUpgradeable { uint public x; function _authorizeUpgrade(address implementation) internal override {} function initialize(uint _var) external initializer { x = _var; __Ownable_init(msg.sender); } function cal() external { x = x * 2; } } 解释一下: UUPSV1: 逻辑合约,第一个版本 UUPSV2: 升级合约,升级版本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("UUPS", function () { it("test_UUPS", async function () { const UUPSV1 = await hre.ethers.getContractFactory("UUPSV1"); const v1 = await hre.upgrades.deployProxy(UUPSV1, [1], { initializer: "initialize", kind: 'uups' }); await v1.waitForDeployment(); // 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 console.log(await v1.getAddress()); console.log(await v1.x()); await v1.cal(); console.log(await v1.x()); // UUPS升级 const UUPSV2 = await hre.ethers.getContractFactory("UUPSV2"); await hre.upgrades.upgradeProxy( await v1.getAddress(), UUPSV2 ); // 当前状态 console.log(await v1.x()); await v1.cal(); console.log(await v1.x()); }); }); 总结: 1、还是继承了delegatecall的基本原理 2、还是UUPSV2中的x保留了UUPSV1中的状态 3、UUPS的proxy只是起到了代理合约,而决定是否升级则是由逻辑合约自己决定,这是与透明可升级合约最大的区别,在整个过程中没有了proxyAdmin ## 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