本案例仅供参考学习,目前漏洞尚未研究请勿用于项目实例

官方教程
https://docs.openzeppelin.com/upgrades-plugins/1.x/hardhat-upgrades

env $(cat .env) npx hardhat run –network ropsten scripts/deploy_box_v1.js

Downloading compiler 0.8.10
Compiled 2 Solidity files successfully
Box deployed to: 0xc1524bCbC56162F272Db68Bc1379039a95546085

部署完成三个合约
ProxyAdmin 0xad6c3eff51E8ecEde381E55Bd7Ee34274896A97A
TransparentUpgradeableProxy 提供透明可升级代理和uups,我们案例使用透明代理 0xc1524bCbC56162F272Db68Bc1379039a95546085
Box

开源Box合约 需要彻底科学上网 内部api有可能通不过 多试几次还不行就要用remix里的flattener插件合成一个文件再去浏览器verify
0x29B500C91f5a50C5c6BE6ccF346f986Db037574b
env $(cat .env) npx hardhat verify –network ropsten 0x29B500C91f5a50C5c6BE6ccF346f986Db037574b

运行命令报错 我们更新下插件
yarn add @nomiclabs/hardhat-ethers
yarn add @nomiclabs/hardhat-etherscan
yarn add @openzeppelin/hardhat-upgrades
npm i -s @nomiclabs/hardhat-etherscan@3.0.1 版本降级 暂未使用

注意在 hardhat.config.js 中添加引入
https://www.npmjs.com/package/@openzeppelin/hardhat-upgrades

require('@openzeppelin/hardhat-upgrades');

部署完成后在etherscan执行 more options -> Is this a proxy?

升级到v2
env $(cat .env) npx hardhat run –network ropsten scripts/upgrade_box_v2.js

升级后再次执行
etherscan执行 more options -> Is this a proxy? 更新合约

相关代码 https://github.com/t4sk/hello-oz-upgradeable

Box.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

contract Box {
    uint public val;

    // 不支持构造函数 constructor

    function initialize(uint _val) external {
        val = _val;
    }
}

BoxV2.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

contract BoxV2 {
    uint public val;

    // function initialize(uint _val) external {
    //     val = _val;
    // }

    function inc() external {
        val += 1;
    }
}

scripts/deploy_box_v1.js

const { ethers, upgrades } = require("hardhat");


async function main() {
    const Box = await ethers.getContractFactory("Box");

    const box = await upgrades.deployProxy(Box, [42], {
        initializer: "initialize",
    });

    await box.deployed();

    console.log("Box deployed to:", box.address);  
}

main();

scripts/upgrade_box_v2.js

const { ethers, upgrades } = require("hardhat");

// 代理合约地址
const PROXY = "0xc1524bCbC56162F272Db68Bc1379039a95546085";


async function main() {
    const BoxV2 = await ethers.getContractFactory("BoxV2");
    await upgrades.upgradeProxy(PROXY, BoxV2);
}

main();