区块链最终性工程指南
许多安全关键型链下应用使用简单的区块延迟来确定最终性:即交易在区块链账本中变得不可变的时刻(若不付出极端经济成本则无法"撤销")。但这对于大多数网络来说并不足够,并可能成为依赖交易最终性的中心化交易所、多链桥和L2扩容解决方案的单点故障。若未充分考虑区块链的最终性标准,看似最终的交易可能被恶意行为者通过称为"重组"的事件从链上清除,导致双花攻击和从应用中窃取价值。
我们研究多个链下应用和L2网络后,发现两个L2客户端Juno和Pathfinder要么未检查最终性,要么错误使用区块延迟检测以太坊区块是否最终化。我们向各产品团队披露了发现,随后Juno在v0.4.0版本、Pathfinder在v0.6.2版本发布了修复。本文汇集了我们从这项研究中获得的知识与见解,解释重组的危险、不同最终性机制的差异,以及编写消费各类区块链数据的应用时如何预防双花攻击。
理解重组
当用户向区块链提交交易时,其生命周期在所有链上几乎相同。首先,交易通过区块链的点对点网络传播至区块提议者。提议者接收交易并将其纳入区块后,区块在网络中广播。
问题由此开始:有些区块链未明确定义下一个区块提议者,而明确定义的链需要在该提议者离线时恢复。这些情况导致区块链存在两种或更多有效前进路径(分叉),网络必须确定哪个分叉应作为规范链。
图1:PoW网络上两个矿工同时为槽4提议有效区块
区块链设计时已考虑这些问题,并定义了分叉选择规则来确定规范分叉。分叉有时可能持续多个区块,网络的不同部分认为不同的链是规范链。
图2:PoW网络中槽4、5、6的候选区块快速连续挖出并构建在不同父块上,导致分叉
假设网络软件无漏洞,分叉最终会被调和,导致单个分叉成为规范链。其他分叉、其区块和交易将从区块链历史中清除,称为重组。
当交易通过重组从链上清除时,该交易可能重新排队等待纳入新区块,或其排序或区块号更改为规范链中的值。攻击者可利用这些更改修改交易行为或完全取消交易,具体取决于其所处分叉。
图3:经过三区块重组后的网络。区块4a、5a、6a中的交易不再属于规范链
重组是区块链生命周期的正常部分,可能因区块生产速度、网络延迟和网络健康状况等因素定期发生。但攻击者可利用(甚至策划!)重组进行双花攻击:攻击者提交存款交易,等待其被纳入区块,然后策划重组将其交易从规范链清除,同时在链下应用中获得存款信用。
正因如此,最终性考量至关重要。若中心化交易所或桥接器索引非最终存款交易,则易受攻击者通过引发区块链重组进行的双花攻击。
区块链使用多种不同共识算法,因此每条链都有多种不同的最终性条件需考虑。
概率性最终性
示例:比特币、币安智能链(BEP-126前)、Polygon PoS、Avalanche——或任何基于PoW的区块链
使用概率性最终性的链独特之处在于其区块从未真正最终化——而是随时间推移变得概率性最终或更"最终"。给定足够时间,先前区块被重组出链的概率趋近零,因此区块变为最终。
在大多数概率性最终链中,确定规范链的分叉选择规则基于哪个分叉构建了最多区块,称为中本共识。在中本共识下,若向网络广播更长的链,即使该链排除已包含在较短链中的区块/交易,链也可能重组。
概率性工作量证明网络上的双花攻击
针对工作量证明网络的经典攻击是51%重组攻击。此攻击需要链下交易所、桥接器或其他应用极快索引存款交易,理想情况下区块产生后立即索引或延迟极短。
攻击者必须积累、购买或租用足够计算资源以控制网络大部分算力。这意味着攻击者有足够资源私下挖取比诚实规范链更长的链。注意这是概率性攻击;控制网络51%算力使攻击最终必然成功。理论上攻击者可用远低于51%算力进行双花攻击,但可能需要多次尝试才能成功。
准备就绪后,攻击者在公共规范链上提交交易,将资金从其钱包存入交易所/桥接器。
随后,攻击者必须创建第二笔冲突交易,将资金从其钱包转移至另一个攻击者控制地址。攻击者配置其挖矿资源以挖取包含转移交易而非存款交易的新分叉。
图4:攻击者创建包含转移交易而非存款交易的私有分叉
鉴于攻击者控制网络大部分算力,最终其私有分叉将比规范分叉拥有更多区块。一旦获得存款交易信用且私有分叉区块数超过规范链,攻击者指示其网络向遵循规范链的诚实节点发布私有链区块。
诚实节点应用"最长链"分叉选择规则,触发围绕攻击者更长链的重组,并排除包含攻击者存款交易的区块。
图5:攻击者发布私有分叉后,网络重组并清除包含其存款交易的分叉
实际上,这使攻击者能够"双花"其币:交易所或桥接器为币授予攻击者信用,而币仍存在于攻击者控制钱包中。
测量概率性最终性
由于概率性最终链未定义最终性条件,必须基于目标交易/祖先区块后经过的区块数概率性测量最终性。给定祖先区块上构建的区块越多,攻击者重组成本越高。
正确区块延迟应基于历史因素和经济因素,为应用索引延迟选择两者中较大值。
历史因素中,链下应用开发者应考虑链重组频率和典型重组规模。若区块生产是概率性的(如PoW网络),则应考虑更大延迟以补偿极短时间内产生多个区块的可能性。
经济因素中,应考虑执行给定经济价值交易重组攻击的成本。鉴于51%攻击的概率性,工程师应构建安全边际,并考虑25%攻击而非51%攻击的成本。例如,若对比特币执行25%攻击、六区块重组攻击最低成本为50万美元,则接收50万美元存款的链下应用应等待至少六个区块后再认为交易最终并索引。
使用Crypto51,我们可计算以25%攻击阈值(截至2023年6月)进行7.5万美元存取款所需的区块延迟。
- 比特币:最终性需两个区块(约20分钟)
- 莱特币/狗狗币:最终性需48个区块(约两小时)
- 比特币现金:最终性需103个区块(约17小时)
- 以太坊经典:最终性需3,031个区块(约11小时)
- 以太坊PoW:最终性需23,600个区块(约89小时)
- Zcash:最终性需1,881个区块(约40小时)
这些延迟代表特定存款金额在单个时间点的数据。随着各网络算力增减,最终性时间也会变化且必须相应更新。各网络挖矿算力与链代币价格高度相关,因此算力可能快速下降,需要集成应用监控和快速响应。未及时调整最终性延迟将导致双花攻击。
对于某些类交易所应用,可通过链上监控、自动系统暂停、交易限额和提款延迟减少工作量证明链的最终性延迟。但这些机制可能过度复杂化应用逻辑并使其易受其他形式攻击。
应注意算力极低的链可能易受远超过网络51%算力的攻击。现有服务提供易于租用的算力容量,可能超过链算力多倍。此类情况下,建议避免与该链集成,或基于可租用算力容量计算最终性。
使用权益证明/权威证明的概率性链需稍不同考量,因为区块提议者不能自由进入提议者集,且可能具有与工作量证明网络不同的分叉选择规则。
- 币安智能链:经过区块数等于验证者集中验证者数量的三分之二时,区块视为最终。最终性需20个区块(约60秒)。
- Polygon PoS:集成者应使用L1状态根检查点作为最终性度量。当包含给定交易的状态根检查点在L1最终化时,Polygon交易可视为最终。状态根检查点约每30分钟发生一次。
可证明最终性
延迟最终性示例:以太坊PoS(Casper FFG)、Polkadot(GRANDPA)、Solana 即时最终性示例:Cosmos、Celestia、Algorand、Aptos
使用可证明最终性的系统为最终性做特殊考量,以确保其比大多数概率性最终链构建更快发生且具有更好经济保证。
可证明最终性有两种类型:具有即时可证明最终性的链和具有延迟可证明最终性的链。
具有即时最终性的链不需要链下应用特殊最终性考量。网络发布的所有区块根据定义立即可证明最终。
具有延迟最终性的链对新产生区块和最终化区块有独立共识机制。这些链通常比即时最终性链具有更优活跃性,但代价是增加复杂性、易受重组影响以及链下应用更复杂集成考量。
图6:延迟最终性链。最终性边界右侧的区块可能被重组,不应由交易所或桥接器索引
延迟最终性链上的双花攻击
历史上,大多数区块链没有可证明最终性,因此桥接器、交易所和其他链下应用使用区块延迟测量它们集成的任何新链的最终性。
但对于具有可证明延迟最终性的链,存在最终性机制可能停滞或失败的情况,如2023年5月以太坊最终性小工具Casper FFG停滞的事件。当最终性机制失败时,链可能继续产生区块,创建可能被漏洞或攻击者重组的长串未最终化区块。
以太坊事件期间,链最终性机制停滞了九个epoch——相当于139个区块的确认(考虑错过槽提议后)。此时,大多数桥接器/中心化交易所使用区块延迟规则确定以太坊上交易的最终性,延迟范围从14个区块到100个区块。
若以太坊最终性事件由攻击者策划,攻击者可能通过策划极长重组对这些桥接器/交易所进行双花攻击。
检查最终性
对于延迟最终性链,如先前示例所示,区块延迟不是"等待"区块最终化的充分方式。相反,应用必须查询链的RPC以获取确切最终性条件,确保正在索引的区块实际最终。
以太坊权益证明
以太坊JSON RPC为各种端点定义"默认区块"参数,应设置为"finalized"以查询最近最终化区块。使用eth_getBlockByNumber(“finalized”, …)获取最近最终化区块。该参数可用于其他端点,如eth_call、eth_getBalance和eth_getLogs。
Polkadot
调用chain.getFinalizedHead()获取最近最终化区块的区块哈希,然后使用chain.getBlock()获取与该哈希关联的区块。
Solana
使用getBlocks() RPC方法,承诺级别设置为finalized。
可证明最终性的谎言
可证明最终性/权益证明系统的一个主要警告是无法提供强主观性保证。区块链的主观性指从创世同步的节点是否始终到达相同链头,以及攻击者能否操纵同步节点的最终状态。
在工作量证明区块链中,为部分同步节点创建替代链的成本等于矿工从创世到规范链头执行的所有工作,使得任何主观性攻击对工作量证明网络不切实际。
但在权益证明网络中,创建替代链的成本只有一个要求且成本未知可能为零:链历史验证者的私钥。历史验证者的密钥可通过多种方式获取;私钥可能泄露或暴力破解,或不再使用其密钥的验证者可能出售它们。
旧验证者密钥的重复使用创造了长程同步攻击的可能性,新同步节点可能表现得好像特定交易已提交并最终化,而实际上它从未提交到规范链。
为防止长程同步攻击,运营团队应始终从弱主观性检查点开始节点同步。这些检查点本质上用作创世区块,为节点同步提供可信起点。弱主观性检查点可从已同步节点获取或通过社交过程获取。
L2的特殊情况
示例:Arbitrum、Optimism、StarkNet、Scroll、ZKSync、Polygon zkEVM
L2网络独特之处在于它们不像普通区块链那样有共识机制。在普通区块链中,验证者集必须就状态转换函数的输出达成共识。在L2网络中,是底层L1网络负责验证状态转换函数。最终,这意味着L2网络的最终性条件取决于底层L1的最终性条件。
当L2定序器或证明者接收交易时,它为交易排序/生成证明,然后返回L2交易收据。定序器/证明者接收足够交易后,将交易组装成批次提交到L1网络。
图7:用户交易在L2网络上的流程。值得注意的是,定序器/证明者在交易在L1上包含或最终化前很久向用户提供交易收据
对于ZK-Rollups,批次包含代表批次中每个交易执行的证明。L1合约验证证明,一旦批次交易最终,证明中包含的所有L2交易也最终。
对于Optimistic Rollups,批次包含批次中每个交易的调用数据。L1合约不运行任何状态转换函数或验证调用数据有效性。相反,Optimistic Rollups使用挑战机制允许L2节点质疑L1批次。这意味着提交到Optimistic Rollup的交易只有在包含在L1上的批次中、批次及其父批次有效且L1交易最终后才可视为最终。
检查最终性
要确定L2交易的最终性,必须验证承诺/证明交易已在L1上包含并最终化。L2提供商通常提供方便链下集成商使用的RPC方法以确定给定L2交易的最终性。
Arbitrum Nitro/Optimism
Arbitrum和Optimism节点都实现以太坊JSON RPC,包括"finalized"区块参数。因此,可使用eth_getBlockByNumber(“finalized”, …)确定最终性。
StarkNet
StarkNet的定序器提供商有getTransactionStatus()函数,报告交易在StarkNet交易生命周期中的状态。tx_status为ACCEPTED_ON_L1的交易可视为最终。
ZkSync Classic
ZkSync的v0.2 API有多个接受最终化参数的端点。
- /accounts/{accountIdOrAddress}/{stateType}可将stateType设置为finalized
- /blocks/{blockNumber}接受lastFinalized作为blockNumber参数
- /blocks/{blockNumber}/transactions{?from,limit,direction}接受lastFinalized作为blockNumber参数
实践安全最终性
与区块链领域其他近期创新一样,可证明最终性极大地改变了区块链可提供的安全保证类型。但链下或多链应用开发者必须了解不同架构的特定最终性要求,并在必要时使用正确技术确定交易是否最终。
确定最终性的旧技术(如区块延迟)对新架构不充分,使用不正确最终性标准可能使应用面临双花攻击风险。
如果您正在设计新区块链或链下应用并关注最终性问题,请联系我们。