作者:Janusz

来源:https://insider.btcpp.dev/p/bitvm-based-bridges-and-emergency

原文出版于 2025 年 8 月。

随着基于 BitVM 的桥接合约接近于进入生产环境,我开始思考被称为 “紧急更新” 路径的课题。在 Citrea 团队的帮助下,我能够理解验证 BitVM 桥接合约的花费路径的不同方式,从而确定它是否带有紧急更新机制。本文尝试讨论未来的项目会如何实现这些花费路径。请注意,紧急更新路径,以及花费合约的多签名装置,并不是 “BitVM 的专属特性”,它们是广泛用于由证明系统来保护的桥接合约的机制,而我认为,它也将在基于 BitVM 的桥接合约构造中得到利用。本文是解释性的,希望能够点燃关于我们应该如何披露这些花费路径的类型的讨论。

你是否遭遇过需要立即从银行中取钱的困境?比如你的车子坏了,你要立即给修理工付钱。又或者,你的朋友在酒吧喝太多酒了,你要交一笔钱保他出来。

BitVM 桥接合约可能也想要同样的保证。我们希望桥接合约的运营者被绑定在具体的 BitVM 初始设置的规则中。但是,要是哪里出了问题呢?如果系统有一个漏洞、攻击者可以凭空拿走其中所有的钱、或者导致其中的资金永久冻结呢?

即使是友好的人发现了 bug,可能也希望有一种方式能够抢先将所有的钱从桥接合约中转移出来,防止合约被爆破。

实现这种保证的方式是紧急多签名装置 —— 这是一条额外的花费路径,可以在 BitVM 桥接合约中实现,让一组(或一个)签名人能够完全绕过挑战游戏和乐观的报销机制、将资金从一个桥接合约中转出。

BitVM 是一种新的技术,其对应的桥接程序也是新生事物。一些团队不希望在没有保险机制的情况下发布这些新的桥接合约构造。尝鲜的桥接合约运营者和流动性供应商,可能也希望有紧急开关,这样能保证他们的资金可以在发现 bug 时转移出来。不可变更性并不总是跟商业上的激励完全一致。

一些已经上线的 BitVM 桥接合约实现中可能已经有了用于紧急更新的多签名装置。更多的桥接合约构造即将上市,它们在启动时可能会有安全理事会 —— 一组得到许可的、操作紧急多签名装置的签名人。如果这些系统的安全模式最终回归到了一个需要许可的 M-of-N 多签名装置(哪怕是一次性的),用户也有权利知情。

我花了两周时间来研究建立这样的安全理事会的方法,并且一直在思考验证他们的存在的方法(当然,是在一些 BitVM 阵营的成员的帮助下)。

这些练习提出了一个有趣的 “问题”。我们无法(在区块链内)验证这些花费路径,直到它们真的被使用。也就是说,如果内部人完全不披露,一些用户甚至永远不会知道,一个需要许可的 M-of-N 多签名装置是一个基于 BitVM 的桥接合约的最终信任假设。

BitVM 桥接合约回顾

BitVM” 是由 Robin Linux 提出的一种方法,可以在比特币区块链内执行任意计算。它激发了比特币开发的新浪潮,许多团队都在使用这种技术来开发 layer 2 桥接合约。这些合约所支持的 layer 2 可以 设置多个运营者来保管比特币,作为所在 layer 2 上的封装的比特币资产的背书。但是,更重要的是,它还额外启用了一种乐观的侦测其中的机制,可以用来质疑来自运营者的任何恶意的(或者不正确的)取款尝试。

在启动阶段,一组签名人要形成一个 N-of-N 多签名装置,以为一个桥接合约预先签名交易图。只要其中任何一个人销毁了自己用在这个预签名仪式中的私钥,那么锁定在这个桥接合约中的 UTXO 就只能被预先定义的花费脚本花费。

在一些涉及中,运营者必须垫付资金(作为流动性),然后从桥接合约中请求报销。在一段时间之后,运营者才能支付给自身。另一种设计是让用户能够跟诚实运营者合作,后者会给前者释放将资金转移出桥接合约所需的私钥。

不管是哪一种设计,都需要至少一个诚实运营者,才能处理取款。如果运营者是不诚实的,比如说,他们见证了一次取款、这一取款与所在系统的最先状态有冲突,那么一个观察者(瞭望塔服务)可以挑战他们。

这里说的瞭望塔是一个实体(或者一个人),自己运行 BitVM 验证器软件,可以挑战然后叫停来自 BitVM 桥接合约操作者的取款请求。

