Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文

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

fzny61226
42 0 0
###什么是广义状态通道?
; ?  _1 a  V+ ~
& X1 b. v; L% b/ E# _$ n广义状态通道的意思是,用户可以用同一个通道做多种不同的事情。, a8 A. L6 R0 [: Z8 e: V. r

6 {6 z, t5 p! K$ V7 W###广义状态通道有何意义?
* ^1 j8 \2 R2 _; F7 ^' N. |# B
  u) ?0 `( [" s0 p+ j没有状态通道,任何以太坊上的 App 都必须承担高额手续费,忍受延迟,因为 App 高度依赖于链上交易。使用 App 定制型状态通道,我们可以创建更经济更高效的 App ,用户只要在启动和关闭 App 时支付就可以了。广义状态通道更进一步地改善了这种情况,用户只需要在关闭 App 时支付。1 Q+ \1 I7 |2 v; u3 P/ T
% q" g$ `' {. _4 F! v
注意:当我说“支付”的时候,我的意思是向链上提交交易。( F* E( {/ e: C8 Q  }! `

0 s- Q0 t# }$ t4 j###广义状态通道9 l* f( v1 L2 l& H8 E. E9 D
  ?* [. d; ^( {7 H- t
在技术上,要开启广义状态通道,所需要求与 App 定制型状态通道一般无二:一个足够强大的多签钱包就足够了,参与者用于锁住状态。区别在于,用户无需为每一个应用都“安装”链上组件——即便要使用多个应用,该多签钱包也将是用户所需的唯一链上组件。
& Q& d" O; |& H8 j: f8 p
: b& @  b. j5 I; [; HApp 定制型状态通道(回顾)
  U% x" v, p/ X, L3 N8 `% d0 H+ n- w; V; v6 w5 b
鉴于在部署链上组件这一点上差别极大,我们先回顾一下我们在前面的文章中讲到的内容。在前文中,我们遵循下列步骤在多方间打开一个 App 定制型状态通道:1 i& t0 `  A! R+ B8 O
( Y' B' ^. v: c( z9 M& @
与相关方一起,部署一个多签钱包,把规则集(用来解析发送给钱包的交易)加到链上。' Q8 {+ l- K& ]! s
8 x. b6 F: V# [* \5 ^
在他们进行不同的操作时,在参与者之间广播已签名的消息。
! t' X& g, v: `5 G3 g+ ?+ R9 l  `0 q3 i! }
当参与者准备好开启或退出通道时,他们会把所有参与者签名的最新状态提交到多签钱包,多签钱包根据内置的规则集,决定如何在参与者之间分钱。3 `) @1 W0 O, Q" c0 Q( d2 a4 x
9 T" e" A; a7 M/ f( N
这种配置看起来就是下图的样子:
' \, Z3 X# Z4 I2 r& e- S# d
7 y( o4 S# i  |# g" h- N% S-在任何时候,Bob 和 Alice 都可以把双方都签过名最新状态提交到多签钱包,来配置通道。-5 d* ~$ I# b$ r# Q
$ Y& t" u# W' L, V* r
注意,上述过程所用的多签钱包只支持符合其内置规则集的 App 。再次强调,广义状态通道通过“反事实实例化(Counterfactual Instantiation)”扩展了 App 定制型状态通道的功能:允许新的 App 安装在现有的状态通道中。
. ]6 \4 ~0 |( X; [
4 S  w/ ~, a( @4 M2 ]) @( t###反事实实例化
- @& `+ {( U: W" q! K
, e4 H9 U/ d9 v2 Y6 a反事实实例化是一个通道内成员同意接受链下智能合约约束过程。这是一个比较奇怪的概念,因为它意味着“链下代码即法律”(给 Liam Horne 点小费吧,这是他提出的),一下是一个简单的例子:1 y$ J7 u- V# X1 U6 J

8 n$ [9 m* m- L6 O, aSo Easy (作者你是认真的吗?)-% G4 H! ~8 K0 f! Y3 k, `: b6 Y

/ [8 Y1 w+ l5 B6 S0 x要创建广义状态通道,我们唯一需要的就是一个多签钱包。我跟阿剑各往钱包了存了 5ETH,并且决定要在我们之间创建一个支付通道。所以,我们在链下创建了一个支付通道,并且都对合约代码签过了名,同意在关闭通道时部署它。我们同样也对基于已部署的支付通道的最终状态、发往多签钱包的条件支付请求签了名。
' M3 I9 x2 b. g" r+ l1 J) I1 t/ z4 P& d( x: W7 O
那么,使用同样的方式——所有参与者都签名,我们不仅能保证状态的可信,也能保证代码的可信。所以,只要我们都签署了代码,我们就可以像该代码已在链上部署的那样,放心地签署相关的状态。两种方式最主要的不同就是,我们只需要在想要结算状态通道时部署代码。% w+ P; D2 ]0 h  B& C9 D$ l: d% Q

8 u* E5 j1 W8 |, v那么,当我们想结算时的时候,我们需要:1 e- j3 p2 @$ c) p- F- Z

  A% `! K2 v4 L* p" ?4 Z部署支付通道合约
6 q, t1 O# R1 o! R  K( r& M. G( V! d' p; R1 `' ^; C. [/ Z2 \0 ]! o
向该合约提交所有参与者签名的最新状态
$ `2 T/ Q% B; k2 z& C- C3 x1 z, m# f8 H8 y
(基于支付通道的余额)将条件支付请求提交给多签钱包
$ E: s2 f+ ?8 p2 U/ A) i/ z1 {9 c* S
多签钱包给各参与方支付+ x: u8 g8 z" B- [2 _

* Q0 b2 V2 w1 N& q- w- v$ R0 F# ~那么,反事实实例化使我们可以假设链下代码已经被部署到了链上,并据此行动;因为我们可以在任何时候部署上链并提交最新状态。但是,这就有个问题——我们如何在没有链上地址的情况下签署状态转换?这就是注册合约的用武之地!
3 A3 @8 g% T8 |0 p- i3 E' G
9 M' ~" P6 l0 o2 s. C6 p###注册
" e' Z% x' x/ F: k: V1 x! w/ N# x8 ~$ B: P% U" a. N
从比较抽象的层面上讲,注册器智能合约允许我们做以下操作:) _5 H; Q! U5 n" C$ x/ s: T$ d* W

8 L8 r( G& m7 S4 I1 o+ Q基于合约字节码,创建一个链下地址(cfAddress)* e! ]' A: ]# R$ }  Y1 k

( `3 N% P- j& r& F. o) }7 z* `+ j3 Z  X6 ]部署智能合约,并把 cfAddress 和链上地址进行映射
' v" Y9 k' r- @$ U8 s
& Q- @* Q+ a6 ^5 M8 A3 u通过 cfAddress 执行链上合约代理调用
( e0 b1 ^# ^' E2 {- x* e) f( G6 t, l
注册合约伪代码:
' T' I$ T, k5 a! R9 @
( J( M% R, i6 g9 U% a+ Hcontract Registry {) j( ]& _5 C% k: H

9 u2 l# T& |6 U3 @2 C  mapping(bytes32 => address) resolver;; R3 y. G; q  t& J5 {, e( {( R

/ f$ V' ]* f( t6 D+ ]  function cfAddress(bytes code) returns (bytes32) { ... }
% B0 X3 d4 U0 n% y: a
  k% j* |  P2 ^9 T, u5 O  function deploy(bytes code) { ... }
% \9 {) B$ s4 p. b% u/ r+ ?' T
( H0 ]. v  Q, J- n4 |- \  function proxyCall(Registry r, bytes32 addr, bytes data) { ... }
- O) P' C* i; b* s$ ]$ `) |
" v' y4 L# @& ^" u( Y+ ?}: c& T, W; Y* C' {& w4 ^( F: Z

