如何使用hardhat进行合约uups模式升级

这篇具有很好参考价值的文章主要介绍了如何使用hardhat进行合约uups模式升级。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

id:BSN_2021
公众号:BSN研习社

背景:在开发或维护solidity语言的智能合约时,经常会因为业务逻辑变动而变动合约内的逻辑,这就要考虑在不影响以前智能合约中已上链的数据的同时,修改或扩展新的业务逻辑,所以合约第一次开发时就需要考虑其本身支持可升级功能

目的:本篇文章是为了让读者快速上手使用hardhat并搭配openZeppelin的uups升级模式对合约进行可升级适配以及指导后续如何进行合约升级

适用对象:适用于BSN开放联盟链武汉链(基于ETH),也可适用于其他支持solidity语言的链框架

如何使用hardhat进行合约uups模式升级

  • 安装hardhat
  • 初始化项目
  • 编写合约
  • 编写测试文件
  • 编辑配置文件
  • 执行项目
  • 参考

安装hardhat
1.创建空的文件夹demo-uups并进入文件夹里面,执行npm init
2.执行安装命令npm install --save-dev hardhat
3.安装依赖npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers
4.安装openZeppelin的uups可升级合约包 npm install --save-dev @openzeppelin/contracts-upgradeable
5.安装测试工具mocha npm install --save-dev mocha
初始化项目
执行npx hardhat选择Create a basic sample project

安装@openzeppelin/contracts,区块链初始化完成后的目录结构为安装@openzeppelin/contracts,区块链 

编写合约

在contracts目录下面新建两个名称分别为MyLogicV1和MyLogicV2的.sol文件并进行代码编写。实现openZeppelin的uups升级模式必须要引入openZeppelin相关库文件,且必须在constructor()方法上加@custom:oz-upgrades-unsafe-allow constructor字样注释


// contract/MyLogicV1.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

contract MyLogicV1 is Initializable, UUPSUpgradeable, OwnableUpgradeable {
    function initialize() initializer public {
      __Ownable_init();
      __UUPSUpgradeable_init();
    }

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() initializer {}

    function _authorizeUpgrade(address) internal override onlyOwner {}

    mapping(string => uint256) private logic;

    event logicSetted(string indexed _key, uint256 _value);

    function SetLogic(string memory _key, uint256 _value) external {
        logic[_key] = _value;
        emit logicSetted(_key, _value);
    }

    function GetLogic(string memory _key) public view returns (uint256){
        return logic[_key];
    }
}

// contract/MyLogicV2.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

contract MyLogicV2 is Initializable, UUPSUpgradeable, OwnableUpgradeable {
    function initialize() initializer public {
      __Ownable_init();
      __UUPSUpgradeable_init();
    }

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() initializer {}

    function _authorizeUpgrade(address) internal override onlyOwner {}

    mapping(string => uint256) private logic;

    event logicSetted(string indexed _key, uint256 _value);

    function SetLogic(string memory _key, uint256 _value) external {
        logic[_key] = _value;
        emit logicSetted(_key, _value);
    }

    function GetLogic(string memory _key) public view returns (uint256){
        return logic[_key]+100;
    }
}

MyLogicV1实现了一个对于logic的map的写入方法和读取方法,MyLogicV2只是改写了MyLogicV1的GetLogic方法中的处理逻辑,使得每次返回的值加了100

编写测试文件
在test目录下创建生成名称为update-test的.js文件并进行代码编写


// test/update-test.ts
const { expect } = require('chai');
const { ethers, upgrades } = require('hardhat');


let myLogicV1;
let myLogicV2;

describe('uups mode upgrade', function () {
  it('deploys', async function () {
    const MyLogicV1 = await ethers.getContractFactory('MyLogicV1');
      myLogicV1 = (await upgrades.deployProxy(MyLogicV1, {kind: 'uups'}));
      console.log(myLogicV1.address);
  })
  it('myLogicV1 set', async function () {
    await myLogicV1.SetLogic("aa", 1);
    expect((await myLogicV1.GetLogic("aa")).toString()).to.equal('1');
  })
  it('upgrades', async function () {
    const MyLogicV2 = await ethers.getContractFactory('MyLogicV2');
      myLogicV2 = (await upgrades.upgradeProxy(myLogicV1, MyLogicV2));
      console.log(myLogicV2.address);
  })
  it('myLogicV2 get', async function () {
      expect((await myLogicV2.GetLogic("aa")).toString()).to.equal('101');
  })
})

测试文件步骤详解

  • deploys: 调用upgrades中的deployProxy方法以uups的方式部署MyLogicV1合约
  • myLogicV1 set:调用MyLogicV1合约中的SetLogic方法将值传入,并调用GetLogic方法确认返回值为1
  • upgrades:调用upgrades中的upgradeProxy方法升级
  • myLogicV2 get:调用MyLogicV2合约中的GetLogic方法确认返回值为101

编辑配置文件
编辑hardhat.config.js文件


require("@nomiclabs/hardhat-waffle");
require('@openzeppelin/hardhat-upgrades');

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  solidity: {
    version: "0.8.4",
    settings: {
      optimizer: {
        enabled: true,
        runs: 200
      }
    }
  },
  mocha: { timeout: 60000 }
};

执行项目
1.执行编译合约
npx hardhat compile

2.启动本地测试节点
npx hardhat node

