闪电网络深度解读

个人思考/推荐理由
较为系统地介绍了闪电网络的技术实现
核心内容概括
本文较为系统地介绍了闪电网络的技术实现,包括通道、时间锁、哈希时间锁合约(HTLC)、网络和路由等
难度
入门
https://blog.lopp.net/bitcoin-and-the-rise-of-the-cypherpunks/
专题
比特币
Layer2
 
notion image
闪电网络是一种去中心化的链下技术方案,可支持每秒上万笔交易并发,接近于 Visa 系统能做到的程度(举个例子)。而在当前的比特币(世界上最流行的密码学货币)区块链上,只能支持每秒处理约 7 笔事务,还要付出高昂的手续费,并等待很长时间来确认交易生效,这些因素都使得几乎不可能用比特币发送小额交易。而闪电网络把这两个问题都解决了

引言

闪电网络是一种支付通道系统,与常见的多签名钱包没有任何区别。所谓开启通道,就是参与方创建一个多签名钱包,并向该钱包充入资金。这个钱包接收到的资金数量就成为这个通道的余额。再然后,参与方之间的后续交易就全部在区块链以外的环境中发生了。任一参与方都能随时关闭这个通道,这时候,最后一笔链下的交易(决定着该通道各参与方的余额)会被发送到区块链上,同时作废掉所有中间的交易,因为所有这些交易都使用同样的交易输出。结果是,我们只需一笔交易来开启通道、一笔交易来关闭通道,中间所有的中间交易都是即时收发的,无需记录在区块链上(因此无需等待)。
(译者注:比特币不是账户里面的余额,是一张张的支票;所有的支票都是由具体的某笔交易创造的;每一张支票都只用一次就会作废(也即只能用在一笔交易中)。交易可以任意分配所用支票的价值来生产任意数量的新支票。)
这样的通道所组成的网络使你可以向网络的另一个参与者发送资金,即使你们之间并无直接的通道。唯一的条件是你们之间要能形成一条 “路径”,即有通道能前后相接地把你和对方联系起来。此外,得益于特殊的智能合约(HTLC,哈希时间锁合约),你不需要信任网络中的任何人,合约会保证安全地交付你支付的资金。
要理解闪电网络是如何运行的,首先要理解的是支付通道的运行以及构成支付通道基础的 HTLC。这些话题都不小,所以我把文章分成了两部分,从解释支付通道的工作原理开始。

支付通道

如上所述,连接两个参与者的支付通道实质就是一个普通的多签名钱包。第一笔交易决定了一个通道的余额,我们称为 “充值事务” 或者 “锚点事务”。这笔交易需要广播到网络中并记录到区块链上,以表明通道开启。
做完了这一步之后,要更新通道双方的余额时,双方就需要手动交换签过名的 “承诺事务”。这些交易本身都是有效的,随时可以发送到比特币网络中,但双方都会暂时保存起来,不会广播出来,除非已准备关闭通道。如此一来,通道内双方的余额状态,一秒内变动几千次也没问题,更新的速度仅受限于双方创建、签名和向对方发送承诺事务的速度。
每次双方交换了一笔新的承诺事务,他们也就把通道的前一个状态作废掉;因此,只有最新的一笔承诺事务可以 “执行”。这样设计的目的是防止某一方欺诈对方,把一个过时的但对自己有利的状态发送到链上来关闭通道。下文我会讲解几种防止这种欺诈的机制。
最后,通道既可以双方一致同意关闭 —— 就是把一笔关闭事务(叫做 “结算事务”)发送到比特币网络中 —— 也可以单方决定关闭,就是把最后一笔承诺事务发送到网络中。这是为了防止某一方离线导致另一方在通道中的余额一直 “锁定” 的情形。
在通道存在的整个生命周期里,只有两笔事务被发到了比特币网络中并记录到了比特币区块链上(就是充值事务和结算事务)。在这两笔事务之间,双方可以交换无数次承诺事务,这些事务都不需要提交到区块链上。
notion image

一个简单的支付通道案例

