这篇文章上次修改于 796 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
Zeppeline 使用几种代理模式进行实现合约升级。
1 Inherited Storage
proxy 和 contract 都需要继承相同的存储结构 UpgradeabilityStorage
,以确保两者都存储相同的代理状态变量。
Registry
合约用来跟踪不同版本的 contract 实现。
2 Eternal Storage
proxy 和 contract 都继承一个相同的外部存储结构 ExternalStorage
。ExternalStorage
包含了 contract 所需的所有状态变量。因为 proxy 也能感知到 ExternalStorage
,所以它可以定义升级所需的变量而无需担心被覆盖。需要注意的是,contract 的新版本将不能再定义其它的状态变量,只能使用一开始定义好的 ExternalStorage
。
3 Unstructured Storage
Unstructured Storage 和 Inherited Storage 很像,但是 contract 不需要继承任何与升级相关的状态变量。该模式使用 proxy 中定义的 unstructured storage slot。
在 proxy 中以特定字串的哈希值作为 Slot Index 去存储 _implementation。
bytes32 private constant implementationPosition =
keccak256("org.zeppelinos.proxy.implementation");
因为常量不占用 storage slots,所以不需要担心 implementationPosition
会被 contract 覆盖。
这种模式中,contract 不需要知道 proxy 的存储结构。但是 contract 的新版本都必须继承前一个版本的存储变量。和 Inherited Storage 模式一样,contract 的新版本可以升级已有的方法,也可以引入新方法和新的存储变量。
没有评论