不变性长期以来一直被认为是区块链技术的核心特征和信任基础,确保一旦源代码部署到网络上,任何个人或组织都无法干预或更改既定规则。然而,根据Tan Phat Digital的研究,近年来去中心化生态系统的实际运行表明,绝对的不变性是可持续发展的重大障碍。无法修补的关键安全漏洞、无法更新的监管变化以及添加新功能的需求,促使开发者社区寻找在不破坏地址和数据完整性的情况下“升级”智能合约的方法。
本研究深入分析了允许部署后逻辑更改的技术,从流行的 Proxy 模型到有争议的 Metamorphic 技术,并评估了风险安全风险和相关治理障碍。
不变性的悖论与需要可变性
从技术上讲,智能合约的字节码一旦永久存储在以太坊等区块链上的区块中,就无法更改。每个合约地址都与一段固定的代码相关联。然而,程序员可以通过完全分离状态存储和逻辑执行来模拟可变性。这就产生了一个破坏层,用户与固定的“外壳”进行交互,但实际行为是由可变实体驱动的。
对可变性的需求源于三个主要因素:安全维护、产品演进和风险管理。如果不及时解决,一个小的逻辑错误可能会导致数百万美元的资产损失。在传统金融系统中,维护停机是很正常的,但在协议24/7运行的区块链中,通过逻辑升级“热修复”的能力对于项目的生存至关重要。
区块链平台之间的设计理念比较
当今流行平台之间设计思维的差异:
以太坊(EVM):
默认状态:不可变。
逻辑变更机制:使用Proxy和
delegatecall。升级方式:应用层(应用模式)。
透明度:取决于验证源代码Proxy。
Stellar(Soroban):
默认状态:可变。
逻辑变更机制:直接更改WASM字节码。
升级方式:协议级。
透明度:内置于合约元数据中。
这种差异指出了一种新趋势:以太坊需要复杂的设计模式,而 Soroban 允许合约在协议级别修改自己的字节码,有助于降低因代理实施不正确而产生的风险。
另请参阅:防范恶意智能合约
代理合约基础设施和操作码 DELEGATECALL
EVM 兼容网络上的大多数升级技术都基于单个操作码:delegatecall。当合约 A(代理)对合约 B(实现)执行delegatecall时,合约 B 的代码将被执行,但执行上下文(存储、余额、msg.sender)完全属于合约 A。
这种机制允许开发人员部署新版本的逻辑(实现 V2),只需更新 Proxy 中的地址变量以指向 V2。从用户角度来看,交互合约地址保持不变,账户余额和相关数据不受影响,但处理规则发生了变化。
现代代理模型的深入分析
代理部署需要仔细考虑gas成本、管理安全性和可扩展性。
透明代理模式(TPP)
该模型解决了“函数选择器冲突”问题根据呼叫者身份分离访问。如果调用者是管理员,他们只能看到代理的管理功能。如果是用户,则调用将委托给实现。
缺点:由于必须执行管理员身份检查,每笔交易需要花费约 2,100 额外的 Gas 费用。
通用可升级代理标准(UUPS)
UUPS (EIP-1822) 将升级逻辑放入实施合约本身。代理现在只是一段极简代码。
优点:对于最终用户来说非常节省gas(仅花费大约100额外gas)。
风险:如果新升级缺少
upgradeTo函数,合约将被“变砖”(永久锁定),无法再升级。
Beacon Proxy Pattern
该方案适合大规模部署类似合约。代理不存储逻辑地址,而是指向中间合约(Beacon)。更新 Beacon 时,将同时更新数千个依赖合约。这是一种有效的机制,但产生了巨大的“集中弱点”。
钻石标准(EIP-2535)
这是最复杂的升级架构,允许单个代理(钻石)委托给许多不同的实现(Facet)。
钻石代理:单点交互,存储映射
Facets:独立的逻辑合约帮助系统克服 EVM 的 24KB 限制。
DiamondCut:管理功能允许添加、替换或删除特定功能。
Diamond Loupe:界面允许检查当前结构钻石。
查看更多:什么是智能合约审计?
打破界限:变形合约而CREATE2
更极端的改变逻辑的方法是“变形契约”。与代理不同,此技术允许使用 CREATE2 操作码完全替换同一地址的字节码。
“转换”过程涉及使用未指定的 init_code(初始化代码)。 init_code 可以编程为调用另一个合约并检索新的可执行字节码,而不是包含固定逻辑。当需要更改时,开发人员执行命令SELFDESTRUCT删除旧合约,并使用具有相同salt值的CREATE2在同一地址部署新代码。这种技术通常被认为是危险的,因为它会清除状态(存储)并且可以被用来欺骗审计组织。
变量合约中的安全风险矩阵
允许逻辑更改会引入特定的安全漏洞:
存储布局冲突:在新版本更改变量顺序时发生,导致错误数据被覆盖。例如,Audius 黑客攻击 (2022) 由于新变量覆盖了初始化标志,导致项目损失了 600 万美元。
初始化漏洞:由于代理不使用
构造函数,因此它们需要initialize()函数。如果您忘记调用此函数,攻击者可以接管管理员权限。虫洞黑客攻击(3.2亿美元)就是这种错误的典型例子。管理后门:一些欺诈项目在吸引资金后故意使用代理安装恶意代码。
后门的流行类型:
铸造后门:管理员创造无限
黑名单/冻结:锁定账户,使用户无法提取或出售代币。
引流逻辑:修复提现功能,将资产直接转移到攻击者的钱包。
代理重定向:将实现地址重定向到恶意地址
治理策略和多层防御
为了平衡灵活性和安全性,Tan Phat Digital建议项目采用严格的治理流程:
使用多重签名:升级权必须由具有 2/3 或 3/5 批准门槛的多重签名钱包(如 Gnosis Safe)持有,以消除个人弱点。
时间锁定机制:对所有升级命令应用至少 24 小时至 7 天的时间锁定。这使得社区有时间检查源代码或在检测到异常时撤回资产。
维护存储间隙:在存储中保留间隙,以确保将来的升级可以添加变量而不会引起冲突。
持续审核:每次逻辑升级都应被视为一个新项目,并且必须经过独立的审核流程。
常见问题(FAQ)
1.什么是代理合约?为什么它很重要?
代理是一种保存数据和资产的中介合约,而执行逻辑驻留在另一个合约中。它允许在不更改合约地址的情况下进行逻辑更新,有助于保持用户体验和协议连续性。
2.是否可以将合约从 Solidity 升级到 Vyper?
可以。因为Solidity和Vyper都被编译成在EVM上运行的字节码。只要新Vyper版本的存储布局与旧Solidity版本完全匹配,交换逻辑在技术上是可能的。
3.如何在 Etherscan 上检查合约是否为代理合约?
用户可以使用 Etherscan 的“代理合约验证”工具。符合EIP-1967标准的合约会有“Read as Proxy”或“Write as Proxy”选项卡,让您可以看到后台运行的实际实现地址。
4. 24KB 源代码限制是多少?Diamond Standard 如何解决这个问题?
EVM 将合约的字节码大小限制为最大 24KB。钻石标准 (EIP-2535) 允许将逻辑分解为多个“Facet”(合约片段),从而使单个地址可以执行几乎无限量的逻辑。
5。到底什么是“存储冲突”?
这是指代理合约和逻辑合约不小心使用了内存中的同一位置(槽)来存储两个不同的变量。这会导致一个变量覆盖另一个变量,从而可能导致严重的逻辑错误或允许攻击者接管。
6。为什么项目在升级时需要Timelock?
Timelock会在升级生效之前创建一个等待期(通常>=24小时)。这让社区有时间做出反应、检查源代码,或者在不信任新更新时撤回。
7.透明代理和UUPS有何不同?
透明代理将升级逻辑放在代理中,消耗更多的gas,但更安全,因为它明确分离了管理员权限。 UUPS将升级逻辑放在Implementation中,这样可以节省更多gas,但风险较高,因为如果升级失败,合约将永远无法再次修复。
8. Metamorphic 合约与常规代理有何不同?
代理将字节码保留在该地址,仅更改其指向的逻辑地址。 Metamorphic 合约直接替换了站点本身的整个源代码,但清除了所有现有数据和残留。
9. EIP-6780 如何影响合约升级?
EIP-6780 限制 SELFDESTRUCT 命令仅在启动合约的同一事务中运行。这会禁用大多数旧的“变形”技术,这些技术依赖于随时销毁合约来重新部署新代码。
10。 “存储间隙”有什么用?
它是放置在基础合约中的空变量数组(通常是uint256 __gap)。它预留了存储空间,以便将来在升级时,开发人员可以向其中添加新变量,而不会扭曲遗留合约的存储布局。
11.合约可以从“可升级”转换为“不可变”吗?
可以。开发者可以执行最终升级以删除升级功能或将管理员(Owner)移至“零”地址(0x0)。一旦升级功能消失,逻辑就被永远锁定。
12。 “未初始化代理”有什么风险?
如果开发者忘记在部署后立即调用初始化函数(initialize),任何人都可以调用它成为合约所有者。虫洞黑客攻击就是一个典型的例子,这个错误几乎造成了数亿美元的损失。
13.实际进行升级的合约比例是多少?
研究表明,以太坊上只有约 3% 的合约是为升级而设计的,其中只有约 0.34% 在部署后实际进行了升级。
14.什么时候使用 Beacon Proxy?
当您需要部署数千个相同的合约(例如智能钱包)时使用它。您无需更新每个合约,只需更新“Beacon”上的单个地址,所有钱包都会同时更改其逻辑。
15。什么时候应该使用“合约迁移”而不是Proxy?
当您需要更改核心数据结构(例如从ERC-20更改为ERC-777标准),而Proxy由于存储槽冲突而无法处理时。此时,你必须部署一个全新的合约,并要求用户将资产转移到新地址。
智能合约可变性的未来
升级技术的发展打破了静态区块链源代码的刻板印象。虽然不变性是最终的理想,但受控的可变性对于应对安全缺陷和市场变化至关重要。
未来的趋势将是通过 DAO 和使用 OpenZeppelin 升级插件等自动化测试工具来分散升级权限。当透明且正确地实施时,可变性不会减损区块链的价值,而是会创建一个具有弹性且能够持续进化的生态系统。
分享








