Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文

菜鸟学习状态通道 广义状态通道

fzny61226
62 0 0
###什么是广义状态通道?
1 a/ Z4 y. ]9 p% D
4 _1 ^- J- d- D广义状态通道的意思是,用户可以用同一个通道做多种不同的事情。
% X8 R5 `  n" x( g3 w: [' Q4 y# z: u& i4 r: y
###广义状态通道有何意义?
0 o1 g6 q# z2 ]4 o) b) \2 R3 ?
6 N' i% r1 d: F# H# c9 P没有状态通道,任何以太坊上的 App 都必须承担高额手续费,忍受延迟,因为 App 高度依赖于链上交易。使用 App 定制型状态通道,我们可以创建更经济更高效的 App ,用户只要在启动和关闭 App 时支付就可以了。广义状态通道更进一步地改善了这种情况,用户只需要在关闭 App 时支付。& w4 Z2 t! l7 y/ y2 B
2 k1 ?0 t6 |0 C+ a- D
注意:当我说“支付”的时候,我的意思是向链上提交交易。
2 k/ e- K+ u. N+ z
! Y0 W' P' F( B* k; H###广义状态通道' }7 g+ p* X, o8 ^/ g) I3 _) o7 A

6 P3 r! p- H/ H# g" o  S在技术上,要开启广义状态通道,所需要求与 App 定制型状态通道一般无二:一个足够强大的多签钱包就足够了,参与者用于锁住状态。区别在于,用户无需为每一个应用都“安装”链上组件——即便要使用多个应用,该多签钱包也将是用户所需的唯一链上组件。
0 C* d4 l9 u: y" ]4 y; R$ _5 n3 W# \3 @) w" d- H( I. V
App 定制型状态通道(回顾)
0 P$ V4 @. r- ^  C& Y
5 h8 l8 x2 Z; S鉴于在部署链上组件这一点上差别极大,我们先回顾一下我们在前面的文章中讲到的内容。在前文中,我们遵循下列步骤在多方间打开一个 App 定制型状态通道:
5 M$ q% v8 q0 U" i1 L& w4 ]* u, L/ z; l
与相关方一起,部署一个多签钱包,把规则集(用来解析发送给钱包的交易)加到链上。$ l3 X# c: t& g* a: L) k8 ^

4 z0 _! M. b- A在他们进行不同的操作时,在参与者之间广播已签名的消息。3 R+ _8 n$ @- J& x9 j$ |6 q

- W, I7 [  H7 Q' M. x8 l当参与者准备好开启或退出通道时,他们会把所有参与者签名的最新状态提交到多签钱包,多签钱包根据内置的规则集,决定如何在参与者之间分钱。
6 W7 C; }, y# ~- ~/ n/ L: @8 P6 B& k  ^9 L' a4 x" N  G( t
这种配置看起来就是下图的样子:! X3 Q" o1 J3 t  m* H) O

  l; u& a8 _$ u- p  e: b. a-在任何时候,Bob 和 Alice 都可以把双方都签过名最新状态提交到多签钱包,来配置通道。-) v8 p5 `+ s, ]7 t  X' b, U5 h

