第16课 闪电网络(Lightning Network) 之 HTLC

有兴趣朋友也可以进一步关注公众号“架构之道与术”, 获取原文。
或扫描如下二维码:
这里写图片描述

在第14课 闪电网络(Lightning Network) 之 RSMC 中,我们知道了RSMC实现了买家和卖家之间的双向支付通道。

但这还不够方便,任何时候2个人之间要交易,就得建立支付通道。 有没有更便捷的办法,在买卖双方不建立通道的情况下,也可以实现交易?

闪电网络的基本思路
如下图所示,Alice和Eric之前想进行交易,但没有支付通道。

Alice和Bob之间,Bob和Carol之间、Carol和Diana之间、Diana和Eric之间,已经有了支付通道,那把这些通道串联起来,就相当于建立了Alice和Eric之间的支付通道。

这个过程怎么达成呢?
如下图所示,假设Alice需要付给Eric 1个比特币:

首先,由最终的收款方Eric构建了1个秘钥R和对应的Hash值H,然后他把H给了Alice。

Alice呢,就和Bob之间达成了一个合约:Alice对Bob说,如果你在4天内,可以给我H对应的密钥R,我就给你1.003比特币,超过4天,我就拿回这钱;

在这打个比方,Alice就好像搞了个“谜题悬赏”:Alice抛了一个问题,然后悬赏,谁能给出这个问题的答案,就支付给他1.003比特币。这里的问题,就是H;答案,就是密钥R。

很显然,密钥只有Eric有,Bob没有。那Bob怎么办呢?
Bob和Carol达成1个合约:Bob对Carol说,如果你在3天内,可以给我H对应的密钥R,我就给你1.002比特币,超出3天,我就拿回这钱;

同理,Carol也没公钥,
Carol和Diana达成1个合约:Carol对Diana说,如果你在2天内,可以给我H对应的密钥R,我就给你1.001比特币,超过2天,我就拿回这钱;

同理,Diana也没公钥,
Diana和Eric达成1个合约:Diana对Eric说,如果你在1天内,可以给我H对应密钥R,我就给你1个比特币,超过1天,我就拿回这钱。

所以整个的交易顺序是:Eric把R给了Diana,拿到1.0比特币; Diana把密钥给Carol,拿到1.1比特币;。。。密钥一直传递,最终到Alice那。

最终结果就是:Alice付出了1.3个比特币,Eric收到1.0个比特币,每个中间方,收到0.1个比特币的手续费。

HTLC脚本分析
上面的交易过程中,核心就是“一方用密钥R向另1方换钱,超过时间没有换,钱自动回到打款人的账号”,这个过程就是所谓的HTLC(Hashed Time Lock Contract),通过这几个英文单词,就大概知道其意思。Hashed,就是上面说的Hash值,也就是密钥R; Time Lock,就是这个交易有个时间锁,也就是我们前面所讲的nLockTime。

HTLC的脚本长下面这个样子:
假设buyer要给seller付钱,seller提供了密钥R,就会执行OP_IF后面的statement,seller收到钱;
seller提供不出密钥R,就会执行OP_ELSE后面的statement,钱会返回到buyer的账号。

OP_IF
    [HASHOP] <digest> OP_EQUALVERIFY OP_DUP OP_HASH160 <seller pubkey hash>            
OP_ELSE
    <num> [TIMEOUTOP] OP_DROP OP_DUP OP_HASH160 <buyer pubkey hash>
OP_ENDIF
OP_EQUALVERIFY
OP_CHECKSIG

下面详细分析一下这个脚本的执行过程:

对比上节课所讲的Script Language,这个脚本在OP_IF前面,显然缺了condition,没有condition,怎么执行分支语句呢?

这就涉及到了这里的关键点:这个script,对应在交易里面,也就是scriptPubKey的部分(output里面),交易类型是P2SH(Script Hash)。 下1笔交易要花这个钱,需要scriptSig,也就是私钥签名。
那串私钥签名(也就是上面说的密钥R),拼接在这里的OP_IF前面,也就是condition。