在解释更加复杂的机制之前,我们先来考虑一个简单的、单向的通道的例子。为了简化这个解释,我们假设双方都是诚实的。后面我们会再考虑帮助我们阻止欺诈的机制。
假设一个通道有两个参与者,Emma 和 Fabian。Fabian 提供付费的视频流服务,而观看者通过通道来实现小额支付 —— 每观看一秒就要付出 0.00001 btc,相当于每小时 0.036 btc 。Emma 是一个想看视频的普通用户。
notion image
Emma 和 Fabian 使用一个特殊的程序来同步播放视频和运行支付通道。Emma 在自己的网络浏览器中启动这个程序,而 Fabian 在自己的服务器上使用同一个程序。这个程序具有一个普通的比特币钱包软件的所有功能,它可以创建和签名交易。支付通道的整个机制可以完全隐藏起来,用户看到的事实就是这个视频是按秒计价的。
现在我们来看看这个付费服务的具体工作流程。一开始,Emma 和 Fabian 要开启通道:建立一个 2-2 的多签名地址。从用户的视角来看,这个程序创建了一个 P2SH 地址(一个多签名钱包)并要求用户充入足以支付一个小时视频服务的资金。Emma 转了 0.036 btc 到这个地址,而这笔交易也就成了所谓的充值事务。
充值事务被打包到某个区块之后,这个通道就算开启了,视频也就开始播放。在第一秒钟,用户创建并签名了一条承诺事务,改变了通道内的余额:现在 Fabian 有了 0.00001 btc,Emma 还剩 0.03599 btc 。这笔事务使用了充值事务的输出,并创建了两个输出,含义就如我们这里所述。从服务商的角度看,程序收到了这笔事务,于是也签上名、连同第一秒的视频发回给 Emma。现在双方都有了一笔对方手动签过名的、反映通道最新状态的承诺事务;如有需要,任何一方都可以把这笔交易发送到比特币网络中。
到了第二秒,Emma 这边的程序又创建了一笔新的承诺事务,使用的同样是充值交易的输出(跟第一笔一样),这一次,承诺事务的第一个输出给了Fabian 0.00002 btc,把 0.03598 给了 Emma。这笔事务用来支付第二秒的视频下载。
我们假设,Emma 看了 10 分钟的视频,然后就退出了。在这段时间里,她签名并发送了 600 笔承诺事务(600 秒的视频)。最后的一笔有两个输出:0.03 btc 给 Emma,和 0.006 给 Fabian。Emma 关闭了通道,把最后一笔承诺事务广播到了比特币网络中作为 结算事务。如此,这个通道只有一头一尾两笔事务记录到了区块链上
notion image

免信任的通道

当然,从这个例子来看,一切都好,但这是因为双方都是诚实的。不难想象某些时候,其中一方会欺骗对方,像上面这么简单的设计可能就不够用了。
  • 虽然通道开启着,Emma 还是需要 Fabian 的签名来取出资金,因为这个通道是 2-2 的多签名地址。如果 Fabian 消失了,Emma 的资金可能会永远锁在这个通道里面。
  • 虽然通道开启着,Emma 可以使用任何一笔双方都签过名的承诺事务。在观看视频 10 分钟之后,她可以拿第一笔承诺交易上链,完全不需要经过 Fabian 的再次同意。

时间锁

这些问题的一种解决方案是在承诺事务中使用时间锁(事务层面的时间锁(nLocktime))。为了保证资金不会在通道中永远锁定,Emma 使用她的充值事务的输出创建了一个退款事务。她先给 Fabian 发送这笔事务,等 Fabian 签名并发回后,Emma 才把充值事务广播到比特币网络中,开启他们的通道。
这笔退款事务也成了第一笔承诺事务,而且它的时间锁为通道设置了一个存在时间的上限。假设 Emma 把时间锁设置为 30 天(4320 个比特币区块)(即 30 天之后这笔事务才能记录到区块链上)。接下来所有的承诺事务,所设置的时间锁会一个比一个短,这样更新的事务就能更早广播到网络中。
现在 Emma 不用再担心了,她知道即使 Fabian 玩失踪,她也可以在 30 天之后取回自己的资金(如果这是一条双向的支付通道,即 Fabian 也会存钱进去,那他也从自己的角度提出一笔退款事务)。
notion image
每一笔新的承诺事务的时间锁都比前一笔要短,因此,新一笔承诺事务总是能比旧的更早上链并使旧的事务作废(无法上链),这样就能防止任何一方恶意使用旧的承诺事务。如果一切顺利,Emma 和 Fabian 只需广播双方一致的普通结算事务,因此带时间锁的承诺事务只有一方下线时才会派上用场。
举个例子,如果第一笔承诺事务的时间锁是 4320 个区块,那么第二笔承诺事务可以设成 4319 个区块,以此类推。如此一来,第 600 笔承诺事务可以比第一笔承诺事务早 600个区块上链。
notion image
你可能也注意到了,这种方法虽然有助于防止某一方把更早的承诺事务上链(欺诈),但它有两个明显的缺点:
  • 第一笔承诺事务的时间锁限制了这个通道的寿命。如果这个时间锁设置的时间太长(比如 1 年),通道可以存在很久,但如果某一方玩失踪,另一方就不得不等待很长时间才能广播最后一笔承诺事务、取回自己的资金。
  • 第一笔承诺事务的时间锁也限制了可以在通道内发生的交易次数。在我们的例子中,这个数值是 4320,这个通道内只能发生 4320 笔事务,因为每一笔新事务都会把时间锁的时间减去 1 个区块。而且,以区块(10 分钟)为间隔,等于是强迫参与方要追踪比特币网络的区块,以免错过什么,以及在情形不对时尽早把最后一笔承诺事务上链。当然,这个间隔是可以延长的,但代价是通道内可以发送的交易数量会变得更少。
