【比特币专题03】隔离见证、闪电网络

本文最后更新于:2023年12月17日 下午

前言

最近通读了一遍《精通比特币》,对比特币中运行机制和实现原理有了初步的认识和了解。其中隔离见证和闪电网络是此前学习中遇到到两个困惑点,现在也大致有所了解,故而本篇文章就来谈谈我的个人理解,基本上是对书里关键知识点的提炼和总结,下方也给出了电子书连接。如有任何错误,欢迎批评指出~

精通比特币电子书链接

隔离见证

隔离见证提出的背景:随着比特币火热发展,网络上的交易量越来越大,而由于区块大小受限,一个区块能打包的交易数量是有一定限制的,而出块速度限定在10分钟一次,这就导致无法满足交易吞吐量的增长。那么隔离见证提出,挑战了交易结构,使得一个区块可以容纳更多的交易,从而提高了交易吞吐量,当时隔离见证还有别的好处,可以去看书中内容隔离见证的好处。当然提高比特币性能(比如提高交易吞吐量)的方法还有很多,这里不再展开。

隔离见证相关BIP方案:
BIP-141 隔离见证的定义
BIP-144 隔离见证网络序列化

关键知识

  • 在比特币环境中,数字签名是见证的一种类型,但更广义来说,见证是指能够满足对UTXO施加的条件并解锁该UTXO以供消费的任何解决方案。术语“见证”是“解锁脚本”或“scriptSig”的更一般的术语。
  • 在引入隔离见证之前,交易中的每一个输入后面紧跟着的就是解锁它的见证数据。见证数据作为每个输入的一部分嵌入到交易中。术语隔离见证(简称segwit)只是指把特定输出的签名或解锁脚本隔离开。“单独的scriptSig”或“单独的签名”就是它最简单的形式。
  • 乍一看,隔离见证似乎只是对交易构造方式的改变,属于交易级特性,但事实并非如此。其实,隔离见证是对单独的UTXO花费方式的更改,因此可以说是每个输出层面的特性。
  • 当交易使用UTXO时,必须提供一个见证。在传统的UTXO中,锁定脚本要求见证数据内嵌在花费UTXO的交易的输入部分。但是,隔离见证UTXO指定了一个锁定脚本,该脚本可以用输入之外的见证数据(隔离)满足。
  • 隔离见证是一个软分叉

TXID 和 WTXID

  • 隔离见证的最大好处之一就是消除了第三方交易延展性
  • 在隔离见证之前,交易可以通过第三方巧妙地修改其签名,在不改变任何基本属性(输入,输出,金额)的情况下更改其交易ID(哈希)。这为拒绝服务DOS攻击,以及对有缺陷的钱包软件的攻击创造了机会,这些软件假定未经证实的交易哈希是不可变的。
  • 通过引入隔离见证,交易有两个标识符txid和wtxid。传统的txid是序列化交易的双SHA256哈希,没有见证数据。交易的wtxid是具有见证数据的交易的新序列化格式的双SHA256哈希。
  • 传统txid的计算方式与非隔离见证交易完全相同。但是,由于隔离见证交易在每个输入中都有空的scriptSig,不存在可由第三方修改的交易部分。因此,在隔离交易中,即使交易未经确认,txid也是不能被第三方修改的。

提示 隔离见证交易有两个ID:txid和wtxid。txid是没有见证数据的交易的哈希,wtxid是包含见证数据的哈希。所有输入都是隔离见证输入的交易,不受第三方交易延展性影响。


  • TXID的生成和传统方式一致:是对version, txins, txouts, nLocktime序列化后的数据,进行两次SHA256哈希
1
[nVersion][txins][txouts][nLockTime]
  • WTXID的生成:对version, marker, flag, txins, txouts, witness, nLocktime序列化后的数据,进行两次SHA256哈希
1
[nVersion][marker][flag][txins][txouts][witness][nLockTime]

TXID与WTXID的生成

隔离见证的数据到底放在哪里

