solidity0.8.0的应用案例9:代理合约

代码由OpenZeppelin的Proxy合约简化而来。

代理模式

Solidity合约部署在链上之后,代码是不可变的(immutable)。这样既有优点,也有缺点:

  • 优点:安全,用户知道会发生什么(大部分时候)。
  • 坏处:就算合约中存在bug,也不能修改或升级,只能部署新合约。但是新合约的地址与旧的不一样,且合约的数据也需要花费大量gas进行迁移。

有没有办法在合约部署后进行修改或升级呢?答案是有的,那就是代理模式

solidity0.8.0的应用案例9:代理合约_第1张图片

 

 代理模式将合约数据和逻辑分开,分别保存在不同合约中。我们拿上图中简单的代理合约为例,数据(状态变量)存储在代理合约中,而逻辑(函数)保存在另一个逻辑合约中。代理合约(Proxy)通过delegatecall,将函数调用全权委托给逻辑合约(Implementation)执行,再把最终的结果返回给调用者(Caller)。

代理模式主要有两个好处:

  1. 可升级:当我们需要升级合约的逻辑时,只需要将代理合约指向新的逻辑合约。
  2. 省gas:如果多个合约复用一套逻辑,我们只需部署一个逻辑合约,然后再部署多个只保存数据的代理合约,指向逻辑合约。

提示:对delegatecall不熟悉的朋友可以看下本教程第23讲Delegatecall。

代理合约

一个简单的代理合约,它由OpenZeppelin的Proxy合约简化而来。它有三个部分:代理合约Proxy,逻辑合约Logic,和一个调用示例Caller。它的逻辑并不复杂:

  • 首先部署逻辑合约Logic
  • 创建代理合约Proxy,状态变量implementation记录Logic合约地址。
  • Proxy合约利用回调函数fallback,将所有调用委托给Logic合约
  • 最后部署调用示例Caller合约,调用Proxy合约。
  • 注意Logic合约和Proxy合约的状态变量存储结构相同,不然delegatecall会产生意想不到的行为,有安全隐患。

你可能感兴趣的:(区块链)