如何利用delegatecall进行以太坊智能合约升级

  • powervip
  • 更新于 2021-10-20 16:05
  • 阅读 2504

如何利用delegatecall进行以太坊智能合约升级

以太坊智能合约升级

在以太坊智能合约的开发过程中,对于一些复杂的合约开发,要开发出完美没有bug的智能合约,要求是相当高的。即使编写出来的智能合约能完美没有bug,也很难保证以后的需求和应用业务逻辑一成不变。所以,在开发智能合约的同时,就要考虑好以后的合约更新和升级问题。

思路

以太坊智能合约的更新和升级,其中一种思路就是:在智能合约的编写过程中,要做到数据和应用逻辑的分离。简单来说,就是把数据和应用逻辑分别放在2个独立的合约里(本文称之为数据合约和业务合约)。我们在升级合约时,保证存放数据的数据合约里的数据结构不改变,改变的只是存放应用逻辑的业务合约。这样才能保证原有的业务数据不被破坏和能够继续使用。

Solidity有三种合约间的调用方式 call、delegatecall 和 callcode。其中,delegatecall可作为智能合约升级的一个较好的途径。关于合约间的调用方式 call、delegatecall 和 callcode,详见我另一篇文章<<图文并茂详细介绍Solidity的三种合约间的调用方式 call、delegatecall 和 callcode>>,有兴趣的同学们可以看一下。原文链接: https://blog.csdn.net/powervip/article/details/104330170

例子

假设我们要计算一个求和公式:numC = numA + numB 我把数据numA、numB、numC作为数据存放在数据合约contract A中,把求和的业务逻辑放在数据合约contract B中。为了演示合约升级,我故意把contract B中的业务逻辑函数calcSum()中的加法运算故意写成乘法运算,以便后面进行合约升级。代码不是很复杂,代码如下:

img

我们先部署合约A,再部署合约B。通过合约A的setNumA()函数把NumA设为1,通过合约A的setNumB()函数把NumB设为2,再复制合约A的地址 0x692a70D2e424a56D2C6C27aA97D1a86395877b3A。

然后,我们部署合约B,并把合约A的地址粘贴到函数run_sum()的参数栏中,见下图。运行函数run_sum()(直接点击函数名即可)。这时候,我们再点击numC,会看到numC的值为2。显然,这不是我们想要的求和结果。

图2 部署合约B,并把合约A的地址粘贴到函数run_sum()的参数栏中

我们把函数calcSum()的 return a * b; 这句注释掉,把 return a + b; 这句的注释去掉,变成下面的代码:

图3 升级后的合约代码

先删掉合约B(点击合约B地址栏右边的"x"),重新编译和部署合约B,并把合约A的地址粘贴到函数run_sum()的参数栏中重新运行run_sum()。这时候,我们再点击numC,会看到numC的值为3。合约B升级成功,由原来的乘法运算升级为加法运算。合约A原来的NumA和NumB的内容完美地保留了下来。

如果你觉得这篇文章写得还可以,请帮忙点个赞,谢谢! 你的鼓励,我的动力!

我的github:https://github.com/powervip

本文首发于:https://blog.csdn.net/powervip/article/details/105367928

点赞 1
收藏 3
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
powervip
powervip
区块链程序猿,追求有深度的文章 我的知乎:https://www.zhihu.com/people/powervip 我的csdn:https://blog.csdn.net/powervip 我的github:https://github.com/powervip 我的学习笔记:www.study.win 我的公众号:区块链战斗机 我的网盘:https://pan.baidu.com/s/1frOZuMxdp5IVaY94ZdoN-A