$ E3 o% B2 @) a3 W% z& b# Z注意,上述过程所用的多签钱包只支持符合其内置规则集的 App 。再次强调,广义状态通道通过“反事实实例化(Counterfactual Instantiation)”扩展了 App 定制型状态通道的功能:允许新的 App 安装在现有的状态通道中。+ t1 o  ?- B$ Z. w
" a( u7 H  @$ R' t6 q8 N1 ?/ Z+ S
###反事实实例化
$ O4 a' U1 Q) d( P  y( i1 c' C1 x. ^9 J3 |% n
反事实实例化是一个通道内成员同意接受链下智能合约约束过程。这是一个比较奇怪的概念,因为它意味着“链下代码即法律”(给 Liam Horne 点小费吧,这是他提出的),一下是一个简单的例子:
8 y. s. v, Z( |# n
1 [  c8 T) o/ x2 n2 m$ CSo Easy (作者你是认真的吗?)-
8 h# I% A; _/ q' Q- ^
4 ~% V, Q0 N: z& K要创建广义状态通道,我们唯一需要的就是一个多签钱包。我跟阿剑各往钱包了存了 5ETH,并且决定要在我们之间创建一个支付通道。所以,我们在链下创建了一个支付通道,并且都对合约代码签过了名,同意在关闭通道时部署它。我们同样也对基于已部署的支付通道的最终状态、发往多签钱包的条件支付请求签了名。
1 @& z. \0 @2 z. S7 r) p$ r4 }9 o/ Z
0 u; R3 ?1 v# l( H. \* ?那么,使用同样的方式——所有参与者都签名,我们不仅能保证状态的可信,也能保证代码的可信。所以,只要我们都签署了代码,我们就可以像该代码已在链上部署的那样,放心地签署相关的状态。两种方式最主要的不同就是,我们只需要在想要结算状态通道时部署代码。
$ p# T; N/ q4 K% L5 i; x3 y( u0 O7 u0 F
那么,当我们想结算时的时候,我们需要:
) I: Z: f3 U/ z6 x/ C3 V! o7 t
& L! O, N/ |' Y0 X) R部署支付通道合约/ ?" X$ G6 o: F* G
! C" F6 a$ q: `/ f* b6 W1 Q$ f; F
向该合约提交所有参与者签名的最新状态! v# l# d; }) a0 w* a& C8 t( c) O+ I7 s
- i; [) k8 n  x3 S5 W- u
(基于支付通道的余额)将条件支付请求提交给多签钱包
9 P  s+ F& K+ F' k& e% M$ V. X$ b8 ~& y4 o  z
多签钱包给各参与方支付; ]; g0 x& v3 [& B5 Y# ]) M8 h7 `

+ h1 h% O) v4 J+ r8 g0 S那么,反事实实例化使我们可以假设链下代码已经被部署到了链上,并据此行动;因为我们可以在任何时候部署上链并提交最新状态。但是,这就有个问题——我们如何在没有链上地址的情况下签署状态转换?这就是注册合约的用武之地!6 K) Z7 c5 H( v5 r9 n

7 f: @. ~+ ^+ U6 H: W###注册: S% F; a1 a: t: I5 r
. C: |" ^. f2 V1 S' K- i
从比较抽象的层面上讲,注册器智能合约允许我们做以下操作:- _4 b2 }% J* Q& W" |- Q
- k2 x' b& W, [" y. K, T) I3 A
基于合约字节码,创建一个链下地址(cfAddress)# c4 m6 m3 ~+ _6 j( T  r7 i$ Y
0 r9 c# _2 I) \1 ]2 E2 z) U
部署智能合约,并把 cfAddress 和链上地址进行映射7 |& m. i- t2 `  ?! \6 e0 B

# V9 p  U$ j. |, L% ^5 N1 M通过 cfAddress 执行链上合约代理调用" n+ ?/ e" T, O) A
" r0 q) S  @* f7 @# y# {7 d4 A
注册合约伪代码:( a) G4 y2 v: }9 \* \
  i" k- o/ g! ]: l# }3 j
contract Registry {
: u0 m2 R% Q) W2 Q9 J8 h' J, k: O" V$ @4 [% D1 ]8 S
  mapping(bytes32 => address) resolver;
' c+ V; E- D8 L9 K7 I8 ?  g
) G& t6 }! z2 K& Q3 z  function cfAddress(bytes code) returns (bytes32) { ... }
- k" Y% g  e# `2 Y3 P: A% k
* w% f& y, _: E3 j  ]  function deploy(bytes code) { ... }% R. ^- l' _9 p  O, X; t
/ c9 J0 L) B2 k# z: K" }& ^
  function proxyCall(Registry r, bytes32 addr, bytes data) { ... }; t" R& P+ ]% |! m9 m$ R7 q; H
