审核依赖于 软分叉/限制条款 的 Layer 2 方案

作者:Peter Todd

来源:https://petertodd.org/2024/covenant-dependent-layer-2-review

链上钱包实现了从交易到交易的(大致上)一一映射:对于用户要执行的一笔 经济 的交易,大致上需要一笔 区块链 交易。交易的聚合、coinjoin、cut-through,等等技术,都稍稍偏离了一点点,但大体上,我们这个说法还是对的。

闪电通道则实现了一种 多对一 映射:闪电通道的魔法就在于,实质上不限量的经济交易可以在一条通道内发生,而通道自身绑定在一个未花费的交易输出(UTXO)中。本质上,我们抓住了 “时间” 维度 —— 交易 —— 并通过让这个维度塌缩实现了显著的扩容。

但是,让每个用户创建一个 UTXO 是不够好的(至少可以争议)。所以,出现了许多提议,尝试让多个用户可以自主保管地共享一个 UTXO 来实现更大的扩容效果。这一次,塌缩的是 “空间” 维度 —— 用户 —— 化为一个 UTXO。

我在这里的目标是审核所有这些提议,找出它们共有的技术模式,找出它们所需的新的操作码类型或软分叉升级,然后建立一个综合性的表格,将所有方案都放入表格中。在这个过程中,我们也会定义什么是 “Layer 2 协议”、闪电网络已经能够实现何种扩容,并理解要实现这些提议,我们需要对交易池(mempool)作那些升级。

感谢 Fulgur Ventures 资助这项研究。他们对本文的内容没有编辑权限,在正式出版之前也没有审核过。

感谢 Daniela BrozzoniSarah Cox 等人在出版前的审核。

1 定义

1.1 什么是 “Layer 2”?

通常人们会给 “Layer 2” 采用宽泛的定义,以至于连银行一样的实体(例如 Liquid)也可以被定义成 Layer 2。出于本文的目的,我们会采用一种更狭窄的定义:Layer 2 是一种以比特币为主导(Bitcoin-denominated)系统,其存在目的是允许 BTC 以高于链上交易的频率在相关人之间转移,并且:

  1. 考虑了 系统内 的惩罚和代价之后,没人能从系统中偷盗资金而获利。系统外的成本和惩罚,比如声誉损失、法律后果,等等,在我们的定义中是 不考虑的
  2. (优先)资金的真正所有者可以单方面取出自己的资金(减去交易手续费),而无需任何第三方的合作。

第一项是有必要的,因为我们希望我们的 L2 系统可以表示价值很小、小到无法在链上表示的数额和交易。举个例子,在闪电通道中,HTLC 可以有小到无法在链上表示的面额。在这种情况下,HTLC 的价值会被加到承诺交易的交易手续费中。虽然闪电节点可以有针对地关闭通道来 “盗取” 一个粉尘 HTLC,但这样做是非常昂贵的 [1],代价超过 HTLC 本身的价值,所以盗窃是无利可图的。

第二项则是说,单方面取款总是我们的首要设计目标 [2]

在这个定义下,闪电通道会被认为是一种 L2 系统。但是,像 Liquid、Cashu、和 Fedemint 这样的系统,则 不是 L2,因为是另一方(或几方)控制着你的资金。“客户端验证(client-side validation)” 方案(比如 RGB)也不是 这个定义下的 L2,因为它们是无法免信任地转移 BTC 本身的。最后,“Statechains”也不符合这个定义(中文译本),因为如果 Statechain 实体(服务商)有意不遵守协议,就可以偷盗资金。

1.2 什么是 “限制条款”?

……那么,为什么 L2 系统需要限制条款来实现更强的可扩展性呢?

在比特币的脚本编程中,“限制条款” 指的是一种机制,可以提前限制一个交易输出(txout)被花费的方式,从而花费这个 txout 的交易的形式是预先定义好的,或者,以一种不完全取决于电子签名的方式来限制它的花费。在多个参与者之间共享 UTXO 的 L2 系统需要限制条款,因为它们需要限制 UTXO 的花费方式,以实现 L2 协议的规则和激励因素。

1.2.1 递归型限制条款

递归型限制条款是具有这样的属性的限制条款:限制一个 UTXO 花费方式的规则可以递归地应用,无限地延伸到花费交易的子 UTXO 中。递归型限制条款长期被一些人认为是不可取的,因为它们可能导致资金被永远拘限。或者,至少,在没有第三方(比如政府)的许可时就会永远受困。

2 目标

闪电通道是目前 Layer 2 系统中的 “翘楚”。但它也有局限性,即:

  1. 可扩展性 —— 闪电通道目前要求每个终端用户至少要有一个 UTXO [3]
  2. 流动性 —— 闪电通道要资金被绑定在通道中。
  3. 交互式 —— 闪电通道要求支付的接收者在线,以免信任地收取支付。

在评估 Layer 2 系统时,我们的目标是能够在这些关键的局限性上有所提升,最好是不会引入新的局限性。

2.1 闪电通道的可扩展性限制

在真实场景中,“每个终端用户需要一个 UTXO” 意味着什么?因为闪电通道可以无限期运行,分析它的一种办法是搞清楚每年可以创建多少条新的通道 [4]?创建一个 taproot 输出的边际成本是 $43vB$;如果通道的创建可以平摊,也就是许多通道可以在一笔交易中开启,那么其它的交易开销就会变得微不足道,并且每年都可以新开相当多的通道来容纳新的用户。 举个例子,假设 90% 的区块空间都被用来开启新的 taproot 闪电通道:
$$
52{\small,}560\frac{\mathrm{blocks}}{\mathrm{year}} \times 1{\small,}000{\small,}000\frac{\mathrm{vB}}{\mathrm{block}} \times 90% \times 1\frac{\mathrm{channel}}{43\mathrm{vB}} = 1.1,\mathrm{billion}\frac{\mathrm{channels}}{\mathrm{year}}
$$
(结果是每年可以开启 11 亿条新通道)

预估全世界有一半人口拥有智能手机,也就是 43 亿人。所以事实上,每年我们都可以引导有可能用得上闪电网络的人群中的一大比例进入闪电网络。