因此,时间锁让我们可以作废旧的承诺事务并保证通道双方都可以安全地关闭通道:如果他们都同意通道的最新状态,他们可以发送一笔不带时间锁的结算事务(与最后一笔承诺事务意思相同),关闭通道;如果某一方不在线,另一方也可等待最后一笔承诺的时间锁解锁,然后把该笔承诺事务广播到比特币网络中。

不对称的可撤销承诺

另一种解决上述信任问题的办法是取消早前的承诺事务。实际上,“取消(cancellation)” 这个词是不准确的,因为在比特币网络中,一笔上链的事务(得到区块确认的事务)是永远不可取消的。不过,特殊的构造方式可以使得上链较早的承诺事务无利可图。只需给予各方一个 “撤销密钥(revocation key)” 即可。
假设 Hitesh 和 Irene 决定开启一个通道。双方都充值了 5 btc 到这个通道中,确定了通道的初始余额。现在,双方不是签署同一笔标准的承诺事务,而是各自创建两笔不同的、不对称的承诺事务。
Hitesh 拿到的由 Irene 签名的事务有两个输出,第一个输出不带时间锁,立即给 Irene 支付 5 btc,而第二个输出带有时间锁,支付 5 btc 给 Hitesh,但要等(这笔事务上链后的) 1000 个区块之后,这个输出才能花用。详情如下:
Input: 2-of-2 funding output, signed by Irene Output 0 <5 bitcoin>: <Irene’s Public Key> CHECKSIG Output 1: <1000 blocks> CHECKSEQUENCEVERIFY DROP <Hitesh’s Public Key> CHECKSIG
与此同时,Irene 也可拿到由 Hitesh 签名的一个承诺事务,有两个输出:一个立即给 Hitesh 支付 5 btc,另一个输出则给 Irene 支付 5 btc,但要等 1000 个区块之后才能花。
Input: 2-of-2 funding output, signed by Hitesh Output 0 <5 bitcoin>: <Hitesh’s Public Key> CHECKSIG Output 1: <1000 blocks> CHECKSEQUENCEVERIFY DROP <Irene’s Public Key> CHECKSIG
因此,双方都拿到了一笔由对方签名的承诺事务。Hitesh 和 Irene 都可以随时把手上的承诺事务签名后广播出去,但是,一旦这么做了,另一方都会立即拿到钱,而自己只能等到 1000 个区块之后才能拿到,这可是大大的不利。不过,这还不足以让双方都诚实守信。
notion image
这就要讲到我们的最后一个功能了,可撤销的密钥,使得任一方如果试图欺诈,对方都可以惩罚 TA,使之血本无归。
如上所述,每一笔承诺事务都有一个 “延后” 的输出,我们把这个输出做得再复杂一点:这个输出既可以被等待了 1000 个区块的承诺事务发送者使用,也可以被通道的另一方使用,如果 TA 持有撤销密钥的话。当 Hitesh 创建承诺事务并交给 Irene 时,他的第二个输出既可以为自己所用(要等待 1000 的区块)也可以为 Irene 使用,如果后者掌握了撤销密钥的话。
Hitesh 会秘密地保管这个密钥,仅当他决定使用新的一笔承诺事务来更新通道内状态时才会发给 Irene。事务的详情如下:
Input: 2-of-2 funding output, signed by Irene Output 0 <5 bitcoin>: <Irene’s Public Key> CHECKSIG Output 1 <5 bitcoin>: IF # Revocation penalty output <Revocation Public Key> ELSE <1000 blocks> CHECKSEQUENCEVERIFY DROP <Hitesh’s Public Key> ENDIF CHECKSIG
(译者注:看代码会更清晰一些:第一个输出是给立即 Irene 支付 5 btc;第二个输出则是带条件的,既可以使用撤销密钥,立即获得 5 btc,也可在 1000 个区块后,使用 Hitesh 的私钥来使用这个输出。注意这里的 “IF…ELSE…” 式条件,它跟我们在其它的计算机编程中的含义是一样的。)
附带一个例子可能会更容易理解。假设 Irene 希望给 Hitesh 发送 2 btc,这时候他们要更新通道的状态,也就是要创建一笔新的承诺事务。双方各自创建一个不对称的承诺事务,并且,在签名之前,先把上一笔承诺事务的撤销密钥交给对方,如此便 “撤销” 了上一笔承诺事务。如果 Hitesh 希望以通道最后的余额来结算,而 Irene 看着觉得更旧的状态对自己更有利,她可以尝试把自己手中的上一笔承诺事务签名后广播到网络中,但这笔承诺事务的撤销密钥已经暴露给了 Hitesh;如果他发现这笔承诺事务上链了,他有足足 1000 个区块的时间可以把通道内的所有钱都拿走(第一个输出当下就给了他,而第二个输出只需他提供撤销密钥就可以立即使用)(没错,这个 “取消” 的动作没法自动化,Hitesh 必须关注 Irene 是否发送了旧的承诺事务到网络中,然后使用撤销密钥)。
(译者注:这种只设撤销密钥的实现是不够安全的,因为,即使撤销密钥已经曝光,欺诈的一方依然掌握着撤销密钥,也即双方都掌握着撤销密钥,因此,欺诈的一方可以跟被欺诈的一方赛跑,先将相应的花费交易上链的人就可以拿走资金。合理的实现是使用 “被承诺者的哈希锁 + 承诺交易签名者的签名”。假设是 Alice 给 Bob 签名,那么这第二个输出可以使用 Bob 给出的哈希值的原像 + Alice 的签名来花费,或者 Bob 自己在时间锁结束后花费)
因此,这种使用不对称可撤销承诺的通道的效率要更高,因为它不限制通道的寿命,也不限制交易发送的次数。

