深入理解合约升级(1) - 概括

这篇文章开始,我将用一个系列的文章详细介绍智能合约升级原理,尽量会以 Solidity 初学者的角度来探究,同时也能帮助自己更加巩固对这个知识点的了解。

了解合约升级

我们知道,区块链上的内容都是不可变的,一旦数据上链之后,那么便是不可修改的。智能合约也是一样,部署在链上之后,合约本身的代码便是不可修改的,如果部署之后发现了合约中有 bug,那就完全没办法,只能另外部署一份合约了。其实这样也是有好处的,因为如果一份合约没有问题的话,那么也就代表它能够一直正确运行,而没有人能够修改合约的运行逻辑,真正达到的 Code is law 的理念。

但是,作为项目开发而言,这样就不是很友好了。首先,如果代码中有 bug,无法修改,如果这个 bug 是关乎用户 token 转账等场景,可能会造成用户的资产永久锁死在合约中。其次,项目发展是一个长期的过程,不可能一开始就能把所有的功能都考虑到。如果后期想要添加功能,那么就只能更换合约,并且需要用户手动操作,将旧合约中的数据(资产)转移到新合约中,这样可能会造成用户的困扰。

那么我们自然想到,合约开发能不能也可以像传统互联网开发那样,有问题随时修改,并且对于用户是无感知的呢?这时就引入了我们要介绍的合约升级的概念。

合约如何升级

首先,我们来看传统的合约调用逻辑:

用户最初与旧合约进行交互,如果更新了新的合约,那么用户需要更换交互地址,迁移数据。新旧合约分别保存了各自的数据,两者互不关联。那么如果我们想要做成前面说的无感知升级,该怎么操作呢?

我们知道,合约本身是不能更改的,那么我们考虑,能不能用一种代理人的方式,也就是说,我们去调用一个代理合约,代理合约将我们发送的请求,也就是函数调用,转发给实际执行逻辑的合约,当需要更换新合约的时候,只需要在代理合约转发请求时,将请求发送给新的合约地址就可以了。而用户对这一切是不知道的,因为用户自始至终都是与代理合约做交互。来看看一个简单的图示:

如图中所示,我们在实际执行逻辑的合约前面加了一个代理合约,用户一直是与代理合约交互,开始时代理合约将请求转发给旧合约,当需要升级时,部署一个新的合约,同时代理合约会将请求转发给新合约,这样对于用户来说就是无感知的。

但是这里还有一个问题,我们前面说到,在传统合约模式中,用户是需要将数据从旧合约迁移到新合约中的,现在加了一个代理合约,请求是转发过去了,那么数据怎么办呢,用户的 token 不是还在旧合约中吗?此时,我们应该想到,其实代理合约不仅仅是起到转发请求的作用,而且承载了所有的合约数据,包括用户的 token 也都是存放在代理合约中,右边的逻辑合约也就仅仅是实现逻辑而已,不保存任何数据:

这样一来,我们就能随意更换逻辑合约,而不用担心数据迁移问题。也就是说,我们已经做到了和传统互联网开发一样,能够对合约进行升级。这样对于用户体验和项目方维护来说都是一个很大的优点。

那么既然合约升级这么好,为什么不是所有的项目都采用可升级合约呢?前面我们说到,可升级与不可升级之间,各自都是有利有弊的,这取决于项目方的权衡。

对于可升级合约来说,好处是优化用户体验,利于项目方维护。而坏处就是项目方可以随时更改后面的逻辑合约作恶,将用户的 token 转走,这对于用户来说是无能为力的。(现在有很多项目的升级权限都是由多签管理,但是仍然存在风险)

相对应的,对于不可升级合约,一切都写在了代码中,真正实现了 Code is law 的理念,即使项目方自己也不能随意更改合约,操纵用户资产。例如 Uniswap 的合约都是不可升级的,用户在与其进行交互时,是可以放心将资产放在上面的。但是代价就是项目开发时要做到各种测试,包括项目审计也要做很多遍,因为一旦部署,就无法更改了。(这里并不是说使用了可升级合约就可以省去这些安全步骤,安全一定是合约开发的重中之重,只是说可升级合约即使发现了 bug,也可以后期修改)

综合而言,两者都有各自的优缺点,取决于项目方的考虑与权衡。但要注意的是,并不是说不可升级合约就一定是安全的项目方,而可升级的合约就一定是是不安全的项目方。项目方之间差距也很大,例如 USDC 就是可升级合约,但是 USDC 几乎可以说是不会作恶的。

总结

通过代理合约模式可以实现合约升级,对于用户是无感知的。同时合约升级也是有利有弊,需要针对具体场景判断选择哪种模式。

合约升级系列文章

  1. 深入理解合约升级(1) - 概括
  2. 深入理解合约升级(2) - Solidity 内存布局
  3. 深入理解合约升级(3) - call 与 delegatecall
  4. 深入理解合约升级(4) - 合约升级原理的代码实现
  5. 深入理解合约升级(5) - 部署一个可升级合约

关于我

欢迎和我交流

Subscribe to xyyme.eth
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.