然而,通道不会永远不关闭。有些时候,用户想要切换钱包、增加或减少通道的容量,等等。改变通道容量最高效的办法就是 “通道拼接”,尤其是 Phoenix Wallet 的实现。

就像通道的开启,通道拼接也可以平摊,以提高效率:多个拼接操作可以共享一笔交易,以减少为添加和移除资金而需要的输入和输出的数量 [5]。因此,每个用户的拼接操作所需的增量区块空间,假设用户使用 musig,是 $43vB$ 的 taproot 输出加上 $57.5vB$ taproot 密钥路径花费的见证数据,总计是 $100.5vB$。如果我们再一次假设 90% 的区块空间都被用于这个用途,那么是:
$$
52{\small,}560\frac{\mathrm{blocks}}{\mathrm{year}} \times 1{\small,}000{\small,}000\frac{\mathrm{vB}}{\mathrm{block}} \times 90% \times 1\frac{\mathrm{splice}}{100.5\mathrm{vB}} = 470,\mathrm{million}\frac{\mathrm{splices}}{\mathrm{year}}
$$
(结果是每年可执行 4.7 亿次通道拼接)

最后,注意,在钱包之间切换闪电通道是可以在一笔交易中完成的,要么是信任新钱包,在资金已经被发到承诺地址后再签名一笔承诺交易;要么是在新旧两个钱包实现中支持合作式 “关闭又开启新通道”。

当然,在闪电通道之外,会有别的比特币应用场景来争夺区块空间,而且很难知道这会怎样转化为手续费率。但这些数字给了我们一个粗糙的估计,说明以当前的技术,至少在技术上,是可能做到支持数亿自主保管的闪电网络用户的。

3 L2 综述

在我们的 L2 定义下,比特币开发者社区一直在讨论的设计模式有两个:

  1. 通道
  2. 虚拟 UTXO

在通道模式中,闪电通道是一个主要的例子,状态的推进是通过参与者交换预先签名的、可以 被挖出(但不代表 “皆大欢喜” 结局)的交易来实现的。这些预先签名的交易会在参与者之间分割一个 UTXO 的价值;经济往来是通过反复使用新的预签名交易改变分割的结果来实现的。因为会有许多有效交易在花费同一个 UTXO,就需要一些激励机制来保证只有正确的交易会真正得到区块确认。

而在 “虚拟 UTXO(V-UTXO)” 设计模式中,Ark 是最显著的例子,V-UTXO 是通过限制条款或多方的约定创造出来的;表示价值的交易 可以 被挖出,从而将各方的 V-UTXO 在链上变成真正的 UTXO,但这样的交易也不代表 “皆大欢喜” 结局。从这个角度看,V-UTXO 也类似于通道。但与通道不同的是,V-UTXO 方案是通过花费 V-UTXO 自身来实现交易的,(概念上)是是用单笔 [6] 预先签名的交易。

而 “皆大欢喜” 设计模式是使用 “所有参与者都同意” 的脚本路径,例如一个 N-of-N 的多签名装置;taproot 是专门为这个概念而设计的,允许密钥路径(通过 musig)成为一个 N-of-N 的多签名装置。假设所有参与者都同意,这一路径会允许资金被高效(且私密)地花费。

有趣的是,因为虚拟 UTXO 在许多方面是 “真实的”,在虚拟 UTXO 上建立通道是非常容易的,只需让虚拟 UTXO 在被挖出时会导致通道所需的 UTXO 被创建即可。在这个意义上,虚拟 UTXO 比通道稍微低层一些。

3.1 闪电网络

截至目前为止,在生成环境中实现的闪电网络,主要基于 BOLT 标准。闪电网络是一系列技术的组合,包括闪电通道和 HTLC、P2P 路由网络、洋葱路由、发票标准,等等。重要的是,闪电网络 不是 一个公示系统,所以 “闪电系统” 的不同模块不需要被所有用户以完全相同的方式采用。出于本文的目的,在我们说 “闪电网络” 的时候,我们采取广义,包括对现有的(典型的)、已被广泛使用的闪电网络协议(们)的易于预见的升级。

如前所述,闪电网络的关键特征是终端用户的可扩展性限制,来自于每个用户都需要至少一个 UTXO 的要求。也就是说,对于闪电网络的 “核心” 路由模块来说 —— 公开的、转发大量交易的闪电节点 —— 这些可扩展性限制并不是很大的困扰,因为只要终端用户的数量比路由节点多得多,闪电网络就能良好运作,每一条公开的、用户支付转发的通道都可以瞬时地轻松处理大量交易。这也是为什么许多新提出的 L2 系统都被期望能够参与闪电网络。我们也可以观察到,现有的、并不那么符合 L2 标准的系统,比如 Cashu,要重度依赖于闪电网络,才能真正变得有用:Cashu 的主要用法可能就是发送和收取闪电支付。

3.1.1 非交互式通道

这种构造通过使用 OP_CTV 来减少交互需求、优化闪电通道。不过,它并不能优化 “每个用户一个 UTXO” 的可扩展性限制,所以我们不会进一步讨论它。

3.2 通道工厂

在这种构造中,我们可以让多方协调进入一个 n-of-n 的多签名地址,与之匹配的一笔预签名交易会花费这个多签名地址、创造出 n个不同的 UTXO 来分割资金。而这 n 个 UTXO 分别都会用作一个支付通道。这些通道的安全性跟直接在链上开启是相同的,因为在需要将通道状态发布到链上的时候,分割资金的交易可以被挖出。这可能可以节约链上的空间,因为当通道关闭的时候,因为 —— 理论上 —— $n$ 个参与者可以合作一次性关闭所有 $n$ 条通道。

因为通道工厂是协调型 UTXO,是 可以 被挖出的,但在愉快结局中并不被期望要实际挖出,所以它是 V-UTXO 的一个 非常 原始的例子。

通道工厂的实现并不要求任何软分叉。但是,上面所述的简单的通道工厂可能在参与者稍微多一些之后就会变得不实用,因为需要用户的协作才能真正实现扩容的好处。因此,OP_Evict 或者 CTV(通过 txout 树)这样的限制条款提议可能会带来帮助,它们允许发布更细粒度的结果 —— 单方可被弹出到链上,而无需强迫所有人都同时出现在链上。

3.3 Eltoo/LN-Symmetry

