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

