当我们编写一个可升级合约时 通常使用opz的"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"来进行合约构建,只需要直接继承并完成初始化即可
如图所示


需要注意的是,当我们使用UUPS时,我们的变量是无法通过直接赋值的,如图
这样赋值是无法正确给到blockLiquidate正确的值 读取到的blockLiquidate为空值,这是因为:
如果是在普通的非可升级合约中,blockLiquidate变量会在合约部署时存储在合约的存储插槽中,并被初始化为 50。
但是在使用UUPS代理合约模式时,情况有所不同。当可升级合约部署后,合约会分为代理合约(proxy)和逻辑合约(通常也被叫做实现合约impl),代理合约不会存储逻辑合约中的状态变量,而是使用自己的存储空间,它是一个完全没有任何函数和变量的空合约,有的只是存储插槽(所有的变量值会存储在这里),这些值本身并没有变量名,并不能通过变量名来得知这些值,它们仅仅是按顺序排列下来的不同值,但是这些值的顺序(存储插槽的顺序)和逻辑合约中申明的变量名的顺序一一对应,由此来实现存储值(代理合约)和变量名(逻辑合约)的一一对应。这意味着,当在变量声明时赋值,实际上这个值只是在逻辑合约的上下文中存在,并且值被逻辑合约本身进行了存储,而不在代理合约的存储中生效,而当我们读取变量的值时,实际上的过程是逻辑合约通过变量名的顺序来指定获取到代理合约中处于这个顺序的存储插槽中存储到的值。
正确的赋值如下: 应该在initialize函数中赋值,该函数为初始化函数,类似于构造函数,能在合约被部署时进行变量赋值和函数调用,当通过initialize函数来实现变量赋值时,这个值能够正确的存储在代理合约的存储插槽中,并在获取变量时读取到正确赋值


1238

被折叠的 条评论
为什么被折叠?



