最近几个月里,国内外社区(尤其是海外)对于闪电网络的讨论愈演愈烈,火炬传递行动(连 Twitter 的创始人杰克多西都加入其中)更是让闪电网络热潮到了新的高峰,这其实是让人很开心的事情,因为毕竟,在闪电网络这件事上,比特币社区实在是做了太多的努力,能走到今天,着实不易!
在闪电网络这方面,最初的论文作者当然是做了非常大的贡献,并且 Lightning Labs 研发的 lnd 也成了今天闪电网络最为流行的节点解决方案,另外还有像 Blockstream 这类的公司长期一直以来在闪电网络方面长期的技术投入,包括引入 Rusty 这样的技术大牛(Linus 的左膀右臂)来 All-in 了好几年,这对于闪电网络能走到今天至关重要。
今天,我们就将尽可能的用最浅显的语言来给大家讲述下这一基本原理,看看能不能做到让大家能基本明白闪电网络到底是怎么一回事。
首先,我做个比喻,假设大家现在在打一桌麻将,并且赌的是比特币,如果每打完一局大家都按输赢转账的话,考虑到比特币矿工费,成本其实是很高的,如果再考虑还需要等待一个块的确认时间,那个体验就很成问题了。那现在换一种方法,我们准备一个账本,账本上面列上甲乙丙丁四个人,以及每一局每个人的输赢情况,打满八圈之后,统一算一次帐,最终按最后一次算账的结果转一次币,这样的成本就低了非常多,因为只付一次矿工费就行了,玩儿的时候也不用再等了,因为每一局不再需要和比特币区块链打交道,也就不再需要等待交易确认时间。
日常生活中,很多人打麻将、玩牌其实都是这么算账的,因为哪怕是每一局给钱,都是件麻烦的事情,记个账最后算一下就好了。而这种算账方式,其实就跟闪电网络的思想有点类似了。但这里有几个问题要解决,作为无需信任的、去中心化的解决方案,如何确保打了这么多局之后,输的一方一定会认账?牌桌上我们能做到,那是因为互相之间有信任,陌生人之间必须是提前压钱的,必须有第三方来负责解决信任。而去中心化的像比特币这样的系统里,想做到这一点那可就难了,闪电网络牛逼就牛逼在彻底从逻辑上解决了这一问题。
首先,让我们来看图一:
首先说说这里的 Funding Tx(入资交易),假设 Alice 和 Bob 要往通道里各放 0.5 BTC。所谓的通道其实从技术实现角度上讲,就是一个 2/2 的多重签名地址,2/2 的意思就是要是想往外转这个地址上的币的话,需要 Alice 和 Bob 双方都同意(都签名)才行,这就像是打麻将你上桌前要先压钱一样。
只有一个 Funding Tx 的问题是,虽然这能保证双方都往里放了足额的资产(之后的操作都需要双方达成共识才行),但如果一方不配合,另一方的资产就被冻结在里面了,这显然不是我们想达到的目的。极端情况下,假设 Bob 把私钥给弄丢了,那 Alice 的币也没了,这显然是不行的。
所以,就需要提前准备好一个 Commitment Tx(承诺交易),即在往多签地址上发币之前,先准备好从多签地址给 Alice 和 Bob 各自转回 0.5BTC 的未签名交易,并且(因为是多签),Bob 要对这笔交易签名,并把签名发给 Alice,反之亦然,这样,Alice 和 Bob 都具备了从多签地址把币提回到自己手里的能力了(因为有了对方的签名),通过这种方式,现在双方就不用担心对方不配合了,可以放心的往多签地址里存入资产(因为不需要对方同意也能拿回资产),这就比前面有要好了一些。
当做好这些步骤之后,双方就可以把 Funding Tx 广播到比特币网络上了,也就是往通道里存好币,而无需担心对方的配合,因为可以随时把多签的币提走。(当然,双方要各自保管好对方给自己的 Commitment Tx 的签名)
这里我要简要的说一下隔离验证对于闪电网络的意义,首先隔离验证通过把签名从未签名交易的内部拿了出来,最终彻底解决了“交易延展性的问题”,而通过刚才的 Funding Tx + Commitment Tx 的例子我们能看出,闪电网络里大量的运用了对尚未广播交易的后续交易的依赖,这种依赖对于 tx id/hash 的确定性是有要求的,否则前置交易的 hash 如果变了,后面的交易就都作废了(你保管好的凭证也就都没用了),这样显然是不行的,这就是隔离验证对于闪电网络的意义之所在。
现在,让我们再来看看图二:
到了图一的内容之后,其实还不够,因为静态的一个通道是满足不了用户的需求的,玩麻将的时候会有输赢,我们需要通道能体现每一局的输赢关系,比如说 Alice 输给了 Bob 0.1BTC。
我们假设,用类似图一的方式,同样准备好未签名交易,给 Alice 转0.4BTC,给 Bob 转0.6BTC,双方互相签署交易后,把签名给对方。这样,跟原来的 0.5/0.5 相比,通道又多了一个状态 0.4/0.6,双方都有能力广播这笔交易,各自拿回 0.4 和 0.6 BTC。
但问题又来了,从 Alice 的角度,她更有动力广播 0.5/0.5 的那笔交易,而 Bob 则更有动力广播 0.4/0.6 的那笔交易,这种情况下,其实还没有达到我们的目的。
这里其实要说明一下,现在我们需要的其实是能标记出 0.5/0.5 和 0.4/0.6 先后次序的方法,并且,还得在后面的凭证生效后,前面的凭证作废,也就是当 0.4/0.6 生效后,0.5/0.5 得作废才行。
现在让我们看下图三:
(这里我们要说明一下,紫色的表示 Alice 手中已经有了 Bob 的签名,自己再签一下广播出去就能生效的交易;蓝色的反过来)。
图里有一个词叫 Revocable Sequence Maturity Contract (RSMC) 可撤销序列成熟合约。
图三里的逻辑主要就在于,如果 Alice 想中断交易,她就得把 C1a 和 RD1a 广播到比特币网络上(因为 Bob 已经把这两个的签名给了她),当 C1a 广播后,Bob 直接得到了 0.5BTC,而 Alice 的 0.5BTC 被转入了另一个 RSMC 合约里,RD1a 的交易需要等C1a确认后的1000个块才能生效,Alice 才能拿到自己的 0.5BTC。
通过图三,做到了先后次序依赖及对于主动提出断开通道者的轻微处罚(即等待1000个块的确认)。也就是说,任何时候,通道的一方都可以在无需对方配合的情况下断开通道,断开通道操作会让对方马上得到币,而自己要等待一段时间。
继续看图四:
现在我们可以参考图三的方式,更新通道内的装态,从图三的状态更新到图四的状态,C1a/C1b 更新到 C2a/C2b,但我们必须得废除旧的状态,这又该如何做到呢?
其实我们需要引入的是惩罚机制,请看图五:
在Alice生成C2a/RD2a之前,他要把自己在C1a里面的私钥Alice2发给Bob;同样,Bob把自己的C1b里面的私钥Bob2发给Alice。
这里要说明一点,其实,这里给的是 RSMC 合约对应的多重签名地址的私钥,以 C1a 为例,Bob 对 C1a 的未签名交易做了签名,并且给了 Alice,但 Bob 是没法广播 C1a 的,因为 Alice 没签。也就是说,只有 Alice 能广播这笔交易。但当通道状态更新到了 C2a 之后,Alice 就不敢在广播 C1a 了,因为在更新到 C2a 之前,她得把 C1a 中 RSMC 的私钥(另一个私钥)Bob,而 Bob 得到这个私钥后,如果在比特币网络上看到了 C1a ,说明 Alice 作弊,Bob 就可以用 RSMC 中的 Alice2 私钥加上自己的 Bob2 私钥直接把 Alice 的 0.5 BTC 拿走,而 Alice 还要等待 1000 个 区块才能拿回 0.5 BTC,Bob 广播的交易会先生效,惩罚成功。
而如果 Alice 不违约广播 C1a 交易(而是按照约定废掉了这笔交易),那 C1a 就永远不会出现在比特币网络上,Bob 虽然拿着 RSMC 中的 Alice2 私钥,但也没任何用处,因为该地址上没币。
通过这种方式,最终做到了将通道状态从 C1 更新到了 C2,并且 Alice 和 Bob 都不敢回到之前的装态,因为谁回去,谁就被惩罚,币就全归了对方了。
这其实就是闪电网络最根本的原理。
这样,每一局我们都可以遵循这个规则,C1 更新到 C2,C2 更新到 C3……
最终,我们就能做到了打八圈麻将,每一局都记好账了,但后一局的结果会作废掉前一局的账目,在这个过程中谁也不敢作弊,作弊者将被处罚。
这其实就是闪电网络的基本逻辑。
这里我们可以额外补充一点,通过上面的介绍,大家应该能明白,对于 Alice 和 Bob 来说,把闪电网络通道中对方所发给自己的全部凭证(包括签名、包括历史私钥等)都安全的保留好,至关重要,如果你遗失了任何凭证,在对方违约的情况下,你就无法做到对对方进行惩罚了,也就是说,你将面临资产损失。
另外,对于闪电网络通道中的任何一方,还必须一直保持对区块链上数据的监控,比如说在通道更新到 C2 状态之后,Bob 必须一直监控着区块链上的数据,看看 Alice 有没有广播 C1a,因为他需要在 Alice 广播 C1a 之后的一段时间之内处罚 Alice,否则 Alice 的违约就成功了,而 Bob 将面临资产损失。这其实又是一个技术上需要解决的问题,这需要你要么自己运行个 SPV 轻节点来监控比特币区块链的数据,要么依赖别人提供的 Watch Towers 瞭望塔来监控。
闪电网络既然称其为网络,自然是有道理的,如果仅仅是 1:1 的通道,显然不能叫网络。
当我们理解了闪电网络底层支付通道的最基本原理之后,现在面临的一个问题就是我们不可能让所有的人之间都两两建立通道,首先,操作层面就不现实,更何况通过上面的原理大家明白了通道双方要各自往通道里存入一定数量的比特币,如果让你和所有的比特币用户都建立通道,那显然是不可能的。
这就需要一个网络结构,比如说,Alice 和 Bob 之间有通道,Bob 和 Carol 之间,Carol 和 Dave 之间都已经有了通道,那把这些通道串联起来,就相当于在 Alice 和 Dave 之间有了通道,Alice 就能通过闪电网络给 Dave 转币了。
相关步骤参见图六:
首先,Dave 准备一个随机数 R (除了 Dave 以外,Alice、Bob、Carol 都不知道 R)并计算其哈希 H,然后把 H 给了 Alice 。
Alice 和 Bob 之间达成一个协议,如果 3 天内 Bob 能给出 R ,则 Alice 会给 Bob 0.102 BTC,如果超过3天,就拿回这些币;
Bob 和 Carol 之间达成一个协议,如果 2 天内 Carol 能给出 R ,则 Bob 会给 Carol 0.101 BTC,如果超过2天,就拿回这些币;
Carol 和 Dave 之间达成一个协议,如果 1 天内 Dave 能给出 R ,则 Carol 会给 Dave 0.1 BTC,如果超过1天,就拿回这些币;
当这些协议都成立之后,Dave 把 R 给 Carol,得到 0.1 BTC,Carol 把 R 给 Bob,得到 0.101 BTC,Bob 把 R 给 Alice,得到 0.102 BTC。最终,我们达到了这个目的,即 Alice 支付了 0.102 BTC,Dave 得到了 0.1 BTC,Bob 和 Carol 得到了 0.001 BTC 的手续费。
上述的逻辑在闪电网络中是通过一个叫 Hashed Timelock Contract(HTLC)哈希时间锁定合约来实现的。比特币脚本是支持 HTLC 这类的合约编写的,具体的脚本因为是比较简单的条件判断,我这里就不详述了。 通过上面的逻辑描述,理解了原理的用户就应该能明白,为什么闪电网络的交易过程会是这样的,即:
收款者先准备个二维码,然后付款者扫码支付,其中是不是二维码这种形式并不重要,最重要的其实是需要收款者先准备出一个信息(要准备出个 R,然后计算出其哈希 H,并把 H 和公钥提供出来),付款者用这个信息付款,这一过程其实就是 H 的传递过程,然后大家再拿 R 来领钱。
也就是说,闪电网络的交易一定是由“接收者”发起的,这也是为什么习惯了比特币、以太坊钱包的用户往往会别扭的地方,大家都会说,你先给我个地址啊,我给你转币,以后我还可以反复的向这个地址转币。现在不行了,我得先给你个 H(加公钥),然后你再通过闪电网络通道给我转币,这个 H 只在一段时间之内有效,并且只能用一次,向另一个人收款的时候,我还得再给一个 H’,不能服用之前的 H,现在大家明白这是为什么了吧?
当我们把 HTLC 合约嵌入到 RSMC 通道时,更完整的闪电网络(多节点模型)就成立了,其中,闪电网络的白皮书用了很多篇幅来描述在网络模型下如何基于 RSMC + HTLC 做到去中心化+无需信任,最终来到今天大家终于可以体验的闪电网络。对于开发闪电网络基础设施来说,基本的原理可以通过我上面讲述的内容就能有一定的了解,但具体实现起来要考虑的方方面面就非常多了,比如说哪怕只是上面说描述的那些通道建立过程及节点传递过程,其实就是一个非常复杂的工程,再加上对于闪电网络这种“网络”系统来说,还得考虑类似于互联网上的节点查找、路由协议(手续费/通道大小等方面还会影响到路由的选择)等内容,这其实都是非常复杂的工作,这也是为什么直到今天闪电网络基础设施的初步进入到能让用户广泛尝试的阶段的原因。
在这里,我们应该感谢那些为了闪电网络付出艰苦努力的码农们,谢谢!
比太钱包 2019-03-20 20:14