/ I# K2 o! t0 X+ ]. r2 \
}+ y, k+ n/ j4 X3 Y  A9 F
3 r9 _  z) a4 x' e$ M! N/ m( M
所以,如果你想部署一个合约,你需要用交易调用 deploy 函数,并以合约的 initcode(初始码)作为参数(一般来说,它是与 ABI 编码的构造函数参数连接的合约构造函数字节码)。这个函数把智能合约部署到链上,并且把合约地址加到注册映射表中。; T9 g: j7 @% T# _7 b
$ N' s2 a3 @3 u# c( s
以这种方式,你可以通过注册表中的解析器创建相互引用并互相依赖的链下合约。那么,要是想让我们上述例子中的通道运行起来,我们就得通过注册合约来部署支付通道,在多签钱包的条件支付中解析出支付通道的地址。
+ t7 o3 W/ X* @4 P/ h" Z: ]) t6 z, V! \. h" Q
###依赖0 }5 }( z# p9 Z) X

; t: _. r7 u  Q* C注册合约允许我们做的就是可以建立互相依赖的链下合约,就像合约 A 依赖于合约 B,只有在 B 最终确定之后,A 才能确定(条件层级确定性)。' ~" [9 y1 X- D7 W. _
6 u3 ?9 N# r& G$ p
-以上我们可以看到,除非 Nonce 合约确定了,否则 PC 合约无法确定。-
4 m- o+ E1 I% e, Q7 d, G5 k9 g7 t# O/ q- Y1 x6 k4 N
你看,上面是一个比较基础的例子,我们要求当前合约基于另一个合约的布尔条件值。我们可以扩展这个条件,允许所谓的“原子状态转换”。
6 n9 Y8 W8 Y! d( w3 i5 ?7 O
; C1 G" [# M% A###原子状态转换, X1 Q9 c! h6 B3 T2 T0 e, I# E
2 y" [" r2 D# r% m4 X
根据这种层级的依赖结构,我们可以进行原子状态转换,转换的同时,伴随着一些合约生效,一些合约失效。下面例子表明,一个 10 ETH 的支付通道,基于 nonce 值,转换为一个 8 ETH 的支付通道,加一个 2 ETH 的扑克游戏。
3 D1 |& |- o; V& M' f( D
+ q- F$ m9 w6 @" f; y4 I-合约的有效性基于 nonce 值-" p9 [) Z  t6 F% N! G( b1 X

& L! P% y, B/ h# x9 J7 d% n: U# Y如果支付通道的双方都同意用支付通道里的 2 ETH 来创建一个扑克游戏,他们可以签署支付通道的余额更新变化,从(5,5)到(4,4),同时签署一个内置 2 ETH 的扑克合约,nonce 合约的 nonce 值是 4 的时候,这两个合约才会生效。- }- B: o" Z+ B3 U$ V- k. `

( K+ B9 |' {& G) S3 O# ~-基于新 nonce 值的原子状态转换-7 m3 ^/ ~: o% @; v
( b  O8 @; O6 z* ~" u+ G
当支付通道的双方都签署了支付通道和扑克合约的条件更新之后,他们可以签署 nonce 合约,使得 nonce 值加 1。一旦 nonce 值更新为 4,旧的支付通道状态就会失效,同时扑克合约和新的支付通道状态就会生效。! P4 t- X/ y% C
" H; E  t5 X3 ^( u
有原子状态转换,代码升级就会变得容易。如果之前支付通道的参与双方想修复代码中的 bug,他们可以在更新余额的时候修复代码。当更新 nonce 值后,之前有 bug 的代码就失效了。, X, V8 z7 N; V

5 N1 M8 L; o8 i4 y5 t% q3 S下面有个例子,这就是基于“根 nonce”合约的一系列反事实合约:! R# N* m: H' p  r% `
6 T( ?4 _* P9 [5 `2 X  ]8 ^! A
根据这种架构,我们可以通过一个“根 nonce”合约有条件地更新所有链下合约的有效性。这允许我们可以根据参与方的需求,迭代地从状态通道中添加和删除链下合约。, y) |" c( R% T/ S% @0 g
; Q% W- j1 g: n; H/ T: d( I+ ~! e. R4 [
配置通道8 F* W/ E: i  k% z) ^

* }( C; ^9 I) b假设我和阿剑想玩四子连珠的游戏。我们将会这样做:
+ w5 W; H4 F/ V: c0 G( Z. m2 w6 V& u, U: S3 i6 p
部署根 nonce 合约、ETH 支付通道(PC)、ETH 条件支付通道(CPC)和四子连珠智能合约5 R" g8 ]0 L( {4 Z

* Y) l) j5 a' }) e4 {5 P0 u! f  k向四子连珠游戏提交最新的签过名的状态
9 P- s: T$ g8 q  t+ {- y
) K; Q& d, X  V9 ]0 q基于四子连珠的游戏规则确定 CPC/ C' A; V: A. K; f+ }3 Q
- i& }% G, i3 {4 Z' ^
基于 CPC 确定 PC
6 I* d( Y7 R: H% X; B9 ^
4 Y9 }8 @5 z6 Q% F1 m向多签钱包提交已签名的条件支付(基于 PC 的最终确定状态进行支付)
$ j+ p- U3 O& B. z, j* r+ v$ |  ]4 x
. _1 m1 w! d* E; G- K因此,我们可以一直开启其他状态通道,甚至允许我们重用已经部署在链上的四子连珠游戏的代码。下一次我们想要玩游戏的时候,我们只需要对游戏状态进行签名,然后提交到已经部署好的智能合约上。唯一需要实现的是取消现有链上代码的确定性,这是一个实现细节。
' w3 K- D4 ?: M
9 @5 r  |4 }$ W" X. d& y: g9 ?###注意:你不需要像我展示的四子连珠、CPC 和 PC一样,为你的合约加上这么多的依赖。无论你希望怎么做,这都取决于你和你状态通道中的伙伴。/ V& R0 R; \3 }; Z- Z9 ?3 ~

' ?) L+ C8 K! y现在,假设阿剑的朋友 Hunter 想跟阿剑玩四子连珠游戏,但是他只跟我开了一个状态通道,这时候 Metachannels 就可以派上用场啦。& C7 k& V# D8 Y3 e6 X2 t2 @) B3 \  }5 R

2 M6 T9 C" I+ V* @- H! e###Metachannels5 K& f- K8 G$ ]: }2 D$ m

+ [7 J' g0 \& [, L! B7 {( A8 XMetachannels 是状态通道上的虚拟通道(参见本系列 Part-4)。要创建一个 Metachannels,你需要两个想交互的参与者,他们各自有一个状态通道,并且通道的另一方是同一个人。两个参与者同意创建一个新的合约,通道另一方(即共同的中心)会与他们一起创建一个代理合约,指向两个参与者的新合约。看起来就像下面这张图:3 ~5 @* r8 E4 v2 v+ }6 |

! e& O. _. J7 Z. n' e7 Z-广义虚拟状态通道 = Metachannels !-
: b' I+ ~2 B" x& l7 v, n
* N; ?; `/ W0 ^% k' Q我们可以无限地扩展这个模型,让我们想跟谁玩四子连珠,就能跟谁玩。
' F: n8 i8 ?+ c# {( H8 s: r; I
###广义状态通道的优点0 S: e. C2 O# p5 _6 F) W* o" ]* M
1 c8 C9 b. N. _$ K& S
引导——因为我们所需要的只有一个多签钱包,我们可以很容易在链上现有的多签钱包中选择一个开始开发。! Y7 A* E. x5 C; \6 y

" `9 m) |3 [' p* G- G隐私——除了参与者之外,没有人知道状态通道内发生了什么,对于外部世界来讲,参与者之间只有一个多签钱包。# `( q# @- ^! [. s" `, C1 [; u

: y. F# E/ S# G# [6 Y可升级——如果链下代码中有 bug,所有参与者可以通过链下的操作修复 bug,不需要进行任何链上操作。
/ h! R, `; W$ I, o" _6 b% \- v& g& A3 s( y' Q) O- X. k+ c% n1 F
可重用——这种方法有效地鼓励了通用链上库的形成,让所有状态通道都可以引用。0 E8 R! c/ _$ l
# K' b9 z7 M' N: |: P4 D
###Part-6:反讹诈- v5 h$ z" \" E8 T

% F8 S0 H/ {  y在我下一篇博文中,我将会深入讲解状态通道中的反讹诈。讹诈即是说参与者向通道提交一个对自己更有利的较早状态。博文的焦点是 Pisa.
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

fzny61226 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    22