结语

到这里,我们的第一篇文章就结束了,估计你也要一段时间来消化一下,你也可以在评论中提问。在下一篇文章,我们会解释 HTLC 的功能,最终解释闪电网络是如何工作的。
链接
(完)
 
notion image
上一篇文章里,我们详细解释了支付通道的运作,以及多种保证支付安全发生的方法。不过,这些功能,还不足以支撑一个可用的支付通道网络:即使我们很确定在每个通道内每个参与者都是诚实守信的,也没法保证通过多个通道来支付同样是安全的。这就是我们需要 “HTLC(哈希-时间锁-合约)” 这种智能合约的原因。在本文中,我们会讲解 HTLC 工作的方式,并使用一个例子来展示多跳支付是如何在闪电网络中实现的。

哈希时间锁合约(HTLC)

HTLC 的结构并不复杂,但非常高效。它使我们可以创建具有明确 “过期时间” 的支付。你可能也猜得到,HTLC 合约由两部分组成:哈希验证和过期验证。
我们先从哈希值(hash)开始。要创建一笔带有 HTLC 的支付事务,你先要生成一个 秘密数值 R,然后计算出其哈希值。任何词语、任何数字都可以充当这个秘密值,因为,对哈希函数来说,它们都是一堆数据的组合,没有什么分别。
H = Hash(R)
这个哈希值 H 会放在事务输出的锁定脚本中。如此,只有知道 H 所对应的秘密值的人才能使用这个输出。而 R 就是所谓的 “原像(preimage)”。
HTLC 的第二部分是过期时间的验证。如果秘密值没有及时地公开,这笔支付就用不了了,发送者会收回所有的资金。
我们来考虑一个发给某人的 HLTC 支付事务:
# 检查所提供的 R 是否为 H 的原像 HASH160 <H> EQUAL IF # 检查公开 R 的人是否为事务最初的接收者 <Payee Public key> CHECKSIG ELSE # 检查时间锁是否已终止 <locktime> CHECKLOCKTIMEVERIFY # 检查请求返回资金的是不是事务最初的发送者 <Payer Public Key> CHECKSIG ENDIF
在正确的 R(哈希值 H 的原像)公开之后,我们进入 IF 流程,进一步验证提供 R 的是不是这笔支付事务一开始的支付对象。在花费这个输出时,接收方只需提供一个非常简单的解锁脚本:
<sig> <secret R>
如果解锁脚本所提供的 R 是错的,我们跳转入 ELSE 流程,首先验证时间锁解锁了没有。如果时间锁已然解锁,发送者就可以收回所有的资金。收回资金这个操作的解锁脚本也差不多,唯一的区别在于,为了进入 ELSE 流程,需要提供一个错误的秘密值:
<sig> <wrong secret>
当然,这只是 HTLC 的一个非常基础的实现,代表着一个普通的时间锁支付。你可以在脚本中加入任意多的其它条件,比如说,在 IF 流程中移除公钥验证,这样只要知道秘密值 R 的人都可以使用这个输出;也可以在其中加入多签名限制,要求提供多个预设私钥的签名才能解锁。
多说一句,在这个案例中,我们使用的操作码是 CHECKLOCKTIMEVERIFY,这个操作码使用绝对数值来定义时间锁,意思就像:“这个输出在区块 #546212 之前是无法动用的”。而在闪电网络中,还用上了另一种时间锁,更 “灵活” 的一种:CHECKSEQUENCEVERIFY,它用到的是相对数值,意思近于:“这个输出,在使用它的事务上链之后的 1000 个区块内,是无法使用的”(译者注:这里的数值都是例子,实践中当然可以使用别的数值)。

