Solidity--合约升级风险

一. 什么是智能合约

智能合约通俗点说就是写在区块链上面的代码,代码里面编写着严谨完善的规则,一旦某个用户满足了合约里面的规则条件,就会触发里面的代码,执行某个方法。

二. 为什么要使智能合约达到可升级

智能合约的特点之一就是部署到链上之后不能修改,这一机制使得合约的交互方都可以信任合约。但也带来了一系列的问题,并且如果已部署的合约发现漏洞,也是无法修复的。假如发现了bug,致命性的,必须修复,那如何处理? 就是使用合约达到可升级优化才能满足需求

三. 升级合约的机制原理

  • 什么是合约升级 使已经部署上链的合约做到可优化可更改,例如链上的业务逻辑代码和状态变量达到可增删改的功能.
  • 合约升级的实现机制原理

目前实现的方式根据存储区分有各种各样的模式,但是都离不开一个最底层的机制,就是使用delegatecall的特性去实现可升级的合约,达到合约可持续优化更改的效果.

目前调用合约的方式主要有三种

  • call
  • delegateCall
  • staticCall

四.深入解析Call之间的区别

正常call的请求:

使用 DelegateCall请求

delegateCall 每次调用的时候执行环境都是当前委托者的环境,所有状态修改都会更改到委托者的环境中 ,因此使用这种特性可以用来做合约伪升级

五.合约升级架构图

升级之前

 以上概叙:

1.用户访问代理合约

2.代理合约被委托请求到可升级erc20合约

3.此时代理合约主要的作用(以上讲到的特性)

 转发所有请求到指定的合约

 存储所有数据

升级之后

升级思路:

代理合约存储了访问的逻辑目标地址,当需要升级的时候,只需要在代理合约更新目标逻辑合约地址即可,当用户访问的时候永远访问的是代理合约地址(用户无感升级).

最后流程:

用户请求访问到了代理合约,代理合约请求到我们指定的目前合约进行交互,唯一需要注意的是他的底层机制,因为请求的方式是用的是delegateCall,所以当代理合约请求到目标地址合约时,目标地址的所有数据插槽位布局,都会Copy到代理合约.

以上已经介绍完了升级的思路及架构

升级风险

为什么说升级的风险会很大?

因为合约里面升级使用的是delegatecall里面涉及到插槽位的布局管理

EVM是一个栈虚拟机,栈这种数据结构只允许两个操作:压入(PUSH)或弹出(POP)数据。最后压入的数据位于栈顶,因此将被第一个弹出,这被称为后进先出(LIFO:Last In, First Out):

 例如:

简单的一个合约声明变量,我们来看看他背后的插槽

如上图声明了三个变量,每个变量占用了一个插槽

而这个底层插槽位是非常多限制的,例如他不会跟着你定义的变量移动位置而跟着变动。这个是最大的问题,给业务变更造成极大的阻碍。

假如强行更改,或者误操作会造成怎么样的后果?

场景1:(删除)

业务改变,删除age

我要修改身高,最后只会修改到了年龄的数据,真实的身高旧数据依旧存在,最后就会造成**数据混乱。**

场景二(修改)

当把年龄和身高替换.

 我要修改身高,最后只会修改到了年龄的数据,要修改年龄只会修改到身高,真实的身高旧数据依旧存在,最后也会造成**数据混乱**

正确场景三(只增不减不修改)

最后的场景是正确的升级方式,在最后的插槽里面新增数据 .

当然还有更多需要考虑的情况下,例如多种继承关系下的插槽,引用类型基本类型插槽的打包机制

还有合约的状态变量以紧凑的方式存储在存储中,因此多个值有时使用同一个存储槽。除了动态大小的数组和映射(见下文),数据从第一个状态变量开始逐项连续存储,该状态变量存储在 slot 中0。对于每个变量,根据其类型确定以字节为单位的大小。如果可能,根据以下规则将需要少于 32 字节的多个连续项目打包到一个存储槽中:

  • 存储槽中的第一项存储低位对齐。
  • 值类型只使用存储它们所需的字节数。
  • 如果值类型不适合存储槽的剩余部分,则将其存储在下一个存储槽中。
  • 结构体和数组数据总是开始一个新的槽,并且它们的项目根据这些规则被紧紧地打包。
  • 结构或数组数据之后的项目总是开始一个新的存储槽。

所以在实现升级过程需要非常谨慎并且经过严格测试之后才能上线使用.


总结:
由于升级插槽特殊性,他不会根据你声明变量的移动 删除,或者修改 而插槽位跟着变,
所以为了保证升级数据不混乱必须做到只增不减不修改**
 


以上就是今天要讲的内容,以上所以分享的仅代表个人想法,如有不对的欢迎指出,或者dm我: luo425116243

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Zeke链上学堂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值