作者:Anony
前篇文章见此处。
在本系列的上一篇文章中,我们介绍了比特币脚本的时间锁功能。如果说多签名是分散了资金在一个团体中的控制权,那么时间锁就是分配了不同的团体在不同时段的权限,从而分配了主动权。我们已经看到了,它们的组合可以如何多样。
在本文中,我们会再了解一种比特币脚本的功能模块:哈希锁。
“哈希锁”简介
“哈希锁” 也称 “哈希原像检查”,也就是检查某个传入的数据的哈希值是否为某一值。很难直接看出这种模块有什么用,尤其在考虑到这样一个事实:比特币网络是一个公开的网络,而且没有额外的机制为 witness 作伪装,因此,在真的有人能为一个哈希值提出原像之后,这个原像和哈希值的关系也将为所有人所知 —— 也就是说,光凭自身,它无法成为一种安全的 “授权” 机制。
它必须跟其它模块相结合,才能令我们满意。
哈希锁脚本示例
现在,我们要再学习两种 Policy 函数:
sha256(H)
,检查传入的某数据(也称 “原像”)的 sha256 哈希值是否为 H;原像应该是 64 位的 十六进制数。ripemd160(H)
,检查传入的某数据(也称 “原像”)的 ripemd160 哈希值是否为 H;原像应该是 40 位的 十六进制数。
现在,我们来编写这样一种花费条件:假如 Bob 知道某一个哈希值的原像,则可以立即花费它;但是,如果 Bob 一直没有花费它,那么一段时间后,Alice 可以独自花费这笔资金。Policy 语句:
or(and(pk(Bob), sha256(H)), and(after(6), pk(Alice)))
编译 1 出来的 Miniscript 代码是:
andor(pk(Bob),sha256(H),and_v(v:pk(Alice),after(6)))
其 Script 代码是:
<Bob> OP_CHECKSIG OP_NOTIF
<Alice> OP_CHECKSIGVERIFY 6 OP_CHECKLOCKTIMEVERIFY
OP_ELSE
OP_SIZE <20> OP_EQUALVERIFY OP_SHA256 <H> OP_EQUAL
OP_ENDIF
熟悉比特币脚本的读者可能知道,这种花费条件就是大名鼎鼎的 “哈希时间锁合约(Hashed-time-lock-contracts,HTLC)”。它意味着 Alice 给 Bob 的一种条件式支付:这里的的 H 是由 Alice 给出的,如果 Bob 能在一定时间内知晓这个 H 的原像(当然是用某种办法向 Alice 购买,因为密码学哈希函数的单向性和抗碰撞性,理论上只有 Alice 的原像能通过这个检查),则 Bob 就可以取走这个输出中的钱;但如果 Bob 跟 Alice 没有谈妥,不知道这个原像,过一段时间后它就会回到 Alice 的控制中。
这样的条件式支付有一个很重要的用途:它可以将使用同一个哈希值的 HTLC “粘合” 成为一体,即,这些 HTLC 要么一起解锁,要么都得不到解锁。
应用
资助发现哈希碰撞
如果我们在一个链上输出中使用且仅使用哈希锁,并在社交媒体上广而告之,这就等于是用这个输出中的资金鼓励矿工发现一个原像来解开这个锁。由于哈希函数的单向性,矿工只能使用暴力搜索的方法不断尝试,这就等于是在寻找一个与你手中的原像产生相同哈希值的东西,也就是在搜索哈希碰撞(“碰撞” 指的就是不同的原像产生相同的哈希值的情形)。
为什么只能激励矿工?因为如上所述,一旦有人能够提出这样的原像,它被广播到网络中时,矿工就能够知晓,然后发起一笔交易将其中的资金转给自己;这等于是白送给了矿工。
虽然看起来这像是在资助科学研究,但对我们来说,它其实不是那么有趣 : )
免信任的原子化互换
HTLC 的用途之一。假设 Alice 给了 Bob 一个 HTLC,Bob 也在另一个地方(比如在另一条区块链上,使用另一种资产)给了 Alice 一个使用相同哈希值的 HTLC,则这样的互换就具有原子性:要么它们一起成功,要么一起失败,不存在某一笔成功了另一笔却不能成功的情况;所以,这样的互换也具有免信任性 —— 无需信任交易的对手方。
这种原子化互换可以用来交换两条不同链上的资产,因此也被称为一种 “跨链” 方案,但这个词的具体含义不太清晰。
如果用户满足于低频的交易,这种免信任的原子化互换就能替代托管式密码货币交易所。
闪电通道
闪电通道利用了我们已知的所有模块:多签名、时间锁、哈希锁;但是,为了更好地展现其面貌,我们在下一章中集中讲解,顺带总结我们已知的所有概念、测试一下我们的知识,并展现比特币脚本围绕闪电网络的应用。
闪电网络中的支付路由
假定 Alice 希望给 Carol 支付,但是,因为一些原因她无法直接支付,但她知道 Bob 可以给 Carol 支付,而自己可以给 Bob 支付,于是,Alice 就让 Carol 给她一个哈希值,并制作出了一个给 Bob 的 HTLC,并指示 Bob 去找 Carol;Bob 依样画葫芦,给 Carol 一个使用相同哈希值的 HTLC。但这个哈希值正是 Carol 给 Alice 的,她知道背后的原像是什么!于是,Carol 拿走 Bob 给她的 HTCL 中的资金,与此同时,Bob 也知晓了这个原像,因此可以拿走 Alice 的 HTLC 中的资金。当 Alice 看到这个原像时,她就知道,支付已经送达了。
如上所述,HTLC 在这里,就起到了将多笔支付 “粘合” 为一笔的作用。假设 Carol 不交出原像,那么她就无法得到资金,时间锁超时之后,Alice 就知道支付没有送达。
闪电网络中的支付路由,就是这样实现的。关键在于,这种 “Alice 不能直接给 Carol 支付” 假设,在比特币链上是不成立的,拥有比特币的人可以给任意人直接支付,但是,在闪电网络中,却恰好是如此。在下一章中,我们讲解闪电网络时,会有更详细的解读。
潜水艇互换
一种特殊的原子化互换,是将比特币链上的资金换成闪电网络中的通道余额(反之亦成立)。发起互换的一方在自己的环境中给出哈希值和 HTLC,接受互换的另一方在自己的环境中制作使用相同哈希值的 HTLC。
这种互换功能对闪电网络用户来说非常重要,因为闪电支付通道是一对一的(它是一个 2-of-2 的多签名合约),用户发起支付和接收支付的能力分别受限于自己的 “本地余额”(在该用户参与的各个通道中属于 TA 自己的资金)和 “远端余额”(分别属于各通道对手的余额),某一些用户可能经常支付或收取支付,从而用尽余额(因此无法支付)或让通道中的资金全部归属于自己(因此无法接收支付)。潜水艇互换可以让用户置换出闪电通道中的资金,或向通道内注入资金,而无需 关闭/重新开启 通道。
小结
哈希锁虽然看起来平平无奇,却能够将多笔不同环境中的支付粘合成一笔、为它们赋予原子性。
在下一篇文章中,我们将深入学习闪电网络,看看这些脚本模块如何创造出不可思议的东西。这也是一个测试我们的知识的好机会。
参考文献
1. https://bitcoin.sipa.be/miniscript/ ↩
2. https://lightning.engineering/loop/ ↩
*续篇见此处*。
https://www.btcstudy.org/2023/04/23/interesting-bitcoin-scripts-and-its-use-cases-part-4-hash-locks/