关于不正确的取款,举个例子,一个运营者尝试从所在的 BitVM 实例中取出超过他们应当具有的余额的资金。这就是为什么来自桥接合约的支出都包含了一个时间锁。它让瞭望塔有时间来提交挑战。这个从取款合约被广播到时间锁解锁的时间窗口,叫做 “挑战窗口”。

仅在挑战窗口结束斥候,运营者(或用户)才能够从桥接合约中取走资金。在基于 BitVM 的桥接合约中,盗窃需要所有运营者和瞭望塔合谋(可以把桥接合约洗劫一空)。只要其中一个是诚实的、定期检查区块链、TA 的验证器也在线、愿意提交挑战,资金就不会被盗。这个 1-of-N 信任假设是好的,因为这意味着我们要信任的人的数量 少于 标准的联盟,在后者中,只要不诚实的人占到了多数,就足以盗窃资金。

上述机制,创造了一种比已经在比特币网络中服役的装置更加信任最小化的桥接装置。但在现实中,这种核心的信任假设,可能还是会回落到一个得到许可的多签名装置中(尽管只是临时的)。(译者注:回落后的情形与当前已经实现的装置(用于侧链的多签名联盟)是一样的。)

紧急多签名的引入

如引言所指出的,各开发团队可以(也将会)在他们的 BitVM 实例中加入一个紧急花费路径。他们应不应该这样做,并不重要。更重要的是,你只需知道,几乎所有进入生产环境的基于 BitVM 的桥接合约,在还未成熟的时候,都会包含一个紧急花费机制。我们应该期待的是这些开发团队会妥当地披露这些紧急花费路径的性质。

紧急多签名装置并不是 BitVM 的特性。它是广泛用于由证明系统保护的桥接合约的机制,用于在发现 bug 时更新系统。其它生态系统中的 Rollup 实例已经在这方面建立了先例。

BitVM 桥接合约使用隔离见证 v1(Taproot)脚本来创建和预签名桥接合约的花费路径。Taproot 脚本使用了 MAST,使得大量花费条件可以存在于一个 UTXO 中。当使用一个叶子脚本来花费这个 UTXO 时,只有这一个叶子脚本才会公开(其它同时存在的叶子脚本不需要公开)。

BitVM2 论文正确地指出,预签名的交易可以限制运营者在取款时仅能使用可以被挑战的方式。但是,没有什么能阻止具体的一个 BitVM 实例的开发者在 Taproot 脚本树上包含允许从桥接合约中取款的 额外花费路径

在 Taproot 脚本树上,每一条花费路径都叫做一个 “叶子” 脚本。为了解锁和花费携带由这个脚本树锁定的 UTXO,只需要揭示其中一个有效的叶子(并提供满足该叶子脚本的见证数据)。

我们来看一个例子:第一条路径(或者说第一个叶子)是标准的取款路径,带有挑战窗口。另一条路径,则是紧急花费路径,可以绕过挑战窗口。

叶子 A:由 1-of-N 欺诈证明来保护的花费条件

OP_PUSHBYTES_2 <SomeDelay>
OP_CSV
OP_DROP
OP_PUSHBYTES_32 <OperatorPubKey>
OP_CHECKSIG

叶子 B:2-of-3 紧急脱锚花费条件

OP_PUSHBYTES_32 <pubkey1>
OP_CHECKSIG
OP_PUSHBYTES_32 <pubkey2>
OP_CHECKSIGADD
OP_PUSHBYTES_32 <pubkey3>
OP_CHECKSIGADD
OP_PUSHNUM_2
OP_NUMEQUAL

“叶子 A” 是 BitVM 实例中的常规取款报销条件。在经过一段挑战期(<SomeDelay>)之后,一个预先指定的运营者可以从桥接合约中取款。如果花费在桥接合约中锁定的 UTXO 的运营者是不诚实的,一个瞭望塔可以在挑战期内(也就是花费 BitVM 合约之后,<SomeDelay>时间锁过期之前的这段时间里)挑战他们,阻止不诚实的取款请求。

叶子 A 可被 N-of-N 预先签名委员会构造的一笔预签名交易花费。

另一方面,“叶子 B”,则是一个马上生效的花费路径,一个 2-of-3 多签名装置可以立即转移 BitVM 合约中的所有资金。如果开发团队在合约中发现一个可被利用的 bug,或者他们决定捐款潜逃,就可以这样做。

当我说 “合约” 的时候,我指的总是掌管一个比特币 UTXO 的花费条件的 BitVM 合约。

这两个花费条件可以同时存在于一个桥接合约的 taproot 脚本树上。虽然增加一个能够绕过 BitVM 挑战-响应 游戏的花费条件并不总是合理的,但客观上没有什么能够阻止开发者实现这样的花费条件。

