Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文

比特币闪电网络上的谨慎日志合约

落日余晖97
183 0 0
我们已经在主网上开启和关闭了第一条嵌入了一个谨慎日志合约(DLC)的闪电通道。我们CryptoGarage一直在开发可以在闪电通道中工作的DLC,而我们最终也到达了一个重要的里程碑:我们成功开启了一条闪电通道并在其中建立了一个DLC,最终关闭了整个通道。在本文中,我会解释闪电通道与DLC建立和关闭的技术细节。
; g5 N6 x  _9 K+ L% K  @
; C( D( H; n. W+ `! w) m. q- [( ?    什么是闪电通道中的DLC(以及什么不是)
" l& V) V, w) L$ N9 E, \3 D2 K
  h- T/ q+ b7 U# u8 r. r    出于本文的目的,我们所谓的“在闪电通道中开启DLC”,意思是两个节点直接建立一条通道,并在通道内使用(部分)资金建立一个DLC。这个DLC可以关闭(让通道回归常规的闪电通道),也可以更新,而且通道也可以在非合作情境下关闭(我们也正是这么做的,这样会让闪电通道和DLC合约的交易结构完完整整在链上展示出来)。2 w9 R0 C8 o+ E
; v! B" x2 p6 q" L) X( b: ~
    我们要强调的是,当前无法做到通过闪电网络来路由DLC(即无法跟没有直接通道的节点开设DLC)。这份邮件组帖子提供了更多信息。
2 }* G* @. h9 B: e6 a3 X, ~% B& Q1 G4 [! L6 q" ^' w
    预备知识2 [  w. J% A6 V/ j/ A
( K0 u4 }2 ?( H/ n# Q7 E* Z, j
    为了热身以及让这篇文章自足,我们将历数在闪电通道中建立DLC所需的各种元素:闪电通道、适配器签名、DLC和DLC通道。* E+ j5 ?8 P8 ?4 Y+ T

) [+ U/ M* w; X: m, w% ^4 s  W! B    闪电通道; a; M/ }; X- ~/ Z

4 P. b& S+ R. X, M    如果对常规闪电通道的交易结构没有起码的理解,就很难理解如何在一条闪电通道中建立DLC,所以我们快速回顾一下闪电通道的原理(若要获得更深入的理解,请看BitcoinMagazine的系列文章)。我们仅仅关注跟我们的需求相关的部分,所以跟路由相关的部分我们全部跳过。+ W$ V1 D$ z: K
9 r* ^  R3 h/ E6 k0 D
    当两个闪电网络节点要开设一条通道时,他们会合作构造和签名两种类型的交易,“注资交易”和“承诺交易”。
5 |0 \% b% C/ F/ ?/ ]  G3 |# h; i2 X: e# T# b$ o
    注资交易以其中一方的几个UTXO作为输入(如果支持双向注资技术,也可以双方都提供UTXO),然后将资金锁入一个2-of-2的多签名输出中,为通道所用;这样的输出需要双方同时提供签名才能花费。
: O- ]) @; ]3 s+ t) }
. R2 n6 y& Q# u; P1 [    承诺交易则以注资交易的输出为输入,产生两个输出,这两个输出的面额对应双方的余额。注意,这些余额会在通道的生命周期中不断改变,所以,承诺交易需要不断更新以反映这些变化。这是通过让承诺交易变得可以撤销(revocable)来实现的。在实践中,这意味着每一方都保存着每一笔承诺的不同版本;在他们保管的承诺交易中,一个支付给他们自己的输出被锁定在这样一个脚本中:这个脚本即可以在一段事件后由他们自己解锁,也可以被掌握了某个秘密值的对手直接解锁。当双方都同意更新通道余额时(例如,一方希望给另一方支付一些钱),他们就构造并交换新的承诺交易和签名,并向对方揭晓在上一笔承诺交易中使用的秘密值,从而撤销掉上一笔交易。如果一方想要欺诈对手——广播比较旧的承诺交易,对方有时间可以反击——使用本地保存的秘密值,拿走通道中所有的资金。6 {4 }  n( ^) }( h
2 x% U8 Y  ~: k* l- g( k+ Y
    -闪电通道的交易结构-
& {% p9 z& p) T. c
9 l! s. P0 e5 P& O7 I    适配器签名
" U8 e7 U4 J2 R8 p. V. G( A+ H  ^0 }# Z2 D
    适配器签名是一种加密过的签名(使用了某一个公钥),而且我们可以证明,在(使用对应的私钥)解密之后,可以得到对某条消息的有效签名。它还有一种属性:知晓了适配器签名、加密公钥和解密后的签名,就可以恢复出用来加密的秘密值。这里对所设计的模块作了概要的介绍。
. ?. v9 u5 n) q; x) t5 j) A- j9 d1 o# v" A& u4 v: N
    下图展示了加密、验证和解密适配器签名的不同操作,以及恢复秘密值的过程。% f0 [; r* e1 s/ T/ ?
. A3 B! x, V: N& h0 W
    谨慎日志合约
% z$ P7 y& T- r1 {# e' i' T' n6 a, E5 \2 X' n3 I" U2 J$ S
    DLC让两方可以建立一个依赖于某些事件(体育比赛、资产价格……)的合约,并且直接在比特币区块链上结算。参与的双方需要提前选择一个播报事件的实体(“断言机”),这个实体会通过放出对结果的签名来见证事件的结果。3 E& e) e  v; D7 m; Y
; m3 q, {0 z2 F0 p! V, u4 N
    DLC乍看起来可能跟闪电通道很像,但是它并不使用从注资交易中花费的承诺交易,而是“合约执行交易(CET)”,每一笔CET都对应着事件的一种可能结果(以及支付数量)。双方都使用断言机会为不同事件结果创建的签名作为原像,加密自己的签名(从而产生适配器签名)(更多细节可见此处),然后交换并验证它们。一旦断言机见证了某个结果,DLC的任意一方都可以解密对方的某一个签名,然后广播对应的CET、结算合约。注意,因为使用了适配器签名,双方手中的CET是一样的。一个DLC的交易结构如下图所示。
+ M3 `9 {1 S; A/ I; L0 a: c# L  y3 `5 |9 J1 l: v; E* v
    -链上CDL的交易结构-/ E& A/ \8 m' T6 a% ?
' t" a7 u. l* e' c
    DLC通道
/ E8 r: ?% r1 J! v3 Q1 B9 d; X- l5 o; A% D( k2 e% M, v$ t
    那么,如果双方希望在上一个DLC到期后新建一个合约呢?当然,他们可以先关闭一个,再新建另一个。但是每一笔上链的交易都需要支付手续费。相对的,他们可以使用DLC通道(ItchySats已经撰写了一份很棒的详细介绍)。DCL通道允许双方新建合约、在到期之前提前结算合约,当然,也可以在他们希望回收资金的时候在链上关闭合约。一种简单的实现办法是让CET变成可以撤销的。但是,那会导致新建合约的时候出现问题。即使某一方撤销掉了以前的CET,也无法防止对手使用它们。这就意味着,对手方总是可以选择使用旧的CET或新的CET来关闭通道,而先撤销自己的CET的一方则没有选择,只有等待新的合约到期(因为他们需要等待断言机放出签名,这样才能广播CET)。这给了其中一方不公平的优势。为了解决这个问题,我们引入了一种“缓冲交易”,它将花费注资交易的输出,并产生相同价值(减去手续费)的输出;缓冲交易的输出再作为CET的输入。这样,当我们需要新建合约时,如果某一方不及时撤销前一个合约,另一方可以直接广播新合约的缓冲交易、防止恶意(或误操作的)对手方使用旧合约的CET关闭通道。* K; Q1 z* J1 A# Z
" b2 r1 a. C& y# m+ B; b6 C8 I6 n$ N
    那我们要如何撤销旧的缓冲交易呢?一种办法是借鉴闪电网络,让双方都保存缓冲交易的不同版本。幸运的是,还有另一种更好的解决方案(最早是由这篇论文提出的)。它也依赖于适配器签名,只不过跟常规的DLC利用它的方式不同。每一方都使用三组密钥。第一组是注资密钥,用在注资交易输出的2-of-2输出中。第二组是撤销密钥,每当一个合约被撤销时就公开。最后一组是公示密钥。这三个密钥都用在缓冲交易的输出脚本中,让这个输出有三种不同的花费方式(我们使用“Alice”和“Bob”作为两方的代称):/ K+ ]* A6 l& `* b4 q

2 G4 i6 G* H* X; S( o    使用Alice和Bob双方的注资密钥的签名(用在CET交易中,就像链上DLC一样,必须知道断言机对事件结果的见证才能使用)
8 j1 P% x' X- P( U7 a* m3 H) s9 l9 Z
& @& h* x& g, O& Y: T, T    一个来自Alice注资密钥的签名,以及来自Bob的公示密钥和撤销密钥的签名
$ e/ v& ~3 k9 L4 {+ r8 a; ~' T# O2 m1 D. _+ m- u! _/ ~; r. i5 a
    一个来自Bob注资密钥的签名,以及来自Alice的公示密钥和撤销密钥的签名; b$ k: t2 g4 a+ F! e" R* N
0 l7 X  I5 x; T4 d1 \
    当一个合约在通道中建立的时候,Alice和Bob各给对方一个用于缓冲交易输入的适配器签名,是用对手的公示公钥加密过的。要是其中一人希望广播缓冲交易,TA就要使用自己的公示私钥解密从对方处获得的适配器签名。但是,广播了缓冲交易(其中包含了解密后的签名),TA就向对方揭开了自己的公示私钥(对方已经知道了适配器签名和加密密钥)。如果缓冲交易还未被撤销,那就没有什么问题,他们可以使用某一条CET正当地花费缓冲交易的输出。但如果缓冲交易已经被撤销了,对手方必然就知晓了撤销私钥,因此可以拿走全部的资金。最后,CET带有一个相对时间锁,让被欺诈的一方可以花费已作废的缓冲交易输出。5 h% h0 q4 t) |4 `
2 ^, e" \; ?9 V* M/ {
    -DLC通道的花费条件-
6 w& l9 h% F# X; s
! r1 x/ G+ a* O; f    闪电通道中的DLC
5 m" Z0 \6 ~! `* Q0 x% y5 l
/ s( E; P; ?5 {4 R1 a' y4 X    我们已经解释完了所有的基本模块,现在我们来看看如何在闪电通道中嵌入一个DLC通道。. g# v7 R# a- L" u

4 Y* c2 J5 T; j    第一种明显的思路是在闪电通道的承诺交易中增加一个输出,以形成一个DLC通道。然而,这就意味着,每一次我们更新承诺交易的时候,DLC的所有适配器签名都要重新计算(以及重新验证),这对于拥有大量可能结果的合约来说是非常昂贵的(这个问题可以靠SIGHASH_NOINPUT以及类型的升级修复)。为避免这一点,我们引入了一种“分割交易”。它会花费注资交易的输出并形成两个输出:一个用于闪电通道,一个用于DLC(可以通过增加输入来同时开启多个DLC通道、同时执行多个合约)。为了能够将通道恢复成“标准”的闪电通道,,我们使用跟DLC通道同样的、基于适配器签名的机制,让分割交易变成可撤销的。
! ?0 z' ^& j2 W: d5 V+ o% ]% M/ T  c! u( J: l0 p: N1 Y
    不过,这样一来闪电通道又会出问题。为了让一方能够到欺诈的另一方(广播已被撤销的分割交易)作出反应,分割交易需要带有时间锁以阻止立即花费。但是,闪电网络的规范已经用到了承诺交易的nLockTime和nSequence字段,以指定承诺号。为了解决这个问题,我们在分割交易与闪电通道承诺交易之间插入了一个粘合交易,以实施一个相对时间锁(感谢MattCorallo提出了这个简单的解决方案)。注意,这实际上是一个工程问题,可以通过为承诺交易使用不同的规范来解决(但这将需要闪电网络实现加入更多变更以支持它)。
; O$ l6 \# {& A' ^8 Y, a' N8 O! c( [6 P: @/ ^- r0 }
    总结一下,如果双方有一个直接的闪电网络通道,并希望在其中建立一个DLC,他们可以合作创建并签名分割交易、粘合交易以及更新后的承诺交易(反映双方保留在闪电通道中的资金)、缓冲交易以及DLC的CET。然后,他们就可以在闪电通道中路由支付、在DLC通道中更新和结算DLC合约。如果他们想要关闭DLC通道,他们可以作废分割交易,并合作创建和签名更新后的承诺交易。
9 r/ H2 [* S9 R  N2 E& U2 L( C4 ^2 |4 s
    下图演示了这个交易结构。注意,分割交易和缓冲交易用到了不同的公示和撤销密钥。" d' l' t4 C& n6 a% d

% s1 O( @1 B6 V1 T- D    -在闪电通道中嵌入DLC通道的交易结构-
0 c3 T4 @+ Q. O* g; E) v3 K: o% M; m' D9 q! @; K9 `' d2 a/ l% [
    实现
- q% J$ X& f1 N& k! g0 t9 H
9 |6 F4 R  p! R2 s2 L5 F4 |    上述构造已经在我们的rust-dlc库中实现了,这个库使用了LightningDevelopmentKit(LDK)的一个分叉,加入了对分割闪电通道的特性的支持。我们也实现了一个基于LDK样本的小型命令行工具,除了常规的闪电通道功能,还启用了开启和管理DLC通道的功能。注意,代码还非常不稳定,而且我们要强调,在主网上使用非常有可能导致资金丢失。
8 P5 r- {- @7 E1 ^: v# M7 X7 V& ~; t' R
    主网执行
+ n/ e& h, m  @  u: d' K  d" J# U
% s. f$ O9 ?! x6 X* }7 e7 ^1 N    我们于11月21日在我们的两个启用了闪电网络的节点中开启了一条通道,注资交易是这一笔。然后,我们从开启通道的节点给另一个节点发送了一笔keysend支付(等到LDK实现了双向注资的时候,就不必执行这一步了)。我们定义了一个基于比特币在11月21日下午4点(JST)的价格的DLC,并在闪电通道中开启了一条DLC通道。在这个合约到期时,我们让其中一个节点强制关闭通道。这个节点先是广播了分割交易(见此处)。分割交易得到确认的288个区块(缓冲交易和粘合交易的nSequense数值)之后,我们让这个节点广播缓冲交易和粘合交易(见此处和此处),以及本地的承诺交易(见此处)。缓冲交易得到确认的288个区块之后,节点获得了断言机对结果的签名,从而解密了另一方对相应结果的适配器签名,然后广播一笔CET,结束了这个DLC(见此处)。  l) i; P8 f0 j8 n" t0 O; C$ [

) m/ ?, k6 X0 F0 X  M    结论7 |: b& k  C9 W) c- {" J! j+ f" j

8 _2 a3 a5 L4 H# w0 O$ ], k    可以在闪电通道中开启DLC的能力,开启了一些很棒的应用,例如将部分通道的价值与其它货币挂钩、使用通道中的资金交易一些衍生品合约(同时无需放弃资产托管),甚至可以直接跟朋友打赌球赛的胜负。在rust-dlc库中实现功能支持,并通过在闪电通道中执行和关闭DLC演示了器用途,我们已经证明了我们提出的方法的可行性。要分析和优化这个提议并强化这个实现,还有非常多工作要做。所以,如果你有兴趣贡献一份力量或使用这种技术,甚至仅仅是想了解更多,都欢迎联系我们!
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

落日余晖97 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    22