因为 Eltto 是一个糟糕的容易引起混淆的名字,我们在下文中只使用更新后的名称 “LN-Symmetry”。

Poon-Dryja 通道惩罚发布不正确的状态的行为来激励发布正确的状态,LN-Symmetry 则反其道而行之,允许不正确的状态用额外一笔交易来更新。它的好处是通过移除惩罚的复杂性简化了闪电通道。不过,在不可信任的环境中,它可能也会有不利之处,因为可以说为了遏制其中,惩罚是有必要的。

LN-Symmetry 需要一个软分叉来启用 SIGHASH_ANYPREVOUT,以允许新的状态交易可以重复花费旧的状态交易。

就其自身而言,LN-Symmetry 并不能为传统的闪电通道带来扩展性能提升。但其支持者们主张它会让通道工厂更容易实现。

3.4 Ark

Ark 采用了新的方法来实现交易扩容:完全可转移的虚拟 UTXO(V-UTXO),这些虚拟 UTXO 可以在原子化的 [7] 链下交易中合并及分割。在 Ark 中,一个中心协调者 “Ark 服务商(ASP)” 给用户提供定义好时限(比如 4 周)的 V-UTXO。这些周期叫做 “轮次”。这些 V-UTXO 是通过资金池交易输出创造出来的,每一轮会创造一次,通过某种机制(比如 CTV)来让单个链上交易输出能够承诺一棵 V-UTXO 的树。轮次的过期机制是 Ark 实现可扩展性好处的关键:在一轮的末期,资金池交易的输出会解锁,允许 ASP 单方面在一笔小体积的交易中用一个签名来花费它。因为轮次有过期时间,被资金池交易输出创建出来的 V-UTXO 也就有了过期时间:持有 V-UTXO 的用户必须要么在相应池交易输出过期之前花掉这个 V-UTXO,要么将它发布到链上(单方面取款)。

为了转移 V-UTXO,Ark 协调者要一同签名花费一个或多个 V-UTXO 的交易,并让交易仅在 另一个 轮次中创造出一个或更多其它 V-UTXO 时才会生效。结合一些精心设计的超时机制 —— 完整的细节要看 Ark 的文档 —— 这一依赖就是让 V-UTXO 的花费变得免信任的地方:除非新的 V-UTXO 在另一个池交易中创造出来,旧的 V-UTXO 就无法在链上(随着池交易输出被花费而一并)取走。有一些办法可以实现这种依赖。但确切的细节跟本文的目的不相关。

注意,这意味着一个 ASP 将同时操作多个活跃中的轮次。新的轮次会被频繁创建,以允许现有轮次中的资金被转移。但现有的轮次会跟新的轮次重叠,因为它们一般会在新的轮次(新的池交易)创建之后过期。

3.4.1 Ark 的经济模型

在一个 V-UTXO 被花费掉的时候,ASP 必须在一个表示新轮次的池交易输出中提供匹配的 BTC。但是,在当前的轮次结束之前,他们是无法动用被花费 V-UTXO 的价值的。因此,V-UTXO 的花费有一个成本:货币的时间价值,这是因为 ASP 必须垫付资金。

确切地说,这个代价是在 V-UTXO 被 花费 的时候才产生的。在 V-UTXO 没有被花费的时候,它代表着一个非常真实的、可以被发布到链上以单方面取出资金的潜在 UTXO;用户自己控制着自己的资金。然而,为了花费这个 V-UTXO,ASP 必须创造一个 新的 池交易输出,用的是 ASP 从别处获得的资金,而被花费的 V-UTXO 中的资金,在其轮次到期之前,是不能为这个 ASP 所用的。

因此,花费一个 V-UTXO 需要一个短期的贷款,以覆盖从现在到轮次过期的这段时间。意思是,随着 V-UTXO 的老化(逐渐逼近轮次的到期时刻),花费一个 V-UTXO 的流动性成本会逐渐下降 —— 理论上 —— 最终趋于零(也即在轮次最终过期的时候)。

最后,还要记住的是,花费一个 V-UTXO 的成本是跟被花费的 V-UTXO 的 大小有关的,而 不是 由交给接收者的数额决定的。这意味着,有意直接转移多个 V-UTXO 的钱包(与之相对的是为了(例如)基于 V-UTXO 的闪电通道而管理一个 V-UTXO 的钱包)需要作出取舍:决定将一笔资金分割成多少个 V-UTXO。只留一个 V-UTXO 可以尽可能降低单方面取款的代价,但会让基于流动性的交易手续费变得最大;分割成许多 V-UTXO 则正好相反。这跟链上比特币以及闪电交易的经济模型都完全不同。

什么是流动性成本?截至本文撰写之时,闪电网络钱包 Phoenix 为持续 1 年的通道流动性收取 1% 的手续费;在最差请胯下,Phoenix 将不得不将资金绑定 1 年时间。然而,这里面的假设是这些流动性没有被使用。很有可能,对 Phoenix 来说,资金成本在事实上高于一年 1%,但他们假设普通客户用尽这些入账流动性的时间会短于一年。Phoenix 也从交易手续费中赚取收入,因此也能补贴通道流动性。最后,Phoenix 还有可能不赚钱!

美国的国债(US Treasury Bill)收益率可以给我们另一个估计。在本文撰写之时,3 月期的国债收益率大概是年化 5% 。因为美元的通胀会使这个收益率有水分,出于分析的目的,我们就假设以 BTC 为本位的资金的流动性成本是年化 3%。

如果一轮长 4 周,那么交易的流动性成本会从 $3% / \frac{52}{4} = 0.23%$ 开始,逐步降低到 0 。假设用户在当前轮过期的两周之前移动资金,为实现资金的自主保管而需支付的流动性成本大约是年化 1.5% 。另一方面,如果用户一直等待到最后一刻 [8],这个流动性成本将接近于零,风险是错过到期时间。

用户可能不会认为这代价很便宜。而且,这个代价假设了每一轮的成本都是固定的,并且已经通过大量参与者来摊销交易手续费和其它代价,使它们都已经变得微不足道。