让我们再回到上1节课,仔细看一下OP_IF, OP_ELSE的详细语义:

//OP_IF,表示栈顶元素不为0,就执行接下来的statement。
具体到我们上面的HTLC脚本,栈顶元素是密钥R(也就是condition),肯定不为0,所以就会把statement也入栈。密钥R在下面,OP_IF后面的statement在上面,拼接在一起,进行估值。

//OP_ELSE 当OP_IF后面的stament不执行时,就执行OP_ELSE后面的statement。

所以,知道了OP_IF/OP_ELSE的语义,同时在这个脚本签名拼接上密钥R,我们也就基本知道了这个脚本的执行过程。

借用RSMC通道
在第14课 闪电网络(Lightning Network) 之 RSMC里面,我们知道RSMC建立了Alice和Bob之间的一个双向通道。

对于HTLC呢,会借用这个通道,通俗点,“加塞”。在通常的RSMC交易通道里面,塞进1个HTLC的合约。这样才能达到上面所说的,复用现有的双向支付通道,而不建立新的通道。

具体怎么复用呢,如下图所示:
本来呢,Alice和Bob各有0.5比特币在这个通道里面,现在Alice和Bob建了一个HTLC(Alice向Bob支付0.1元,只要Bob能提供密钥R)

也就是图中红线圈起来的部分,在这个Transaction里面,新加了1个output,也就是HTLC(本来RSMC里面,只有2个output,现在加塞进了1个)

Bob想兑现这0.1比特币呢,就以这个output2为输入,构建左边分支的Delivery Transaction(里面包含了密钥R);
Alice想拿回这0.1比特币,同样以output2为输入,构建右边分支的Timeout Transaction(时间到了之后,钱就回到Alice账号)。

套上了RSMC的HTLC
在上面,我们说了,HTLC这个合约是作为一个output,加塞在Commitment Transaction里面的,但这有一个问题:

假设这个HTLC的锁定期是3天,超过3天之后,旧的Commitment在网络上出现了,那上图中的左右2个分支,都可能被执行!!!

也就是说,如何保证在Commitment Transaction 3达成之后,因为某种原因,Transaction 2被广播出去了,导致2里面的HTLC被双方同时执行?

答案:为HTLC套上RSMC
也就是下图中的output2(是一个HTLC),也类似RSMC,生成了HED1a和HT1a,用于达成下面的目的:Bob能提供key就拿到0.1元,3天后,Alice拿回这0.1元。

如何在通道不关闭的情况下,结束HTLC

正如上面所讲的,HTLC是加塞在Commitment Transaction里的。但是Commitment Transaction并不会被广播。

那如何可以在不广播Commitment Transaction的情况下,让HTLC的合约得以履行?换句话说,如何在RSMC通道不关闭的情况下,双方完成HTLC交易,让Alice得以成功的把这0.1元,转给Bob?

想想在RSMC里面:我们是如何保证双方在达成Commitment Transaction 3之后,双方都没有人反悔,把Commit 2广播出去的呢??

答案:为Commitment Transaction2 也生成“把柄Transaction”(也就是BR2a, BR2b),各自攒在对方手上,谁广播,惩罚谁!!!

同样的,借鉴这个思路:我们也需要为HTLC加上“把柄Transaction”,使得1方不能反悔!!

如下图所示,是Commitment Transaction 2 对应的HTLC的处罚交易HBR1a与HTBR1a,如果在Commitment Transaction 3达成之后,有谁广播了Commitment Transaction 2,那么就处罚谁。

总结
HTLC本身的想法并不复杂,但要使用它,需要和RSMC紧密结合,才能形成一个完善的、具有多个中间节点的支付通道。

本文只是粗略分析了HTLC的几个关键点,关于HTLC和RSMC如何结合的详细协议,还是要参考“闪电网络的白皮书”,这个网络上都有,读者可以自行下载。

相关链接:
《第15课 闪电网络之 Script Language与Script Engine》
《第14课 闪电网络(Lightning Network) 之 RSMC》

猜你喜欢

转载自blog.csdn.net/chunlongyu/article/details/80417309