这是一个很好的问题!虽然 UUPS 逻辑合约确实增加了升级函数,但它仍然比透明代理更省 Gas。以下是详细的原因和解释:
1. UUPS 的升级函数对 Gas 的影响
- 在 UUPS 模式中,升级逻辑(如
upgradeTo)确实存在于逻辑合约中,但这些函数只在升级时调用,而不是在每次用户交互时调用。 - 升级操作是一个低频操作,通常只在合约需要升级时才会执行。因此,升级函数的存在对日常操作的 Gas 消耗没有影响。
2. 为什么 UUPS 仍然更省 Gas?
UUPS 的优势主要体现在日常调用的 Gas 消耗上,而不是升级操作本身:
(1) 代理合约更轻量
- UUPS 的代理合约只负责调用转发(
delegatecall),没有额外的逻辑(如管理员权限检查)。 - 透明代理的代理合约中包含了升级逻辑和管理员权限检查,这些逻辑会在每次调用时增加额外的 Gas 消耗。
(2) 减少存储槽的使用
- 透明代理需要额外的存储槽来记录管理员地址等信息,而 UUPS 不需要这些额外的存储。
- 存储操作(
SSTORE和SLOAD)是 EVM 中最昂贵的操作之一,因此减少存储槽的使用可以显著降低 Gas 消耗。
(3) 调用路径更短
- 在透明代理中,每次调用都需要检查调用者是否是管理员(以避免管理员调用逻辑合约的函数),这会增加额外的 Gas 消耗。
- UUPS 没有这种检查,调用路径更短,因此更高效。
3. 升级函数的 Gas 消耗是一次性的
- UUPS 的升级函数(如
upgradeTo)只在合约升级时调用,Gas 消耗是一次性的。 - 升级操作通常由管理员发起,频率极低,因此对整体 Gas 成本的影响可以忽略不计。
4. 透明代理的日常调用更昂贵
- 在透明代理中,代理合约需要检查调用者是否是管理员,以决定调用逻辑合约还是代理合约的升级函数。这种检查逻辑会在每次用户调用时执行,增加了日常操作的 Gas 消耗。
- UUPS 将升级逻辑移到了逻辑合约中,代理合约不需要进行这些检查,因此日常调用的 Gas 消耗更低。
5. 总结
虽然 UUPS 的逻辑合约增加了升级函数,但这些函数只在升级时调用,对日常操作的 Gas 消耗没有影响。相比之下,透明代理的代理合约由于包含升级逻辑和权限检查,会在每次调用时增加额外的 Gas 消耗。因此,UUPS 在日常调用中更省 Gas,而升级操作的成本是一次性的,可以忽略不计。
选择 UUPS 或透明代理需要根据具体需求权衡:
- 如果关注日常操作的 Gas 成本,UUPS 是更好的选择。
- 如果需要更清晰的升级逻辑分离,透明代理可能更适合。