闪电网络的基本原理解析
扫描二维码
随时随地手机看文章
终于,我们越过了“可扩展”技术的“泥淖”,来到了看起来非常美好的无限扩展技术。
在可扩展技术中,我们介绍了可扩展的POW的两种思路——领袖选择和DAG,以及可扩展BFT的思路同时详细分析了HotStuff BFT的三阶段共识。然后,从输出的角度,我们发现两者是殊途同归地达到了O(N)的消息复杂度,因此,在输出上,如果采用一个比较新的,设计得足够好的算法,两者最终都应该受限于网络传输的上限,比如,在一个节点数量在10^2量级的网络中,达到10^3量级的TPS,而不会有本质上的区别。
最终,两者最本质的差别,还是1),类POW可以用于非许可的网络,而BFT算法需要用于许可,即参与共识节点已知的网络;2),两者达成的共识类型,确切的说是“一致性”的程度是不同的,中本聪共识达到的是概率的一致,而BFT共识达到的是绝对的一致。
当然,必须要清楚的一点是——我在这系列文章中做出的分类是基于“可扩展性”或者说消息复杂度这个主线来进行的,而不是按照许可/非许可,或者共识类型,所以其实具体到算法,并不是所有基于POW的算法都是非许可的算法或者达到概率的一致,这点是需要注意的。
闪电网络的基本原理
这里面描述了一种叫做“闪电网络”的技术,这种技术可以允许两个节点在链上锁定一笔钱开启一个支付通道,然后双方可以在链下,即不用通过将交易传输上链的方式进行快速的即时确认的交易,只要每方交易的总额都小于这个锁定的数值。
我先来大概讲解一下这个是怎么实现的:
首先Alice与Bob二人想要建立这么一条快速支付通道,于是两人先草拟一条抵押交易(Funding Tx),这笔抵押交易的格式是:“交易名称:F;输入:Alice:100元,Bob:100元;输出:Alice+Bob 200元。”这里,Alice+Bob是Alice和Bob的联合签名。这笔交易完全可以通过Alice和Bob双方在链下在不信任对方的情况下生成(具体细节有兴趣的同学可以参见白皮书)。但注意,在这个时候,双方还不对这笔交易的输入签名,因为如果这笔抵押交易真的生成了,那么如果这个时候如果对方消失,这笔钱就拿不回来了。
2. 于是,双方会分别开始构建接下来的承诺交易(Commitment Tx),Alice构建的交易格式是:“交易名称:CA;输入:Alice+Bob 200元;输出:Alice2+Bob:100元,Bob:100元”,而Bob构建的交易格式是:“交易名称:CB;输入:Alice+Bob 200元;输出:Alice+Bob2:100元,Alice:100元”,这里Alice2和Bob2是双方拥有私钥的另一个地址。这两笔承诺交易都会指向之前那个还没有发布的交易,因此,如果前面那笔交易没有发布,那么这两笔交易目前还是非法的。
3. 接着,双方再分别构建指向承诺交易的退款交易(Refund Tx),Alice构建的交易格式是:“交易名称:RA;输入:Alice2+Bob 100元;输出:Alice:100元,延时:1000区块”,而Bob构建的交易格式是:“交易名称:RB;输入:Alice+Bob2 100元;输出:Bob:100元,延时:1000区块”。这里延时100区块的意思是,矿工会判定这笔交易和它指向的那笔交易之间的间隔,只有在1000个区块之后,矿工才会认为这笔交易是合法的。
4. 接着,双方互换构建的承诺交易和退款交易,并且为对方的交易签名。以Bob为例,Bob会收到Alice的交易“交易名称:CA;输入:Alice+Bob 200元;输出:Alice2+Bob:100元,Bob:100元”和“交易名称:RA;输入:Alice2+Bob 100元;输出:Alice:100元,延时:1000区块”。Bob会签上两笔交易中Bob签名的部分并且将交易发回给Alice。注意在这个时候,由于第一笔抵押交易还没被签名,所以后续的所有交易都还是非法的,任何在这个阶段出现的问题都不会真正影响到双方的钱。
Alice将两笔交易发给Bob,Bob签完名发回给Alice
5,当双方都确认收到对方签名的交易之后,就可以在抵押交易上签名并上链了:我们以Bob为例来看这里的逻辑——Bob此时手中握着Alice签过字的,自己的承诺交易“交易名称:CB;输入:Alice+Bob 200元;输出:Alice+Bob2:100元,Alice:100元”和Alice签过字的Bob的退款交易:“交易名称:RB;输入:Alice+Bob2 100元;输出:Bob:100元,延时:1000区块”。这个时候Bob不担心自己的100元的安全,因为如果他想,他可以公布这两个交易,并且在1000个区块之后取回这100元。同时,Alice也拿不走这100元,因为如果Alice想要拿回自己的钱,那么她必须先公布CA,而CA中会立即将100元退回给Bob。于是,到此为止,我们完成了闪电网络的一个支付通道的创建。
6,那么,如何支付呢?实际上双方并不是进行支付,而是双双更新目前这个通道中的余额状况。我们假设Alice想要付给Bob10元钱,那么Alice和Bob需要创建新的承诺交易“交易名称:CA1;输入:Alice+Bob 200元;输出:Alice3+Bob:90元,Bob:110元”和“交易名称:CB1;输入:Alice+Bob 200元;输出:Alice+Bob3:110元,Alice:90元”以及新的退款交易“交易名称:RA1;输入:Alice3+Bob 90元;输出:Alice:90元,延时:1000区块”和“交易名称:RB1;输入:Alice+Bob3 110元;输出:Bob:110元,延时:1000区块”,并且如之前一般互换签名,最后,Alice将Alice2的私钥发给Bob以完成交易。
7. Alice和Bob此时手中都有两个同样对方认可过的账户余额数:100/100和90/110。那么,如何约束Alice不会在付完钱之后不认账呢?答案就是Alice最终发给Bob的Alice2的密钥。如果Alice试图用之前的CA取回100元,那么她唯一的方法就是先发布CA然后再发布RA,但是,RA必须在CA之后的1000个区块后发才是合法的。那么,如果Bob在链上发现了CA,即“交易名称:CA;输入:Alice+Bob 200元;输出:Alice2+Bob:100元,Bob:100元”,由于他已经有了Alice2的密钥,这个时候他可以立即构建一个交易“交易名称:P;输入:Alice2+Bob 100元;输出:Bob:100元”来在Alice之前拿走这100元钱。
由上可以看出,我们说闪电网络可以扩容,或者说提供了一种链下小额支付的渠道,实际上是提供了一种新的类似于储值卡或者积分卡的交易形式。通过这种交易形式,只要双方提前约定锁上一笔钱,就可以开启一个链下通道,在链下进行无限次数仅限额度的快速交易。
HTLC的基本原理
当然,其实大家都能看出来,这种技术的应用场景十分苛刻——一条链下通道其实就是一张储值卡,只供双方使用。但闪电网络实际上并不仅于此,以上所说的这种闪电网络被称为RSMC,然后,还有一种进阶的闪电网络,被称为HTLC。HTLC的具体实现要更复杂一些,在这里,我们只介绍HTLC的原理。
HTLC全称叫(Hashed Timelock Contract),基本原理是:假设A想要发1BTC给C,但是A和C之间没有链下通道。然而,双方都与一个节点B有一条链下通道(这条通道必须是支持HTLC并且余额足够的)。于是,收款方C先设定一条谜题和答案,实际上就是自己生成一个Y,并且用哈希算出H(Y)=X,并把哈希值Y发给A。然后,A与B根据给的Y,协商出一个链下的HTLC:“如果B能在2天内给出Y的原像,即X,则可以获得A的1.1BTC,否则,这个合约失效。”接着,B再与C协商出一个链下的HTLC:“如果C能在一天内给出Y的原像,即X,则可以获得C的1BTC,否则,这个合约失效。”当两个合约都建立之后,C给出X,并从B那里获得1个比特币,然后,获得X的B给出X,从A那里获得1.1个比特币。这里,0.1个比特币是B作为中介的费用(现实中这个费用显然不会这么高)。然后请注意,这里的“币”与之前闪电网络中的类似,并不是真的币,而是协商完成的分配协议,双方如果愿意的化,可以根据这个分配协议,在给定的时间内去链上取回自己的币,或者,在这个分配协议的基础上再次更新分配协议。
以上是正常的情况,那么我们看看这里如果有恶意节点会怎么样:首先A没有作恶的空间,因为至始至终他只能出钱。而在合约建立之后,C是收款者,所以没有理由不愿意提供X来收到钱。而如果C提供了X,那么B也没有理由不去用X从A那里收钱。这个原则适用于有多个中介的情况——收款方会先提供X拿到自己的钱,而后一个理性的中继节点自然不会愿意平白无故地掏这笔钱,于是一定会用X从他上一个节点那里拿到钱。当然,这个支付链条的构建需要满足一个原则,即链条越长,最初付款的时候设定的时间需要越宽松,因为每个节点都需要给自己预留足够的时间来防止来不及从上家那里拿钱——
加入说,如果B跟C的协定是“如果C能在47小时内给出Y的原像,即X,则可以获得C的1BTC,否则,这个合约失效。”那么,如果C拖到47小时的最后一分钟给出X,这个时候,由于A的期限是两天,于是B就只剩下1小时从A那里拿到“钱”。注意,这里的“钱”需要打引号是因为这仍旧只是在闪电网络中的交易“协议”。B可以凭借这个协议从链上拿到钱,但是那样就需要关闭这个闪电网络通道,并且B只有在锁定期之后才能拿到真正的“钱”。所以说,B需要的是在这一小时内和A通过链下协商一个新的“财产分配协议”,然后,如果A不配合的话,B会把去链上拿回钱作为“迫不得已的选择”。因此,如果B给自己的时间太少,它大概只能做出“迫不得已的选择”。甚至连这个选择都来不及做了。
为了避免这种情况,每个节点都会预先告知一个自己需要预留的时间,就相当于“想从我这过可以,但是除了交易费之外,你得给我一天的处理时间”,于是,路径越长,这个时间也会累加得越长。但除此之外,我们还是说这个技术是“安全”的。这里“安全”需要打个引号,具体原因,我们放在下一篇再说。
闪电网络的局限性
有了HTLC之后,我们就实现了一个较为理想的状态——每个人都将一定的资金锁定在链上,而日常的小额支付都可以通过这种中继的方式通过链下进行。这个方法看起来很繁琐,但是所有的这些步骤都是在链下进行的,这也是最早二层网络这个词的由来——在支持者眼中,区块链的理想状态应该是第一层的结算网络,加上第二层的支付网络。
那么,我们能说因此我们实现了无限扩展吗?看起来好像又有哪里不对。因为从应用上说,闪电网络的确可以解决一部分的支付场景,但是一方面,我们无法把所有的支付场景都用储值卡或者积分卡代替,另一方面,闪电网络的反对者也并不是完全在危言耸听——一个将大部分交易场景都挪到第二层的网络是不安全和相当中心化的。一种可能是,第一层的交易减少会减少交易费,使得整个区块链的安全模型受到影响,而如果想要避免这种情况出现,如果还需要维持第一层网络的安全性,则需要提高交易费,于是导致第一层网络完全无法进行日常交易,于是这个系统难免退化成一个日常交易完全需要依靠某些能够付得起交易费有高额抵押的大节点进行的中心化系统。
当然,即便是这样,链下技术看起来还是很有前途的,毕竟其实在生活中我们有很多需要先提供抵押的支付场景,而且,储值卡和积分卡在现实之中也不少见。于是,有没有可能我们在加密货币这个领域,在小额快速支付的领域推广这种方法呢?
答案是很难,我们来对比一下闪电网络实现的功能与普通交易、积分卡和充值卡之间的区别。
本质上,区块链的交易假设交易发起者是理性的:交易发起者想要发起交易,例如付款买东西,因此,向交易接收者证明交易成功是交易发起者的职责。于是,交易发起者需要能够提供一个接收者能够接受的证据——在中心化系统里,这个证据是来自可信第三方的交易确认,而在区块链系统里,这个证据是这笔交易上链,并且得到了确认。为了取得这个证据,交易发起者要么自己出块,参与共识过程,要么把交易发给矿工,委托矿工做这个事情,然后付一定的交易费。而在这里面,接收者只需要记好自己的私钥,并且一次性的验证自己的钱收到了,就可以高枕无忧了。
以上的这个逻辑是顺畅的,也是非常接近于传统中心化系统的,只不过把传统中心换成了矿工+区块链。于是,其实大部分的现实场景都可以无缝第对接到这样的系统中来,用区块链来实现。
然而,闪电网络交易需要同时假设交易发起者和接收者都是理性的。实际上如果你仔细分析闪电网络的话,你们交易的并不是真的钱。
在区块链的交易中,一笔交易是“A付给B10块钱。”
这个交易经过所有节点的认证,所以不能被逆转。
而在闪电网络中,一笔交易的实质是“A付给B10个积分,凭借着这些积分B可以:a)和B之间当作钱用;b)在一天之后付出一定手续费,换成10块钱;c)如果一天之内发现A尝试作弊,那么发现A作弊并且及时反制,获得A的100元抵押;d)在一天之内A作弊你没能及时反制,于是积分作废。”
这个凭证的真实性,只需要通过B的验证。
其中,b相当于是一个储值卡的作用,而且是个相当不错可靠的储值卡——相比于储值卡的好处在于,首先,你不用担心你充的钱退不回来,相当于不用担心对方跑路,但是,你通常需要等到约定的时间结束才能解锁这笔钱,除非对方愿意重新和你协商一个解锁时间。但大家仔细想想储值卡的使用场景——如果不是因为储值卡通常有优惠,谁会使用储值卡呢?但功能b并不提供优惠,而仅仅提供交易的便捷性和低手续费。那么,采用储值卡对于普通用户有多少吸引力就大打折扣了。
以上说明,闪电网络能够作为一个没有折扣的储值卡。但比较复杂的地方是a,c和d,也就是储值卡之外的部分——也就是这张卡不仅能储值,还能收积分,积分还能换钱,但虽然这个积分规则上说的是和货币1比1等值兑换,实际上积分的价值不仅跟你自身的能力有关,还跟网络的安全性有关。在闪电网络中,接收者不仅仅只需要一次性的验证接收者发出的交易结果,而且还要不定期在线观测主链以防交易发起方作弊。如果交易发起方作弊的话,交易接收方需要发起反制拿走交易发起方的保证金。
综上所述,闪电网络的应用场景受到以下几个限制:
1,无论是用作付款(储值卡)还是收款(积分),使用者都需要是非常高频的交易者,才能够有意愿为了降低交易费付出流动性和积分无法兑换的风险。然而,这必须建立在闪电网络交易费低于链上交易费的前提下。
2,闪电网络的使用者需要更高的技术门槛——一笔收到的钱并不保险,他们必须同时保持定期观察链上。如果更现实一点说,比特币的技术门槛已经可以让大部分普通用户望而却步了,但是好歹在了解了基本概念之后,一个比特币的非活跃交易者还是可以自己用一个钱包,自己记住助记词,当一个真正意义上的比特币“用户”。但是如果换做要用闪电网络,尤其是还需要通过闪电网络收款的话,那么基本上你除了依赖于提供闪电网络服务的机构别无选择,因为任何人都无法保证随时观察链上并且及时反制。于是,
3,闪电网络不是全无副作用的升级,而是另一种支付选择——闪电网络需要抵押,同时赎回抵押需要较高的延迟以防止作恶。因此,实际上使用闪电网络的用户实际上并不仅仅是把一笔钱放进了闪电网络用于快速支付,而且还必须自愿承担当你不需要使用这个服务时需要超过了锁定期才能把钱拿回来的流动性风险,同时,还需要面对钱有可能拿不回来的风险(这个我们最后再说)。
那么,闪电网络的应用场景有哪些呢?我们留到下篇再说。
链下技术发展的局限性
闪电网络本身就像开启了一扇门,让很多人误以为跨过了这扇门,后面就是广阔的一望无际的新天地了。于是,有了闪电网络就开始让无数人畅想第二层网络是什么样子——它应该和闪电网络一样,有一个在主链上的锚定做抵押,然后,在链下世界,就应该有无限可能,所有我们能够想到的在链上的场景,甚至,那些现实中我们还不知道怎么搬到链上的场景,统统都可以在链下,在第二层实现……
然而,实际上,在这扇门后的并不是一个新世界,而是一个漆黑的迷宫,和一扇又一扇的门。
闪电网络这种技术并不是通用的——当放在交易这种场景的时候,它看上去好像天然就是成立的,因为在交易中我们可以假设交易接收者因为有利益驱使(如果不定期观察链上的话交易接收方收到的钱就没有了)。但是这种假设仅仅适用于交易接收方有利益驱使的场景,而并不适用于普遍的场景。
有人可能会问——你说的这种场景是什么呢?
其实这种场景有很多——例如存证,例如溯源,例如几乎所有基于真实评价而成立的平台……这些场景都无法用类似于闪电网络的技术搬到链下,因为我们找不到一个有利益驱使的接收者负责一致观测一致性是否被篡改。比如一个文件的存证,我们可以解决第一步,说文件存证方需要提供一个证明给某个节点证明文件确实存证了。可是证明方有什么动机去一直观测这条链呢?或者换个场景,B通过100块在链上的担保进行了某份文件的存证,那么如果后来这份成了某个涉及到几百万元利益的商业纠纷的关键证据时,B会不会放弃自己100块的担保呢?
这就是闪电网络和链下技术的最大局限所在——
首先,闪电网络只能用于参与方都有利益因此愿意长期观测主链并且反制对方恶意行为的场景。
其次,链上押金的设计和应用场景强相关,因此对于每个场景的链下技术都是不通用的。甚至说,已有的技术随着场景的增加和改变都有可能不再安全。
那有人可能会说——实际上我们有个通用的方案啊:
无论是什么场景,我们干脆就找一个节点A放押金在链上,他负责验证某些事情e,然后,如果我们发现他作恶,我们就可以拿走他的押金。
然而这又引入了第三个问题——如何定义或者描述节点A作恶这个事情呢?
在我看来,一个理想的链下技术应该能够用智能合约实现如下功能:
对于某个场景,一个节点A放押金在智能合约内,他负责验证某些事情e并且保证能够即时地给出他们验证过e,并且e正确的证明p(e)。然后,如果B需要知道e和e的正确性的时候,他们就联系A,A会给他们提供e和p(e)。如果,A没有能够提供这个证明,那么B可以提供自己“没有获得应有服务”的证据,记为p(e,A,fail),然后拿走智能合约中那部分押金。
这就是第二层网络技术发展得举步维艰的原因——
1,我们知道小额支付,即充值卡这个场景,是个很实际,很有用,而且可以缓解链上压力的场景。而且这个场景中闪电网络看起来是个完美的解决方案,不需要依赖可信第三方,而且完全保证安全,因为没有人会冒着大概率丢掉100块的风险去偷10块钱。但对于其他场景,多少押金才是一个合适的担保,这一点本身就很难通用化。我们也还是需要针对不同的场景,设计不同的担保模型。如果最终我们认为“抵押了一笔足够大的金额就是可信的”的话,那么实际上,这和传统的中心化金融系统就并无区别了。
2,这里最难的部分,在于我们需要针对不同的事件e,设计数学上可证明的p(e)和p(e,A,fail)。而这一点本身就很难找到一个通用的解决方案,比如零知识证明就是这个问题的最贴近的技术,然而现有的零知识证明方案本身就不是通用的,它对于不同问题的证明难度大相径庭,同时,把一些场景用数学的方式描述出来就已经很困难了。于是,在很多时候,我们还是只能依赖于可信第三方来提供p(e)和p(e,A,fail)。而这在我看来就失去了大部分的链下技术的意义。因为同样的事情,我们可以对比一下以下的几种实现方案:
我们希望能够对于某个事件e的真实性进行验证。
1)中心化方案:某个权威机构或者某个可信第三方对其进行验证,并负责提供关于这个事件为真的声明s(e)。
2)联盟链方案:某些权威机构对其进行验证并提出关于这个事件为真的声明s(e),通过BFT类共识算法达成共识,并发布上链。只要超过2/3的机构是可靠的,那么e就是真实的。
3)公有链方案:矿工对其进行验证并提出关于这个事件为真的声明s(e),通过共识算法达成共识,并发布上链。只要超过1/2的算力/权益/抵押/被选出的节点……是可靠的,那么e就是真实的。
3.5)基于抵押的POS方案:矿工对其进行验证并提出关于这个事件为真的声明s(e),通过共识算法达成共识,并发布上链。只要超过1/2的进行抵押的节点是可靠的,那么e就是真实的。
4)真·链下方案:某个矿工A在链上进行一部分抵押,对于e进行验证,并提供e为真的证明p(e)。如果矿工验证有误或者无法在需要的时候提供p(e),则其他人可以用p(e,A,fail)拿走A的抵押。如果p(e)和p(e,A,fail)可靠的话,我们保证如果e的价值小于抵押,那么e就是真实的。
5)伪·链下方案:某个矿工A在链上进行一部分抵押,对于e进行验证,并提供e为真的一个通过可信第三方T认证的证明p(e)。如果矿工验证有误或者无法在需要的时候提供p(e),则其他人可以通过可信第三方T获取p(e,A,fail)并拿走A的抵押。那么,如果可信第三方可靠,并且e的价值小于抵押,那么e就是真实的。
链下方案的局限性通过以上方案的对比就很明显了:
如果对于一个作恶获利严格小于抵押的场景,并且存在数学上可证明的p(e)和p(e,A,fail),真·链下方案是非常有意义的。
如果作恶获利无法准确估计,或者对于通用的场景,那么采用抵押的链下方案,相比于基于抵押的POS方案,相当于将e的安全性从整条链1/2的抵押,降为了A一个节点的抵押。相应的,输出也得到了相应的提升,因为这笔交易不再通过所有参与抵押的矿工验证,而仅通过A验证。
如果不存在数学上可证明的p(e)和p(e,A,fail),那么链下方案实际上只是用更复杂的方案实现了一个依赖于可信第三方的认证或者仲裁系统而已。