但如果这个固定成本并不小呢?假设一个 ASP 有1000 个用户,平均一个小时创建一笔池交易。在 4 周时间里,就会有 672 笔链上交易。这意味着,只是为了保管自己的资金,这个 ASP 的用户整体上就必须为几乎跟用户数量一样多的交易支付手续费!对他们来说,如果都跑去开启自己的闪电通道,可能还会更便宜,而且 ASP 还会让他们等待一个小时来确认交易。

3.4.2 冷启动 Ark

一个只有少数用户的新 ASP 会面临一个困局:要么 ASP 的轮次不那么频繁地发生,从而用户需要等待很长时间才能等到相应的轮次收集到足够多的 V-UTXO 来实现有用的可扩展性喝交易手续费减免;要么,ASP 的池交易发生得很频繁,然后每个用户都要支付较高的交易手续费。如我们在上一节讨论的,它可能需要大量的用户来摊销频繁发生的轮次以及相应的池交易。

由于存在过期时间,这个问题会变得更加严重,甚至比闪电通道要面临的更严重:至少一条闪电通道可以无限期有用,在一条通道开启之后,它可以在接下来几个月里逐步摊销。其次,因为轮次会过期,在创建支持这些轮次的交易输出的 时机 选择上,不够灵活:如果高手续费的情形持续一周或两周,即将过期的池交易输出的用户就别无选择,只有(集体)支付高手续费率来维持资金的保管。而在闪电通道中,开启通道的时机选择会灵活得多。

虽然 Ark 的作者一开始想得非常乐观,认为只需几秒就可以创建新的一轮,但是,如果交易费无法得到补贴,Ark 的初次启动也许只能发生在可以等待几个小时来确认交易的应用场景中。

3.4.3 交互性

非托管的 Akr 是一种高交互需求的协议:因为你的 V-UTXO 会过期,你需要在过期之前跟 ASP 交互,不然,ASP 可以取走你的资金。这种交互需求也是无法外包的:相比之下,闪电通道有 “瞭望塔”,可以遏制你的对手尝试欺诈你 —— 即使你的节点离线了,而 Ark V-UTXO 的持有者为了免信任,必须使用自己的私钥来刷新资金。在 Ark 中,与瞭望塔最接近的东西是签名交易以允许瞭望塔在到期之前代你单方面取回资金,而这会有高昂的交易费成本。

考虑一下,要是资金所有者离线,它的 V-UTXO 会发生什么事:在轮次过期之后,ASP 需要回收资金,以应对未来轮次的流动性需要。如果一个 V-UTXO 的持有者离线,将 V-UTXO 发布到链上将面临高昂的交易代价,因为 ASP 需要取出多层的 V-UTXO 树上的资金。ASP 可以在一个新的轮次中重新创建出未花费的 V-UTXO,但是,从 V-UTXO 持有者的角度看,这不是免信任的,因为他们将无法在缺乏来自 ASP 的数据 [9] 的前提下花费这些 V-UTXO。ASP 也可以直接将未花费的 V-UTXO 记录成托管的余额。甚至可以有没收资金的条款!

我个人的看法是,考虑到 Ark 中自主保管的代价并不便宜,许多用户会转而选择可以自动滚动资金到新轮次中的 ASP、直接接受每一轮的末尾都可能出现欺诈的风险。这比预防性转移资金以保证资金安全(例如,不会因为没有及时打开手机、控制钱包转移资金)要更便宜。

3.4.4 更高级的 Ark

使用更高级的限制条款来减少 Ark 的流动性需求,也许是可信的,如果典型的情形是流动性会在一轮中全部用完的话。举个例子,我们假设一个交易池输出中所有 V-UTXO 总价值的 50% 会被花掉。如果 ASP 可以仅回收交易池输出的一部分的话,他们就可以更快地回收资金、降低整体的流动性成本。虽然现在还没有公开出现这样的具体提议,似乎只要有 充分高级TM 限制条款,是可以做到的。最有可能的是通过某种 “脚本复活(Script Revival)”软分叉,一次性添加多个有用的操作码。

类似地,通过这样的 充分高级TM 限制条款,完整的交易输出树结构可以被替换成具有某种滚动取款方案,从而节约空间。我们会在下一个章节中讨论这个话题,因为这种技术可能对其它方案也有用。

轮次结束时候的保管问题是 充分高级TM 限制条款 可以解决的另一个问题:一种限制条款,尤其是一种可以验证零知识证据(ZK-proof)限制条款,可以强制 ASP 在下一轮中重新创建所有未花费的限制条款,消除在一轮结束时监护权被交给 ASP 的问题。虽然可能这也不足以让它成为 免信任的,因为用户可能依然需要来自 ASP 的一些数据来花费自己在新轮次中的 V-UTXO,这可以防止 ASP 从对离线用户的欺诈中获得好处。

3.4.5 单方面取款时候的链上手续费支付

类似于闪电通道,链上手续费率支付的经济原理和一个 V-UTXO 在支付完手续费后的实际价值,决定了 Ark 的用法是否符合我们的 L2 定义(可以单方面退出,不会让 ASP 从欺诈中获利)。我们会在下文讨论交易输出树设计模式时进一步讨论。

3.5 Validity Rollups

一个类似于侧链构造的大类,普遍被提议使用某种形式的零知识证明技术来强制执行规则。这样的零知识证明技术是 “有效性 rollup(validity rollup)” 跟其它形式的侧链的关键区别:如果相关的零知识证明方案能够工作,交易的有效性将由数学来保证,而不需要信任一个第三方。在这个用法中,零知识证明的 “零知识” 特性并不是必要的:即使证据 “泄露”了它要证明的东西的信息,也是完全没问题的。只是碰巧这类数学方案中的绝大部分都恰好是零知识证明方案。

从比特币的角度,有效性 rollup 方案需要一种限制条款,因为我们希望能够为这样的方案创建出一种 UTXO,仅在方案的规则得到遵守时才能被花费。这也并不 必然 是一种去中心化的系统。许多有效性 rollup 方案实际上完全是中心化的;rollup 证据仅用来证明一个中心化的交易排序者为一组排序好的交易应用了规则。

至于要用什么限制条款 …… 零知识证明技术依然是一个非常新的领域,经常有进展出现。所以,我们极不可能看到任何直接验证某一种零知识证据的操作码被添加到比特币中。相反,普遍接受的事情是具体的方案会用更通用的操作码(尤其是 OP_CAT)以在脚本中验证零知识证据。举个例子,StarkWare 正在争取OP_CAT 能被采用。

