Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文

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

fzny61226
58 0 0
###什么是广义状态通道?
$ d8 D* \; T- L( ^2 c) N8 k  v9 I: E, I
广义状态通道的意思是,用户可以用同一个通道做多种不同的事情。
- W$ C/ }1 E4 l3 |; U$ Q3 F5 r1 ]6 u* I: z! ]; z
###广义状态通道有何意义?
/ [8 i2 T6 g; w) V( r
& U6 L6 ]9 x6 @. F+ _4 F( f没有状态通道,任何以太坊上的 App 都必须承担高额手续费,忍受延迟,因为 App 高度依赖于链上交易。使用 App 定制型状态通道,我们可以创建更经济更高效的 App ,用户只要在启动和关闭 App 时支付就可以了。广义状态通道更进一步地改善了这种情况,用户只需要在关闭 App 时支付。
/ |: J8 `! u6 Q( S7 U! B' O3 U7 K1 ^$ F# v3 w8 }$ y  V  L# N5 h
注意:当我说“支付”的时候,我的意思是向链上提交交易。. F3 O/ S8 Z2 Y/ _& s; N" F

/ Z* H# l8 j* L, [###广义状态通道
/ j* e0 Y( c$ s( T: m2 b7 D& e: g2 ?" Q
在技术上,要开启广义状态通道,所需要求与 App 定制型状态通道一般无二:一个足够强大的多签钱包就足够了,参与者用于锁住状态。区别在于,用户无需为每一个应用都“安装”链上组件——即便要使用多个应用,该多签钱包也将是用户所需的唯一链上组件。; `; I! P& g" a0 Z2 X" q
$ t* v5 }8 P+ z( A/ b6 z: r" u# x
App 定制型状态通道(回顾)! X/ P0 T4 F. {' W
- X! s& ]# M+ J1 T* r- g. }
鉴于在部署链上组件这一点上差别极大,我们先回顾一下我们在前面的文章中讲到的内容。在前文中,我们遵循下列步骤在多方间打开一个 App 定制型状态通道:
# N8 L- u# _9 z, u6 N: S4 h; p% G# m
" V  q8 [4 U2 ^" S* i  |1 K& U( U与相关方一起,部署一个多签钱包,把规则集(用来解析发送给钱包的交易)加到链上。
% z& t. M3 O$ T3 q) R' h
) b; C, A0 S* O0 x' B) T在他们进行不同的操作时,在参与者之间广播已签名的消息。
. J4 |/ h, g* L( B4 r' G: b5 X( l* ^" l) u. O
当参与者准备好开启或退出通道时,他们会把所有参与者签名的最新状态提交到多签钱包,多签钱包根据内置的规则集,决定如何在参与者之间分钱。6 u6 }. F) h' P+ S
! U0 m$ [# w* P  ]( X
这种配置看起来就是下图的样子:" Y- B/ y: c  A9 ?/ i: M# {" P
3 D4 q6 L) g5 \& t# V; V6 K5 c
-在任何时候,Bob 和 Alice 都可以把双方都签过名最新状态提交到多签钱包,来配置通道。-) c: Y! a: ]# ?# v: q' y) S, Z