3.新开一个窗口运行测试文件
npx hardhat test test/update-test.js --network localhost

安装@openzeppelin/contracts,区块链

测试通过,合约地址都为代理合约地址,测试说明成功升级改写了GetLogic中的处理逻辑,使得每次返回的值都在原来的基础上多加了100

参考

Hardhat官方文档:Overview | Hardhat | Ethereum development environment for professionals by Nomic Foundation[1]

OpenZeppelin官方文档:Using with Upgrades - OpenZeppelin Docs[2]

References

[1] Overview | Hardhat | Ethereum development environment for professionals by Nomic Foundation: https://hardhat.org/getting-started/
[2] Using with Upgrades - OpenZeppelin Docs: https://docs.openzeppelin.com/contracts/4.x/upgradeable文章来源地址https://www.toymoban.com/news/detail-604488.html

到了这里,关于如何使用hardhat进行合约uups模式升级的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用hardhat验证智能合约(goeril测试网)

    使用openzeppelin写了个简单的Erc721合约,成功部署到goerli测试网,但是在验证的时候一直报错:

    2024年02月11日
    浏览(25)
  • 简介智能合约开发框架-Hardhat

    ​ Hardhat是一个编译、部署、测试和调试以太坊应用的开发环境。 Hardhat内置了Hardhat网络,这是一个专为开发设计的本地以太坊网络。主要功能有Solidity调试,跟踪调用堆栈、 console.log() 和交易失败时的明确错误信息提示等。 node.js python 安装 安装中如果出现这样的报错 下载

    2024年02月16日
    浏览(31)
  • 智能合约开发笔记-hardhat入门

    Hardhat是一个编译、部署、测试和调试以太坊应用的开发环境。 先安装nodejs环境; 然后打开命令行执行以下命令, 在项目目录pj_220509下安装hardhat环境: pj_220509目录下, 执行命令 npx hardhat  然后按提示安装相关的nodejs包,如下;完成安装; 装完后呀,可以在本地启动一个区块

    2023年04月11日
    浏览(25)
  • 基于Hardhat编写合约测试用例

    为智能合约编写自动化测试至关重要,毕竟写智能合约多多少少都会跟用户资金挂钩。 这里假设自己正在开发一个NFT交易平台,这个平台可以让用户售卖自己的NFT,包括ERC721和ERC1155,并且用户可以指定购买者需要支付指定的 ERC20 Token 购买。 我们先确定自己的测试功能和目标

    2024年02月02日
    浏览(29)
  • 8.区块链系列之hardhat框架部署合约(二)

    现在我们来实践hardhat部署合约中的其他更多技术要点 1. 代码方式验证合约 注册 https://etherscan.io/ , 如下图添加拷贝API_KEY 在.env文件中新增 ETHERSCAN_API_KEY hardhat.config.js中新增配置 覆盖deploy.js 验证合约 如果用的使用了clash代理的话开启Tun模式,否则可能会报Connect Timeout Error 2.

    2024年01月22日
    浏览(26)
  • 10.区块链系列之hardhat部署抵押赎回Fund合约

    本文继续通过笔者学习到的抵押赎回智能合约Fund来进一步学习solidity语言,加深对开发的理解,其中通过storage节省gas是需要重点实践的,毕竟涉及到资产 代码已提交至https://gitee.com/SJshenjian/blockchain/tree/master/hardhat-fund-me-fcc 1. 依赖安装 若出现如下错误 在yarn.lock中ethereumjs-abi指

    2023年04月09日
    浏览(22)
  • Hardhat工具包1--安装使用

    参考资料: 官方文档 : https://hardhat.org/getting-started/ https://hardhat.org/hardhat-runner/docs/getting-started#overview 基于Hardhat和Openzeppelin开发可升级合约(一) 基于Hardhat和Openzeppelin开发可升级合约(一)_灬倪先森_的博客-CSDN博客 ---------------------------------------------------------------------------------

    2023年04月11日
    浏览(106)
  • 使用viem与链上智能合约进行交互

    viem是一个由paradigm出品的ethers.js的替代品,相比后者,viem具有更小的软件包和更佳的性能,目前已经被sushiswap、mint.fun等项目采用,由于超高的性能,viem将来一定会成为ethers.js的一大竞争者,由于在CSDN还没有相关文章介绍,因此笔者就简要介绍一下如何利用viem与链上合约进

    2024年02月03日
    浏览(25)
  • 如何在Python中进行升级?

    如何在Python中进行升级? 在Python中,升级通常指的是将Python解释器本身升级到较新的版本。升级Python可以获得新功能、修复错误以及提高性能。本文将介绍如何在不同操作系统上升级Python,并提供相应的源代码示例。 1. 在Windows上升级Python 在Windows上升级Python可以通过以下步

    2024年02月04日
    浏览(23)
  • 如何修复ssh漏洞进行版本升级

    目录 一、ssh低版本漏洞信息 OpenSSH GSSAPI 处理远端代码执行漏洞 OpenSSH GSSAPI认证终止信息泄露漏洞 OpenSSH X连接会话劫持漏洞 二、升级ssh版本进行修复漏洞 第一步 安装Telnet服务 第二步 重启服务 第三步 安装依赖环境 第四步 备份ssh老版本文件 第五步 导入服务包并解压 第六步

    2024年02月13日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包