闪电网络案例

现在,我们终于讲解完所有元素了,可以尝试理解闪电网络运作的全景了。
我们假设现在闪电网络有 5 个参与者:Alice、Bob、Carol、Diana 和 Eric,他们各自有一个支付通道相连,而每个通道的每一边都有 2 btc 的余额可用。现在,我们尝试让 Alice 通过通道链条给 Eric 支付。
notion image
  • 一系列相连的双向支付通道,组成了闪电网络,可以转介 Alice 对 Eric 的支付 -
假设 Alice 现在要给 Eric 支付 1 btc。但是,如我们所见,他们并无直接的通道相连,而开设通道需要时间和金钱。幸运的是,Alice 连接着闪电网络,可以在一系列 HTLC 合约的帮助下完成间接支付。我们一步一步拆开来看。
  • 逐步分解闪电网络中的支付路由 -
  1. Eric 生成了一个秘密值 R,并把其哈希值发给了 Alice(他不会把 R 展示给其他人)
  1. Alice 使用这条哈希值创建了一个 HTLC,而时间锁设置成未来 10 个区块,输出的数额是 1.003 btc。这额外的 0.003 btc 是给支付通道链条中间方的手续费。那么,Alice 现在用 HTLC 锁住了 1.003 btc,而 HTCL 的具体条件以大白话表述如下:“Alice 会给 Bob 支付 1.003 btc,只要他能在 10 个区块内交出秘密值 R,否则这些钱会返回给 Alice”。他们之间的通道的余额也会因为这笔承诺事务而发生这般变化,现在 Bob 在通道内拥有 2 btc,Alice 有 0.997 btc,还有 1.003 btc 锁在 HTLC 里面
  1. 到了 Bob 这里,他可以随意处置 Alice 的承诺事务(这笔 HTLC 事务是通过他们之间的通道来发送的)。他在自己跟 Carol 的通道中创建了一个 HTLC 输出,数额是 1.002,时间锁设定为 9 个区块,使用了跟 Alice 所提供的同样的哈希值。Bob 知道 Carol 如果想获得这笔钱,就不得不找出秘密数值 R 来解锁这个 HTLC,而一旦她这么做了,他就会知道这个 R,因此也能解锁 Alice 的 HTLC,拿到 1.003 btc。如果 Carol 没法找到这个秘密值 R,Bob 和 Alice 都能在时间锁解锁后拿回自己的钱。注意,Bob 发送的资金数额比自己能够得到的数额小 0.001 btc,这就是他收取的手续费数额。Bob 和 Carol 在通道内的余额变成:Carol 拥有 2btc, Bob 拥有 0.998 btc,还有 1.002 btc 锁在 HTLC 中
  1. Carol 获得 Bob 发出的承诺事务之后,也如法炮制,在与 Diana 的通道中创建一个 HTLC,使用的哈希值与 Bob 提供的无二,时间锁设置为 8 个区块,数额为 1.001 btc。如果 Diana 能在 8 个区块以内揭示这个秘密数值 R,就能解锁这个 HTLC,获得 1.001 btc,相应地,Carol 也会知道这个秘密数值,解锁 Bob 给她的 HTLC,获得 1.002 btc,赚得 0.001 btc。Carol 和 Diana 通道内的余额变成:Diana 拥有 2btc、Carol 拥有 0.999 btc,还有1.001 btc 锁在 HTLC 里面
  1. 最终,当 Diana 将一个 HTLC(使用同一个哈希值作为锁)通过通道发送给 Eric 时,她把数值设为 1 btc,时间锁设为 7 个区块。Diana 和 Eric 的通道内余额变成:Eric 拥有 2btc、Diana 拥有 1 btc,还有1 btc 锁在 HTLC 里面
  1. 现在,我们来到了这个连锁支付的终点。Eric 拥有这个秘密值 R,这个 R 的哈希值用在了所有的 HTLC 承诺事务中。Eric 可以解锁 Diana 发给他的 HTLC,获得 1 btc;而 Eric 取回资金之后,Diana 也会知道这个 R。Diana 与 Eric 的通道内余额会变成:Eric 拥有 3 btc,Diana 拥有 1 btc。
  1. Diana 收到这个秘密之后,也拿来解锁 Carol 发给她的 HTLC,获得 1.001 btc 的同时也向 Carol 公开了秘密值。他们通道内的余额变成了:Diana 拥有 3.001 btc,Carol 拥有 0.999 btc。
  1. Carol 收到秘密值 R 之后,解锁了 Bob 发过来的 1.001 btc,因此 Bob 也知道了这个秘密值。他们通道内的余额变成了:Carol 拥有 3.002 btc 和 Bob 拥有 0.998 btc
  1. 最后,Bob 使用秘密值 R 获得了和 Alice 通道中的 1.003 btc。于是通道内的余额变成了:Bob 拥有 3.003 btc,Alice 拥有 0.997。
