Page 43 - 《软件学报》2026年第1期
P. 43
40 软件学报 2026 年第 37 卷第 1 期
引发存储冲突 [53] , 例如管理员地址被覆盖为随机地址, 导致权限被篡改或丢失. 此外, 以太坊中函数调用是根据数
据有效负载的前 4 个字节函数选择器 (函数名称及其签名的哈希值) 标识, 4 个字节长度的低碰撞性这意味着两个
函数之间可能会发生冲突: 两个具有不同名称的不同函数最终可能会具有相同的选择器. 当代理和执行合约为不
同的目的使用相同的存储槽时, 代理合约的调用意图因函数选择器冲突而发生偏移时, 可能意外触发实现合约中
的其他函数, 导致代理合约被错误升级至随机地址. 这种情况下, 系统的安全性取决于对实现合约地址的严格管理
和权限控制.
图 7 clone() 函数
1.3 透明代理
2019 年, EIP-1967 提案 [54] 规定了透明代理 (transparent proxy), 旨在避免函数冲突, 并确保只有管理员 (admin)
才能调用升级函数. 这意味当普通用户调用代理合约时, 始终会执行实现合约中的函数, 而不会意外触发代理合约
的管理函数. 并且利用代理存储槽 (proxy storage slots) 的方法, 明确规定代理存储地址的位置, 确保代理不会向最
终用户暴露可能与实现合约冲突的函数. 函数调用对于用户来说是透明的. 图 8 展示透明代理的设计结构.
透明代理: EIP-1967
代理存储槽
代理合约 调用地址 逻辑函数
地址权限 other fallback() 地址 V1 现实合约 V1
调用方 检查
proxy admin upgrade() 地址 V1 现实合约 V2
图 8 透明代理
1) 透明代理 (transparent upgradeable proxy) 主要实现 3 个核心功能.
● 构造函数: 初始化 admin 和实现合约地址.
● fallback(): 回调函数, 将调用委托给实现合约, 并禁止 admin 调用.
● upgrade(): 升级函数, 改变实现合约地址, 仅允许由 admin 调用.
2) 管理员合约 (proxy admin): 负责管理 admin 地址和升级功能.
3) EIP-1967 Proxy: 规定代理存储地址的特定位置, 并确保数据位置一致, 以防止存储冲突.
4) 实现合约 (implementation): 管理核心业务代码.
透明代理首先检查调用方的地址, 依据其权限将调用委托给底层逻辑代理. 如果调用方是 other 地址, 则代理
合约只接受调用实现合约, 通过 delegatecall() 将调用转发给当前存储的实现合约地址. 实现合约在代理合约的上
下文中执行, 并返回结果给代理合约. 代理合约再将结果返回给用户; 如果调用方是代理的管理员, 则代理不会接