有效性 rollup 是一个非常大的领域,有许多的 低质量/高炒作 的项目。除了指出可能需要什么操作码来让这一类设计变得可行之外,我们不会进一步讨论。

3.6 BitVM

非常粗糙地说,BitVM 是一种在两个参与者之间构造一条闪电通道、让闪电通道的规则能够用一种零知识证据来强制执行的方法。因为它不需要限制条款就能在当今的比特币上实现,而且它无法直接用来创建可扩展性强于 “每个用户要有 1 个 UTXO” 的 L2 系统,我们不会进一步讨论。

3.7 层级式通道

层级式通道 [10] 致力于让通道的容量调整(resizing)更快更便宜:“层级式通道之于通道容量,如果闪电通道之于比特币。”然而,在根本上,它依然不能超越 “每个用户要有 1 个 UTXO” 的限制。它也不要求对比特币协议的任何变更。所以我们我们也不会进一步讨论。层级式通道的支持者们应该直接实现它!这不需要我们的许可。

3.8 CoinPool

Coinpool 让多个用户可以共享一个 UTXO、在用户之间转移资金,并且用户都可以单方面取款。CoinPool 的书面提议需要三种新的软分叉特性:SIGHASH_ANYPREVOUTSIGHASH_GROUP 以允许一个签名仅能应用到某一个 UTXO 上,以及 OP_MerkleSub 以验证某一个分支从一棵默克尔树上移除了;后者也可以用 OP_CAT 来实现。

目前,CoinPool 的开发似乎有些停滞,表述其规范的网页的最后一次更新是两年前的了。

3.9 Enigma Network

虽然我被请求讨论 Enigma Network,似乎没有文档能说明这个提议真正的样貌。Bitfinex 的博客文章提出了一系列口号;而 MIT 的页面是空白的。因为这篇博客文章并没有真的说清楚它的实际构造,我们不再进一步讨论。

4 交易池的考虑

Bitcoin Core 当前的交易池策略对 L2 系统来说是不理想的。在这里,我们会介绍它所面临的一些重大挑战,以及可能的优化。

4.1 交易钉死

最终来说是一种经济上的爆破。“交易钉死攻击”,指的是多种情形,一些人可以有意(或无意)让一笔目标交易变得难以挖出,因为另一笔与之冲突的交易被抢先广播并且也 没有 挖出。这是一种经济上的爆破,是因为在一个真正的交易钉死场景中,目标交易是矿工一旦挖出就能得到好处的;而相冲突的交易在很长时间(可能是永久)里 没有 被挖出。

钉死攻击的最简单例子来自一个事实:没有 “full-RBF”(即节点默认所有交易都是可被替换的),交易替换特性可以被关闭。然后,我们可以发起一笔低手续费率、关闭了替换特性的交易,那么它既不会被挖出,也无法被替换。基本上,所有的出块者都开启了 full-RBF,从而解决了这个问题;并且,截至本文撰写之时,在下一版本的 Bitcoin Core 中,full-RBF 应该会默认开启了(在努力了 11 年之后!)。

这让 BIP-125 规则 #3 相关的钉死攻击,变成了剩余唯一跟多方 L2 协议有关(且在 Bitcoin Core 还没有得到解决)的钉死攻击。此处引用 BIP-125 规则 #3:

替代交易需要支付更高的手续费绝对值(而不仅仅是手续费率);要高出所有被替换的交易所支付的手续费总和。

这一规则是可以被利用的:可以广播一笔(或者一组)大体积但低手续费率的钉死交易、花费跟多方协议相关的输出。因为交易的手续费率很低,它就不会很快被挖出(可能永远不会)。然而,因为它的手续费总和较高,用另一笔交易来替换它是不经济的。

BIP-125 规则 #3 相关的钉死攻击在 “手续费率替换(RBFR)” 中是很容易解决的,而且在所有情形中都可以解决。遗憾的是,尚不清楚 RBFR 会不会很快被 Bitcoin Core 采用,因为他们在一种较差的不完整解决方案 “TRUC/V3 交易” 中花了大量时间(中文译本)。

4.2 手续费支付方法

RBF、CPFP、SIGHASH_ANYONECANPAY、锚点输出和手续费资助

因为手续费率是无法预测的,可靠而又经济的手续费,在交易被预签名的情形中,是非常难做到的。手续费支付的黄金标准是使用 RBF(手续费替换),从一个 “低估” 数值开始,逐步替代以更高手续费的版本,直到交易被挖出。举个例子,OpenTimestamps 日历软件已经用这种办法很多年了,而且 LND 也在 v0.18 中支持了 “考虑终止期限的 RBF”。

RBF 之所以是黄金标准,因为它在几乎所有 [11] 场景中,都是最节约区块空间的:相对于一开始就猜对了正确的手续费的交易而言,替代交易并不需要额外的输入或输出。

效率是重要的,因为手续费中支付中的低效率会让暗箱的手续费支付变成大矿工的利润来源;而体量小的、分散的矿工,则无法从中获益,因为给小矿工支付以期望交易确认是不切实际的、没有用的。协议外的支付也可能会招来 AML/KYC 问题:目前,大部分的协议外手续费支付支付系统都要求某种形式的 AML/KYC 流程;一个显著的例外是 mempool.space 加速器,在本文撰写之时(2024 年 8 月),可以用闪电支付,无需账户。

为了在预签名交易的情形中直接使用 RBF,你需要预签名同一交易携带不同手续费的变体,以覆盖手续费的完整可能区间。虽然这在许多情形中是相当可行的,因为必要的变体数量通常很少 [12],但目前,生产环境中的闪电网络协议 —— 以及提议中的其它协议 —— 都转而选择了 “子为父偿(CPFP)”,通常会通过 “锚点输出”。

锚点输出背后的想法是,向一笔交易添加一个或更多小额(或是零价值)的输出,让子交易在追加手续费(即 CPFP)时可以花费这些输出。在应用到闪电通道这样使用小体积链上交易的协议上时,这自然是非常低效的,会让使用临时锚点输出的承诺交易的总体积膨胀到原来的几乎两倍。在应用到使用较大体积交易的协议 —— 比如使用 OP_CAT 来实现限制条款 —— 上时,就不会那么令人困扰了。

