# 第12章 区块链应用
现在,让我们把比特币作为一个应用平台application platform,进一步加深理解。现在很多人使用“区块链”这个词来表示任何共享了比特币设计原则的应用平台。 该术语经常被滥用,并被应用于许多不能提供比特币区块链主要功能的事情。
在本章中,我们将介绍比特币区块链作为应用平台所提供的功能。 我们将考虑应用程序的开发要素primitives,即组成任何区块链应用程序的开发模块。我们将研究使用这些要素的几个重要应用程序,例如支付(状态)渠道和路由支付通道(闪电网络)。
# 12.1 介绍
比特币系统被设计为一个去中心化的货币及支付系统。然而,它的大部分功能都是从底层的概念派生出来的,这些概念被更广泛用于许多应用程序。比特币不是由帐户,用户,余额和付款等组件构建的。相反的,就像我们在【第6章交易】 (opens new window)中看到的,它使用的是具有低级加密函数的交易脚本语言。就像账户,余额和付款这些更高级的概念可以从基本要素衍生出来一样,许多其他复杂的应用也是如此。 因此,比特币区块链可以成为一个向诸如智能合同等应用程序提供信任服务的应用平台,远远超出了作为数字货币和支付的最初目的。
# 12.2 开发模块(要素)
当比特币系统长期稳定运行时,它就提供了一定的保证,可以作为开发模块来创建应用程序。 这些包括:
杜绝双重支付
比特币去中心化共识算法的最根本保证是确保同一UTXO不会被花费两次。
不可篡改性
一旦交易被记录在区块中,并且随后的区块中添加了足够的工作量,该交易数据就变得不可篡改。不可篡改性是由能源进行保证的,因为重写区块链需要花费能源才能产生工作量证明。随着在包含交易的区块之后被提交的工作量增加,所需的能源以及由此带来的不篡改的程度也在增加。
中立
去中心化的比特币网络传播有效的交易,而不管这些交易的来源或内容如何。这意味着任何人都可以支付足够的费用来创建有效的交易,并相信别人会随时传输该交易并将其包含在区块链中。
安全时间戳
共识规则拒绝任何时间戳距离现在太远的区块,包括过去或将来。这可以确保区块上的时间戳是可信的。区块上的时间戳意味着一种保证,保证交易包含的全部输入之前都是未花费的。
授权
在去中心化网络中验证过的数字签名可提供授权保证。未经脚本中隐含的私钥的持有人的授权,包含数字签名要求的该脚本就不能被执行。
审计能力
所有交易都是公开的,可以被审计。所有的交易和交易所属的区块都可以在一个完整的链中链接回到创世区块。
会计
在任何交易中(创币交易除外),输入的金额等于输出的金额加上交易费。在交易中不可能创建或销毁比特币价值。输出不能超过输入。
永不过期
有效的交易永远不会过期。如果今天有效,它在将来仍然有效,只要那个输入未被花费,共识规则没有改变。
公正性
使用SIGHASH_ALL签名的比特币交易或由另外的SIGHASH类型签名的交易的部分,不能在未使签名无效的情况下被修改,如果修改将导致交易本身无效。
交易原子性
比特币交易是原子性的。 它们要么是有效的并且经过确认的(挖矿),要么不是。不存在挖出不完整的交易,交易也不存在过渡状态。在任何时间点,交易要么被挖出,要么没有被挖出。
离散(不可分割)价值单位
交易输出是离散和不可分割的价值单位。它们要么整体被花费,要么未被花费,不能被分割或者部分被花费。
法定人数控制
脚本中的多重签名约束强制执行多重签名方案中预定义的法定人数授权。M/N要求由共识规则执行。
时间锁/老化
任何包含相对或绝对时间锁的脚本子句只能在其期限超过指定时间后执行。
复制
区块链的去中心化存储确保了在交易在被挖出之后,经过充分的确认,它被复制到整个网络上,就变成永久性的,并且能够抵御断电,数据丢失等的影响。
伪造保护
每笔交易只能花费现有的经过验证的输出。不可能创建或伪造价值。
一致性
在没有矿工分区的情况下,记录在区块链中的区块将根据记录深度进行重组,或者其不一致的可能性将以指数递减。一旦被记录在深层,如果想要改变,所需的计算和能量将大到几无可能。
记录外部状态
每个交易可以通过OP_RETURN提交一个值,表示外部状态机中的状态转换。
可预测发行量
总计不到2100万个比特币将会以可以预测的速度发行。
上述开发模块的列表并不完整,还会有新功能将被介绍添加到比特币中。
# 12.3 源于开发模块的应用
由比特币提供的开发模块是可信平台的组成部分,可用于构成各种应用程序。以下是今天在用的应用程序的一些示例及其使用的开发模块:
存在证明(数字公证)Proof-of-Existence(Digital Notary)
不可篡改性+时间戳+永久性。数字指纹可以通过一个交易提交给区块链,证明在记录时存在一个文档(时间戳)。数字指纹不能在事后修改(不可篡改性),证据将被永久保存(永久性)。
众筹(Lighthouse项目)Kickstarter(Lighthouse)
一致性+原子性+完整性。如果您签署了一个众筹交易的输入和输出(完整性),其他人可以为资金众筹做出贡献,但在目标(就是输出值)获得资金(一致性)之前,不能使用(原子性)。
支付通道Payment Channels
法定人数控制+时间锁+杜绝双重支付+永不过期+耐审查+授权。带有时间锁(Timelock)的2/2(法定人数)多重签名被作为支付通道的“结算”交易时,可以被持有(永不过期)或者在任何时间由任何一方(授权)的情况下(耐审查)进行花费。然后双方可以创建更短的时间锁(Timelock)的承诺交易,双重支付(杜绝之前的双重支付)该结算交易。
# 12.4 合约币(Counterparty)
合约币是在比特币之上建立的协议层。“合约币协议”提供了创建和交易虚拟资产和代币的能力。此外,合约币提供了去中心化的资产交换。合约币还在实施基于Ethereum虚拟机(EVM)的智能合约。
合约币使用OP_RETURN操作码或1/N多重签名的公钥地址将元数据嵌入到比特币交易中,该地址用于代替公共密钥进行元数据编码。使用这些机制,合约币实现了在比特币交易中编码的协议层。额外的协议层可以由能理解合约币的应用程序来解读,如钱包和区块链浏览器,或使用合约币库(library)构建的任何应用程序。
反过来合约币可以用作给其他应用程序和服务的平台。例如,Tokenly是一个建立在合约币之上的平台,允许内容创作者,艺术家和公司发行表示数字所有权的代币,并可用于租赁,访问,交易或购买内容,产品和服务。利用交易合约币的其他应用包括游戏(Spells of Genesis)和网格计算项目((Folding Coin)。
更多关于合约币的内容参见https://counterparty.io (opens new window)。开源项目可以在https://github.com/CounterpartyXCP (opens new window)中找到。
# 12.5 支付通道和状态通道
支付通道Payment channels是在比特币区块链之外,双方交换比特币交易的无信任机制。这些交易,如果在比特币区块链上结算,则是有效的,然而他们却是在链外被持有的,以期票promissory notes的形式等待最终批量结算。由于交易尚未结算,因此可以在没有通常的结算延迟的情况下进行交换,从而可以满足极高的交易吞吐量,低(亚毫秒)延迟和精细(satoshi级)粒度。
实际上,通道channel 一词是一个比喻。状态通道是区块链外,由双方之间的交换状态代表的虚拟构想。实际上没有“通道”,底层数据传输机制也并不是通道。我们使用通道这个术语来表示链外双方之间的关系和共享状态。
为了进一步解释这个概念,想一想TCP流。从高层协议的角度来看,它是一个横跨互联网连接两个应用程序的“socket”。但是,如果您查看网络流量,TCP流只是IP数据包之上的虚拟通道。TCP流的每个端点通过排序并组装IP数据包以产生字节流的错觉。实际上在背后,所有的数据包都是断开分散的。同理,支付通道只是一系列交易。如果妥善排序和连接,它们会创建可赎回的合约,即使您不信任通道的另一方,也可以信任这些合约。
在本节中,我们将介绍各种形式的支付通道。首先,我们将研究用于构建计量小额支付服务(如流媒体视频)的单行(单向)支付通道的机制。然后,我们将扩大这一机制,引入双向支付通道。最后,我们将看看首先在 闪电网络Lightning Network 中提出的,如何在路由网络中端到端地连接双向通道以形成多跳通道。
支付通道是更广泛的状态通道state channel概念的一部分,状态通道代表了链外状态的变化,通过最终在区块链上结算得到保障。支付通道是一种状态通道,其中被改变的状态是虚拟货币余额。
# 12.5.1 状态通道基本概念和术语
通过在区块链上锁定共享状态的交易,在交易两方之间建立了一个状态通道。这被称为注资交易funding transaction或锚点交易anchor transaction。这笔交易必须传送到网络并被挖矿确认,才能建立通道。在支付通道的示例中,锁定的状态即为通道的初始余额(以货币计)。
随后双方交换已签名的交易,这被称为承诺交易commitment transactions。承诺交易会改变初始状态。这些交易是有效的交易,因为它们可以被任何一方提交进行结算,但是在通道关闭之前,每一方都会将其在链下保留。状态更新的创建速度可以与每一方创建、签名并将交易传输给另一方的速度一样快。实际上,这意味着每秒可以交换数千笔交易。
当交换承诺交易时,双方同时废止之前的状态,这样最新的承诺交易总是唯一可以兑换的承诺交易。这样可以防止任何一方在通道中某个先前状态比最新状态更有利于己方的时候通过单方面关闭通道来进行欺骗。我们将在本章的其余部分中研究可用于无效先前状态的各种机制。
最后,通道可以协商关闭,即向区块链提交最后的结算交易settlement transaction,或者由任何一方单方面提交最后承诺交易到链上。单方面关闭的选项是必要的,以防万一交易中的一方意外断开连接。结算交易代表通道的最终状态,并在链上进行结算。
在通道的整个生命周期中,只有两个交易需要提交给链上进行挖矿:注资交易和结算交易。在这两个状态之间,双方可以交换任何数量的承诺交易,任何其他人永远不会看到,也不会提交到链上。
下图12-1说明了Bob和Alice之间的支付通道,显示了注资交易,承诺交易和结算交易。
图12-1 Bob和Alice之间的支付通道,展示了注资交易,承诺交易和结算交易
# 12.5.2 简单支付通道示例
要说明状态通道,我们必须从一个非常简单的例子开始。 我们展示一个单向通道,意味着价值只向着一个方向流动。为了便于解释,我们以一个天真的假设开始,假设没有人要试图欺骗他人。一旦我们解释了基本的通道概念,我们将研究如何使其不可信,以便双方都不能作弊,即使他们试图作弊。
对于这个例子,我们假设两个参与者:Emma和Fabian。Fabian提供视频流服务,使用微支付通道按秒计费。Fabian每秒视频收费0.01毫比(millibits)(0.00001 BTC),相当于每小时视频收费36毫比(0.036 BTC)。Emma从Fabian这里购买流媒体视频服务。下图12-2显示Emma使用支付通道从Fabian购买视频流服务。
图12-2 Emma使用以秒计费的支付通道从Fabian购买视频流服务
在这个例子中,Fabian和Emma使用专门的软件来处理支付通道和视频流。Emma在浏览器中运行软件,Fabian从服务器端运行软件。这个软件包括基本的比特币钱包功能,可以创建和签署比特币交易。“支付通道”的概念和术语对于用户都是完全不可见的。他们看到的是以秒为单位付费的视频。
为了设置支付通道,Emma和Fabian建立了一个2/2的多重签名地址,双方各持一个密钥。从Emma的角度来看,她的浏览器中的软件提供了一个带有P2SH地址的二维码(以“3”开头),并要求她提交最多1小时视频的“押金”。Emma向该地址支付资金。Emma支付给该多重地址的交易,就是支付通道的注资交易或叫锚点交易。
就这个例子而言,我们假设Emma支付了36个毫比(0.036 BTC)到通道中。这将允许Emma消费长达1小时的流媒体视频。这笔注资交易设定了可以在这个通道上发送的最大数量(数据量),即设置了通道容量 channel capacity。
注资交易从Emma的钱包中消耗一个或多个输入以汇集资金。它创建一个价值为36毫比的输出,支付给Emma和Fabian之间共同控制的2/2多重签名地址。它也可能有一个作为找零到Emma的钱包的额外输出。
一旦注资交易得到确认,Emma可以开始观看视频。Emma的软件创建并签署一笔承诺交易,改变通道余额,将0.01毫比归入Fabian的地址,并退回给Emma35.99毫比。Emma签署的交易消耗了由注资交易创造的36毫比输出,并创建了两个输出:一个用于找钱,另一个用于Fabian的付款。交易只是部分被签署了,它需要两个签名(2/ 2),但现在只有Emma的签名。当Fabian的服务器接收到此交易时,它会添加第二个签名(用于2/2输入),并将其与时长1秒的视频一起返回给Emma。现在双方都有谁都可以兑换的完全签署的承诺交易,这个承诺交易代表着通道中的最新正确余额。双方都不会将此交易广播到网络中。
在下一轮,Emma的软件创建并签署另一个承诺交易(2号承诺交易),该交易从资金交易中消耗相同的2/2输出。2号承诺交易分配0.2毫比的一个输出到Fabian的地址,还有一个输出为35.98毫比,作为找零返回给Emma的地址。这个新交易支付的是累积两秒的视频内容。Fabian的软件签署并返回第二个承诺交易,再加上另一秒视频。
利用上述的方法,Emma的软件继续向Fabian的服务器发送承诺交易,以换取流媒体视频。因为Emma观看了更多秒数的视频,通道中属于Fabian的钱逐渐累积变多。假设Emma观看600秒(10分钟)的视频,创建和签署600笔承诺交易。最后的承诺交易(600号承诺交易)将有两个输出,将通道的余额分成两半,分别为6毫比属于Fabian和30毫比属于Emma。
最后,Emma点击“停止”停止流媒体视频。 Fabian或Emma现在可以发送最终状态交易以进行结算。最后一笔交易即为结算交易,向Fabian支付所有Emma消费的视频,并退还给Emma注资交易中剩余的资金。
图12-3显示了Emma和Fabian之间的通道以及更新通道余额的承诺交易。
最后,只有两个交易记录在块上:建立通道的注资交易和在两个参与者之间正确分配最终余额的结算交易。
图12-3 Emma和Fabian之间的支付通道,承诺交易不断的更新通道余额
# 12.5.3 制造无需信任的通道
我们刚才描述的渠道是有效的,但前提是双方合作,没有任何失败或欺骗企图。我们来看看破坏这个通道的一些场景,并且看看需要什么来解决这些问题:
一旦注资交易发生,Emma需要Fabian的签名才能收回自己的任何资金。如果Fabian消失,Emma的资金将被锁定在2/2中,造成实际损失。这个通道一旦建立,如果在双方共同签署至少一个承诺交易之前,有任何一方断开,就会导致资金的流失。
当通道正在运行时,Emma可以把Fabian已经会签的任何承诺交易,提交到区块链上。如果她可以发送1号承诺交易,只需支付1秒的视频,为什么还要支付600秒的视频?通道失败是因为Emma可以通过广播对她比较有利的之前的承诺交易来欺骗。
这两个问题都可以用时间锁(timelocks)来解决,下面看看如何使用交易级时间锁(nLocktime)。
除非有退款保证,否则Emma不能冒风险支付到2/2多重签名地址。为了解决这个问题,Emma同时建立了注资交易和退款交易。她只是签名了注资交易,但暂时不发送给任何人。Emma只将退款交易传送给Fabian,并获得他的签名。
退款交易作为第一个承诺交易,其时间锁规定了通道生命的上限。在这种情况下,Emma可以将nLocktime设置为30天或将来的第4320个区块。所有后续承诺交易必须具有较短的时间锁,以便在退款交易之前能把它们兑换。
现在,Emma已经有一个完全签署的退款交易,她可以自信地发送签署过的注资交易,因为她知道最终可以在时间到期后赎回退款交易,即使Fabian消失也不会有问题。
在通道生命中双方交换的每一个承诺交易都会被时间锁锁进未来的时间点。但是每个承诺交易的延迟时间会稍短一点,因此最近的承诺可以在先前的承诺失效之前兑现。由于nLocktime,任何一方都只有其时间锁到期后才能成功传播任何承诺交易。如果一切顺利,他们将协商并通过结算交易正常关闭通道,这样就无需发送中间的承诺交易了。如果发生意外,则可以传播最近的承诺交易进行账户结算,并使以前的所有承诺交易都失效。
例如,如果1号承诺交易被时间锁锁定到未来的第4320个区块,则2号承诺交易被时间锁锁定到未来的4319个块。就是说在1号承诺交易变为有效之前还有600个区块时,600号承诺交易就可以被花费了。
图12-4显示每个承诺交易设置较短的时间锁,允许在它在之前的承诺变为有效前被花费
图12-4 每个承诺交易设置较短的时间锁,允许在它在之前的承诺变为有效前被花费
每个后续承诺交易必须具有较短的时间锁,以便可以在上一个承诺交易和退款交易之前进行广播。提前广播承诺的能力可以确保只有它最先能够花费资金输出,并阻止任何其他承诺交易通过花费输出实现兑换。比特币区块链提供的担保,即防止双重支出和强制执行时间锁,有效地允许每个承诺交易废止其上一个承诺交易。
状态通道使用时间锁跨时间维度强制执行智能合约。在这个例子中,我们看到时间维度如何保证最近的承诺交易必须在任何之前的承诺之前先行有效。所以,才可以先发送最近的承诺交易,花费输入,并且使先前的承诺交易无效。执行绝对时间锁的智能合约可以防止其中任何一方的欺骗。实现这个只需要绝对的交易级时间锁(nLocktime)。接下来,我们将看到如何使用脚本级时间锁,CHECKLOCKTIMEVERIFY和CHECKSEQUENCEVERIFY来构建更灵活,有用和复杂的状态通道。
2015年,阿根廷的一个开发团队将第一种单向支付渠道作为视频流应用的原型进行了演示。你可以在streamsium.io (opens new window)看到它。
时间锁并不是使之前的承诺交易无效的唯一方法。在接下来的章节中,我们将看到如何使用撤销密钥来实现相同的结果。时间锁是有效的,但其有两个明显的缺点。在通道首次打开时建立最大时间锁,这限制了通道的使用寿命。更糟糕的是,允许通道长时间保留,和如果其中一位参与者提前关闭通道需要等待很长时间才能退款,它们迫使通道要在这二者之间实现一种平衡。例如,如果退款时间设置为30天,那么就是允许通道保持开放30天,如果其中一方立即消失,则另一方必须等待30天才能退款。终点设置越远,退款时间越远。
第二个问题是,由于每个后续的承诺交易必须缩短时间锁,所以在双方之间可以交换的承诺交易数量有明确的限制。例如,一个30天的通道,设置了位于未来第4320个区块的时间锁,在必须被关闭前这段时间只能容纳4320个承诺交易。将时间锁承诺交易的间隔设置为1个区块存在风险。如果将承诺交易之间的时间锁设置为1个区块,开发者会给通道参与者带来了非常高的负担,参与者必须保持警惕,保持在线并监视,并随时准备传送正确的承诺交易。
现在我们了解如何使用时间锁来使先前的承诺无效,我们可以看到协商关闭通道和通过广播承诺交易单方面关闭通道之间的区别。所有承诺交易都是时间锁定的,因为广播承诺交易总是要等待时间锁到期。但是,如果双方同意最后的余额是多少,并且知道双方都持有最终使该余额成为现实的承诺交易,那么他们就可以构建一个结算交易,而不需要代表相同余额的时间戳。在协商关闭中,任一方都接受最近的承诺交易,并建立一个各方面完全相同的结算交易,唯一差别就是它省略了时间锁。双方都可以签署这笔结算交易,因为知道无法作弊以得到更多的余额。通过协商签署和发送结算交易,可以关闭通道并立即兑换余额。最差的情况下,当事人之一可能是卑鄙小人,拒绝合作,强迫另一方单方面关闭最近的承诺交易。但是如果他们这样做,他们也必须一直等待他们的资金。
# 12.5.4 不对称可撤销承诺
处理先前承诺状态的更好方法是明确撤销它们。但是,这不容易实现。比特币的一个关键特征是,一旦交易有效,它一直有效,不会过期。取消交易的唯一方法是在交易被挖矿前用另一笔交易双重支出它的输入。这就是为什么我们在上述简单支付通道示例中使用时间锁,以确保最新的承诺交易可以在旧承诺生效之前被花费。然而,把承诺在时间上排序造成了许多限制,使得支付通道难以使用。
虽说一个交易无法取消,但是它可以被构造成无法再使用的样子。我们这样做的方法是通过给予每一方一个撤销密钥,如果对方试图欺骗,可以用来进行惩罚。撤销先前承诺交易的这种机制首先被作为闪电网络的一部分提出。
为了解释撤销密钥,我们将在由Hitesh和Irene经营的两个交易所之间构建一个更加复杂的支付通道。 Hitesh和Irene分别在印度和美国运营比特币交易所。 Hitesh的印度交易所的客户经常向Irene的美国交易所的客户发送付款,反之亦然。目前,这些交易发生在比特币链上,但这需要支付交易费还要等待几个区块进行确认。在交易所之间设置支付通道将大大降低成本并加快交易流程。
Hitesh和Irene通过合作建立注资交易来启动通道,每人向通道注资5个比特币。初始余额为Hitesh有5比特币且Irene有5比特币。注资交易将通道状态锁定在2/2多重签名中,就像在简单支付通道的例子中一样。
注资交易可能有一个或多个输入(加起来5个比特币或更多)来自Hitesh,以及Irene的一个或多个输入(同样加起来5个比特币或更多)。为了足够支付交易费用,输入必须略微超过通道容量。该交易有一个输出,将总共10个比特币锁定到由Hitesh和Irene控制的2/2多重地址中。如果他们的输入超过他们需要的金额,注资交易也可能有一个或多个输出将找零返回给Hitesh和Irene。这是由双方提供和签署的输入形成的单一交易。在发送之前,必须合作构建并由各方签署。
接着,Hitesh和Irene创建了两个不对称的asymmetric承诺交易,而不是创建一个双方都签署的单一承诺交易。
Hitesh有一个带有两个输出的承诺交易。第一个输出是立即支付欠Irene的5比特币。第二个输出是支付欠Hitesh自己的5比特币,但条件是只有在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
2
3
4
5
6
7
8
9
10
Irene也有带有两个输出的不同的承诺交易。第一个输出支付欠Hitesh的5比特币。 第二个输出支付给欠Irene自己的5比特币,但同样必须经过1000个区块的时间锁。 Irene持有的承诺交易(由Hitesh签署)看起来像这样:
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
2
3
4
5
6
7
8
9
10
这样一来,双方各有一笔承诺交易,可以花费2/2的资金输出。该承诺交易的输入是由对方署的。在任何时候,持有承诺交易的一方都可以签字(完成2/2签名)并进行广播。然而,如果他们广播承诺交易,承诺交易会立即支付对方,而他们自己的资金则必须等待时间锁到期。通过强制延迟兑换其中一方的输出,我们可以做到让各方在选择单方面广播承诺交易时处于轻微的不利地位。 但是单靠时间延迟还不足以鼓励公平的行为。
下图12-5显示两个不对称承诺交易,其中承诺持有人的输出被延迟
图12-5 显示两个不对称承诺交易,其中承诺持有人的输出被延迟
现在我们介绍这个方案的最后一个要素:一个防止作弊者广播过期承诺的撤销密钥,它允许被欺诈的一方通过占有通道的所有余额来惩罚骗子。
撤销密钥由两个密语组成,每个密语由每个通道参与者独立生成。它类似于2/2的多重签名,使用椭圆曲线算法构造。虽然双方都知道撤销公钥,但其实每一方只知道撤销密钥的一半。
在每一轮交易中,双方都将其撤销密语的一半透露给另一方,从而使另一方(现在双方都有)在广播此撤销的交易时,可以要求获得惩罚输出。
每个承诺交易都有一个“延迟”的输出,该输出的兑换脚本允许一方在1000个区块后兑换它,或者另一方如果拥有撤销密钥也可兑换它。
所以当Hitesh为Irene签署承诺交易时,他将在1000个区块之后把第二个输出定支付给自己,或者支付给撤销公钥(他只知道其中一半的密语)。Hitesh构建了这个交易,他只会在准备改变通道状态,并希望撤销这一承诺交易时,才会把半个撤销密语透露给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
2
3
4
5
6
7
8
9
10
11
12
13
14
Irene可以自信地签署这笔交易,因为一旦被发送,它将立即首先支付欠她的款。Hitesh持有交易,但知道如果自己单方面关闭通道发送交易,将不得不等待1000个区块才能获得付款。
当通道进入下一个状态时,Hitesh必须在Irene同意签署下一个承诺交易之前撤销此承诺交易。要做到这一点,他所要做的就是将撤销密语发送给Irene。一旦Irene拥有这一承诺的两个半部分撤销密语,她就可以自信地签署下一个承诺。她知道,如果Hitesh试图通过发布先前的承诺交易来作弊,她可以使用撤销密钥来兑换Hitesh的延迟输出。*如果Hitesh作弊,Irene会得到两部分输出。*同时,Hitesh只有该撤销公钥的一半撤销密语,并且在1000个区块之前无法兑换输出。Irene可以在1000个区块过去之前兑换输出并惩罚Hitesh。
撤销协议是双边的,这意味着在每一轮中,随着通道状态的推进,双方交换新的承诺,并且交换之前承诺的撤销密语,签署双方新的承诺交易。当他们接受新的状态时,他们通过给予对方必要的撤销密语来惩罚任何作弊行为,使先前的状态不可用。
我们来看一个它是如何工作的。Irene的一个客户希望向Hitesh的一个客户发送2比特币。要通过通道传输2比特币,Hitesh和Irene必须更新通道状态以反映新的余额。他们将提交一个新的状态(状态号2),通道的10个比特币被分割,7个比特币属于Hitesh和3个比特币属于Irene。为了更新通道的状态,他们将各自创建反映新通道余额的新承诺交易。
如上述内容所说,这些承诺交易是不对称的,所以每一方所持的承诺交易都迫使他们等待兑换。至关重要的是,在签署新的承诺交易之前,他们必须首先交换撤销密语以使先前的承诺无效。在这种情况下,Hitesh的利益与通道的真实状态是一致的,因此他没有理由广播先前的状态。然而,对于Irene来说,状态号1中留给她的余额比状态2中的更高。当Irene把她以前的承诺交易(状态号1)的撤销密语提供给Hitesh时,她实际上放弃了恢复通道状态到前一状态而从中获益的权利。因为有了撤销密语,Hitesh可以毫不迟疑地兑换先前承诺交易的两个输出。也就是说一旦Irene广播先前的状态,Hitesh可以行使他的权利,占有所有的输出。
重要的是,撤销不会自动发生。虽然Hitesh有能力惩罚Irene的作弊行为,但他必须认真观察区块链中作弊的迹象。如果他看到先前的承诺交易广播,他有1000个区块时间采取行动,并使用撤销密语来阻止Irene的欺骗行为,并占有所有余额,也就是全部10比特币来惩罚她。
带有相对时间锁(CSV)的不对称可撤销承诺是实现支付通道的更好方法,也是区块链技术非常重要的创新。通过这种结构,通道可以无限期地保持开放,并且可以拥有数十亿的中间承诺交易。在闪电网络的原型实现中,承诺状态由48位索引识别,允许在任何单个通道中有超过281万亿(2.8×1014)个状态转换!
# 12.5.5 哈希时间锁合约(HTLC)
支付通道可以通过特殊类型的智能合约进一步扩展,该合约允许参与者将资金用于可兑换的有到期时间的密钥。此功能称为哈希时间锁定合约Hash Time Lock Contract或HTLC,用于双向和可路由的支付通道。
首先我们来解释HTLC的“哈希”部分。要创建一个HTLC,预期的收款人将首先创建一个密钥(secret)R。他们然后计算这个R的哈希H:
H = Hash(R)
这步产生可以包含在输出的锁定脚本中的哈希H。知道这个密钥的任何人可以用它来兑换输出。密钥R也被称为哈希函数的原像preimage。原像就是用作哈希函数输入的数据。
HTLC的第二部分是“时间锁”组件。如果密钥一直没有被泄露,HTLC的付款人可以在一段时间后得到“退款”。这是通过使用绝对时间锁CHECKLOCKTIMEVERIFY来实现的。
实现HTLC的脚本可能如下所示:
IF
# Payment if you have the secret R
HASH160 <H> EQUALVERIFY
ELSE
# Refund after timeout.
<locktime> CHECKLOCKTIMEVERIFY DROP
<Payer Public Key> CHECKSIG
ENDIF
2
3
4
5
6
7
8
任何知道密钥R,其哈希值等于H的人,都可以通过行使IF语句的第一个子句来兑换该输出。
如果密钥R没有被透露,HTLC中写明了,在一定数量的区块之后,付款人可以使用IF语句中的第二个子句申请退款。
这是HTLC的基本实现。任何拥有秘密R的人都可以兑换这种类型的HTLC。通过对脚本进行略微变化,HTLC可以采用许多不同的形式。例如,在第一个子句中添加一个CHECKSIG运算符和一个公钥来将哈希值的兑换限制为指定收款人,这个人还必须知道密钥R。
# 12.6 可路由的支付通道(闪电网络)
闪电网络是一种端到端连接的双向支付通道的可路由网络。这样的网络可以允许任何参与者在不信任任何中间人的情况下将支付从一个通道路由到另一个通道。2015年2月,Joseph Poon和Thadeus Dryja首次对闪电网络进行了描述【参见闪电网络白皮书】 (opens new window),该网络建立在许多其他人提出和阐述的支付通道概念的基础上。
“闪电网络”是指路由支付通道网络的具体设计,现已由至少五个不同的开源团队实现。这些独立的实现由一组互操作性标准进行协调,这些互操作性标准在【闪电技术(BOLT)基础白皮书】 (opens new window)中进行了描述。
闪电网络的原型实施已经由几个团队发布。
闪电网络是实现可路由支付通道的一种可能方式。还有其他几种旨在实现类似目标的设计,如Teechan和Tumblebit。
# 12.6.1 闪电网络示例
让我们看看它是如何工作的。
在这个例子中,我们有五个参与者:Alice, Bob, Carol, Diana, and Eric。这五名参与者已经彼此之间开设了支付通道。Alice和Bob有支付通道。Bob连接Carol,Carol连接到Diana,Diana连接Eric。为了简单起见,我们假设每个通道每个参与者都注资2个比特币资金,每个通道的总容量为4个比特币。
下图12-6显示了闪电网络中的五个参与者,通过双向支付通道连接,可以连接到从Alice到Eric的支付。
图12-6 闪电网络中的五个参与者,通过双向支付通道连接,可以连接到从Alice到Eric的支付
Alice想要支付给Eric1个比特币。但是,Alice并没有直接连接Eric的支付通道。创建支付通道需要注资交易,而这笔交易必须首先提交给比特币区块链。Alice不想建立一个新的支付通道还要支出更多的手续费。有没有办法间接支付给Eric?
下图12-7显示了通过在连接各方参与者的支付通道上通过一系列HTLC承诺将付款从Alice路由到Eric的一步步过程。
图12-7 闪电网络中支付路由的步骤
Alice正在运行闪电网络(LN)节点,该节点正在跟踪其向Bob的支付通道,并且能够发现支付通道之间的路由。Alice的LN节点还可以通过互联网连接到Eric的LN节点。 Eric的LN节点使用随机数生成器创建一个密钥R。Eric的节点不会向任何人泄漏这个密钥。Eric的节点计算密钥R对应的哈希H,并将此哈希H发送到Alice的节点(请参阅图12-10步骤1)。
现在Alice的LN节点构建了Alice的LN节点和Eric的LN节点之间的路由。所使用的路由算法将在后面进行更详细的解释,但现在我们假设Alice节点可以找到一个有效的路由。
然后,Alice的节点构造一个HTLC,支付到哈希H,具有10个区块时间的退款超时(当前块+10),金额为1.003比特币(参见图12-10的步骤2)。额外的0.003将用于补偿参与此支付路由的中间节点。Alice将此HTLC提供给Bob,从和Bob之间的通道余额中扣除1.003比特币,并将其提交给HTLC。该HTLC具有以下含义:“如果Bob知道密钥,Alice将其通道余额的1.003支付给Bob,或者如果超过10个区块后,则退还入Alice的余额”。Alice和Bob之间的通道余额现在由承诺交易表示,其中有三个输出:Bob的2比特币余额,Alice的0.997比特币余额,Alice的HTLC中承诺的1.003比特币。Alice的余额中减少了在HTLC中承诺的金额。
Bob现在有一个承诺,如果他能够在接下来的10个区块内拿到密钥R,他就可以获得Alice锁定的1.003。手上有了这一承诺,Bob的节点在和Carol的支付通道上构建了一个HTLC。Bob的HTLC提交1.002比特币到哈希H共9个区块时间,这个HTLC中如果Carol有密钥R,她可以兑换(参见图12-10步骤3)。Bob知道,如果Carol要获取他的HTLC,她必须出示密钥R。如果Bob在9个区块的时间内拿到R,自己就可以用它来获得Alice的HTLC。通过承诺自己的通道余额9个区块的时间,他也赚了0.001比特币。如果Carol无法获取他的HTLC,那么他也无法获取Alice的HTLC,那么一切都将恢复到以前的通道余额,没有人会亏损。Bob和Carol之间的通道余额现在是:2比特币给Carol,0.998给Bob,1.002由Bob承诺给HTLC。
Carol现在有一个承诺,如果她在接下来的9个区块时间内拿到R,就可以获取Bob锁定的1.002比特币。现在她可以在她与Diana的通道上构建HTLC承诺。她提交了一个1.001比特币的HTLC到哈希H,共计8个区块时间,如果Diana有密钥R ,她就可以兑换(参见图12-10步骤4)。从Carol的角度来看,如果能够实现,她就可以获得的0.001比特币,否则也没有失去任何东西。她提交给Diana的HTLC,只有在拿到R的情况下才可行,到那时候她可以从Bob那里索取HTLC。Carol和Diana之间的通道余额现在是:2给Diana,0.999给Carol,1.001由Carol承诺给HTLC。
最后,Diana可以提供给Eric一个HTLC到哈希H,承诺1比特币,7个区块时间(参见图12-10的步骤5)。Diana与Eric之间的通道余额现在是:Eric有2个,Diana有1个,还有Diana承诺给HTLC的1个。
不过,在这一跳路由上,Eric拥有密钥R,他可以获取Diana提供的HTLC。他将R发送给Diana,并获取1个比特币,添加到他的通道余额中(参见图12-10的步骤6)。通道平衡现在是:1给Diana,3给Eric。
现在,Diana有密钥R,因此,她现在可以获取来自Carol的HTLC。Diana将R发送给Carol,并将1.001比特币添加到其通道余额中(参见图12-10的步骤7)。现在Carol与Diana之间的通道余额是:0.999给Carol,3.001给Diana。Diana已经“赚了”参与这个付款路线0.001比特币。
通过路由回传,秘密R允许每个参与者获取未完成的HTLC。Carol从Bob那里获取1.002个比特币,将他们通道余额设为:0.998给Bob,3.002给Carol(参见图12-10的步骤8)。最后,Bob获取来自Alice的HTLC(参见图12-10的步骤9)。他们的通道余额更新为:0.997给Alice,3.003给Bob。
在没有和Eric创建新支付通道的情况下,Alice实现了支付给了Eric 1个比特币。付款路线中的中间方不必要互相信任。在他们的通道内做一个短时间的资金承诺,他们可以赚取一小笔费用,唯一的风险是,如果通道关闭或路由付款失败,退款有段短短的延迟时间。
# 12.6.2 闪电网络传输和路由
LN节点之间的所有通信都是点对点加密的。另外,节点有一个长期公钥,它们用作标识符并且彼此认证对方 (opens new window)。
每当节点希望向另一个节点发送支付时,它必须首先通过连接具有足够容量的支付通道来构建通过网络的路径。节点公布路由信息,包括他们已经打开了什么通道,每个通道拥有多少容量,以及他们收取多少路由支付费用。路由信息可以以各种方式共享,并且随着闪电网络技术的进步,可能会出现不同的路由协议。一些闪电网络实施使用IRC协议作为节点公布路由信息的一种方便的机制。路由发现的另一种实现方式是使用P2P模型,其中节点在“洪水泛滥”模型中,将通道公告传播给他们的对等体,这类似于比特币传播交易的方法。未来的计划包括一个名为Flare (opens new window)的建议,它是一种具有本地节点“邻居”和远程信标节点的混合路由模型。
在我们前面的例子中,Alice的节点使用这些路由发现机制中的一个,来查找将她的节点连接到Eric的节点的一个或多个路径。一旦Alice的节点构建了路径,她将通过网络初始化该路径,传播一系列加密和嵌套的指令来连接每个相邻的支付通道。
重要的是,这个路径只有Alice的节点才知道。付款路线上的所有其他参与者只能看到相邻的节点。从Carol的角度来看,这看起来像是从Bob到Diana的付款。 Carol不知道Bob实际上是转发Alice的汇款。她也不知道Diana将会向Eric转款。
这是闪电网络的一个重要特征,因为它确保了付款的隐私,并且使得应用监视,审查或黑名单变得很困难。但是,Alice如何建立这种付款路径,而不向中间节点透露任何内容呢?
闪电网络实现了一种基于称为Sphinx方案的洋葱路由协议。该路由协议确保支付发送者可以通过闪电网络构建路径和在路径上通信,使得:
- 中间节点可以验证和解密其部分路由信息,并找到下一跳。
- 除了上一跳和下一跳,他们无法了解作为路径一部分的任何其他节点。
- 他们无法识别支付路径的长度,或者他们自己在该路径中的位置。
- 路径的每个部分被加密,使得网络级攻击者不能将来自路径的不同部分的数据包彼此关联。
- 不同于Tor(互联网上的洋葱路由匿名协议),没有可以被监视的“退出节点”。付款不需要传输到比特币区块链,节点只是更新通道余额。
使用这种洋葱路由协议,Alice将路径的每个元素包裹在加密层中,从尾端开始倒过来工作。她用Eric的公钥加密了Eric的消息。该消息包裹在给Diana的加密消息中,将Eric标识为下一个收件人。给Diana的消息包裹在给Carol的公钥的加密消息中,并将Diana识别为下一个收件人。对Carol的消息被Bob的密钥加密。这样一来,Alice已经构建了这个加密的多层“洋葱”的消息。她把这个发送给Bob,Bob只能解密和解开外层。在里面,Bob发现一封给Carol的消息,他可以转发给Carol,但不能自己破译。沿着路径,消息被转发,解密,转发等,一路到Eric那里。每个参与者只知道各自这一跳的前一个和下一个节点。
路径的每个元素包含承载于HTLC的必须扩展到下一跳的信息,HTLC中的要发送的数量,要包括的费用以及CLTV锁到期时间(以区块为单位)。随着路由信息的传播,节点将HTLC承诺转发到下一跳。
在这一点上,您可能会想知道节点为什么不知道路径的长度及其在该路径中的位置。毕竟,他们收到一个消息,并将其转发到下一跳。难道它不会将路径缩短,或者允许他们推断出路径大小和位置?为了防止这种情况,路径总是固定在20跳,并用随机数据填充。每个节点都会看到下一跳和一个要转发的固定长度的加密消息。只有最终的收件人看得到没有下一跳。对于其他人来说,似乎总是有20多跳要走。
# 12.6.3 闪电网络优势
闪电网络是第二层路由技术。它可以应用于支持一些基本功能的任何区块链,如多重签名交易,时间锁定和基本的智能合约。
如果闪电网络在比特币网络上实现,那么比特币网络可以大大提高容量,隐私性,颗粒度和速度,而不会牺牲无中介机构的无信任操作原则:
隐私
闪电网络付款比比特币区块链的付款更私密,因为它们不是公开的。虽然路由中的参与者可以看到在其通道上传播的付款,但他们并不知道发件人或收件人。
可替代性
闪电网络使得在比特币上应用监视和黑名单变得更加困难,从而增加了货币的可替代性。
速度
使用闪电网络的比特币交易将以毫秒为单位,而不是分钟,因为HTLC在不用提交交易到区块就进行结算的。
粒度
闪电网络可以使支付至少与比特币“灰尘”限制一样小,甚至更小。一些议案还允许以子聪级增加。
容量
闪电网络将比特币系统的容量提高了几个数量级。每秒可以通过闪电网络路由的付费数量没有具体上限,因为它仅取决于每个节点的容量和速度。
无信任操作
闪电网络使用节点之间的比特币交易,这些节点作为对等节点运行,彼此不信任。因此,闪电网络保留了比特币系统的原理,同时显著扩大了其运行参数。
当然,如前所述,闪电网络协议不是实现路由支付通道的唯一方法。其他被提出的系统包括Tumblebit和Teechan。然而,当前,闪电网络已经部署在testnet上了。几个不同的团队已经开发了正在竞争的LN实现,并且正在努力实现一个通用的互操作性标准(称为BOLT)。闪电网络很可能是第一个部署在生产中的路由支付通道网络。
# 12.7 结论
我们仅研究了几个新兴应用程序,它们都是使用比特币区块链作为信任平台构建的。这些应用程序将比特币的范围扩大到支付和金融工具之外,涵盖了信任至关重要的许多应用程序。通过去中性化的信任基础,比特币区块链将会是一个在各种行业中催生许多革命性应用的平台。