这样一个流程下来,Alice 就给 Eric 支付了 1 btc,无需在彼此间另开一个直接相连的通道。整个支付链条中,也没有人需要信任另一个人,而且他们还因为中介服务赚到了 0.001 btc。即使支付在某个环节卡住了,也没有人会遭受损失,因为资金还锁在那里,时间过了就可以取回。

清除故障

在我们这个例子中,整个流程都是很平滑、没有阻碍的,但在现实生活就像所谓的 “墨菲定律”:如果某种坏事可能发生,那这种坏事就一定会发生。于是我们要考虑闪电网络的 “保护” 机制。
从实践来看,支付链条越长,最终无法交付资金的概率就越大:某些参与者可能会关闭通道,或者某些节点会掉线。我们来考虑两种可能的出错情形。

通道故障

先考虑一种情形:我们假设资金已经达到了目的地,但在秘密数值一路返回到支付起点的过程中,某个参与者拒绝合作或者无法配合。假设是 Bob。
notion image
  • 因为一个通道关闭,资金无法交付 -
当 Diana 收到了秘密值时,就立即取回了资金,并把秘密值暴露给了 Carol。Carol 也想从 Bob 发出的 HTLC 里面拿回资金,但 Bob 没有响应,为了避免风险,她关闭了通道,将自己手上的最后一笔承诺事务(也即 Bob 之前发出的、带有 HTCL 输出的事务)广播到了比特币网络中,而且,因为她知道秘密值,所以能取回资金。此时,Bob 还有三天时间可以从 Alice 处拿回自己的钱(因为 Carol 的事务已经上链,Bob 可以很容易地知道 R 的数值)。否则,等时间锁一解锁,Alice 就可以收回资金。
可以看出,即使某个参与者因为某种原因离开了网络,TA 自己是唯一一个可能损失资金的人,而其他人的资金都是安全的。

重新路由

在第二种情形中,我们假设资金无法到达目的地,也是因为某个参与者出了错。假设是 Carol。
第一种也是最明显的解决方法是,等待 HTLC 的时间锁过期,然后各参议者各自拿回自己的资金。
notion image
  • 支付路径中的某个节点没有响应 -