锚点输出的一个不那么显著的问题是,需要保留额外的 UTXO(用在子交易中)来支付手续费。在一个标准的 “客户端” 应用中,这可能是一个重大的开销负担,因为不使用锚点输出的时候,通常完全不需要保管超过一个 UTXO。实际上,在现有的一些面向消费者的闪电钱包中,无法在高手续费环境中支付手续费可能会让他们容易被通道对手攻击(偷盗资金)。

SIGHASH_ANYONECANPAY 可以在某些场合下用来支付手续费,它允许给签好名的交易增加额外的输入;SIGHASH_SINGLE 则允许也加入输出。闪电网络协议将它们用在 HTLC 交易中。在目前,如果没有谨慎处理 [13],这种用法是容易遭到钉死攻击的,因为攻击者可以加入许多输入 以及/或者 输出来制作 高手续费/低费率 的钉死交易。RBFR 可以解决这个问题;而用在 TRUC/V3 交易中的方法则不能解决这个问题。这种手续费支付方法不如 RBF 那么高效,但可以比锚点输出更高效。

最后,也有许多软分叉提议,要给比特币协议加入一种手续费资助系统。这让交易可以声明对其它交易的依赖关系,使得,资助交易只能在被资助交易被挖出的时候挖出(极可能在同一个区块)。这可以比传统的 CPFP 效率高得多,因为资助交易可以使用比交易输入少得多的字节来声明这种依赖关系。

4.3 替代交易循环攻击

“替代交易循环攻击”[14] 尝试用替代交易阻挡一笔目标 L2 交易足够长事件,并让一笔不那么好的交易被挖出。本质上,对攻击者来说,替代交易循环攻击是交易钉死攻击的一种替代,因为攻击者的意图是阻止一笔好的、诚实的交易足够长事件(不让它被挖出),从而让一笔不那么有价值的的、不诚实的交易被挖出。不同的是,替代交易循环攻击不可能是无意中触发的。

典型的例子是针对闪电通道中的 HTLC 交易的。虽然人们可能会认为 HTLC 是一种合约,要么 一笔交易通过揭晓原像来花费它,要么它就会超时。但事实上,因为比特币脚本的限制,通过揭晓原像来花费它的机会是 永远 存在的,在超时之后,只是会 额外 开启一种超时花费机制。

替代交易循环攻击就利用了这一点,在超时 之后 继续尝试使用原像花费交易,来替换尝试通过超时机制赎回价值的交易,同时,不让受害者知道这个原像。成功的替换交易循环攻击要持续足够长时间,直到另一条通道中的 HTLC 超时。

要从替换交易循环中获利,一大挑战在于攻击的每一轮都需要消耗资金。一个能够觉察最终期限的闪电网络实现会使用越来越高的手续费,以尝试在下一个 HTLC 输出过期之前花费(赎回)当前的 HTLC。其次,一旦替代循环结束,任何人都可以通过重新广播被替代的交易 [15] 来挫败这种攻击。

跟钉死攻击一样,替代交易循环也是对矿工的经济爆破。在每次循环结束的时候,都又一笔交易会从交易池中移除,虽然它是完全有效的,也是可以挖出的,只要矿工的交易池中保留了它的话。

5 特性模式与软分叉

我们已经为多种依赖于限制条款的 L2 系统以及交易池所面临的挑战作了概述,接下来我们要提炼一系列著名的软分叉特性(主要是新的操作码)和这些 L2 系统共有的设计模式。对软分叉提议,我们也会讨论跟这些提议相关的技术风险,以及部署它们所面临的挑战。

5.1 OP_Expire

我们先把这个搞清楚。OP_Expire 是作为一种直接消除替代交易循环攻击的办法而被提出的 [16],它直击根本:HTLC 是可以同时被两种不同方式花费的。在 L2 系统的语境下,这跟所有使用 HTLC 及类似机制的系统有关,可能也会跟其它用法有关。OP_Expire 将让一个交易输出在某个时间点 之后 不能再被花费,从而 HTLC 的花费条件变成真正排他性的 OR,而不是 “程序员的 OR”。

真正的 OP_Expire 软分叉可能会由两个特性组成,类似于分两步到来的 OP_CheckLockTimeVerifyOP_CheckSequenceVerify(译者注:分别是脚本层面的绝对时间锁和相对时间锁):

  1. 交易的过期高度字段,最有可能通过 taproot annex 来实现。
  2. 一个 OP_Expire 操作码,可以检查交易的过期高度不低于目标高度。

虽然 OP_Expire 自身很难算是限制条款,却似乎对许多依赖于限制条款的 L2 系统都是有用的。不过,给定替代交易循环也可以通过互助重广播 [15] 来缓解,它又可能不够有用。

部署和使用 OP_Expire 的一个非常明显的挑战在于区块链重组:在比特币的技术社区中,从重本错 [17] 开始,就在尝试保证比特币的共识协议具有这样一种特性:即使发生了深度的重组,以前被挖出的交易也可以进入新区块。这一设计原则尝试避免得到了大量确认的 UTXO 一夕之间变成永久无效的恶魔场景 —— 依赖这些 UTXO 的人就会丢失资金 —— 如果一次共识错误导致了大规模的重组。

在大规模重组事件中,使用上述过期机制的交易可能会变成无法再挖出,因为抵达了它们的过期高度。OP_Expire提议认为可以将使用上述过期机制的交易当作 coinbase 交易,让它的输出也在 100 个区块内无法花费,从而缓解这个问题。

部署交易过期机制的一种重大负担是达成共识:这种取舍是可接受的吗?甚至,我们需要它吗?在 OP_Expire能够起作用的交易中,已经包含了冻结用户资金的长时间锁定。加入更长的超时时间是不合适的。此外,在区块重组之后,重复花费总是能够作废某一些 UTXO:随着 RBF 的普及和 “无密钥锚点输出” 的是由,交易超时机制还会有很大作用吗?

5.3 SIGHASH_ANYPREVOUT

