openzeppelin可升级合约详解

安装 @openzeppelin/truffle-upgrades

npm i @openzeppelin/truffle-upgrades

编写合约和脚本

为了更加清晰的认识可升级合约,这里一次部署两个合约

// contracts/Test1.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Test1 {
    function get() external pure returns(uint a) {
       a = 1;
    }
    uint public x;
    function add() external {
      x++;
    }
}
// contracts/Test2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Test1 {
    function get() external pure returns(uint a) {
       a = 1;
    }
    uint public x;
    function add() external {
      x++;
    }
}
const { deployProxy } = require('@openzeppelin/truffle-upgrades');
const Test1 = artifacts.require("Test1");
const Test2 = artifacts.require("Test2");

module.exports = async function (deployer) {
  await deployProxy(Test1);
  await deployProxy(Test2);
};

部署、验证合约

truffle migrate --network ropsten
truffle run verify Test1 Test2 --network ropsten

可升级合约解析

简单介绍

通过刚才的部署,可以看到我们部署了5个合约,分别是 :
Test1:我们编写的 Test1 合约
TransparentUpgradeableProxy:Test1 的代理合约
Test2:我们编写的 Test 合约
TransparentUpgradeableProxy:Test2 的代理合约
ProxyAdmin:管理员合约,用于管理所有代理合约,后续 Test1、Test2 合约升级就是改变对应代理合约的指向。
这便可以清晰的认识到,我们编写的每个合约,都会对应一个代理合约,
发布两个合约的作用已经起到,后面讲解便忽略 Test2 合约

ProxyAdmin 合约

三个读函数
getProxyAdmin:获取代理合约管理员地址,输入 Test1 代理合约地址,返回本合约(ProxyAdmin )地址
getProxyImplementation :获取代理合约实现合约地址,输入 Test1 代理合约地址,指向 Test1 合约地址
owner:合约owner,部署合约的地址,也就是项目网络配置中 mnemonic 对应的账户地址

在这里插入图片描述

五个写函数,
1.更换代理合约管理员
2.放弃合约所有权
3.更换合约owner
4.升级合约
5.升级并调用合约

在这里插入图片描述

TransparentUpgradeableProxy:Test1 的代理合约

该合约没有读合约,略过,看写合约,五个函数:
1.管理员:该函数实际上是一个读函数,但函数并没有加 view 关键字,并且加了 ifAdmin 修改器,只有管理员可以访问,一定程度上起到了保护 admin 合约地址的作用
2.变更管理员:需要admin地址访问
3.代理实现:同admin函数
4.升级合约:需要admin地址访问
5.升级并调用合约:需要admin地址访问
综上所述,这五个函数都是为管理员合约提供的专用函数,无法直接访问

在这里插入图片描述
后面的代理函数,则是我们 Test1 合约的函数,先调用写合约add函数,再查询结果
在这里插入图片描述

合约升级

工作原理

熟悉委托调用的朋友都知道,合约A中函数委托调用合约B中函数,只是使用合约B中函数的逻辑,改变的是合约A中的变量,这里代理合约便是委托调用我们编写的逻辑合约,所以合约升级只是更换我们的逻辑合约,原数据还在代理合约中不会丢失。接下来顺便验证这一点

修改合约 和脚本

// contracts/Test1.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Test1 {
    function get() external pure returns(uint a) {
       a = 10;
    }
    uint public x;
    function add() external {
      x+= 10;
    }
}

deployProxy部署合约会部署一个代理合约和一个逻辑合约,
升级合约只部署新的逻辑合约并修改指向便可,采用普通的部署方式

const Test1 = artifacts.require("Test1");

module.exports = async function (deployer) {
  deployer.deploy(Test1);
};

部署验证略过

修改代理实现

调用 ProxyAdmin 合约 upgrade 函数
第一个参数为 TransparentUpgradeableProxy 合约地址
第二个参数为 刚刚部署的 Test1 合约地址
需要连接 ProxyAdmin 合约的owner地址

在这里插入图片描述

测试

查看 TransparentUpgradeableProxy 合约
x 的值还是1 并没有丢失
调用add方法后 再次查看 x 的值变为11,说明我们合约已经升级成功。

在这里插入图片描述

验证

查看新部署的Test1合约,x的值依旧是0,验证了代理合约只是使用逻辑合约的逻辑,改变了代理合约的变量,逻辑合约内变量没有变化
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
OpenZeppelin是一个开源的智能合约开发框架,它提供了一系列的安全、可靠的合约库和工具,帮助开发者构建和部署智能合约。在引用\[1\]中,安装步骤展示了如何在Ubuntu系统上使用Truffle和OpenZeppelin来初始化一个合约目录,并导入OpenZeppelin合约库。引用\[2\]展示了如何在部署合约时使用OpenZeppelin升级功能,通过deployProxy函数来部署一个可升级合约。引用\[3\]展示了如何准备升级一个已部署的合约,使用prepareUpgrade函数来准备升级到新版本的合约。总之,OpenZeppelin提供了一套强大的工具和库,帮助开发者构建安全可靠的智能合约。 #### 引用[.reference_title] - *1* [区块链入门教程openzeppelin详解](https://blog.csdn.net/u013288190/article/details/123769975)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [部署OpenZeppelin升级合约](https://blog.csdn.net/watson2017/article/details/122745389)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bug的搬运工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值