- G8 v: x/ _  N注意,上述过程所用的多签钱包只支持符合其内置规则集的 App 。再次强调,广义状态通道通过“反事实实例化(Counterfactual Instantiation)”扩展了 App 定制型状态通道的功能:允许新的 App 安装在现有的状态通道中。
1 K  Y. j: m3 ], l2 i( ]; h% e5 |0 N/ M6 K* o5 n
###反事实实例化
9 C9 A* M: D! ?: ?: ^! W8 T. `. C* q1 J7 M! Z( X
反事实实例化是一个通道内成员同意接受链下智能合约约束过程。这是一个比较奇怪的概念,因为它意味着“链下代码即法律”(给 Liam Horne 点小费吧,这是他提出的),一下是一个简单的例子:
) W" n& R; H1 G: E" P. o! V
; ~1 g' V) t2 ?, w" ~, BSo Easy (作者你是认真的吗?)-- \/ @  a% n1 l, j

9 o" W! q% }7 c: I. s5 [$ G要创建广义状态通道,我们唯一需要的就是一个多签钱包。我跟阿剑各往钱包了存了 5ETH,并且决定要在我们之间创建一个支付通道。所以,我们在链下创建了一个支付通道,并且都对合约代码签过了名,同意在关闭通道时部署它。我们同样也对基于已部署的支付通道的最终状态、发往多签钱包的条件支付请求签了名。6 H  v; I, D' O9 ?$ K8 I8 `
* e; T6 y4 N# Q- ~" d
那么,使用同样的方式——所有参与者都签名,我们不仅能保证状态的可信,也能保证代码的可信。所以,只要我们都签署了代码,我们就可以像该代码已在链上部署的那样,放心地签署相关的状态。两种方式最主要的不同就是,我们只需要在想要结算状态通道时部署代码。
8 z. n, i5 I% F! m7 q7 k4 I% H" T2 g2 o* A- k
那么,当我们想结算时的时候,我们需要:# N% _  M2 [* l9 Y* R; M% _
- e9 g$ t7 Y: C. ?( q7 q
部署支付通道合约
* v% L; L+ O2 @. d* B& _, X% o# l$ V6 ^( ~3 E- }. S8 f, ^: d! e) \
向该合约提交所有参与者签名的最新状态
3 e( j& d9 y6 g; u, F4 h
: u2 o$ `/ T6 t# a(基于支付通道的余额)将条件支付请求提交给多签钱包
' V) _* c: m" W* [# r$ j2 `5 Q! r; F# ^9 ]( a% X, i9 T' x0 B3 g
多签钱包给各参与方支付& N9 h4 \. b: G. \7 [
* x) Y* W- _  _$ x2 o0 U
那么,反事实实例化使我们可以假设链下代码已经被部署到了链上,并据此行动;因为我们可以在任何时候部署上链并提交最新状态。但是,这就有个问题——我们如何在没有链上地址的情况下签署状态转换?这就是注册合约的用武之地!8 @0 u9 v( W+ |! @
. ^: Q8 a4 I- L2 k+ F' L
###注册
$ T+ F1 T; s/ Z
8 L& a$ \1 e% H从比较抽象的层面上讲,注册器智能合约允许我们做以下操作:, {" j& L) I; o3 A6 t9 U; V1 O

" C4 _5 X( ?$ g基于合约字节码,创建一个链下地址(cfAddress)# {: h( Y) c4 B/ l& l9 N* a" i2 N4 v

; s! e# y: H3 I$ h/ w3 K7 @部署智能合约,并把 cfAddress 和链上地址进行映射
; \3 ^5 F  g: j$ M3 L; |# t# [# k/ [, E' G
通过 cfAddress 执行链上合约代理调用2 x6 Y6 Q1 w8 m! p0 F& `

- [" v; G" }2 a/ R" q  t) v注册合约伪代码:# D. s/ h: k4 z' f( q8 E, p: W

. X0 @/ e0 H% C) A* mcontract Registry {! a6 p- r( n/ q% R/ P6 ~" G
$ I9 G! a" L9 i1 L7 {% n6 {6 x/ U
  mapping(bytes32 => address) resolver;# V0 h8 F: P7 \+ V+ d

: x7 ]) B: X, E7 y- y4 U  function cfAddress(bytes code) returns (bytes32) { ... }
, z% v+ X( m) g/ C  w
. K% H4 k+ o$ P0 o0 B- ^; P  function deploy(bytes code) { ... }
2 s1 n( t3 E) p7 s5 D0 t
$ a' X9 y& o' T, B  function proxyCall(Registry r, bytes32 addr, bytes data) { ... }
0 ?; m9 g2 ^0 S* q* a
. m, d2 L) y9 x; i- |" c. F' Z}9 K, ~, E: `4 u* }
" @9 Q/ K9 w1 y( B/ R: Y3 t& a- B; t2 ~& h
所以,如果你想部署一个合约,你需要用交易调用 deploy 函数,并以合约的 initcode(初始码)作为参数(一般来说,它是与 ABI 编码的构造函数参数连接的合约构造函数字节码)。这个函数把智能合约部署到链上,并且把合约地址加到注册映射表中。
3 ]6 w) v/ C* o* N% g% x- E' F$ Q$ A0 Q) Y1 H& X/ g: q9 k, R
以这种方式,你可以通过注册表中的解析器创建相互引用并互相依赖的链下合约。那么,要是想让我们上述例子中的通道运行起来,我们就得通过注册合约来部署支付通道,在多签钱包的条件支付中解析出支付通道的地址。
' x3 {; @; W# A( k6 C
6 y, m) U6 n) y###依赖3 }9 q3 h4 J( F: Z( ~- j