在了解隔离见证的大致原理后,我其实还是存在一个疑惑:既然说见证相当于是原来的签名数据(解锁脚本),与原来的交易数据隔离开,那么这些见证数据到底放在哪里了?

  • 通过比特币探究之隔离见证 这篇文章,了解到原来的签名数据放到了见证数据中,见证数据在CTxIn 是一个新的字段,但是只有在交易被序列化网络传输时才参与,呼应上文计算TXID时,witness是不需要序列化的;

  • 通过外文- Segwit如何工作的 这篇文章,进一步了解到在生成区块时,输入的见证数据同样构成一棵Merkle Tree,并把root放到了区块中的币基交易的output的锁定脚本中,具体原文描述如下图。

ScriptPubKey of Witness in coinbase

闪电网络

闪电网络其实也是一种提高比特币交易性能的方法,简单来说,就是将大量交易放到比特币区块链之外进行。在具体介绍闪电网络是如何工作运行前,还需要先介绍状态通道,支付通道,HTLC哈希时间锁合约等概念。

状态通道和支付通道

基本概念:

  • 支付通道Payment channels是在比特币区块链之外,双方交换比特币交易的无信任机制。
  • 实际上,通道channel 一词是一个比喻。状态通道是区块链外,由双方之间的交换状态代表的虚拟构想。实际上没有“通道”,底层数据传输机制也并不是通道。我们使用通道这个术语来表示链外双方之间的关系和共享状态。
  • 支付通道是更广泛的状态通道state channel概念的一部分,状态通道代表了链外状态的变化,通过最终在区块链上结算得到保障。支付通道是一种状态通道,其中被改变的状态是虚拟货币余额。