BIP-118 提出了两种新的签名哈希模式,两种都 不会 承诺被花费的具体 UTXO。SIGHASH_ANYPREVOUT,(本质上)转而承诺了 scriptPubKey(脚本公钥);SIGHASH_ANYPREVOUTANYSCRIPT 则允许任何脚本。如前面所讨论的,这最初是为了支持 LN-Symmetry 而提出的,用于避免每一个被签名过的通道状态都可能要求专门的响应。

SIGHASH_ANYPREVOUT 在我们想要使用带有 RBF 手续费变体的预签名交易时,可能也是有用的,因为签名不再依赖于一个具体的交易 id,也就避免了手续费变体的组合爆炸。然而,当前的 BIP-118 没有指出这一应用场景;也可能是不兼容的,因为 SIGHASH_ANYPREVOUT 被提议也承诺 UTXO 的价值。

SIGHASH_ANYPREVOUT 的一种初步反对意见是:钱包可能会因为不合适的使用方式而让自身陷入困境。问题在于,一旦 一个 SIGHASH_ANYPREVOUT 签名被发布,它就可以被用来花费 任何 使用相同脚本的交易输出。因此,只要第二个使用相同脚本的输出被偶然创建出来了,SIGHASH_ANYPREVOUT 就允许一种简单的重放攻击(replay attack),会导致资金被盗。然而,因为钱包和 L2 实现还有许多可能搬起石头砸自己的脚的地方,这一顾虑似乎也消亡了。

在此时,广大的技术社区对于实现 BIP-118 似乎是合理乐观的。然而,就像我们在讨论 LN-Symmetry 时候说的,人们也在辩论他的主要应用场景 —— LN-Symmetry —— 是不是一个好的想法。

5.3 OP_CheckTemplateVerify

我们要讨论的第一个专为限制条款设计的提议是 OP_CheckTemplateVerify,常常也被称为 “CTV”,它致力于创建一种非常具体的、受限的限制条款操作码,只做一件事:以特定方式哈希不包含具体输入 UTXO 的花费交易,然后检查检查得到的哈希摘要是否与脚本堆栈栈顶的元素相等。这使得我们可以提前约束花费一个输出的花费交易,而不会 让真正的递归型限制条款成为可能。

为什么 CTV 不能实现递归型限制条款?因为哈希函数:CTV 用一个模板哈希值来检查花费交易,那么就没有办法 [18] 创建一种可以包含 CTV 和自身哈希值的模板。

话说回来,这不尽然是一种真正的限制:在最新的计算机上,你可以在几秒内轻松哈希出一条深度达到几千万笔交易的 CTV 模板链条。而 nSeuqunce 相对时间锁和有限的区块空间,会让这个链条轻轻松松将一笔资金锁定几千年。

当前 BIP-119 中的 CTV 提议只有一种哈希模式,叫做 DefaultCheckTemplateVerifyHash,本质上就是在模板哈希值中承诺花费交易的每一方面。从实用的角度看,这意味着,在许多情况下,CPFP 会成为唯一可用的手续费支付手段。如前所述,这可能是一个问题,因为它让暗箱的支付变成可以节约大量成本的手段,在使用 CTV 的交易体积较小的时候。

公允地说,CTV 也在围绕限制条款操作码提议的技术社区中得到了广泛的支持,因为它相对简洁,用途广泛。

5.3.1 LNHANCE

一种实现 CTV 的提议是将它与额外两种操作码 OP_CheckSigFromStack(Verify)OP_InternalKey 相结合。问题在于,截至本文撰写之时,相关 PR 和 BIP 中的文档不足以支持或否决这一提议。对于这些操作码被期待在哪一些真实案例中发挥作用,相关的 BIP 完全没有任何分析,更不用说深度的案例脚本了。

虽然这个提议的作者们可能有很好的理由,他们有责任解释这些理由并给予恰当的证明。因此,我们不会再进一步讨论。

5.4 OP_TXHASH

类似于 CTV,这一提议通过哈希来自花费交易的数据,从而实现一种非递归的限制条款功能。与 CTV 不同的是,TXHASH 提议提供了一个 “字段选择器” 机制,允许灵活地限制花费花费。这种灵活性实现了两个主要目标:

  1. 允许为交易添加手续费,而不会打破多交易串联的协议。
  2. 多用户的协议可以允许用户只限制自己的输入和输出。

OP_TXHASH 的主要问题在于,字段选择器机制也带来了非常多的复杂性,让审核以及测试变得更难(相比于简单得多的 CTV 提议)。截至本文撰写时,甚至还没有出现关于字段选择器机制到底能带来什么好处、具体如何使用的设计分析。因此我们不再讨论。

5.5 OP_CAT

这是个拼接操作码,可以拼接堆栈栈顶的两个元素,然后将结果推回栈中。比特币最初发布的时候,是启用了 OP_CAT 的。但中本聪在 2010 年就悄悄移除了它,因为最初的实现缺乏对结果元素的体积限制,从而容易受到 DoS 攻击。看看这样一个脚本:

DUP CAT DUP CAT...

如果堆栈元素的体积没有限制,每迭代一轮 DUP CAT 都会让栈顶元素的体积倍增,最终用尽所有内存。

拼接足以实现许多类型的限制条款,也包括递归型限制条款,通过:

  1. 在堆栈中,使用一个或更多 OP_CAT 装置(以及所需的无论什么限制条款专用型逻辑),组装出 没有见证数据残缺 交易。
  2. 在堆栈中验证组装出来的交易跟花费交易相匹配。

事实证明,通过滥用 Schnorr 签名的数学,就可以用精心构造的签名,在 OP_CheckSig 中执行上述第二个步骤。不过,更可能的是,OP_CAT 软分叉会跟 OP_CheckSigFromStack 相结合,后者允许用验证堆栈中的一个签名是对某一目标交易的有效签名 [19],来执行上述第二个步骤;然后再对同一个签名使用 OP_CheckSig,来验证花费交易跟目标交易一致 [20]

事实上,我们只需要组装交易 而不需要 见证数据,是一个关键点:限制条款只需要验证交易 做了什么 —— 其输入和输出 —— 而不需要验证见证数据(如果有的话)能否让这个操作有效。

模数脚本体积限制,结合 OP_CATOP_CheckSigFromStack,足以开发只是许多类型的限制条款,包括递归型限制条款。相比更高效的解决方案(比如 CTV),这会更贵一些。但代价上的差别会比你想的要小!

