比特币闪电网络:可扩展的链下及时支付-----0592版
Joseph Poon
joseph@lightning.network
Thaddeus Dryja
rx@awsomnet.org
January 14, 2016
初稿版本 0.5.9.2
英文版链接:
http://lightning.network/lightning-network-paper.pdf
今天的比特币协议可以涵盖全球所有金融电子支付系统中的交易量,并且无需一个第三方托管机构持有资金,对于参与使用者的要求也仅仅是一台能够宽带上网的电脑。 人们提出了一种去中心化的系统,通过这个系统,交易通过小额支付通道(也就是支付通道或交易通道)网络发送,其中的价值转移发生在链下。 如果比特币交易可以使用新的sighash类型进行签名,这种类型签名可以解决延展性问题,那么如果附加上合约,这些转移就可以发生在涉及的路径上的不可信参与方之间。根据合约内容,万一存在不合作或敌对的参与者,可以通过一系列递减的时间锁,在比特币区块链广播强制执行。
第一章 比特币区块链可扩展性问题
比特币[1]区块链作为分布式账本,承载着巨大的希望,但区块链作为支付平台,本身却无法在不久的将来颠覆全球的电子商务。区块链是一种流言协议,所有对分类帐本的状态修改都会向所有参与者进行广播。正是通过这种“流言协议”,状态的共识,每个人的余额都达成了一致。 如果比特币网络中的每个节点必须知道全网发生的每一笔交易,那么可能会严重拖累全网金融交易能力。相反,我们希望实现的是涵盖所有交易,却并不牺牲去中心化和安全性。
Visa支付网络2013年假期期间实现了每秒47,000次峰值交易(tps)[2],目前平均每天数亿次。 目前,比特币由于每个区块具有1M的限制,每秒少于7笔交易。如果我们假设每笔比特币交易平均占用300字节,并且区块大小无限制,那么要达到相当于Visa交易量47,000 的 tps,平均每十分钟产生的一个比特币区块大小将会接近8G。 长此以往,每年将会产生超过400T的数据。
显然,今天在比特币网络上实现类似Visa的交易量是不可行的。 当前的家用计算机还不能支持这种带宽和存储。 如果比特币将来取代所有的电子支付,而不仅仅是Visa,将会导致比特币网络的彻底崩溃,或者至多是比特币节点和矿工出现极端中心化,只属于那些能够负担得起的人。 之后,这种中心化将会摧毁比特币以安全著称的去中心化网络,导致验证区块链并确保账本精确安全的能力消除殆尽。
更大的区块,更少的验证者,这不仅意味着更少数量的个体来保障账本准确性,而且会导致作为挖矿过程中关键环节的验证区块链的实体越来越少,这加剧了矿工中心化过程。如果存在非常大的块,例如在上述情况下平均每10分钟产生一个8GB区块,意味着只有少数几方矿霸才能进行区块验证。这使得实体很可能最终只信任中心化的矿霸。拥有特权的获得信任的这些矿霸就可以制造一个社会陷阱,使自己不再代表大多数个人(委托代理人)的利益,例如通过收取更高的费用来减轻自己不诚实行为的动机。在极端情况下,这表现为个人转账的资金发送到了完全保管客户资金的中心化的监管人手里。这种安排,就像今天常见的那样,会造成严重的交易对手风险。防止这种中心化发生的先决条件是,比特币需要由家庭宽带连接上的单台消费者级计算机进行验证。通过确保较低成本进行全面验证,比特币节点和矿工将能够防止极端的中心化和信任,从而确保极低的交易费用。
虽然摩尔定律可能会无限期地继续下去,而且未来可能存在这样的节点,能够经济地计算GB大小区块,但这并不是确定的。
为了实现用比特币进行每秒多于47000笔交易,需要脱离比特币区块链
本身进行交易。如果比特币网络支持每秒几乎无限数量的交易,并且小额支付的费用极低,那就更好了。 许多小额支付就可以在交易两方之间顺序发送,并且可以支付任何额度。 小额支付可以实现不受限制的,无需信任的商品化服务,就像互联网中的按照每兆字节收费。 然而,为了能够实现这些小额支付用户场景,将需要大大减少最终在全网比特币区块链上广播的交易量。
虽然可以小规模进行,但绝对不可能在网络上处理大量的小额支付或包含所有全网交易。 为了使比特币获得成功,有一点必须确信,要使它非常受欢迎,它的现有源于去中心化的优势必须继续存在。 为了让今天的人们相信比特币将在明天继续发挥作用,比特币需要解决区块大小可能导致的中心化问题,大区块毫无疑问将会产生可信任的托管人,并且伴随更高的费用。
第2章小额支付通道网络可以解决扩展性问题
“如果一棵树倒在了森林里,附近没有人,那么它发出声音了吗?”
上面的疑问是指未观察事件的相关性 - 如果没有人听到树倒下,它是否发出声音是无关紧要的。 类似地,在区块链中,如果只有交易双方关心他们之间的日常重复交易,则比特币网络中的所有其他节点不必知道该交易。 相反,最好的应该是区块链上只记录最少的信息。 通过推迟向全世界广播每笔交易,只是在一段时间以后,进行交易双方净值结算,可以使得比特币用户能够进行更多交易,而不会使区块链膨胀,或与一个中心化的交易对手建立信任。 通过使用时间锁作为全网共识的组成部分,可以实现有效的无信任的结构。
目前的小额支付和可扩展性解决方案将交易转交给一个托管人,由一个被信任的第三方托管来持有币,然后更新与其他各方的余额情况。如果受信的第三方来保存所有的人的资金,就可能产生交易对手风险和交易费用。
相反,使用这些小额支付通道网络,比特币可以扩展到今天使用的台式电脑上,利用它们的算力每天可以进行数十亿个交易。在给定的小额支付通道中,大量的支付行为是通过去中心化的方式进行的。这些通道不是比特币上出现的单独的可信网络。它们是真正的比特币交易。
小额支付通道[3] [4]在交易双方之间建立了一种永久更新余额的关系,推迟向区块链主链广播单一交易中的内容,直到总余额出现为止。 这允许双方之间的财务关系无需信任被推迟到以后的日期,却没有交易对手违约的风险。小额支付通道使用真实的比特币交易,只选择将交易结果推迟广播到区块链,保证交易双方在区块链记录当前余额; 这不是一个需要信任覆盖的网络 - 小额支付通道中的支付是真正的比特币通信和链下交换。
2.1小额支付通道不要求信任
就像上面提到的树木倒下发出声音的问题一样,如果所有各方都认为树在下午2点45分倒下了,那么这棵树确实就在下午2点45分倒下了。 同样,如果交易双方都同意通道内的当前余额是Alice有0.07 BTC,Bob有0.03 BTC,那么这就是真正的余额。 然而,如果没有加密技术,就会产生一个有趣的问题:如果交易一方不同意当前的资金余额(或树木落下的时间),那么双方就无法达成一致。 如果没有加密签名,区块链将不知道谁拥有什么。
如果通道中的余额是Alice有0.05 BTC,Bob也有0.05 BTC,交易后为Alice有0.07 BTC,Bob有0.03 BTC,网络需要知道哪组余额是正确的。区块链交易使用区块链账本作为时间戳系统解决了这个问题。 同时,创建这样一种系统也是可取的,但是除非绝对必要,否则不会主动使用这个时间戳系统,因为它对于网络来说是昂贵的。
相反,双方都可以同意签署交易但并不广播此交易。 因此,如果Alice和Bob将资金投入到一个2/2多重签名地址(需要双方同意才能创建支出),他们可以就当前的余额状态达成一致。 Alice和Bob可以同意从2/2的交易中为自己创建退款,每个交易0.05 BTC。 此退款不会在区块链上广播。 任何一方都可以这样做,但他们更可能选择继续该交易,因为他们知道只要他们想这样做,他们就可以赎回资金。 通过推迟此交易的广播,他们可以选择在未来某个日期更新这个余额。
要更新余额,双方都会从2/2多重签名地址创建新支出,例如0.07到Alice,0.03到Bob。 但是,如果没有适当的设计,就会出现时间戳问题,即不知道哪些支出是正确的:是新的支出还是原来的退款。
但是,时间戳和日期的限制,并没有复杂到像比特币区块链中的所有交易那么有序。 对于小额支付通道,只需要两种状态:当前的正确余额和任何旧的已弃用余额。 只有一个正确的当前余额,许多旧的余额被抛弃了。
因此,可以在比特币中设计比特币脚本,从而使所有旧的交易无效,只有新交易有效。 失效由比特币输出脚本和依赖交易强制执行,这就迫使一方将所有资金提供给通道另一方。 通过将所有资金作为惩罚给予对方,从而实现使所有旧的交易无效。
这种无效过程可以通过通道共识过程实现,如果双方就当前账本状态(以及建立的新状态)达成一致,则真实余额就会更新。 只有当一方不同意时,余额才会在区块链上反映出来。 从概念上讲,该系统不是一个独立的覆盖网络;它更像是当前系统状态的延期,因为区块链本身仍在强制执行(只是延期到未来的日期和交易)。
2.2 通道网络
因此,小额支付渠道仅在交易双方之间建立关系。 要求每个人都与其他人一起创建支付通道并不能解决可扩展性问题。 但是使用大量的小额支付通道网络就可以实现比特币的可扩展性。
如果我们假设比特币区块链上存在大型通道网络,并且所有比特币用户都至少打开一个比特币区块链通道来参与这个网络,那么就可以在这个网络内创建近乎无限量的交易。 比特币区块链上被过早广播的唯一交易只是不合作的通道交易一方。
通过使用哈希锁和时间锁将比特币交易输出延迟,通道中的一方就无法直接窃取资金,并且比特币可以在不被窃取的情况下正常交换。 此外,通过使用有差别的超时设计,可以让网络中的多个中介发送资金,而不存在中介方盗窃资金的风险。
3 双向支付渠道
小额支付信道简单地将交易推迟到交易之后某个时间点,之后再将交易状态广播到链上。合约的执行是在某些日期之前或之后,为交易一方制定广播交易到链上的条件。如果区块链是去中心化的时间戳系统,可以使用时钟作为去中心化共识的组成部分[5],来决定数据的有效性,并使用状态作为事件排序的方法[6]。
通过创建一张时间表,其中的某些状态被广播,之后再使之变成无效,这样就可以使用比特币交易脚本创建复杂的合约。先前的星型结构的小额支付通道[7] [8] [9](以及可信的支付通道网络[10] [11])的工作,希望在现在建立一个星型网络。 但是,闪电网络的双向小额支付通道必须满足附录A中描述的延展性软分叉,才能实现近乎有限的可扩展性,同时降低中间节点违约的风险。
通过将多个小额支付通道链接在一起,可以创建交易路由网络。 使用类似BGP的系统进行路由,发送方甚至可以指定到达接收方的特定路径。 输出脚本受到接收方生成的哈希的限制。 通过展示该哈希的输入,接收方的合约方就能够沿着该路径提取资金。
3.1 通道创建中的责任问题
为了参与支付通道网络,交易一方必须与该网络上的另一方创建小额支付通道。
3.1.1 创建无签名保证金交易
创建初始通道的保证金交易(Funding Transaction)时,交易一方或双方都注入资金到这笔交易的输入。 双方都为此交易创建输入和输出,但不签署交易。
这笔保证金交易的输出是一个2/2多重签名脚本,由该通道中的两个参与者,后面我们称为Alice和Bob组成。双方都不交换保证金交易的签名,直到他们从这个2/2的输出中创建了支出,将原始金额退还给原主。 不签署交易的目的是允许后期从尚不存在的交易中支出。 如果Alice和Bob交换了保证金交易的签名,而未能广播从保证金交易中的花费,那么如果Alice和Bob不合作,这笔资金将被永久锁定(或者在抵押情况下,由一方承担对手方的合作费用,造成别人的资金损失)。
Alice和Bob都交换输入,提供这笔保证金交易所需资金(这样可以知道通道的总价值由哪些输入确定),并交换一个密钥用来在之后进行签名。这个密钥用于这笔保证金交易的2/2签名输出:这笔交易需要两个签名才能花费,换句话说,Alice和Bob都需要同意,才能从这笔保证金交易中进行花费。
3.1.2 从未签约交易进行支出
闪电网络使用SIGHASH_NOINPUT交易,从这个2/2多重签名交易输出中花费,这是因为必须从尚未交换签名的交易中花费才可以。使用软分叉实现的SIGHASH_NOINPUT,确保交易可以在所有各方签名之前花费,因为需要签署交易才能获得没有新的sighash标记的交易ID。如果没有SIGHASH_NOINPUT,比特币交易就不能在它们被广播之前花掉 - 就像一方不首先向另一方付款就不能起草合同一样。 SIGHASH_NOINPUT解决了这个问题。 有关更多信息和实施,请参见附录A。
如果没有SIGHASH_NOINPUT,则无法在不交换签名的情况下从交易中产生支出,因为花费这笔保证金交易需要将交易ID作为子交易输入签名的一部分。交易ID的一个组成部分是父交易(指保证金交易)的签名,因此双方需要在子交易花费之前交换父交易的签名。 由于一方或双方必须知道父交易的签名并从中支出,这意味着一方或双方都能够在子交易存在之前广播父交易(保证金交易)。 SIGHASH_NOINPUT通过允许子交易花费而不签名输入来解决这个问题。 使用SIGHASH NOINPUT,操作顺序为:
1.创建父交易(保证金交易)
2.创建子交易(承诺交易和承诺交易中的所有花费)
3.给子交易签名
4.交换子交易的签名
5.签署父交易
6.交换父交易的签名
7.把父交易广播到区块链
任何人在上面的第6步完成之前,都不能广播父交易(步骤7)。 在第6步之前,双方都没有给出从保证金交易中花费所需的签名。此外,如果一方在步骤6中失败,父交易或者被花费,或者父交易的输入可以被双重花费 (以便整个交易路径无效)。
3.1.3承诺交易:一种未执行的构造
在未签名(未广播)的保证金交易创建之后,交易双方签署并交换初始承诺交易。 这些承诺交易可以花费保证金交易(父交易)的2/2输出。 但是,只有这笔保证金交易在区块链上进行了广播。
由于保证金交易已经进入区块链,并且输出是2/2多重签名交易,这就需要双方都同意才能进行花费,承诺交易用于表示当前余额。 如果双方之间只交换了一个2/2的签名承诺交易,那么双方需要确保保证金交易进入区块链后还能收回他们的资金。 只有在交易双方同意关闭通道,他们才会将承诺交易的当前余额广播到区块链。 他们是通过广播当前的承诺交易来实现的。
承诺交易向各方支付相应的当前余额。 一个简单的(不完整的)实现将构建一个未广播的交易,其中来自单个交易的2/2的花费有两个输出,这两个输出将所有当前余额返回给交易双方。 这样就实现了在创建初始承诺交易时就能将所有资金返还给原始方。
图1:此图中描述了一个简单的不完整的保证金交易。 所有其他交易签署后,绿色标注的保证金交易(F)才会在区块链上广播。 当交易一方希望更新其余额时,从保证金交易中花费的所有交易都还没有被广播。这时在区块链上只广播保证金交易。例如,如果Alice和Bob同意创建一个2/2的保证金交易,这笔交易的输出价值是1.0 BTC(每人拿出0.5 BTC),他们会同时创建一个承诺交易,其中Alice和Bob各有自己的0.5 BTC输出。 首先签署这个承诺交易并交换密钥,这样任何一方都能够在保证金交易进入区块链后的任何时间广播这个承诺交易。 此时,可以安全地交换保证金交易的签名,因为任何一方都可以通过广播承诺交易来兑换自己的资金。
然而,当一方希望更新当前余额时,这种构造就会中断。 为了更新余额,他们必须更新其承诺交易的输出值(这时保证金交易已经进入区块链并且无法更改)。
当双方同意新的承诺交易并交换新承诺交易的签名时,可以广播任意一个承诺交易。 由于保证金交易的输出只能兑换一次,因此这些交易中只能有一项是有效的。 例如,如果Alice和Bob同意通道中的余额现在为Alice0.4,Bob0.6,并且创建一个新的承诺交易以反映这个结果,那么就可以广播承诺交易。 事实上,只有一方可以主动广播,另一方将无法限制广播哪个承诺交易,因为双方都已签署并交换了签名。
图2:任何时候,只有一方可以广播其中一个承诺交易,就是说只有一方会从这笔保证金交易中进行花费获得受益。 但这样不行,因为另外一方并不想广播最近的交易。由于任何一方可以随时广播承诺交易,结果就是在生成新的承诺交易之后,获得较少资金的人更有可能广播承诺交易,因为广播承诺交易输出对他来说更有利可图。 这样的结果就是,通道将立即关闭,通道中的资金被盗。 因此,不能在这种模型下创建支付通道。
3.1.4 承诺交易:归咎责任
由于任何经过签署的承诺交易可以在区块链上广播,并且只有一个可以成功广播,因此有必要防止旧的承诺交易被广播。 在比特币中撤销成千上万的交易是不可能的,因此需要找到另一种办法。 不是采用让区块链主动撤销,而是采用与保证金押金类似的方式来构建通道,交易双方都做出共同遵守的承诺,违反这些承诺的行为将受到处罚。 如果一方违反了他们的协议,那么他们将失去通道中的所有资金。
对于这个支付通道,合约条款规定双方必须承诺仅广播最新的交易。 任何一方对较旧的交易进行广播都将属于违反合约,违约一方的所有资金都将作为罚款给予另一方。
只有能够界定清楚广播旧交易的责任,上述操作才能执行。 因此,必须要能够唯一地识别到底是谁在广播旧的交易。 如果每个交易一方都具有一个唯一标识的承诺交易,那么这样做就没有问题。 双方必须都要签署承诺交易的输入,而其中一方负责广播。 由于任何一方都具有一个由另一方已经签署的承诺交易的版本,因此这一方只能广播一个自己拥有的承诺交易版本。
对于闪电网络,所有从保证金交易输出产生的花费,也就是承诺交易,都有两个半签名交易。 一个承诺交易是Alice签署并给Bob(C1b),另一个是Bob签署并给予Alice(C1a)。 这两笔承诺交易来自相同的输出(保证金交易),但是具有不同的内容,只有一个可以在区块链上广播,因为这些承诺交易都是从同一个保证金交易进行花费。 任何一方都可以签署这些版本,并包括对方的签名,从而广播其收到的承诺交易。 例如,Bob可以广播承诺C1b,因为他已经收到了Alice针对C1b的签名 - 他拥有了Alice的签名并且自己也签署了C1b。 该交易需要Alice和Bob同时签名,是来自保证金交易的2/2输出的有效花费。
图3:紫色框是未广播的交易,只有Alice可以广播。 蓝框是也是未广播的交易,只有Bob可以广播。 Alice只能广播承诺交易1a,Bob只能广播承诺交易1b。 保证金交易输出中只能使用一个承诺交易。 责任分清楚了,这样任何一方都可以花费但不会产生处罚。然而,即使采用这种构造,也只是实现分清了责任。 目前还是无法在比特币区块链上执行此合同。Bob只是相信Alice不会广播旧的承诺交易。 此时,他只能通过半签名交易证明,证明Alice会这么做。
3.2 创建可撤销合约通道
为了能够实际执行合同条款,有必要构建一个承诺交易(及其花费),以便一方能够撤销交易。 通过了解有关交易何时进入区块链的相关数据,以及使用交易的成熟度来确定验证路径,就可以实现交易的撤销。
3.3 序列号成熟度
Mark Freidenbach提出,序列号( Sequence Number)可以通过父交易的相关区块成熟度,以软分叉[12]形式来实现。 这就允许在花费脚本上实现某种形式的区块确认时间锁。 此外,一个额外的操作码,OP CHECKSEQUENCEVERIFY [13](又称为OP RELATIVECHECKLOCKTIMEVERIFY)[14],将会在形成永久解决交易延展性的解决方案之前,提供过渡方案。 本文的未来版本将涉及这些方案。
最初比特币发布时设定有一个字段叫序列号,这个序列号本意是在未确认交易的内存池中强制使用。 其机制是如果存在更高的序列号,那么允许用新的交易替换内存池中的旧交易。 但是因为存在拒绝服务攻击风险,最终一直未能得以执行。 其实当初设置序列号的期望目的就是替换未广播的交易。 然而,这种单纯采用更高的序列号进行交易替换的行为在实践中并不可行。 无法保证内存池中旧版本的交易能够被替换掉,区块中包含的只是最新版本的交易。 链下实施交易版本的方法是通过时间承诺。
可撤销交易从单一输出中花费,其中该交易具有唯一类型的输出脚本。 此父级的输出有两个兑换路径,其中第一个可以立即兑换,而第二个必须满足子项之间的最少确认交易数后才能兑换。 这是通过使子交易的序列号需要来自父交易的最小确认数来实现的。 本质上,这种新的序列号行为仅在输出与兑换交易之间的区块数超过指定的区块高度时才允许从该输出进行花费。
通过在序列号中定义的一定数量的区块创建一种限制,可以这种方法实现撤销交易,实现只有父区块上链后特定数量的区块之后支付才有效。 这创建了一个结构,该输出的父交易成为保证金,证明没有撤销。 区块链上的任何人都可以在广播交易后一段时间内立即广播一笔花费来否决此证明。
网友评论