当前位置:网站首页>基于 Openzeppelin 的可升级合约解决方案的注意事项
基于 Openzeppelin 的可升级合约解决方案的注意事项
2022-07-02 09:38:00 【灬倪先森_】
基于 Openzeppelin 的可升级合约解决方案的注意事项
注意事项
构造函数
在编写可升级合约时请不要使用构造函数contructor(),我们知道可升级合约运行时逻辑与数据分离的,合约数据保存在代理合约中,我们编写的合约是逻辑合约,当合约部署时,逻辑合约调用contructor()初始化的数据是逻辑合约的,代理合约中的数据并没有被初始化,所以是无效的。
包括全局变量声明时赋值初始值,因为这种做法相当于在构造函数contructor()中设置这些值。
父类合约初始化
如果MyContract继承自合约 BaseContract, 那么BaseContract合约的初始化函数 initialize() 的modifier(修饰器) 必须使用 onlyInitializing,比如:
contract BaseContract is Initializable {
uint256 public y;
function initialize() public onlyInitializing {
y = 42;
}
}
// BaseContract 继承自 Initializable,这里无需重复显式继承 Initializable
contract MyContract is BaseContract {
int storageValue;
// modifier(修饰器) initializer 可以确保initialize只会被调用一次
function initialize(int initValue) public initializer {
BaseContract.initialize();
storageValue = initValue;
}
......
}
声明状态变量
- 声明状态变量时,不能对其赋值 初始值
像这样做是错误的
contract MyContract is Initializable {
int storageValue = 666; //初始值无效
function initialize() public initializer {
}
......
}
因为这种做法相当于在构造函数contructor()中设置这些值,因此不适用于可升级的约定。
- 定义常量状态变量仍然可以
像这样是可以的
contract MyContract is Initializable {
// constant 常量关键字
int public constant storageValue = 666; //有效
function initialize() public initializer {
}
......
}
在合约代码中创建新合约实例
- 不要在合约中创建新的合约实例,创建出的合约是不可升级的
像这样,即使MyContract是可升级的,但 ERC20 实例不可升级
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyContract is Initializable {
ERC20 public token;
function initialize() public initializer {
token = new ERC20("Test", "TST"); // 这个合约是不可升级的
}
......
}
- 如果你希望在MyContract引用其他可升级合约,那么将已部署好的可升级合约实例注入到MyContract中,是很好的解决方案
像这样
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
contract MyContract is Initializable {
IERC20Upgradeable public token;
function initialize(IERC20Upgradeable _token) public initializer {
token = _token;
}
......
}
升级合约时声明状态变量
在编写合约的新版本时,无论是由于新功能还是 bug 修复,还有一个额外的限制需要遵守:不能更改合约状态变量的声明顺序,也不能更改其类型。
比如当前版本(V1)合约状态变量布局
contract MyContractV1 {
uint256 private x;
string private y;
}
那么在编写新版本合约时,请避免一下错误操作:
- 更改变量的类型
这是错误的
contract MyContractV2 {
string private x;
string private y;
}
- 更改声明它们的顺序
这是错误的
contract MyContractV2 {
string private y;
uint256 private x;
}
- 在现有变量之前引入一个新变量
这是错误的
contract MyContractV2 {
bytes private a;
uint256 private x;
string private y;
}
这是正确的
contract MyContractV2 {
uint256 private x;
string private y;
bytes private a;
}
- 删除现有变量
这是错误的
contract MyContractV2 {
string private y;
}
参考文档:
Openzeppelin编写可升级合约:https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable
边栏推荐
- Introduction to interface debugging tools
- MTK full dump抓取
- TIPC Service and Topology Tracking4
- ImportError: cannot import name ‘Digraph‘ from ‘graphviz‘
- JS——每次调用从数组里面随机取一个数,且不能与上一次为同一个
- Amazon cloud technology community builder application window opens
- Some things configured from ros1 to ros2
- C file and folder operation
- Installation of ROS gazebo related packages
- Skills of PLC recorder in quickly monitoring multiple PLC bits
猜你喜欢

From the perspective of attack surface, see the practice of zero trust scheme of Xinchuang

flink二開,實現了個 batch lookup join(附源碼)

Solve the problem of data blank in the quick sliding page of the uniapp list

mysql链表数据存储查询排序问题

Wechat applet uses Baidu API to achieve plant recognition

由粒子加速器产生的反中子形成的白洞

I STM32 development environment, keil5/mdk5.14 installation tutorial (with download link)
![[in simple terms, play with FPGA learning 3 ----- basic grammar]](/img/f0/0204fa5197033877dc0758203253ae.png)
[in simple terms, play with FPGA learning 3 ----- basic grammar]

A white hole formed by antineutrons produced by particle accelerators

ImportError: cannot import name ‘Digraph‘ from ‘graphviz‘
随机推荐
启牛商学院给的股票账户安全吗?能开户吗?
Summary of data export methods in powerbi
TIPC Getting Started6
原生方法合并word
Redis超出最大内存错误OOM command not allowed when used memory > 'maxmemory'
[play with FPGA learning 4 in simple terms ----- talk about state machine design]
对毕业季即将踏入职场的年轻人的一点建议
Some things configured from ros1 to ros2
C# 文件与文件夹操作
Implementation of six singleton modes
mysql链表数据存储查询排序问题
Wechat applet uses Baidu API to achieve plant recognition
Approximate sum count (approximate
MTK full dump抓取
Flink two Open, implement Batch Lookup join (attached source)
C#多维数组的属性获取方法及操作注意
SQLite modify column type
Gaode draws lines according to the track
MySQL basic statement
ren域名有价值吗?值不值得投资?ren域名的应用范围有哪些?