# 路由闪电网络的缺陷

By [0xKJ](https://paragraph.com/@0xkj) · 2024-08-22

---

本文指出闪电网络原理的重要缺陷。我们通过逻辑推理和归约方法，剔除无关的内容，找出**关键的矛盾**所在。闪电网络核心概念是支付通道 channel，由于单向 channel 更容易帮助我们理解问题，我们使用单向通道 channel 来解释我们看到的不合理的部分。闪电网络使用的多签和哈希时间锁主要用于链上结算，是额外一种保护机制，这部分我们会在文章的最后讨论。

我们的主张是，最初的闪电网络设计：一对一通道在设计上是合理的，在使用上会出现困难，因为锁定了太多资金。之后闪电网络增加的带路由和中继的闪电网络，打破了之前一对一通道的核心原则，使得网络无法再防止双花。闪电网络在此基础上加入了更多工程设计，比如要求每个中间人在线（几天内），这让使用体验大打折扣，使**闪电网络不再“闪电”**。

![1 to 1 Lightning channel](https://storage.googleapis.com/papyrus_images/9492620778893fb8c52dc4edd48baedabffdf3f16cd8b0ad4bcc360674b78cda.png)

1 to 1 Lightning channel

双花和超花（之后解释）对于转账和支付来说，是非常致命的问题。区块链通过引入共识算法，实现了去中心化防止双花。此前，只有中心化机构比如银行，才能保证安全。所以区块链的出现有着跨时代的意义。

闪电网络本身没有共识算法，链下的系统理论上不能防止双花。但是闪电网络中最核心的 channel 设计，绕开了这一点。因为支付通道必须指定接收方（支付行为的本质是用私钥对符合格式的消息链下签名），如果在 A 到 B 的单向 channel 中付款，A 签署消息的收款人必须是 B，否则就是在操作另一个 channel。

所以，闪电网络中 channel 的核心思想就是，锁定收款人，防止向多个收款人同时支付这笔锁定的资金。这排除了向多个收款人同时支付同一笔资金的可能性，一对一的闪电网络不可能实现双花。用户可以试图超花，但这一问题的危害确实不如双花严重。

超花的意思是，如果 A 只在通道中锁定了 10 块，那么他可以签署两张支票，一张付给B 7块，另外一张付给B 8块，B 当然知道 channel 中只有 10 块，所以只接受其中一张付款。此时，B 知道 A 违规了，立刻开启链上清算流程。

再次强调，**一对一**的 channel 的特性**可以防止双花**，是因为**收款人是确定的**，这是最关键的。当然一对一闪电网络不会走向实用，因为占用用户资金太大了。这就好像充值公交卡，但是你不可能给每个潜在消费的饭店预先各充值 500 元，因为这会占用大量资金。

为了解决这个资金占用问题，闪电网络提出了带 relay 路由的支付网络。如果我们无法和所有人建立 channel 链接，那我们就找共同好友 C。当然，闪电网络又要求 C 冻结很多资金和好友们搞好关系，属于富人社交了，我们暂时不讨论这方面问题。

![Lightning channel with routing](https://storage.googleapis.com/papyrus_images/a4c13c468d82cc640f96db91c32fbc73272e9198b414855d8997305c6feba9a1.png)

Lightning channel with routing

当我们签名的时候，我们会指定我们动用资金的 channel 的，然后还要指定最终接收方。注意，带路由的闪电网络已经能付给不同用户 B 和 G 了，除了指定动用哪个 channel 的资金（此时通道 AC 和 AE 都可以动用），我们还需要在待签名的交易中指定最终付款人。

此时，聪明的读者已经发现了根本的问题，一对多的闪电网络本身已经**违反了**一对一闪电网络概念的**最基本原则**，就是支付方必须固定写死。到这里，一对多的闪电网络设计已经出了问题。闪电网络给出的答案是，必须让路由节点在线（一定时间内在线一段时间，处理这些路由支付）。

![Payment route](https://storage.googleapis.com/papyrus_images/0df7d43fee2cd01768d8c4d506d62060c83561dc5382cdb01adb6516b5843bd3.png)

Payment route

设计上，我们让路由节点在线完全离线，是最佳方案。如果我们假设 C 和 D 是一个普通用户，在闪电网络服务器上，只存在 channel 信息，并没有 C 和 D 的私钥，所以在 A 签名后，就算 C 和 D 不在线，B 依然可以收到钱，因为只要看到 A 的签名，并且查询到 A 到 C 的 channel 中 A 的余额已经合法的减少了，系统就会给 B 增加余额。 理论上，就算 A 与服务器的通信中断了，A 把签名数据邮件给 B，再由 B 提交给系统，也是可以完成支付的。但是由于这样做已经违反了一对一闪电网络的基本原则，无法对抗双花了，所以闪电网络要求 C 和 D 必须部分时间在线，并且利用了 UTXO 时间锁，这最终还是在利用区块链的抗双花特性来保护闪电网络。闪电网络自身依然脆弱（另外如此频繁的使用区块链，在15年或许可以，而现在BTC的价格已经不那么便宜了）。

此时，当用户 A 尝试双花，向 B 和 G 同时支付 channel AC 中的余额，此时由于闪电网络没有共识算法，系统是无法判断哪笔交易发生在前的（或许之前签发的交易因为网络延迟了，后收到） B 和 G 就变为争抢这笔付款，而系统无法给出唯一判定。最终两位需要去链上抢这笔付款。

在一对一的网络 channel 中，由于收款人是固定的，只能超花不能双花，所以收款人可以接受一笔付款，并且拒绝另外一笔，不会出现争抢和难以判定。但是在一对多的闪电网络中，这样的判定是不可能的。

![Over payment](https://storage.googleapis.com/papyrus_images/ec882f02d161dd88cdc8b9f7e7d837445ae2587e3d378275f635d12ca2119986.png)

Over payment

当然，利用 BTC UTXO 的特性，在闪电网络的设计中，使用了双向的 channel 设计，并且要求 C 和 D 部分时候在线。但 C 上线后发现 A 尝试的两笔花费超过了 channel 中锁定的资金额度，但无法确定先后顺序，于是 C 判定 A 违规并进行链上回滚。虽然我们无法确定 A 双花的钱到底应该是属于 B 还是 G，但是我们可以发现争议并取消交易，这样 A 并没有付给 B 或者 G 任何资金。回到真实场景，在链下支付的时候，A 有可能向 B 和 G 购买了一杯汽水和一份汉堡，在等待 C 和 D 上线确认的时候，汽水和汉堡已经进肚子了，最终 B 和 G 都没有收到钱。

我们看到闪电网络无论是一对一还是一对多的设计，都有较大缺陷。作为一个差不多10年前的项目，同一时代的以太坊已经差不多叙事枯竭，但闪电网络依然难产。使用技术补丁修复理论缺陷，就算不是徒劳的，也非常复杂。例如，PoS 算法相对于 PoW 算法，就复杂的多，因为 PoS 需要检查很多作弊和违规行为，罚没资金，所以算法实现就会变得臃肿和丑陋，远不如 PoW 简单优雅。我们相信，区块链原生支付拥有广阔的场景，它的未来就像使用纸币一样简单。学习和了解闪电网络有助我们探索全新的区块链支付协议。

---

*Originally published on [0xKJ](https://paragraph.com/@0xkj/DtPYP568e0hdJK2YDfl6)*
