现在,让我们把比特币看做是一个应用程序平台(application platform),把对比特币的理解建立在这种理解之上。 现在很多人使用“blockchain”这个词来指代任何共享了比特币设计原则的应用平台。 该术语经常被滥用,并被应用于许多不能提供比特币区块链主要特性的东西。
在本章中,我们将介绍比特币区块链作为应用平台所提供的特性。 我们将考虑应用程序构建原语(primitives),它构成了任何区块链应用程序的基石(building blocks)。 我们将研究使用这些原语的几个重要应用程序,例如彩色币(colored coins),支付(状态)通道( payment (state) channels)和路由支付通道(Lightning Network,闪电网络)。
比特币系统被设计为一个去中心化的货币及支付系统。 然而,它的大部分功能源于可用于更广泛应用中的较低级别的结构。 比特币不是由帐户,用户,余额和付款等组件构建的。 相反的,正如我们在第六章中看到,它使用的是具有低级加密功能的交易脚本语言。 就像账户,余额和付款这些更高层次的概念可以从这些基础原语中衍生出来一样,许多其他复杂的应用也是如此。 因此,比特币区块链能够成为一个向应用程序提供信任服务的应用平台(application platform),比如智能合约,远远超出了(far surpassing)作为数字货币和支付的原始目的。
当运行正常且长期运行时,比特币系统提供了一定的保证,可以被用于创建应用程序的基石。 这些包括:
杜绝双重支出(No Double-Spend)
比特币分布式共识算法的最根本保证是确保UTXO不会被花费两次。
不可改变性(Immutability)
一旦交易被记录在区块中,并且随后的区块中添加了足够的工作量,交易数据就变得不可篡改。 不可改变性是由能源进行承保的,因为重写区块链需要消耗能源才能产生工作量证明。 所需的能源以及由此带来的不可变的程度随着在包含交易的区块之后提交的工作量而增加。
中立 (Neutrality)
去中心化的比特币网络传播有效的交易,而不管这些交易的来源或内容。 这意味着任何人都可以支付足够的费用来创建有效的交易,并相信他们可以随时传输该交易并使其包含在区块链中。
安全时间戳 (Secure Timestamping)
共识规则拒绝任何时间戳距离将来或者过去太远的区块。 这可以确保区块上的时间戳可以被信任。 区块上的时间戳意味着对其包含的所有交易的输入之前从未被花过的保证。
授权 (Authorization)
被去中心化网络验证过的数字签名可提供授权保证。包含着数字签名的脚本不能在没有私钥(隐含在脚本中)拥有者授权的情况下被执行。
审计能力 (Auditability)
所有交易都是公开的,可以被审查。 所有的交易和区块都可以在未损坏的区块链中回溯到创世区块。
会计 (Accounting)
在任何交易中(coinbase交易除外),输入的金额等于输出的金额加上交易费用。 不可能创建或销毁交易中的比特币价值数值。 输出不能超过输入。
永不过期 (Nonexpiration)
有效的交易永远不会过期。 如果今天有效,它将在不久的将来仍然有效,只要输入仍然没有被花费,并且共识规则没有改变。
公正性(Integrity)
使用SIGHASH_ALL签名的比特币交易或使用SIGHASH类型签署交易的部分,不能在签名还有效的情况下被修改,从而导致交易本身无效。
交易原子性 (Transaction Atomicity)
比特币交易是原子的。 它们要么是有效的并且经过确认的,要么不是。 不存在挖矿出交易的一部分,交易也不存在中间状态(interim state)。 在任何时间点,交易要么被挖出,要么没有被挖。
离散(不可分割的)价值单位 (Discrete (Indivisible) Units of Value)
交易输出是离散和不可分割的价值单位。 他们要么整体被花费要么整体没有被花费。 他们不能被分割或者部分被花费。
法定人数(Quorum of Control)
脚本中的多重签名约束规定了的授权的法定人数,预定义在多重签名方案中。 M-of-N的必要条件由共识规则强制执行的。
时间锁/老龄化 (Timelock/Aging)
任何包含相对或绝对时间锁的脚本语句只能在其年龄超过指定时间后才能被执行。
复制 (Replication)
区块链的去中心化存储确保了在交易在被开采之后,经过足够的确认数,它被复制到整个网络上,并且变得持久的和可恢复的(durable and resilient),可以受得起电力损失,数据丢失等。
伪造保护 (Forgery Protection)
交易只能花费存在的经过验证的输出。不可能创建或伪造(counterfeit)价值。
一致性 (Consistency)
在没有矿工分区的情况下,记录在区块链中的区块,根据记录的深度,被重新组织或者产生分歧的可能性呈指数级下降。一旦被记录在深层,改变所需的计算和能量使得改变是不可行的(practically infeasible)。
记录外部状态 (Recording External State)
交易可以通过操作符OP_RETURN提交一个数据,代表着外部状态机中的状态转换。
可预测的发行量 (Predictable Issuance)
总计不足2100万个比特币将会以可以预测的速度发行。
上述所列的基石并不完整,随着新特性引入到比特币中,列表中会加入更多。
比特币提供的基石是可信平台的要素,可用于构成各种应用程序。 以下是现今存在的应用程序以及他们使用的基石的一些示例:
Proof-of-Existence(Digital Notary,数字公证)
不可篡改性+时间戳+永久性(Immutability + Timestamp + Durability)。数字指纹可以通过一个交易提交给区块链,以证明文件在存档时是存在的(Timestamp时间戳)。数字指纹不能在事后修改(Immutability不可改变性),证据将被永久存储(Durability永久性)。
Kickstarter(Lighthouse)
一致性+原子性+可信(Consistency + Atomicity + Integrity)。如果您发起众筹活动的一个输入和输出(Integrity公正性),别人可以参与众筹,但在目标(output value)筹集完之前(Consistency一致性),这笔钱不能被花费(Atomicity交易原子性 )。
Payment Channels
控制法定人数+时间锁+杜绝双重支付+永不过期+耐审查+授权(Quorum of Control + Timelock + No Double Spend + Nonexpiration + Censorship Resistance + Authorization)。一个带有时间锁(Timelock时间锁)的2-of-2(Quorum法定人数)多重签名被作为支付渠道的“结算”交易时,可以被持有(Nonexpiration永不过期)并且可以在任何时刻(Censorship Resistance耐审查)由任何一方(Authorization授权)花费。然后双方可以用更短的时间锁(Timelock)创建共同承若的交易以双重花费(No Double-Spend)转让契约(settlement)。
我们将讨论的第一个区块链应用是染色币。
染色币是指利用比特币交易来记录除比特币之外的外部资产的创建、所有权和转让的这类技术。 所谓“外部资产”我们是指这些资产不直接存储在比特币区块链上,而不是指比特币本身,因为比特币本身就是这个区块链的固有资产。
染色币用于跟踪第三方持有的数字资产和实物资产,并通过染色币所有权证书来进行交易。 数字资产染色币可以代表无形资产(intangible assets),如股票证书,许可证,虚拟财产(游戏装备)或大多数任何形式的许可知识产权(商标,版权等)。 有形资产染色币可以代表商品(黄金,白银,石油),土地所有权,汽车,船只,飞机等所有权。
该术语源于“着色”或标记某票面上金额的比特币的想法,例如,1聪,用来表示比特币价值本身以外的东西。打个比方,我们给一美元的钞票标上一行信息说:“这是ACME的股票证书”,或者“这张钞票可以兑换1盎司的银”,然后使用这个1美元钞票作为资产权益证明与其他资产进行交易。染色币的第一个实现,名为“基于增强填充订单的着色”或“EPOBC”,将外部资产标记在1聪的输出上。这样,它就成了一个真正的“染色币”,因为每个资产被附加作为1聪的属性(颜色)。
染色币的最新实现是使用OP_RETURN脚本操作码将元数据存储在交易中,与外部数据存储协同工作,从而将元数据与特定资产联系在一起。
今天染色币的两个最杰出的(prominent)实现是 Open Assets 和 Colored Coins by Colu(资料可参考:https://en.bitcoin.it/wiki/Colored_Coins)。这两个系统使用不同的方法来染色,并且是不兼容的。在一个系统中创建的染色币在其他系统中无法看到或被使用。
支付通道是在比特币区块链之外双方进行比特币交易的不可靠机制。这些交易,如果在比特币区块链上结算,则是有效的,然而他们却是在链外被持有的,以期票的形式等待最终批量结算(batch settlement)。由于交易尚未结算,因此他们可以在没有通常的结算延迟的情况下进行交换,从而可以满足极高的交易吞吐量,低(亚毫秒)延迟和精细(satoshi级)粒度。
实际上,通道 一词是一个比喻。状态通道是区块链外,由双方之间的交换状态代表的虚拟结构。实际上没有“渠道”,底层数据传输机制并不是渠道。我们使用通道这个术语来表示链外双方之间的关系和共享状态。
为了进一步解释这个概念,想一想TCP流。从高层协议的角度来看,它是一个横跨互联网连接两个应用程序的“socket”。但是,如果您查看网络流量,TCP流只是IP数据包之上的虚拟通道。 TCP流的每个端点通过按次序组装IP数据包以产生字节流的错觉。实际上在背后,所有的数据包都是断开分散的。同理,支付通道只是一系列交易。如果妥善排序和连接,即使您不信任通道的另一方,也可以创建可以信任的可兑换的债务。
在本节中,我们将介绍各种形式的支付通道。首先,我们将研究用于构建计量微支付服务(如流媒体视频)的单行(单向)支付通道的机制。然后,我们将扩大这一机制,引入双向支付渠道。最后,我们将看看首次以 闪电网络 名称提出的,如何在路由网络中将双向通道端到端链接从而形成多跳通道。
支付通道是更广泛概念的状态通道的一部分,状态通道代表着链外状态的变化,通过在区块链上进行最终的结算从而得到保障。支付通道是一种状态通道,其中被改变的状态是虚拟货币的余额。
通过一笔交易将一个共享状态锁定在区块链上,从而在交易两方之间建立了一个状态通道。这被称为资金交易或锚点交易。这笔交易必须传送到网络并被挖矿以建立通道。在支付通道的示例中,锁定的状态即为通道的初始余额(以货币计)。
随后双方交换已签名的交易,这被称为“承诺交易(commitment transactions)”,承诺交易会改变初始状态。这些交易都是有效的,任何一方都可以提交结算的请求,不需要等到通道关闭再做结算。任何一方给对方创建、签名和发送交易时就会更新状态。实践中,这意味着每秒可进行数千笔交易。
当交换承诺交易时,双方同时废止之前的状态,如此一来最新的承诺交易总是唯一可以赎回的交易。这样可以防止任何一方在通道中某个先前状态比最新状态更有利于己方的时候通过单方面关闭通道来进行欺骗。我们将在本章的其余部分中检验可用于废止先前状态的各种机制。
最后,通道可以合作关闭,即向区块链提交一笔最后的结算交易(settlement transaction),或者单方面的,由任何一方提交最后的承诺交易到链上。单方面关闭的选项是必要的,以防万一交易中的一方意外断开连接。结算交易代表通道的最终状态,并在链上进行结算。
在通道的整个生命周期中,只有两笔交易需要提交挖矿到链上:资金交易和结算交易。在这两个状态之间,双方可以交换任何数量的承诺交易,任何其他人不会看到,也不会提交到链上。
下图12-4说明了Bob和Alice之间的支付通道,显示了资金,承诺和结算交易(showing the funding, commitment, and settlement transactions)。
Figure 12-4. A payment channel between Bob and Alice, showing the funding, commitment, and settlement transactions
要说明状态通道,我们必须从一个非常简单的例子开始。 我们展示一个单向通道,意味着价值只向着一个方向流动。 为了便于解释,我们天真的假设没有人会试图欺骗他人。 一旦我们解释了基本的通道概念,我们将会接着看看是什么使得支付通道可以无信任化,从而让交易双方无法进行欺骗,哪怕他们去尝试进行欺骗也无法成功。
对于这个例子,我们假设两个参与者:Emma和Fabian。 Fabian提供使用微支付通道、按秒计费的视频流服务。Fabian每秒视频收费0.01毫比特币(0.00001 BTC),相当于每小时视频收费36毫比特币(0.036 BTC)。 Emma是从Fabian那里购买流媒体视频服务的用户。下图12-5显示Emma使用支付通道从Fabian购买视频流服务。
Figure 12-5. Emma purchases streaming video from Fabian with a payment channel, paying for each second of video
在这个例子中,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的钱包。
一旦资金交易(funding transaction)得到确认,Emma可以开始观看视频。Emma的软件创建并签署一笔承诺交易(commitment transaction),改变通道余额,将0.01毫比特币记入Fabian的地址,并退回35.99毫比特币给Emma。Emma签署的交易消耗了由资金交易创造的36毫比特币输出,并创建了两个输出:一个用于找钱,另一个用于支付给Fabian。交易只是部分被签署了 - 它需要两个签名(2 - 2),但现在只有Emma的签名。当Fabian的服务器接收到此交易时,它会给交易添加第二个签名(用于2-2输入),并将该交易返回给Emma,同时还附带时长1秒的视频。现在双方都有一个任何一方都可以兑换的完全签署的承诺交易,这个承诺交易代表着通道中的最新的正确的余额。双方都不会将此交易广播到网络中。
在下一轮,Emma的软件创建并签署另一个承诺交易(承诺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-6显示了Emma和Fabian之间的通道以及更新通道余额的承诺交易。
最后,只有两个交易记录在区块链上:建立通道的资金交易(funding transaction)和在两个参与者之间正确分配最终余额的结算交易(settlement transaction)。
Figure 12-6. Emma’s payment channel with Fabian, showing the commitment transactions that update the balance of the channel
我们刚刚描述的通道,只有在双方合作,没有任何失败或企图欺骗的情况下工作。我们来看看破坏这个通道的一些场景,并且看看需要什么来修复这类场景:
这两个问题都可以用时间锁(timelocks)来解决 - 让我们来看看我们如何使用交易级时间锁(nLocktime)。
除非她能保证可以找零退款,否则Emma不能冒风险提供2-of-2 多重签名的资金。为了解决这个问题,Emma同时建立了资金和退款交易(funding and refund transaction)。她签署资金交易,但不传送给任何人。Emma只将退款交易传送给Fabian,并获得他的签名。
退款交易作为第一笔承诺交易,其时间锁确立了通道生命的上限。在这种情况下,Emma可以将nLocktime设置为30天或将来的第4320个区块。所有后续的承诺交易必须具有比它更短的时间锁,以便在退款交易之前能把它们赎回。
现在,Emma已经有一个完全签署的退款交易,她可以自信地发送签署过的资金交易,因为她知道她最终可以在时间到期后赎回退款交易,即使Fabian消失了。
在通道生命中双方交换的每一笔承诺交易都会被时间锁锁进未来时间点。但是,对于每个承诺,延迟时间会稍短一点,所以最新的承诺交易可以在它前一个承诺交易无效前被赎回(译者注:上文提到如果有一个最新的承诺交易,则它前面的承诺交易就已经作废)。由于nLocktime,任何一方在其时间锁到期前都不能成功传播任何承诺交易。如果一切顺利,他们将合作并通过结算交易合理地关闭通道,这样一来发送中间的承诺交易就不必要了。实质上说,承诺交易只在一方断线而另一方不得不单方面关闭通道时才使用。
例如,如果将来承诺交易#1被时间锁定到将来的第4320个块,则将来承诺交易#2被时间锁定到将来的第4319个块。承诺交易#600则可以在承诺交易#1变为有效之前600个区块的时间被消费。
图12-7显示每个承诺交易设置较短的时间锁,允许它在它之前的承诺交易变为有效前被花费
Figure 12-7. Each commitment sets a shorter timelock, allowing it to be spent before the previous commitments become valid
每个后续的承诺交易必须具有一个较短的时间锁,以便可以在其前任之前和退款交易之前被广播。能够尽早广播承诺交易的能力确保了承诺交易能够花费资金输出,并排除任何其他承诺交易通过花费资金输出而被赎回。比特币区块链提供的担保,即防止双重支出和执行时间锁定,有效地允许每个承诺交易使其前一个承若交易无效。
状态通道使用时间锁来在时间维度中执行智能合约。在这个例子中,我们看到时间维度是如何保证最近的承诺交易在任何早先的承诺交易之前变得有效。因此,最近的承诺交易可以传输,花费输入并且使先前的承诺交易无效。执行带有绝对时间锁的智能合约可以防止参与方的任何一方进行欺骗。此实现只需要绝对的交易级时间锁(nLocktime)。接下来,我们将看到如何使用脚本级时间锁,CHECKLOCKTIMEVERIFY和CHECKSEQUENCEVERIFY来构建更灵活,有用和复杂的(sophisticated)状态通道。
第一次出现的单向支付通道在2015年由阿根廷开发商团队演示的原型视频流应用。你仍然可以在streamsium.io看到它。
时间锁并不是使先前的承诺交易失效的唯一方法。在接下来的章节中,我们将看到如何使用撤销密钥来实现相同的结果。时间锁是有效的,但其有两个明显的缺点。在通道首次打开时建立最大时间锁,限制了通道的使用寿命。更糟糕的是,他们迫使通道实现以在允许长期通道,和迫使其中一位参与者在提前关闭的情况下等待很长时间的退款之间取得平衡。例如,如果允许通道保持开放30天,通过将退款时间锁设置为30天,如果其中一方立即消失,则另一方必须等待30天才能退款。终点设置越远,退款时间越远。
第二个问题是,由于每个后续的承诺交易必须减短时间锁,所以在双方之间可以交换的承诺交易数量有明确的限制。例如,一个30天的通道,设置了位于未来第4320个区块的时间锁,在必须被关闭前只能容纳4320个中间承诺交易。将时间锁定承诺交易的间隔设置为1个区块是存在危险的。通过将承诺交易之间的时间锁的间隔设置为1个区块,开发者给通道参与者带来了非常高的负担,参与者必须保持警惕,保持在线并监视,并随时准备传送正确的承诺交易。
现在我们已经了解如何使用时间锁来使先前的承诺交易无效,我们可以看到合作关闭通道和通过广播一个承诺交易单方面关闭通道之间的区别。所有承诺交易都是时间锁定的,因此广播一笔承诺交易总是要等待时间锁到期。但是,如果双方同意最后的余额是多少,并且知道他们都持有最终能实现余额的承诺交易,那么他们可以构建一个没有时间锁代表相同余额的结算交易。在合作关闭中,任何一方都可以提取最近的承诺交易,并建立一个各方面完全相同的结算交易,唯一差别就是该结算交易删除了时间锁。双方都可以签署这笔结算交易,因为知道无法作弊以得到更多有利的余额。通过合作签署和发送结算交易,他们可以立即关闭通道并兑现余额。最差的情况下,当事人之一可以是卑鄙小人,拒绝合作,强迫另一方单方面关闭最近的承诺交易。但是如果他们这样做,他们也必须等待他们的资金。
处理先前承诺状态的一个较好的方法是明确撤销它们。但是,这不容易实现。比特币的一个关键特征是,一旦交易有效,它一直有效,不会过期。取消交易的唯一方法是在交易被成功挖矿前用另一笔交易双重花费它的输入。这就是为什么我们在上述简单支付通道示例中使用时间锁定,以确保最新的承诺交易可以在旧承诺生效之前被花费。然而,把承诺交易在时间上排序造成了许多限制,使得支付通道难以使用。
虽说一个交易无法取消,但是它可以被构造成无法再使用。我们实现这样的方法是通过给予每一方一个撤销密钥,如果对方试图欺骗,可以用来进行惩罚。撤销先前承诺交易的这种机制首先被作为闪电网络的一部分提出。
为了解释撤销密钥,我们将在由Hitesh和Irene经营的两个交易所之间构建一个更加复杂的支付通道。 Hitesh和Irene分别在印度和美国运营比特币交易所。 Hitesh的印度交易所的客户经常向Irene的美国交易所的客户发送付款,反之亦然。目前,这些交易发生在比特币区块链上,但这意味着需要支付手续费用并且需要等待几个区块进行确认。在交易所之间建立支付通道将大大降低成本并加快交易流程。
Hitesh和Irene通过合作建立资金交易来启动通道,每人向通道注资5个比特币。初始余额为Hitesh有5比特币且Irene有5比特币。资金交易将通道状态锁定在2-2多重签名中,就像在简单通道的例子中一样。
资金交易可能有一个或多个来自Hitesh的输入(加起来5个比特币或更多),以及Irene的一个或多个输入(加起来5个比特币或更多)。投入必须略微超过通道容量才够支付交易费用。该交易有一个将总共10个比特币锁定到由Hitesh和Irene控制的2-of-2多重签名地址的输出。如果他们的输入超过他们需要贡献的数值,资金交易也可能有一个或多个输出将找零返回给Hitesh和Irene。这是由双方提供和签名的多个输入形成的单个交易。在发送之前,它必须被合作构建起来并且由各方签署。
现在,Hitesh和Irene创造了两个不对称的不同的承诺交易,而不是创建一个双方都签署的单一承诺交易。
Hitesh有一个带有两个输出的承诺交易。第一个输出立即支付Irene应得的5比特币。第二个输出支付Hitesh应得的5比特币,但条件是只有在1000个区块的时间锁之后。交易输出如下所示:
Input: 2-of-2 funding output, signed by Irene
Output 0 <5 bitcoin>:
CHECKSIG
Output 1:
<1000 blocks>
CHECKSEQUENCEVERIFY
DROP
CHECKSIG
Irene有一个不同的带有两个输出的承诺交易。第一个输出支付Hitesh应得的5比特币。 第二个输出支付Irene应得的5比特币,但只有经过1000个区块的时间锁之后才可以。Irene持有的承诺交易(由Hitesh签名的)看起来像这样:
Input: 2-of-2 funding output, signed by Hitesh
Output 0 <5 bitcoin>:
CHECKSIG
Output 1:
<1000 blocks>
CHECKSEQUENCEVERIFY
DROP
CHECKSIG
这样一来,双方各有一笔承诺交易,以花费2-2的资金输出。 该承诺交易的输入是由对方签署的。在任何时候,持有承诺交易的一方都可以签名(完成2-2签名)并进行广播。 然而,如果他们广播了承诺交易,承诺交易会立即支付给对方,而他们自己必须等待一个短时间锁到期。通过在其中一个输出上强制执行赎回延迟,我们可以做到让各方在选择单方面广播承诺交易时处于轻微的不利地位。 但是单靠时间延迟还不足以鼓励公平的行为。
下图12-8显示两个不对称承诺交易,其中支付给承诺交易持有者的输出是有延迟的。
Figure 12-8. Two asymmetric commitment transactions with delayed payment for the party holding the transaction
现在我们介绍这个方案的最后一个要素:一个撤销密钥,它允许被冤枉的一方通过获得整个通道的余额来惩罚作弊者。
每个承诺交易都有一个“延迟”的输出。 该输出的赎回脚本允许其中一方在1000个区块之后赎回它,或者另一方如果拥有撤销密钥也可赎回它。所以当Hitesh为Irene创建了一个承诺交易并让其签名时,他使得第二个输出可以在1000个区块之后可以支付给自己,或者是可以支付给任何可以出示撤销密钥的人。Hitesh构建了这个交易,并且创建了一个由他秘密保管的撤销密钥。当他准备转移到新的通道状态并希望撤销这一承诺交易时, 他才会把撤销密钥透露给Irene。第二个输出脚本如下所示:
Output 0 <5 bitcoin>:
CHECKSIG
Output 1 <5 bitcoin>:
IF
# Revocation penalty output
ELSE
<1000 blocks>
CHECKSEQUENCEVERIFY
DROP
ENDIF
CHECKSIG
Irene可以自信地签署这笔交易,因为一旦被发送,它将立即支付她被欠的欠款。 Hitesh持有交易,但知道如果他在单方通道关闭时发送,他将不得不等待1000个区块才能获得支付。
当通道进入下一个状态时,Hitesh必须在Irene同意签署下一个承诺交易之前撤销此承诺交易。要做到这一点,他所要做的就是将撤销密钥发送给Irene。一旦Irene拥有这一承诺交易的撤销密钥,她就可以自信地签署下一个承诺。她知道,如果Hitesh试图通过发布先前的承诺交易来作弊,她可以使用撤销密钥来赎回Hitesh的延迟输出。如果Hitesh作弊,Irene会得到BOTH(两方)输出。
撤销协议是双边的,这意味着在每一轮中,随着通道状态的进一步发展,双方交换新的承诺交易,交换用于之前承诺交易的撤销密钥,并签署彼此的承诺交易。当他们接受一个新的状态时,他们通过给予对方必要的撤销密钥来惩罚任何作弊行为,使得先前的状态不可能再被使用。
我们来看一个它是如何工作的例子。Irene的其中一个客户希望向Hitesh的其中一个客户发送2个比特币。要通过通道传输2个比特币,Hitesh和Irene必须更新通道状态以反映新的余额。他们将提交到一个新的状态(状态号2),其中通道的10个比特币被分开,7个比特币属于Hitesh,3个比特币属于Irene。为了更新通道的状态,他们将各自创建反映新通道余额的新的承诺交易。
如上述内容所说,这些承诺交易是不对称的,所以每一方所持的承诺交易都迫使他们如果要赎回则需等待。至关重要的是,在签署新的承诺交易之前,他们必须首先交换撤销密钥以使先前的承诺交易无效。在这种特殊情况下,Hitesh的利益与通道的真实状态是一致的,因此他没有理由广播先前的状态。然而,对于Irene来说,状态号1中留给她的余额比状态2中的更高。当Irene给予Hitesh她以前的承诺交易(状态号1)的撤销密钥时,她实际上废除了自己可以回滚通道状态到前一状态而从中获益的能力,因为有了撤销密钥,Hitesh可以无需延迟地赎回先前承诺交易的两个输出。也就是说一旦Irene广播先前的状态,Hitesh可以行使其获得所有输出的权利。
重要的是,撤销不会自动发生。虽然Hitesh有能力惩罚Irene的作弊行为,但他必须勤勉地观察区块链中作弊的迹象。如果他看到先前的承诺交易被广播,他有1000个区块的时间采取行动,并使用撤销密钥来阻止Irene的欺骗行为并且拿走所有余额也就是全部的10比特币来惩罚她。
带有相对时间锁(CSV)的不对称可撤销承诺交易是实现支付通道的较好的方法,也是这一技术中非常重要的创新。通过这种结构,通道可以无限期地保持开放,并且可以拥有数十亿的中间承诺交易。在闪电网络的原型实现中,承诺状态由48位索引确定,允许在任何单个通道中有超过281万亿(2.8×10^14)个状态转换!
支付通道可以通过特殊类型的智能合约进一步扩展,该智能合约允许参与者在到期时间内将资金提交给可赎回的秘密。此功能称为哈希时间锁定合约或HTLC,并用于双向和路由的支付通道。
首先我们来解释HTLC的“哈希”部分。 要创建一个HTLC,预期的收款人将首先创建一个秘密R。他们然后计算这个R的哈希H:
H = Hash(R)
这步产生可以包含在一个输出的锁定脚本中的哈希H。 知道秘密的任何人可以用它来赎回输出。 秘密R也被称为哈希函数的前图像。 前图像就是用作哈希函数输入的数据。
HTLC的第二部分是“时间锁”组件。 如果秘密没有被透露,HTLC的付款人可以在一段时间后得到“退款”。 这是通过使用绝对时间锁CHECKLOCKTIMEVERIFY来实现的。实现HTLC的脚本可能如下所示:
IF
# Payment if you have the secret R
HASH160 EQUALVERIFY
ELSE
# Refund after timeout.
CHECKLOCKTIMEVERIFY DROP
CHECKSIG
ENDIF
任何知道秘密R(其哈希后的值等于H)的人,都可以通过执行if流的第一个子句来赎回这个输出。
如果秘密没有被透露,HTLC中写明了,在一定数量的区块之后,收款人可以使用IF流中的第二个子句申请退款。
这是HTLC的基本实现。 任何拥有秘密R的人都可以赎回这种类型的HTLC。通过对脚本进行微调,HTLC可以采用许多不同的形式。 例如,在第一个子句中添加一个CHECKSIG运算符和一个公钥,会限制将哈希赎回给一个指定的接受者,该接受者同样还必须知道秘密R。