本文介绍了一种名为“swap-in-potentiam”的新协议,旨在解决将链上资金快速转移到闪电网络的问题。该协议允许用户几乎即时地使用已确认的链上资金进行闪电网络支付,通过与闪电网络服务提供商 (LSP) 合作,在链上资金得到确认后,立即进行单跳互换交易,从而快速转移资金。文章还详细描述了合约的结构、参与者的安全性考虑以及 LSP 如何利用该协议来优化移动钱包的入账容量。
作者:Jesse Posner、ZmnSCPxj
来源: https://lists.linuxfoundation.org/pipermail/lightning-dev/2023-January/003810.html
将资金从链上地址转移到闪电网络上需要很长时间,尤其是你想实现信任最小化的话(这会将零确认解决方案排除在外)。
大体而言,为了降低链上交易的信任要求,链上收款方 必须 确保创建其 UTXO 的链上交易得到确认。
在现实生活中,链上交易至少需要得到 3 个区块确认,因为 2 个区块的重组时常发生。然而,鉴于挖矿的随机性,即使只是 1 个区块确认也需要耗费很长时间。
就手机场景而言,这个问题尤为突出。由于手机依靠电池运行,对于用户未打开的应用程序,手机的操作系统通常会极大地限制 CPU 和其它资源消耗。
现在,假设有一个同时支持比特币区块链和闪电网络的钱包应用,用户接收付款时的经历如下所示:
但是,若使用现有解决方案,将资金从区块链转移到闪电网络,上述流程将需要很长时间才能完成,可能要以数十分钟乃至几个小时来计量,因为需要区块确认:
在此,我们将介绍一种新型协议 “swap-in-potentiam”,能够在上述案例中快速将资金从区块链转移至闪电网络。
为了吊起你的胃口,我们先介绍 swap-in-potentiam 协议的优势:
为了让你明白这是一项技术而非魔法豆(同时也是为了避免过度吹嘘这项技术,因为比特币的媒体报道经常会过分夸大新技术,却避而不谈它们的缺陷),我们再来看看它的缺陷:
如上所述,所有链上资金转移都需要确认,资金从链上转移至闪电网络的交易也不例外。
如果钱包提供的链上地址仅受该钱包的控制,凡是需要跟某个闪电网络参与者互动的操作(如,开通通道、互换和 splice),都需要再发起一个承诺给该闪电网络参与者的链上交易。只有当新的链上交易得到确认时,闪电网络参与者才能依赖该交易的输出,而无需信任发起人。
据此,我们可以思考这样一个问题:如果钱包提供的是一个已经向某闪电网络参与者做出承诺的地址呢?
果真如此的话,当钱包在区块链上收到资金时,“确认计时器” 就会立即启动,而不是等到钱包决定将资金从区块链转移到闪电网络的那一刻(才启动)。
对于移动钱包来说这是很大的区别:移动环境不支持移动钱包长时间在线。因此,在用户打开移动钱包应用之前,移动钱包可能没有任何 CPU 资源能够做出将资金从区块链转移到闪电网络的决定。
人们已经普遍接受了一个事实:由于手机环境的限制,支持闪电网络的手机钱包离不开 LSP 的配合。因此,能够在区块链上收款并通过闪电网络付款的移动钱包可以将交易承诺给另一个闪电网络参与者(必须是与此钱包之间存在支付通道的 LSP)。
然后,当移动钱包应用处于前台且可以使用 CPU 资源时,就能发起与其 LSP 之间的单跳互换交易。只要移动钱包发现资金已经得到确认,即可马上与其 LSP 进行单跳互换交易。LSP 可以立刻处理该互换交易,将资金记入通道余额,同时以原子方式确保只有自己能够取走对应的链上 UTXO。
该合约有两个参与者:资金所有者 Alice 及其潜在互换对象 Bob。
一旦承诺了该合约的地址确认已收到 任何 资金,Alice 就是这笔资金的所有者,可以(在 Bob 的配合下)随心所欲地处置它。
资金的来源不需要是 Alice,可以是有义务经由区块链向 Alice 付款的第三方。
该合约只有两个分支:
OP_CSV
)聪明如你想必已经发现,这实际上就是一个 CLTV 式单向限时通道[1](此通道本身就是 Spilman 式通道的变体)的变体:
可支持的应用场景如下:
此处只需要 Alice 信任 Bob 会与之配合,以便 Alice 立即处理资金。如果 Bob 是不可信的,Alice 可以在超时时间到达后通过时间锁分支找回资金。
Bob 没有窃取资金的余地(实际上,比起窃取 swap-in-potentiam 的资金,窃取闪电网络的资金对 Bob 来说更容易)。
在这个场景下,移动钱包方是 Alice,LSP 方则是 Bob。
Bob 必须 确保的是,对于每个 UTXO,要么签署任意链上交易(即,上述第一个应用场景),要么得到来自该 UTXO 的链上 HTLC。无论 Alice 要求 Bob 配合上述哪一种情况,Bob 必须 确保自己没有签署另一种情况(收到过一种情况的请求之后,Bob 就 必须 拒绝配合另一种情况)。
此外,Bob 必须 确保的是,如果实在“通道”场景中(即,上述第二个应用场景),距离时间锁分支的超时时间还有很长一段时间,长到那时使用多签名分支的花费可能已经确认完毕。
只要 Bob 做到了上述两个保证,就可以确保如果 Alice 通过多签名分支请求互换交易,只有 Bob 能够花费该 UTXO(至少是在超时前)。因此,Bob 无需等待链上确认即可安全地向 Alice 提供闪电网络 HTLC。
在上述第一个应用场景中,Bob 需要知晓 UTXO。因此,实现第一个场景时无法使用盲签名技术。
从根本上来说,收到签名请求时,Bob 必须使用 Alice 提供的数据生成整个 SIGHASH
,这样 Bob 就可以追踪自己签名的 UTXO。
虽然 Bob 通常被认为就是移动钱包方 Alice 的“那个”LSP,闪电网络协议实际上并没有要求 Bob 是 Alice 的直接对等节点。
真正的要求只有 Bob 要能通过闪电网络向 Alice 付款,以换取等额的链上资金。
由此可见,既然移动钱包已经依赖于一个或多个 LSP,它很有可能会选择直接 LSP 而非远程节点。
swap-in-potentiam 地址可由一个根 公/私钥 派生而来。
我们只需要 Alice 和 Bob 各提供一个密钥对。Alice 可以使用标准密钥派生路径来生成其密钥对。
由于 Bob 打算成为 LSP,我们可以直接使用其闪电网络节点 ID 作为公钥。Bob 需要拥有对应的私钥,才能建立 BOLT 8 加密传输。
由于 LSP 是公共网络的一部分,Alice 可以尝试搜索所有公开支持 swap-in-potentiam 的节点。或者说,如果该钱包有一列固定 LSP 可用,可以直接参考该列表。
因此:
有了上述两个密钥对,我们就可以从 xprv
或 xpub
根密钥派生出 swap-in-potentiam 地址。
虽然在最初的 swap-in-potentiam 设计中移动钱包是 Alice,LSP 是 Bob,但是事实证明 LSP 可以提供特殊服务来帮助作为收款方的移动钱包。
假设 LSP 持续追踪统计数据,知道哪些移动钱包客户端有可能成为净收款方。
净收款方的入账容量通常很低(因为其入账容量已经在前几次闪电网络收款时用尽)。
在链上费用处于低谷期间,LSP 可以查看哪个离线移动钱包客户端的入账容量低,且未来有可能上线收款。在这种情况下,LSP 可以在移动客户端的帮助下将资金转入 swap-in-potentiam 地址:LSP 就是“Alice”,移动客户端则是“Bob”。这至少可以让 LSP 在低费用时期搞定一半的互换交易。
如果向 swap-in-potentiam 地址的转账在移动钱包客户端上线时得到确认,LSP 可以立即发起互换交易,为该移动客户端提供入账容量。这样一来,互换交易可以立即完成,移动钱包客户端也可以立即通过闪电网络收到资金。
尤其值得注意的是,如果 TheBlueMatt 设计的“离线收款”成功实现,LSP 将提前知晓离线移动客户端将获得支付。LSP 可以查看离线移动钱包是否有足够多的入账容量来完成收款。如果没有的话,LSP 就可以在客户端的配合下向 swap-in-potentiam 地址转入资金。然后,当移动钱包客户端上线时,LSP 可以立即发起互换交易。一旦互换交易完成(移动钱包有了足够的入账容量),LSP 即可联系作为付款方的 LSP 完成付款。
需要强调的是,就上述应用场景而言,只要移动钱包客户端在前台运行,并且拥有 CPU 时间,即可实现 即时 收款,无需零确认交易以及任何类型的半托管式信托,即使移动钱包客户端的入账容量不足。支付通道仍需事先创建好(无需是零确认通道,如果不想将资金委托给 LSP 的话)。
初步构想是使用 Taproot 和 Schnorr 签名,但是 不 使用 keyspend 路径(至少在初始阶段是这样)。
目前的计划是将 MuSig(A, B)
用作内部公钥,并通过显式方式将分支变成 tapleaf。换言之,有两个 tapleaf 脚本分别对应上述两个分支:
<A> OP_CHECKSIGVERIFY <B> OP_CHECKSIG
<timelock> OP_CHECKSEQUENCEVERIFY OP_DROP <A> OP_CHECKSIG
使用显式 2/2 分支而非 MuSig 可以让协议变得更简单:我们可以让 Alice 在一个半轮中使用 A
发送签名, 无需完成 2 轮 MuSig2 签名流程。
我们之所以考虑使用 Taproot,是因为移动钱包客户端可能需要使用 2/3 或 2/2 签名方案,就像 Blockstream Green 那样。
这样一来,无论是合约中的 Alice 还是 Bob 都可以秘密成为 FROST 2/3 或 MuSig 2/2(或任何 FROST k/n 或 MuSig n/n)。
这也是避免 Alice 和 Bob 之间 2/2 MuSig keyspend 路径的另一个原因,因为(据我们所知)没有公开审查的安全性证明来证明 FROST-in-MuSig 和 MuSig-in-MuSig (或在签名流程中使用了 MuSig2 的相应变体)是否安全。
之后,等到我们对于在 MuSig2 中使用 MuSig2 和 FROST,以及与可能的非受信外部人员一起使用 MuSig2(如果我们在设计 MuSig2 签名协议的实现时出现差池,就有可能给他们留下可乘之机)更具信心时,我们就可以无缝升级 MuSig2 签名协议来使用 keyspend 路径,以节省见证信息的字节。
就链上应用场景(即,Alice 想要将 UTXO 发送至某个链上地址)而言,Alice 和 Bob 之间的协议会如下所示:
request_arbitrary_signature
Alice->Bob:要求 Bob 签署一个使用链上分支花费 swap-in-potentiam 地址资金的 PSBT。response_arbitrary_signature
Bob->Alice:响应上述要求,返回所需签名。reject_arbitrary_signature
Bob->Alice:在 Bob 拒绝合作的情况下作为对 request_arbitary_signature
的响应发送给 Alice(例如,在下述通道应用场景中,Bob 已经接受了 Alice 想要花费的 UTXO)就通道应用场景(即,Alice 想要将 UTXO 发送给闪电网络收款方)而言,我们使用基于以下两个状态的 Spilman 式通道来处理 swap-in-potentiam UTXO:
N
的 HTLC 发送给 Bob,剩余金额则发送至 Alice 的找零地址。N
给 Bob,剩余金额则发送至 Alice 的找零地址。初衷是一开始就将通道置于 HTLC-offering 状态。然后 Bob 通过通道向 Alice 提供对应的闪电网络内 HTLC。Alice 完成闪电网络内 HTLC 后,就可以针对 Resolved 状态发送一个新的签名。一旦通道处于 Resolved 状态,Bob 应 签署最后的状态并将其广播到链上,从而关闭 Spilman 式通道。
通道应用场景的协议消息如下所示:
request_swap_in
Alice->Bob:将 UTXO 连同花费 UTXO 的 swap-in-potentiam 地址、往 Alice->Bob 通道方向充值多少数额,转移至哪个通道,以及 Alice 的找零地址(可选)告诉 Bob。reject_swap_in
Bob->Alice:在 Bob 拒绝合作的情况下作为对 request_swap_in
的响应发送给 Alice(例如,待花费的 UTXO 之一已经通过 response_arbitrary_signature
签署,或者 Bob 无法合法接受一个或多个待花费 UTXO 的资金控制。accept_swap_in
Bob->Alice:作为对 request_swap_in
的响应发送给 Alice,包含状态变为 Resolved 后用于接收资金的 Bob 侧地址。swap_in_signed
Alice->Bob:对 accept_swap_in
的响应,包含 Alice 侧对 HTLC-offering 状态交易的签名。一旦 Bob 收到该响应,Bob 就可以安全地使用 BOLT1 update_offer_htlc
构建一个新的基于闪电网络的 HTLC。swap_in_resolved
Alice->Bob:在 Alice 已经通过对应的基于闪电网络的 HTLC 的 update_fulfill_htlc
获得资金后发送,包含 Alice 侧针对 Resolved 状态交易的签名。Resolved 状态交易将 UTXO 发送至 accept_swap_in
中给出的 Bob 侧地址,并将找零发送至 request_swap_in
中给出的 Alice 侧找零地址。
此处的计划是只保留一个奇数 BOLT1 消息 ID,并将实际的 swap-in-potentiam 消息 ID 作为头两个字节嵌入到 BOLT1 消息中,以减少有限的 BOLT1 消息 ID 空间带来的污染,同时也让 swap-in-potentiam 能够更加灵活地在其消息 ID 空间内扩展新的消息。
为了让协议变得更加丰富,我们会考虑如何将 swap-in 和 splice-in 相结合,以应对通道的当前总容量低于可用链上资金的情况。swap-in 能够将资金即时记入通道余额(但不能超过当前总容量),额外资金可以通过 splice-in 添加至通道(只有当 splice-in 得到确认时才会被记入通道余额)。
我们也可以使用 openv1 实现同样的效果。其中,swap-in 与通道开启相结合,swap-in 即时记入通道余额,通道开启则需要等待确认:
open_channel
。accept_channel
。request_swap_in
,找零地址是通道的充值地址。accept_swap_in
提供充值交易的 TXID(Alice 知道找零地址和 Bob 的最终 Resolved 地址,因此知道最终 Resolved 状态交易的 TXID)。funding_created
。funding_signed
。swap_in_signed
向 Bob 提供花费 swap-in-potentiam 地址上资金的签名。swap_in_resolved
.(上述流程并不安全,因为 Bob 可以使用 HTLC-offering 状态交易完成协议。这个问题的解决方案是让 Alice 开启两个通道并往里充值等额资金,一个使用 HTLC-offering 状态交易充值,另一个则使用 Resolved 状态交易充值,然后在未确认交易所对应的通道上“发生错误”。这就留作各位读者的课后练习。但是,请注意在 HTLC-offering 和 Resolved 状态下,Alice 的找零地址必须区分开来,我们可以为协议进行配置。)
(完)
- 本文转载自: btcstudy.org/2023/03/06/... , 如有侵权请联系管理员删除。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!