但如果 Alice 就是着急支付,该怎么办呢?当然,Alice 可以通过另一条路径发起新的支付,不需要死等资金返回,但要是 Carol 突然之间又回来了,跟 Bob 把链条续上了呢?那 Alice 不就发送了两倍资金了吗?
notion image
  • Alice 如果使用另一条路径 -
这是否意味着,但凡出现了支付失败的情形,都应该乖乖等时间锁超时,然后再发起新的一笔支付呢?
好在,要避免这种等待,我们可以 “取消” 这一次的支付。Diana(收款方)要发送等量的一笔资金给 Alice,也使用跟原来一样的哈希值,也可以使用另一条路径。现在,如果 Carol 重新上线并参与中介,那么资金会走完一个环路,这就意味着那笔原来失败的支付被抵消了,Alice 可以安全地使用另一个路径来支付了。
notion image
  • Alice “取消” 了旧的支付,新的支付现在可以安全地发送了 -

支付数额

你可以也注意到了,当 Alice “取消” 其第一笔支付时,现在的确是可以安全地发起新的一次支付了,但这并没有改变一个事实:她的第一笔支付的资金现在仍然是锁定的,而她可能没有足够的钱来发起第二次支付了。这就是为什么在使用闪电网络时,用 HTLC 来支付时资金额度应该更小。因为承诺事务不会上链,数额可以分割成多个很小的额度。这样,无论什么时候一个路径不通了,都只有一小部分资金会被冻结(就是最后发送的那一笔)。

传输协议

闪电网络的另一个非常重要的特点是:有关这个路径的所有信息都是完全匿名的。也就意味着对于任何一个参与者来说,TA 都只知道跟自己有关的这部分,比如,对于 Carol 来说,这笔支付就像是 Bob 在给 Diana 转账,她不知道 Bob 会从 Alice 处收到资金,也不知道 Diana 会继续转账给 Eric。
闪电网络使用 Sphinx 多重加密协议。在使用闪电网络时,Alice 会为网络的每一部分都做一层加密,从支付路径的末端开始。她使用 Eric 的公钥为 Eric 加密了消息。这条加密消息会被嵌套在给 Diana 的消息里,并用 Diana的公钥对整个消息再做一次加密。再然后,这条给 Diana 的消息又会嵌套在给 Carol 的消息里,也用 Carol 的公钥对整个消息再做一次加密。如此不断重复,得出可以交给下一个人的消息。这样一来,Bob 只能解密消息的最外一层,得到本意发给他的内容;然后把消息转给 Carol;Carol 也是如此。每经过一个人,都只会公开绝对必要的消息:支付的数额、佣金的数额、时间锁的内容,等等。
为了让人不能从消息的长度中推测链条的长度,消息的长度都是一样的,总是像有 20 个人参与这个链条一样。每个人,包括最后一个,得到的都是同样大小的图像,都以为除了自己以外还有 20 个伙伴。

闪电网络的好处和应用场景

当然,闪电网络的好处并不像很多人以为的那样,只有可扩展性一项。我们想想闪电网络到底带来了哪些可能。
  • 即时交易。使用闪电网络时,事务几乎是即时完成的。所以用比特币来买咖啡就变得可行了
  • 交易所套利。当前,从一个交易所转出资金并转入另一个交易所是很不方便的,需要等待 3 至 6 个区块来确认交易。如果交易所能使用闪电网络,那用户就能即时转入资金、参与套利。交易所也不再需要冷钱包来存储资金,极大地降低了盗窃风险。
  • 小额支付。比特币区块链的手续费对小额支付来说太高了。很难想象谁会愿意支付 0.001 btc 就为了转账同等数量乃至更少的金额。有了闪电网络,你就可以即时转移任意大小的金额,举个例子,你可以按 MB 来支付网费。
  • 金融智能合约和交易。金融合约对时延是极度敏感的,而且通常需要许多计算。把大多数负担移到了区块链外,我们就有机会能创建非常复杂的事务以及合约,而无需把这些都记录到区块链上。
  • 跨链支付。如果使用不同共识规则的区块链使用同一种哈希函数,就有可能使用闪电网络来跨链支付。参与者无需信任任何人,也无需使用中介。
  • 隐私。在闪电网络中,事务比起在比特币区块链上要更加隐秘,因为支付链条的参与者并不知道交易的发起方和目的地。

结论

我们已经讲完了闪电网络。在下一篇文章中,我会告诉你如何使用 HTLC 来执行一次跨链的原子互换,用 btc 交换 ltc。
链接
(完)