《精通比特币》中对支付通道的描述感觉过于复杂,这里用Bitcoin Developer Guide里的微支付通道来举例说明,在之前博客[【比特币专题02】Developer Guide导读](https://2017zhangyuxuan.github.io/2021/10/11/2021-10-11比特币专题02-Developer Guide/) 也有介绍。

微支付通道

  • 其工作原理大体上可以这样描述:A给B打工,B首先使用A和B的签名,使用P2SH的方式,发送一定金额到脚本地址,并将该交易立即传播到比特币网络上;然后B创造第二个交易,并用到刚刚A的签名,其输入是第一个交易的脚本地址,输出是B的地址(相当于全额返回给B),然后给这个交易加上Locktime,比如说一天后才能广播这个交易。然后A给B工作一部分内容后,A要求B先支付这份工作量的薪水,那么B就创建一份新的交易,从原来全额给B变成分出一部分金额给A,这个新的交易拷贝给A,这样A就可以广播这个新的交易从而获得薪水。(实际上A只需要在locktime过期前,广播最后版本的交易即可)
    • B创建的第一笔交易和第二笔交易,可以理解为《精通比特币》中的注资交易funding transaction锚点交易anchor transaction:通过在区块链上锁定共享状态的交易,在交易两方之间建立了一个状态通道。在支付通道的示例中,锁定的状态即为通道的初始余额(以货币计)
    • 随后双方交换已签名的交易,这被称为承诺交易commitment transactions。承诺交易会改变初始状态。这些交易是有效的交易,因为它们可以被任何一方提交进行结算,但是在通道关闭之前,每一方都会将其在链下保留。
    • 最后,通道可以协商关闭,即向区块链提交最后的结算交易settlement transaction,或者由任何一方单方面提交最后承诺交易到链上。
  • 为什么采用支付通道这样的方式呢,因为A诉求是及时支付薪水,但是因为量小,B不能每次都立即创造一个交易即刻支付,这样的交易费的成本太高了。所以利用这样的方式,既确保了A的薪水是及时得到确认的,又可以使得只需一个交易就一次性支付薪水
  • 实际上,更改交易金额的输出,这个权利是在B的,因为B有A的签名但A没有B的签名,A拿的是经过B签名后的交易副本(这个交易被B签名过了,所以是有效的)。所以A能实时确保自己对应工作量的薪水能及时支付,就算中途B跑路了,也只是损失一小部分工作量的薪水,之前的薪水都可以得到支付。而对B来说,如果A没有工作,那B也能在locktime 过期后拿回自己的钱(不过这样就需要等待一个locktime的时间)

HTLC哈希时间锁合约

HTLC 哈希时间锁合约 原文中介绍得比较详细了,这里简单总结一下:

1
2
# 通过密钥R生成哈希值H
H = Hash(R)
1
2
3
4
5
6
7
8
9
# 实现HTLC的脚本可能如下所示:
IF
Payment if you have the secret R
HASH160 <H> EQUALVERIFY
ELSE
# Refund after timeout.
<locktime> CHECKLOCKTIMEVERIFY DROP
<Payer Public Key> CHECKSIG
ENDIF
  • 任何知道密钥R,其哈希值等于H的人,都可以通过行使IF语句的第一个子句来兑换该输出。
  • 如果密钥R没有被透露,HTLC中写明了,在一定数量的区块之后,付款人可以使用IF语句中的第二个子句申请退款。

闪电网络运行

左图:支付通道初始状态;右图:闪电网络运行流程

接下来说明一下,闪电网络是如何工作:

  • 在这个例子中,我们有五个参与者:Alice, Bob, Carol, Diana, and Eric。这五名参与者已经彼此之间开设了支付通道。Alice和Bob有支付通道。Bob连接Carol,Carol连接到Diana,Diana连接Eric。为了简单起见,我们假设每个通道每个参与者都注资2个比特币资金,每个通道的总容量为4个比特币,也就是如左图所示的初始状态
  • Alice想要支付给Eric1个比特币。但是,Alice并没有直接连接Eric的支付通道。创建支付通道需要注资交易,而这笔交易必须首先提交给比特币区块链。Alice不想建立一个新的支付通道还要支出更多的手续费。那么就可以通过闪电网络来进行支付。
  1. Alice通过路由发现了一条从Alice到Eric的一条支付路由,由多个支付通道组成。此时Alice和Eric可以进行通信,Eric生成一个密钥R,并进行hash,将哈希值H发送给Alice。
  2. Alice构造一个HTLC,支付1.003BTC到哈希H(多出来的0.003BTC是给路由上3个节点的费用),并可以在10区块内得到退款。Alice将此HTLC提供给Bob,从和Bob之间的通道余额中扣除1.003比特币,并将其提交给HTLC。该HTLC具有以下含义:“如果Bob知道密钥,Alice将其通道余额的1.003支付给Bob,或者如果超过10个区块后,则退还入Alice的余额”
  3. Bob构造一个新的HTLC,支付1.002BTC到哈希H,如果Carol知道了密钥R,可以去取走HTLC中的1.002BTC,然后Bob也可以取走Alice提供的1.003BTC,相当于赚取了0.001BTC;如果Carol不能提供密钥,Bob也可以在9个区块时间内取回1.002BTC
  4. Carol向Diana提供1.001BTC的HTLC,同上面一样
  5. Dinana向Eric提供1.0BTC的HTLC
  6. Eric知道密钥,向Diana出示了密钥R,因此取走了HTLC中的1.0BTC
  7. Diana从Eric知道了密钥R,再向Carol出示密钥R,获得了1.001BTC,此时在Eric和Diana中支付通道中,Diana余额只有1.0BTC了,但在Carol和Diana的支付通道中,Diana余额为3.001BTC,对比原来的2+2,赚取了0.001BTC
  8. Carol向Diana支付了1.001BTC,再从Bob处赚取了1.002BTC,赚取了0.001BTC
  9. Bob向Carol支付了1.002BTC,从Alice处赚取了1.003BTC,赚取了0.001BTC
  10. 最终Alice支付了1.003BTC,实际上1BTC转账给了Eric,0.003支付给了路由上的其他节点

【比特币专题03】隔离见证、闪电网络
https://2017zhangyuxuan.github.io/2021/11/13/2021-11/2021-11-13 比特币专题03-隔离见证、闪电网络/
作者
Zhang Yuxuan
发布于
2021年11月13日
许可协议