OpenZeppelin 的可升级性模式:代理模式与 UUPS

文旅笔记家 2019-06-17 ⋅ 29 阅读

在智能合约开发中,可升级性一直是一个重要的课题。当合约在区块链上运行后,其代码将无法修改。然而,随着合约使用的增加,我们往往需要对其进行功能更新或修复漏洞。

OpenZeppelin 是一个广为人知的智能合约开发库,为开发者提供了许多方便的工具和模式。其中,代理模式(Proxy Pattern)和 UUPS(Universal Upgradeable Proxy Standard)是实现可升级性的两种重要模式。让我们来了解一下这两种模式以及它们在 OpenZeppelin 中的应用。

代理模式

代理模式允许我们将合约的逻辑与存储分离开来。主要包括两个合约:代理合约(Proxy Contract)和实现合约(Implementation Contract)。

代理合约是一个非常简单的合约,它存储合约的地址和一些必要的安全检查。它将所有的调用转发到实现合约。实现合约包含合约的逻辑和状态。当我们需要升级合约时,我们只需要点击指向新的实现合约地址即可。

代理模式的一大优势在于它只需要部署一次代理合约,并且可以多次升级实现合约。这样做的好处是,我们无需担心原合约地址会被替换掉,因此可以保持其他合约或外部工具与该合约的连接。

在 OpenZeppelin 中,我们提供了一个名为 Proxy 的抽象合约,可以用于实现代理模式。开发者只需继承该合约,并按照需要实现自己的代理合约逻辑。

UUPS

虽然代理模式解决了合约可升级性的问题,但它也存在一些限制。最主要的限制是合约只能通过代理调用。这意味着如果外部调用合约,例如通过myContract.doSomething(),调用将无法被转发到实现合约,从而无法使用新的逻辑。

为了解决这个限制,OpenZeppelin 引入了 UUPS(Universal Upgradeable Proxy Standard)标准。UUPS 不再依赖代理合约,并且使用了更智能的内存分配方式。通过 UUPS,我们可以直接调用合约的函数,而无需通过代理。

实现 UUPS 的合约同样简单,只需继承 ERC1967Proxy 并实现 onUpgrade 函数。当我们需要升级合约时,只需调用 upgradeTo 函数,指向新的实现合约地址。而之前的代理合约仍然可以直接调用。

使用 UUPS 的好处是我们可以更方便地使用合约的新功能,并确保与其他外部合约或工具的兼容性。

结语

OpenZeppelin 提供了代理模式和 UUPS 两种可升级性模式,让开发者能够在运行合约后对其进行升级、更新和修复漏洞。这些模式的灵活性和方便性使得我们能够更好地管理和维护智能合约。

无论是选择哪种模式,我们都需要谨慎处理合约升级。在升级之前,应该进行充分的测试和审查。此外,确保与其他合约和工具的兼容性也是非常重要的。

借助 OpenZeppelin 提供的代理模式和 UUPS,我们能够更好地应对合约的可升级性需求,并为用户提供更好的智能合约体验。在接下来的项目中,我相信这些工具和模式将会成为我们的必备利器。

参考链接:


全部评论: 0

    我有话说: