Page 45 - 《软件学报》2026年第1期
P. 45

42                                                         软件学报  2026  年第  37  卷第  1  期


                 时消耗显著, 这进一步加剧        Gas 消耗问题. 而权限管理逻辑的复杂性也增加代码实现的难度, 一旦开发不慎, 可能
                 引发权限漏洞. 最后是升级权限集中风险, 透明代理模式的升级逻辑由管理员集中管理, 这种设计虽然便于操作,
                 但也引入安全风险. 如果管理员权限被泄露或遭到攻击, 攻击者可能通过恶意升级替换实现合约地址, 从而接管整
                 个系统.
                  1.4   变形合约
                    2019  年  2  月  28  日, 以太坊从  7 280 000  区块开始执行君士坦丁堡  (Constantinople) 硬分叉, 并引入新的操作码
                 CREATE2, 该操作码为合约部署提供一种通过指定部署参数生成固定地址的机制. 它允许在不依赖部署者地址的
                 情况下, 通过哈希计算确定合约的部署地址. 这一特性间接支持一种创新的合约升级方式, 即变形合约                             (metamorphic
                 contract)  [55] , 变形合约利用  CREATE2  操作码, 在同一地址上通过销毁原有合约并重新部署新合约的方式, 实现合
                 约逻辑的替换. 与传统升级模式相比, 变形合约无需额外的代理合约或存储迁移, 因而在存储需求较少或合约地址
                 不变场景中更具效率. 如图        11  所示, 合约“变形”过程可通过以下       3  个步骤实现.

                                                                     合约地址:
                                                                    0x0123…ABCD
                                                      变形合约   部署
                                                       工厂          变形合约版本 V1
                                            部署者
                                                                        自毁
                                                            重新部署
                                                                   变形合约版本 V2
                                                                        自毁
                                                            重新部署
                                                                   变形合约版本 V3

                                                      图 11 变形合约

                    1) 通过工厂合约部署具有自毁功能的合约.
                    2) 触发该合约的     SELFDESTRUCT  操作码自毁, 将原合约地址上的代码和状态清除.
                    3) 工厂合约结合     CREATE2  操作码, 在相同地址重新部署一个新的合约.
                    在这一过程中, SELFDESTRUCT        操作码的作用是销毁原合约及其状态, 清理合约地址空间. 随后, 通过
                 CREATE2  操作码, 使用固定的、不确定的初始化代码创建一个新合约, 确保新合约的地址在部署前即可预计算得
                 出. 这样, 新部署的合约既能与链上尚未存在的地址交互, 又不会改变其原有地址. 与透明代理的地址管理方式不
                 同, 这种升级方式更适用于无需持久状态或状态易于重建的合约, 例如时间敏感或一次性用途的代币合约或无需
                 复杂余额管理的身份合约.
                    变形合约利用      CREATE2  操作码的确定性特性, 在销毁旧合约后可以在相同地址重新部署新实现合约. 然而,
                 若开发者未完全清除旧合约的数据状态, 这种地址重用会导致新逻辑与残留数据的冲突或兼容性问题. 攻击者可
                 以利用合约销毁后出现的地址空档期, 部署恶意合约伪装成预期的实现合约, 占用预定地址. 这种“地址抢占”攻击
                 使得重部署失败会导致功能中断, 影响应用的正常运行. 此外, 由于变形合约销毁旧合约时会丢失原有的存储状
                 态, 部署者需要额外的存储管理机制            (例如, 外部状态存储合约) 来保留数据. 如果状态数据在迁移过程中丢失或
                 被篡改, 则导致数据不一致或系统功能瘫痪. 变形合约的设计允许在不更改地址的情况下更换逻辑, 但这种灵活性
                 可能降低透明度, 使得用户对系统的信任度可能下降.
                  1.5   通用可升级代理标准

                    2019  年, EIP-1822  提案  [25] 规定通用可升级代理标准  (universal upgradeable proxy standard, UUPS), 该标准与所
                 有合约普遍兼容, 通过在代理合约中唯一存储位置来完成实现合约的地址存储. 实现合约本身包含升级功能, 不需
                 要代理合约直接参与升级操作. 而是通过让它继承一个包括升级逻辑的通用标准接口, 使实现合约符合                                 UUPS  标
                 准, 如继承  OpenZeppelin  的  UUPS Upgradeable 接口, 继承该接口的实现合约不仅包含业务逻辑, 还包括更新存储
   40   41   42   43   44   45   46   47   48   49   50