大致上,使用 OP_CAT,会需要将花费交易的所有非见证数据部分,都通过见证数据放置再堆栈中。对于标准的 CTV 应用场景,例如交易输出树,来说,花费交易完全没有见证数据。但因为见证数据可以打 75% 的折扣,因此子交易的实质交易手续费仅仅高出了 25% 。还不错!

5.5.1 OP_CAT 是否太过强力?

这可能是部署 OP_CAT 要面临的最大的政治和技术阻力:很难预测 OP_CAT 会让哪些用法成为可能。猫咪一旦出了笼子,想抓回来就不是那么容易的了。

一个很好的例子是,有人主张只需要 OP_CAT 就可以在比特币脚本中实现相当高效且安全的 STARK(可扩展的透明知识陈述)验证。因为 STARK 可以证明相当广泛的语句,所以,可以高效实现 STARK 就有极大的影响,不会只影响 L2 系统,因为它会使得许多不同的系统都可以建立在比特币上。一种强烈的反对一件事:这些用法可能不是对所有比特币用户都好。

产生有害的、会诱发中心化的 “矿工可抽取价值(MEV)”,被 Matt Corallo 命名为 “邪恶 MEV(MEVil)”,是一个关键的潜在问题(中文译本)。简而言之,MEVil 是指 大矿工/大矿池 可以通过使用复杂的交易挖矿策略赚取额外收益 —— 而不仅仅是尽可能多的手续费 —— 而小矿工难以采用这些策略的情形。OP_CAT 可以创造出来的金融工具非常复杂,这会让 MEVil 很难消除。在比特币上,显著的 MEVil 在代币拍卖协议出现的时候,就已经出现;幸运的是,这个问题已经因为 full-RBF 的采用而被解决掉了。

除了潜在的 MEVil,OP_CAT 还有其它几种用法可能是有害的。举个例子,我们之前已经评审过的 Drivechain 提议,就被广泛认为是对比特币有害的。有人认为使用 OP_CAT 就可以实现 Drivechain。另一个例子是 Taproot Assets 这样的代币协议。虽然基本上无法阻止使用 “客户端验证” 概念来实现它们,但也有人提出使用 OP_CAT 来实现它们,这对终端用户可能更有吸引力,但这可能会使用多得多的区块空间,可能会挤出 “正统的” 比特币交易。这些用法可能会带来司法问题,取决于这些代币协议多么经常用在金融欺诈中。

5.6 递进哈希

在限制条款的实现中,OP_CAT 的主要用法是拼接数据,然后哈希它们。另一种实现相同目标的方法是使用某种递进哈希的操作码(incremental hashing opcode),取一个 SHA256 运算的某个中间状态,然后哈希更多数据;SHA256 自身是在 64 字节的数据块上操作的。递进哈希操作码有许多种可能的设计。

一个重要的设计抉择是,在将实际的中间状态字节暴露在堆栈中的时候,要使用某种规范的形式,还是用某种不透明的类型来表示它们(使得实际的字节数值无法被直接操作)。SHA256 被指定了一个具体的、固定的初始化向量,如果可以使用任意的 中间状态/初始化向量,不确定 SHA256 的密码学属性是否还能得到保留。

当然,因为递进哈希可以做到 OP_CAT 能做的许多事,只是效率更高,它也要面临一样的顾虑:太过强大。

5.7 Script Revival

OP_CAT 是中本聪禁用的 15 个操作码之一。除了恢复 OP_CAT,Rusty Russell 正在提议 [21] 通过重启启用其中的大部分操作码、加入 DoS 限制(可能还要在同一个软分叉中加入少量新操作码),将比特币的脚本编程能耐复原成 “中本聪初版”。具体来说,可能会加入一个 OP_CheckSigFromStack

虽然 OP_CAT 自身已经让(递归的)限制条款成为可能,完整的 “script revival(脚本复兴)” 会让更加复杂的限制条款成为可能 —— 实现起来也容易得多 —— 因为可以直接操作花费交易的某些部分。举个例子,你可以事项一种限制条款脚本,使用算数操作码来保证交易的输出的总价值会保持一些有趣的属性。

此外,脚本复兴也面临跟 OP_CAT 相同的顾虑,甚至更多,因为它比 OP_CAT 还要强力。

5.7.1 Simplicity

类似于脚本复兴,Simplicity 跟 L2 和限制条款相关是因为它可以做所有事情。而与脚本复兴不同的是,Simplicity 软分叉可能会给比特币的脚本系统加入一种全新的编程语言,基于 9 种叫做 “结合码(combinator)” 的操作码原语。

实际上,Simplicity 既过于简单,又一点也不简单。结合码过于底层,以至于连加法这样基本的操作都要辛辛苦苦从头实现;裸的 Simplicity 代码在实践中会过于繁琐。因此,Simplicity 的任何真实用法可要利用一种代码替换系统,类似于库函数调用,叫做 “jet”。这就成了一个 实用/政治 问题:如何决定要实现哪个 jet?很可能 jets 会用 C++ 语言来实现,就跟别的操作码一样,从而每加入一个新的 jet 都需要一次软分叉。

5.8 OP_FancyTreeManipulationStuff

人们还提出了许多相对专用的操作码,以更节约空间的方式操作树结构,以供依赖于限制条款的 L2 系统使用。举个例子,Coinpool 提议就提出了 TAPLEAF_UPDATE_VERIFYOP_MERKLESUB,两种操作码都是对 taproot 脚本树的操作,对 Coinpool 提议来说都是必要的,而 MATT 也提出了一种 OP_CheckContractVerify 操作码,基本上,就是验证关于默克尔树的陈述。

从本文的目的出发,我们不需要细究这许多提议中每一种的细节。相反,我们可以把它们都当成一类:它们全部是相对专用的协议,旨在让一类 L2 成为可能,并希望没有意料之外的副作用。它们都有高效的优点:比起使用更通用的操作码(例如 OP_CAT 操作),它们都使用更少的区块空间,就能实现相同的目标。但它们

来源
免责声明:以上内容仅为作者观点,不代表Followin的任何立场,不构成与Followin相关的任何投资建议。
喜欢
收藏
评论