! k) L* f+ c/ r5 j8 g- Y; Y注册合约允许我们做的就是可以建立互相依赖的链下合约,就像合约 A 依赖于合约 B,只有在 B 最终确定之后,A 才能确定(条件层级确定性)。
! O- U! h, L8 b
# o7 @+ _" j: S; n0 G5 @-以上我们可以看到,除非 Nonce 合约确定了,否则 PC 合约无法确定。-& ]  E# B3 o& {; v( \/ a; l0 a+ g+ m
8 J  i7 `" N, k! N- b
你看,上面是一个比较基础的例子,我们要求当前合约基于另一个合约的布尔条件值。我们可以扩展这个条件,允许所谓的“原子状态转换”。
+ j5 q) S- h' B- D) b. ^6 q  }& f
! h/ C7 o  r9 V+ o0 z###原子状态转换" a1 o7 F" E6 z  ~, ]
; D+ R' }% E/ E0 x7 o! k0 E7 y& I- ~3 A
根据这种层级的依赖结构,我们可以进行原子状态转换,转换的同时,伴随着一些合约生效,一些合约失效。下面例子表明,一个 10 ETH 的支付通道,基于 nonce 值,转换为一个 8 ETH 的支付通道,加一个 2 ETH 的扑克游戏。
8 b8 d1 k3 L# Y* z" {; s* y: o) V# l/ l6 J/ w
-合约的有效性基于 nonce 值-
3 g6 M  g" Y1 d8 a+ o( |4 G0 ?" j% S/ I# {6 Q( ^* g8 {, c* a
如果支付通道的双方都同意用支付通道里的 2 ETH 来创建一个扑克游戏,他们可以签署支付通道的余额更新变化,从(5,5)到(4,4),同时签署一个内置 2 ETH 的扑克合约,nonce 合约的 nonce 值是 4 的时候,这两个合约才会生效。
- Z% B- d6 {% s9 P
! F5 c) T; f! Y. O-基于新 nonce 值的原子状态转换-+ Q5 e, s) t- p+ K7 u
7 L6 y. z* W- q
当支付通道的双方都签署了支付通道和扑克合约的条件更新之后,他们可以签署 nonce 合约,使得 nonce 值加 1。一旦 nonce 值更新为 4,旧的支付通道状态就会失效,同时扑克合约和新的支付通道状态就会生效。( V5 U7 Z* @/ E! {+ [

8 [4 [1 U: z' |- w9 ]0 ?有原子状态转换,代码升级就会变得容易。如果之前支付通道的参与双方想修复代码中的 bug,他们可以在更新余额的时候修复代码。当更新 nonce 值后,之前有 bug 的代码就失效了。
! n& X" a/ J, f8 C: u) E7 H. L+ W! c* k3 E4 M
下面有个例子,这就是基于“根 nonce”合约的一系列反事实合约:
8 p& e7 ^6 \& ^1 g+ W" W
6 i; }8 U4 y4 \2 p: O0 @根据这种架构,我们可以通过一个“根 nonce”合约有条件地更新所有链下合约的有效性。这允许我们可以根据参与方的需求,迭代地从状态通道中添加和删除链下合约。
$ x/ D, j- j7 a, \  Y% O
! l! u. P6 K7 h  x. ~配置通道* Q) X8 x- \2 [9 b2 C
) x7 [' G) [1 S5 Z3 y! V  |. K+ s
假设我和阿剑想玩四子连珠的游戏。我们将会这样做:: P' i9 p9 z9 P

# i* n$ ~* i, x3 P部署根 nonce 合约、ETH 支付通道(PC)、ETH 条件支付通道(CPC)和四子连珠智能合约7 u8 }6 @2 K+ K/ e# u

' I9 T4 X9 ]  ]9 ?3 d8 x7 g+ m向四子连珠游戏提交最新的签过名的状态
7 N, i" P! p# {# X$ ?0 }( |' |; q" v, u: u" y& m) x( h
基于四子连珠的游戏规则确定 CPC
3 \) C  \2 M) E$ k
- O7 u& N% ]7 a基于 CPC 确定 PC" {& L( U% w# S) j

7 c- a: l" A1 d5 e- d2 x向多签钱包提交已签名的条件支付(基于 PC 的最终确定状态进行支付)% {/ x" M; ]; c+ T6 p
: P: ~4 K1 l0 p. q$ F
因此,我们可以一直开启其他状态通道,甚至允许我们重用已经部署在链上的四子连珠游戏的代码。下一次我们想要玩游戏的时候,我们只需要对游戏状态进行签名,然后提交到已经部署好的智能合约上。唯一需要实现的是取消现有链上代码的确定性,这是一个实现细节。
6 a$ [/ F) C, Q2 Y. G( n/ k9 [% M. r; f! t- Q
###注意:你不需要像我展示的四子连珠、CPC 和 PC一样,为你的合约加上这么多的依赖。无论你希望怎么做,这都取决于你和你状态通道中的伙伴。/ ]! [& a  e) f( `; Y& ^
7 Z+ {0 ?& F7 v9 D9 C$ ]' E
现在,假设阿剑的朋友 Hunter 想跟阿剑玩四子连珠游戏,但是他只跟我开了一个状态通道,这时候 Metachannels 就可以派上用场啦。
% [5 f; y' X* }. b
$ y+ m7 I7 |% Y###Metachannels
% ?! Z; b9 n7 }' }1 X! P3 n5 `/ h% a. W/ j# J  n
Metachannels 是状态通道上的虚拟通道(参见本系列 Part-4)。要创建一个 Metachannels,你需要两个想交互的参与者,他们各自有一个状态通道,并且通道的另一方是同一个人。两个参与者同意创建一个新的合约,通道另一方(即共同的中心)会与他们一起创建一个代理合约,指向两个参与者的新合约。看起来就像下面这张图:9 p: G- q" F' Z- z6 Z4 ^1 f
) _% M) }: p$ f' R% ^
-广义虚拟状态通道 = Metachannels !-
' f- a# J9 ]! h. W8 c+ F0 _% N  N" m* j3 b8 m
我们可以无限地扩展这个模型,让我们想跟谁玩四子连珠,就能跟谁玩。3 X8 ]' ~" ^& Z$ H& u( O
0 O+ Y- W3 o: _; I
###广义状态通道的优点
6 o, L2 P! T/ Y, a; z
# w. [, a8 ?, ]/ e2 \引导——因为我们所需要的只有一个多签钱包,我们可以很容易在链上现有的多签钱包中选择一个开始开发。& T+ ~8 i$ [4 p) W& w, `
- o8 S, D6 B  T
隐私——除了参与者之外,没有人知道状态通道内发生了什么,对于外部世界来讲,参与者之间只有一个多签钱包。$ e2 b) l2 Q9 w- Y% {" B
) @  q3 U( O: Q
可升级——如果链下代码中有 bug,所有参与者可以通过链下的操作修复 bug,不需要进行任何链上操作。
7 R: E; X9 ?2 v5 _+ W$ `. R- d, H3 z, \$ J# t
可重用——这种方法有效地鼓励了通用链上库的形成,让所有状态通道都可以引用。# `. g; I  l8 E/ @# e5 E9 l( z

, X: ]- R5 Q( [' Z* A$ S###Part-6:反讹诈6 }5 U0 l! R3 r1 D. b

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

本版积分规则

成为第一个吐槽的人

fzny61226 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    22