Solidity--合约升级风险

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

一. 什么是智能合约

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

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

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

三. 升级合约的机制原理

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

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

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

  • call
  • delegateCall
  • staticCall

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

正常call的请求:

solidity 智 能合约升级,以太坊

使用 DelegateCall请求

solidity 智 能合约升级,以太坊

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

五.合约升级架构图

升级之前

solidity 智 能合约升级,以太坊

 以上概叙:

1.用户访问代理合约

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

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

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

 存储所有数据

升级之后

solidity 智 能合约升级,以太坊

升级思路:

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

最后流程:

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

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

升级风险

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

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

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

solidity 智 能合约升级,以太坊

 例如:

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

solidity 智 能合约升级,以太坊

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

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

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

场景1:(删除)

业务改变,删除age

solidity 智 能合约升级,以太坊我要修改身高,最后只会修改到了年龄的数据,真实的身高旧数据依旧存在,最后就会造成**数据混乱。**

场景二(修改)

当把年龄和身高替换.

solidity 智 能合约升级,以太坊

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

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

solidity 智 能合约升级,以太坊

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

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

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

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

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


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


以上就是今天要讲的内容,以上所以分享的仅代表个人想法,如有不对的欢迎指出,或者dm我: luo425116243文章来源地址https://www.toymoban.com/news/detail-589910.html

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

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

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

相关文章

  • 以太坊智能合约开发:Solidity语言中的映射

    本文我们介绍Solidity语言中的映射,包括映射的基本定义、语法、映射的变量声明和基本读写操作。并且通过两个智能合约例子演示了映射的定义与基本操作。 Solidity中关于映射的一些定义: 映射以键-值对(key = value)的形式存储数据; 键可以是任何内置数据类型,包括字节

    2024年02月05日
    浏览(54)
  • 基于以太坊的智能合约开发Solidity(基础篇)

    参考教程:基于以太坊的智能合约开发教程【Solidity】_哔哩哔哩_bilibili (1)程序编译完成后,需要在虚拟机上运行,将合约部署好后便可执行刚刚编写的函数。(注意, 合约一旦部署,就会永久存在于区块链上,且不可篡改 ,不过可以销毁) (2)执行完成后,可以得到以

    2024年02月04日
    浏览(56)
  • 以太坊智能合约开发:Solidity 语言中的数据类型

    本文我们介绍Solidity语言的数据类型,重点是值类型,包括布尔类型、整型、地址类型、字节类型、字符串类型和枚举类型。并且通过两个智能合约例子,用于演示这些数据类型的声明与使用方法。 访问 Github 仓库 获取更多资料。 Solidity中关于数据类型的定义如下: Solidity是

    2024年02月02日
    浏览(67)
  • 以太坊智能合约开发:Solidity语言中的构造函数

    Solidity语言中关于构造函数的定义: 构造函数是使用 constructor 声明的一个可选函数; 构造函数只在合约部署时调用一次,并用于初始化合约的状态变量; 如果没有显式定义的构造函数,则由编译器创建默认构造函数。 构造函数声明语法如下: 其中: ** constructor :

    2024年02月01日
    浏览(51)
  • 基于以太坊的智能合约开发Solidity(事件&日志篇)

    (1)事件用于记录在区块链上的特定活动,“emit ValueChanged(newValue);”语句的作用是触发ValueChanged事件(首先需要声明事件)。 ①触发事件后会生成相应日志,上图黄框就是“emit ValueChanged(newValue);”语句产生的日志,其中“form”指的是触发事件的合约账户。 ②事件主要是供

    2024年02月04日
    浏览(42)
  • 基于以太坊的智能合约开发Solidity(内存&结构体篇)

    参考教程:【内存、引用与持久化存储】1、内存与区块链——storage与memory原理_哔哩哔哩_bilibili (1)所有的复杂类型,即数组、结构和映射类型,都有一个额外属性——“数据位置”,用来说明数据是保存在内存memory中还是存储storage中,保存在memory中的数据,在函数执行完

    2024年02月04日
    浏览(56)
  • 【区块链】以太坊Solidity编写一个简单的Hello World合约

    熟悉一门语言得从Hello World! 开始,因为这是最简单的一个输出形式。 我们先在contracts目录下建立一个helloworld.sol文件 进入编辑 保存退出 在migrations下新建一个部署合约的js文件:3_initial_migration.js 名字可以变动 接下来在test中使用js调用智能合约 在另一个窗口打开ganache 运行智

    2024年02月15日
    浏览(71)
  • 基于openzeppelin编写solidity可升级的智能合约

            现代软件的设计原则是“敏捷开发,迅速迭代”,功能升级或bug修复是所有软件系统都要面对的问题。甚至可以说软件质量在很大程度上依赖于升级和修补源代码的能力。当然Dapp(去中心化应用)也不例外,尤其Dapp一切都是透明的,这使得任何级别的bug都会被成

    2024年01月18日
    浏览(49)
  • 玩以太坊链上项目的必备技能(初识智能合约语言-Solidity之旅一)

    前面一篇关于 智能合约 翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用 程序语言 去编写 智能合约 了。 而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂 智能合约 代码,或找出其中的漏洞,那么,学习 Solidity 这门高级的智能合约语言是有

    2023年04月16日
    浏览(95)
  • Solidity——在合约中创建合约

    在以太坊链上,除了用户可以创建智能合约,智能合约同样也可以创建新的智能合约。两种常见的创建合约的方式: 计算合约地址的预测值: 使用 keccak256 哈希函数计算合约的初始化代码(包括合约的字节码和构造函数的参数)的哈希值。 从创建者地址(通常是工厂合约的

    2024年02月03日
    浏览(44)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包