# UUPS在hardhat中的实现

By [web3zoom](https://paragraph.com/@web3zoom) · 2025-08-05

---

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

---

*Originally published on [web3zoom](https://paragraph.com/@web3zoom/uups-hardhat)*