而且,脚本树上的花费条件可以是非常灵活的。在上述例子中,我们只展示了两种花费条件。然而,开发团队可以创造出包含了多种多样花费条件的脚本树。上面的叶子 B 就是一个例子:这种紧急更新机制没有时延,可被 2-of-3 签名人集合花费,导致用户资金被盗。而更广泛的协议升级可以由 9-of-12 的安全理事会发起,并且带有时间锁。

具体的设计在各个实现上可能有所不同,重要的是,我们得能够验证这些花费条件。现代比特币脚本的一个 “问题” 在于,在一个脚本被花费之前,你是无法公开验证它的。这跟基于 BitVM 的桥接合约严格相关,它意味着我们无法验证所有的花费路径,直到一个具体的叶子脚本被用来花费一个 UTXO 。请记住,当一个叶子被花费的时候,只有这个叶子所表示的花费条件会揭晓。所以,如果在我们的实例中,只执行了常规取款,那么我们无法验证是否存在一个紧急花费路径;反之亦然。

这可能会带来一个问题。如果开发团队向脚本树插入了一个紧急花费机制,但从不公开它,用户可能永远无法确定那里没有受许可的多签名装置(或者受许可的某一个人)可以花费锁定在桥接合约中的所有资金。

想了一个星期以后,我得出了一些开发团队可以揭晓桥接合约花费路径的方法。

披露方法

直接在说明书中披露花费路径

对于开发团队来说,最简单的办法就是在说明书中公开具有特权的角色。开发团队可以直接公开桥接合约的运营者、谁是参与预签名仪式的人、谁是运行轻客户端的人,以及谁是瞭望塔。

有一些披露,总好过没有,但我们还是无法单纯基于说明书网站上的生命来验证桥接合约的花费路径。如果能直接验证脚本,那就更好了。

在存入资金之前先测试

开发团队可以为不同的花费路径发送测试交易。他们可以从一个给定的实例中花费一些资金,最终揭晓所有的花费路径,而用户也可以自己验证花费路径。

这要求开发团队花费脚本树上的每一个叶子。但即使如此,我们还是永远无法确定他们不会插入从未揭晓过的额外花费条件。开发团队总是可以选择性不花费某个叶子、不揭晓器花费条件。这通常被当成 Taproot MAST 的一个特性,但在桥接合约的语境下,这会降低用户对开发团队事实上揭晓了所有花费脚本的信心。

不幸的是,测试交易不能提供我们期待的透明性。

利用大规模的限制条款模拟委员会

另一种办法是,开发团队利用一个足够大的限制条款模拟委员会,并给予独立参与者参与预签名桥接合约交易图内的所有交易的机会。这将给予独立参与者验证紧急多签名存在性、其中有多少签名人的机会。

但是,这依然要求用户信任限制条款委员会的参与者,而不是让他们直接验证脚本。我会说,前进的道路在于,我们能够给予任何用户验证桥接合约的花费路径的机会。

创造一种标准化的披露方法

以我个人来看,我们应该期待开发团队会公开他们为自己的 BitVM 实例创建的完整的脚本树。

如果开发团队提供了创建 tapscript 的内部密钥、叶子脚本的完整集合以及对应的桥接合约地址,我们就可以自己动手了。

使用这些信息 —— 用来生成花费路径的内部公钥、从 taproot 脚本树推导出来的默克尔根 —— 我们就能将他们相加、得出一个调整后的公钥。如果这个调整后的公钥跟 BitVM 桥接合约的地址相匹配,我们就验证了该地址事实上只包含了这些花费脚本。

看!我们有了一种可以验证的披露方法。如果一个开发团队公开了不正确的 taproot 脚本树,那么调整后的公钥就不会跟桥接合约的地址匹配。

这种披露方法让我们能够真正验证跟一个 BitVM 桥接合约实例的关键信任假设。但是,它 需要 开发团队公开整棵脚本树以及相关的内部公钥。

透明性的重要性

即使我们不披露签名人的身份,我们依然需要脚本来理解真正的信任假设。这些系统被设计成带有 1-of-N 诚实参与者信任假设。但如果信任假设最终会回落到一个受许可的多签名装置,把资金存进这些合约的用户有权利知情。

我预计绝大部分基于 BitVM 的桥接合约都会包含这类紧急更新花费路径。我希望这些桥接合约不会永远带有这样的花费路径,我们可以升级到更加信任最小化的设计。但是,我们不能当它们不存在,或者借口说它们不是唯一的信任模式。

只要紧急花费路径存在,它不折不扣就是信任模式本身。

(完)