: W2 B8 O2 K1 S- g7 r所以,如果你想部署一个合约,你需要用交易调用 deploy 函数,并以合约的 initcode(初始码)作为参数(一般来说,它是与 ABI 编码的构造函数参数连接的合约构造函数字节码)。这个函数把智能合约部署到链上,并且把合约地址加到注册映射表中。
: l* c3 |, B9 O: z( l2 R, K" m5 p( `! T* Z2 P% @; l2 v. ~
以这种方式,你可以通过注册表中的解析器创建相互引用并互相依赖的链下合约。那么,要是想让我们上述例子中的通道运行起来,我们就得通过注册合约来部署支付通道,在多签钱包的条件支付中解析出支付通道的地址。0 A$ f4 m1 E& C, M
0 p9 `* X3 T) I" u+ d  \2 X* w6 F
###依赖/ U/ z" F$ q. J7 X
/ L0 j* J+ y# r& ?9 I5 O8 f6 o) \% W# l
注册合约允许我们做的就是可以建立互相依赖的链下合约,就像合约 A 依赖于合约 B,只有在 B 最终确定之后,A 才能确定(条件层级确定性)。0 v+ p4 e1 e2 {# _  B; M

, ?! {7 i! W8 B8 P+ t# e-以上我们可以看到,除非 Nonce 合约确定了,否则 PC 合约无法确定。-
' N5 {7 m2 ]3 M' l7 @- ^. f. G5 j+ {. |5 _; O# t
你看,上面是一个比较基础的例子,我们要求当前合约基于另一个合约的布尔条件值。我们可以扩展这个条件,允许所谓的“原子状态转换”。# o- h1 j. _: b  _" a# n0 ?+ @( o

% `. Y7 p0 b: d6 s% G: \' k  e: R###原子状态转换# n; h4 G3 E$ u/ a5 L0 X8 ?
% n& r" K4 a- P* N! M1 A
根据这种层级的依赖结构,我们可以进行原子状态转换,转换的同时,伴随着一些合约生效,一些合约失效。下面例子表明,一个 10 ETH 的支付通道,基于 nonce 值,转换为一个 8 ETH 的支付通道,加一个 2 ETH 的扑克游戏。8 v/ t% U6 P) x$ c- b' ^

  |6 x9 h+ S" D3 ]-合约的有效性基于 nonce 值-1 k7 S! w- i6 T: c" i$ h# {
