Skip to content
On this page

新版本与API稳定性

开发智能合约比较困难,因此对于其依赖项更偏向于保守的方式来处理。然而,在新版本的头部信息也非常重要:包括修正的Bug,弃用旧模式以支持新模式,最佳实践等。
在这里,我们描述了您应该期待新版本发布的时间,以及这对您作为 OpenZeppelin Contracts 用户的影响。

发布计划

我们遵循 semantic versioning scheme
我们计划每一到两个月发布一个镜像版本。

发布候选

在每次发布前,我们会发布一个冻结了功能的候选版本。候选版本的目的是为了让社区在新代码实际发布前,有一段时间可以复审代码。如果发现了严重的问题,就会需要更多的候选版本。在候选版本不再修改的一周后,新版本将会正式发布。

主版本发布

几个月或一年后我们或许会发布一个主版本。这没有具体的时间表,会根据是否有重大更改,比如核心库的重新设计(比如3.0版本的访问控制)。因为我们重视稳定性,我们的目标是不经常发生这种情况(主版本之间的间隔至少在6个月以上)。如果solidity语音有重大改变的时候,也将会发行新的主版本。

API稳定性

OpenZeppelin合约2.0版本发布时,我们致力于保持稳定的API。我们将更详细的描述我们理解的稳定性API,这样合约库的使用者可以明白这些保证,对在使用时不会发生意外中断更有信息。
概括来说,API稳定的意思是如果你的项目今天运行正常,那么下次小改版升级后,它还会继续运行。新合约的新特性将在升级版本中,并且是向下兼容的。

版本控制方案

我们遵循SemVer,其含义是API在主版本之间可能会出现不兼容的情况(这种情况也不会经常发生)。

solidity函数

当函数的内部实现发生改变时,它们的语义和签名也将保持不变。它们的限制性要求也不会减少(比如转账0是不被允许的,升级后还会保持不被允许)。也不会取消一般的状态限制(比如whenPaused修饰符)。
合约中如果添加了一个新的函数,它会向下兼容:继承者的使用不是强制的,并且它们不会以可能会破坏现有应用程序的方式来扩展功能(比如可以添加一个内部方法,以便更容易检索已经可用的信息

internal

函数功能的扩展不只是externalpublic函数,还包括internal函数:许多合约可以通过继承的方式来使用它们(比如 Pausable,PullPayment,AccessControl),因此通过调用这些函数的方式来使用。简单的说,当所有的OpenZeppelin合约的状态变量都是private的时候,只能通过这样的形式来访问(比如建立一个新的ERC20 Token,通过调用_mint方法,而不是手工修改totalSupplybalances)。

说明

_mint方法是internal的,并且会在方法内部修改private的变量totalSupplybalances

私有函数不能改变其行为,使用和存在方式。
最终,有时语言限定会迫使我们把internal变成private函数,以便以我们想要的方式来实现功能。这些情况将会有特殊说明,正常的稳定性保证将不再使用。

Libraries

有些我们的Solidity库使用struct来处理内部数据,这些结构体不能直接访问(比如Counter)。Solidity存储库中有一个未解决的问题,因此提供了语言上的功能来阻止上述访问,并且看起来短时间内都不会改变。正因如此,我们会使用前置下划线来标记struct来向用户明确其内容和结构不是API的一部分。

Events

事件不会被删除,其参数也不会改变。后续版本如果增加了新的事件,现存事件会在新的合理条件下进行触发。

Drafts

一些合约实现了EIPs,并且仍处于Draft(草稿)状态,可以通过文件名的前缀draft-来识别,比如utils/cryptography/draft-EIP712.sol。由于他们还处于草稿状态,那么这些合约的实现细节可能随时改变,因此我们无法保证它们的稳定性。OpenZeppelin合约次要版本的发布可能会包含有标记为草稿状态的重大更改,这些会在其对应的changelog中充分说明。生产环境中使用包含EIP的项目,会减少它们发生重大更改的可能性。

Gas费用

虽然通常情况下在使用OpenZeppelin合约时会尝试尽量减少燃料费,但对此我们没有保证。尤其是,用户不应该假设在升级库版本时不会增加燃料费。

Bug修复

有时我们为了修复Bug会打破对API稳定性的保证。然而这个决定不会轻易的做出,我们会尝试所有不造成破坏的方式来修复Bug。当条件足够充分时,我们对不安全的行为和函数会采用弃用的方式,而不是删除(比如#1543#1550)。

Solidity编译版本

从0.5.0版本开始,Solidity团队切换到了更快的发布周期,几个星期就会发布一个小版本(0.5.0在2018年11月发布,0.5.5在2019年3月发布)。而主版本,重大更改的版本是几个月发布一次(0.6.0是2019年12月发布,0.7.0在2020年7月发布)。因此,OpenZeppelin合约的稳定性保证也包含编译器版本稳定,而编译器版本的频繁升级迫使我们要么坚持使用旧的编译器版本,要么随着Solidity编译器版本更新而频繁更新。
因此,最低要求的Solidity编译器版本不包含在稳定性保证中,用户在使用新版本的合约时,有可能会需要升级自己的编译器版本。Bug的修复会考虑到之前发布的主版本,因此所有正在使用的版本都会收到这些更新。
你可以阅读更多关于这背后的基本原理,我们考虑的其他选择和为什么我们会选择这种方式

Released under the MIT License.