! U8 X5 q2 Z5 o; a5 x; k
如果支付通道的双方都同意用支付通道里的 2 ETH 来创建一个扑克游戏,他们可以签署支付通道的余额更新变化,从(5,5)到(4,4),同时签署一个内置 2 ETH 的扑克合约,nonce 合约的 nonce 值是 4 的时候,这两个合约才会生效。: r9 h, w4 U# p
: h9 B3 U% l! B. R/ ]% F
-基于新 nonce 值的原子状态转换-
( _0 g' G- ~- J( Y" b7 W8 l$ m$ i& H! z5 Z' o8 m1 X8 A2 l* M
当支付通道的双方都签署了支付通道和扑克合约的条件更新之后,他们可以签署 nonce 合约,使得 nonce 值加 1。一旦 nonce 值更新为 4,旧的支付通道状态就会失效,同时扑克合约和新的支付通道状态就会生效。
' O4 ?$ Q" \3 u5 X& i, X3 h$ l$ v$ K' n2 _- b% R2 f+ o8 {0 K0 N
有原子状态转换,代码升级就会变得容易。如果之前支付通道的参与双方想修复代码中的 bug,他们可以在更新余额的时候修复代码。当更新 nonce 值后,之前有 bug 的代码就失效了。
+ C) T! T- o" p# x" W
# U( e$ b% ]5 V% V下面有个例子,这就是基于“根 nonce”合约的一系列反事实合约:
* y. f- ~1 i1 ]) K8 ?; N' ]- ]
" N  f! g6 u6 b) ]5 b根据这种架构,我们可以通过一个“根 nonce”合约有条件地更新所有链下合约的有效性。这允许我们可以根据参与方的需求,迭代地从状态通道中添加和删除链下合约。
' R. \1 I- F) V8 G1 _8 I( U8 q5 s1 M
& F" S/ L" ^9 R3 V! c& ]配置通道3 G, z" s$ r7 q4 ~$ |2 R7 l6 i

% X& J' r- `" Y* q" B7 ?: c假设我和阿剑想玩四子连珠的游戏。我们将会这样做:+ V  I' h" D6 |! I! a! i

& c3 `* h2 F' N) F/ a" ~! ^部署根 nonce 合约、ETH 支付通道(PC)、ETH 条件支付通道(CPC)和四子连珠智能合约9 Z! t4 d( c% i5 R) i
% g/ K9 n  y' _' `
向四子连珠游戏提交最新的签过名的状态# |* h1 A# T# d4 f2 I

0 W* U" `( l; }! J5 N- |基于四子连珠的游戏规则确定 CPC
7 T" w& l, m; m5 b( t
1 Z' Y7 }, u+ `: Y; Z5 \基于 CPC 确定 PC
# v! j! O$ u# ?. l  N
# R5 K: W0 y+ i- F向多签钱包提交已签名的条件支付(基于 PC 的最终确定状态进行支付)
+ j6 z0 H) G: S% N7 Q/ P( ?" @: j) e& p5 W4 u- Z  a
因此,我们可以一直开启其他状态通道,甚至允许我们重用已经部署在链上的四子连珠游戏的代码。下一次我们想要玩游戏的时候,我们只需要对游戏状态进行签名,然后提交到已经部署好的智能合约上。唯一需要实现的是取消现有链上代码的确定性,这是一个实现细节。
+ T4 H3 V* u9 _, P; ~" A' c# l0 o/ `/ ?; N  m7 b+ j4 R* v' L
###注意:你不需要像我展示的四子连珠、CPC 和 PC一样,为你的合约加上这么多的依赖。无论你希望怎么做,这都取决于你和你状态通道中的伙伴。
8 f, N% u. q7 f  K- a2 X
# T1 u4 ^' L5 W& K' t. [* E9 |现在,假设阿剑的朋友 Hunter 想跟阿剑玩四子连珠游戏,但是他只跟我开了一个状态通道,这时候 Metachannels 就可以派上用场啦。
* o3 D- u! A4 r. ]3 x7 P6 a8 g# x( n: O
###Metachannels
3 \9 ]; H' r" E) a- i
0 }4 v. [  T8 h$ j6 [Metachannels 是状态通道上的虚拟通道(参见本系列 Part-4)。要创建一个 Metachannels,你需要两个想交互的参与者,他们各自有一个状态通道,并且通道的另一方是同一个人。两个参与者同意创建一个新的合约,通道另一方(即共同的中心)会与他们一起创建一个代理合约,指向两个参与者的新合约。看起来就像下面这张图:3 T; H% G+ V. l" W

1 X% R9 G3 s0 b: o6 ?-广义虚拟状态通道 = Metachannels !-+ ]: M1 h- c. D! J) _7 M
. F" S0 Q0 [# Q% x5 W" o, w3 u% H% T
我们可以无限地扩展这个模型,让我们想跟谁玩四子连珠,就能跟谁玩。
8 g# {& T/ F9 h/ p5 I$ ?
7 ^& r2 h) B3 R. H###广义状态通道的优点' [0 O8 ^4 D# A' w
* u2 Q3 H8 {% u: T; y
引导——因为我们所需要的只有一个多签钱包,我们可以很容易在链上现有的多签钱包中选择一个开始开发。/ A( X7 V: h: {2 j* }8 |3 J
8 I, A8 r8 J& F
隐私——除了参与者之外,没有人知道状态通道内发生了什么,对于外部世界来讲,参与者之间只有一个多签钱包。- p: X5 m- C, t% s

7 |4 a* ]9 f& j) S6 l2 R. b可升级——如果链下代码中有 bug,所有参与者可以通过链下的操作修复 bug,不需要进行任何链上操作。9 ^: V, _# r  Y
- B) ^* z$ V6 T8 a) L& [
可重用——这种方法有效地鼓励了通用链上库的形成,让所有状态通道都可以引用。& I, ~) p( _- x$ m
7 w* ~0 M- M# ~7 G$ J, m; G
###Part-6:反讹诈
: D7 W% v, h; E# _9 _. G' J2 V' b
在我下一篇博文中,我将会深入讲解状态通道中的反讹诈。讹诈即是说参与者向通道提交一个对自己更有利的较早状态。博文的焦点是 Pisa.
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

fzny61226 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    22