Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文

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

fzny61226
63 0 0
###什么是广义状态通道?
+ v) _8 T/ N  E" y1 R7 y" T9 J9 A0 R8 X0 w+ \7 |# |8 T/ ^
广义状态通道的意思是,用户可以用同一个通道做多种不同的事情。* K; |; {" v9 w: ^( R

6 S& l. E1 l) j7 u9 O0 ?###广义状态通道有何意义?
6 S" q- D4 w: w: t. z0 R$ f0 N5 Z3 y% I
没有状态通道,任何以太坊上的 App 都必须承担高额手续费,忍受延迟,因为 App 高度依赖于链上交易。使用 App 定制型状态通道,我们可以创建更经济更高效的 App ,用户只要在启动和关闭 App 时支付就可以了。广义状态通道更进一步地改善了这种情况,用户只需要在关闭 App 时支付。0 P. }( P4 Q, u8 ^1 N/ D9 F
) z6 S4 v* c" f& ]+ j
注意:当我说“支付”的时候,我的意思是向链上提交交易。
; J& A# c9 [: E; X2 y
% v  q5 `6 G( Y, A###广义状态通道7 e# R, r. e* A. [
# N% Z9 W. W9 a8 u* R0 t8 K, W
在技术上,要开启广义状态通道,所需要求与 App 定制型状态通道一般无二:一个足够强大的多签钱包就足够了,参与者用于锁住状态。区别在于,用户无需为每一个应用都“安装”链上组件——即便要使用多个应用,该多签钱包也将是用户所需的唯一链上组件。
' _( X+ I* a/ Q9 ]. P& c# ?( K) h5 _4 W2 S
App 定制型状态通道(回顾)
( F9 T8 z6 E! D6 n. X% [: `6 y2 y2 o
鉴于在部署链上组件这一点上差别极大,我们先回顾一下我们在前面的文章中讲到的内容。在前文中,我们遵循下列步骤在多方间打开一个 App 定制型状态通道:6 w  Y1 o. G5 }% a

. |; y& G+ s0 n与相关方一起,部署一个多签钱包,把规则集(用来解析发送给钱包的交易)加到链上。# c7 |5 o! U0 k$ Q$ x% i

, n" _* E8 Z7 H5 ?; U% ]在他们进行不同的操作时,在参与者之间广播已签名的消息。8 Y' K! c) z3 F/ x( m8 r: }. r) i

, x& ]  r) c# _/ D& W5 v当参与者准备好开启或退出通道时,他们会把所有参与者签名的最新状态提交到多签钱包,多签钱包根据内置的规则集,决定如何在参与者之间分钱。
) l! @6 V9 o! L3 V7 N. I3 @3 C0 M  i8 i" n. o
这种配置看起来就是下图的样子:( A2 |! @* i1 X1 T! _. h+ \  |

! V9 ~7 B8 a+ A-在任何时候,Bob 和 Alice 都可以把双方都签过名最新状态提交到多签钱包,来配置通道。-
& h0 n: @! d: M; `3 l7 s2 U0 _- I. o. b; ^6 S
注意,上述过程所用的多签钱包只支持符合其内置规则集的 App 。再次强调,广义状态通道通过“反事实实例化(Counterfactual Instantiation)”扩展了 App 定制型状态通道的功能:允许新的 App 安装在现有的状态通道中。
1 M! ?' K0 @; X! P! ^' o! a' F" ]
% G+ I; ~. i6 F) J0 _; r$ f###反事实实例化% ?  H) O2 _/ c

$ g2 L7 k$ i7 f# Y反事实实例化是一个通道内成员同意接受链下智能合约约束过程。这是一个比较奇怪的概念,因为它意味着“链下代码即法律”(给 Liam Horne 点小费吧,这是他提出的),一下是一个简单的例子:
: d4 c4 t* x# g, n' W9 o
/ E* @/ r& F$ M1 k! I9 X1 gSo Easy (作者你是认真的吗?)-, y5 Q  W  h8 U  H" e
% L3 j/ ?, }  U. S6 y
要创建广义状态通道,我们唯一需要的就是一个多签钱包。我跟阿剑各往钱包了存了 5ETH,并且决定要在我们之间创建一个支付通道。所以,我们在链下创建了一个支付通道,并且都对合约代码签过了名,同意在关闭通道时部署它。我们同样也对基于已部署的支付通道的最终状态、发往多签钱包的条件支付请求签了名。
" R# y' W+ y/ w; \
" o/ p- E1 X5 x) Z8 X那么,使用同样的方式——所有参与者都签名,我们不仅能保证状态的可信,也能保证代码的可信。所以,只要我们都签署了代码,我们就可以像该代码已在链上部署的那样,放心地签署相关的状态。两种方式最主要的不同就是,我们只需要在想要结算状态通道时部署代码。
  b, W8 d/ c* x/ N0 q
* ^; a5 _) a' F/ o那么,当我们想结算时的时候,我们需要:0 y7 O) H% Z# e0 v1 q5 e+ [

, l; S0 P) d6 I. c部署支付通道合约' @- \  ?4 R9 a, b5 R6 z
: \6 g1 F# O6 ?7 c+ r9 J
向该合约提交所有参与者签名的最新状态
" }0 o, y8 k1 h) s& I# u- h6 j9 ]( I, d5 A1 x
(基于支付通道的余额)将条件支付请求提交给多签钱包: }& N  y( w, Y; W3 r
& z0 a! i3 g; T$ E& I, V3 |# u6 e! H
多签钱包给各参与方支付% b+ F6 z5 v' q0 v9 J/ W: O( ~
- V0 E  l( z. s7 `7 k6 p: S2 u
那么,反事实实例化使我们可以假设链下代码已经被部署到了链上,并据此行动;因为我们可以在任何时候部署上链并提交最新状态。但是,这就有个问题——我们如何在没有链上地址的情况下签署状态转换?这就是注册合约的用武之地!3 E+ V% C/ y8 H) }$ n4 n
# E2 v( A) e! e% o& M
###注册) E  i) d; Z3 ^2 M, J$ Z
- X9 V: U6 R2 d; O6 \0 B/ K
从比较抽象的层面上讲,注册器智能合约允许我们做以下操作:: P9 C- Q  O% j( t+ G6 ~& P; [
, M5 g. I2 M4 N0 F/ o) i& F
基于合约字节码,创建一个链下地址(cfAddress)
( ^3 `1 q! [. c1 r: X, v; z0 `; ~/ v  u5 ?4 v2 Q! X3 J9 i
部署智能合约,并把 cfAddress 和链上地址进行映射
' p: {& N7 p; v' f/ Y
+ L6 L. ~% ^5 [, G8 ^通过 cfAddress 执行链上合约代理调用$ W  G2 t: ?) n& }4 Q
( P+ w! L# [* D# Z7 J0 f9 b
注册合约伪代码:
0 V% G3 O+ n3 @3 ?. z4 x) D- ?  t) @8 t$ @" K* y3 o. {5 r
contract Registry {
* N( D8 e7 O- T0 k# d. L7 y# ^
) c  j; N' \, v" i2 V6 Z  mapping(bytes32 => address) resolver;9 Z7 r# e/ K! S) l- e- W+ q

: l& b! S. Y- m1 @$ Y* e  function cfAddress(bytes code) returns (bytes32) { ... }
- y% a0 i1 U" r/ n# O" G' H, q
2 o" \" u) S/ }  function deploy(bytes code) { ... }. R; I" N* E* ~* I  f
# Z5 z& Z! }. \. y5 }/ P
  function proxyCall(Registry r, bytes32 addr, bytes data) { ... }0 h  [2 J7 O0 _9 w
7 i! h' E' j8 [/ G
}( Z. m2 t$ X& g9 _& F" q7 ]
" [+ R+ c! [8 @' b3 w
所以,如果你想部署一个合约,你需要用交易调用 deploy 函数,并以合约的 initcode(初始码)作为参数(一般来说,它是与 ABI 编码的构造函数参数连接的合约构造函数字节码)。这个函数把智能合约部署到链上,并且把合约地址加到注册映射表中。
* A! ~) M7 }  }. K) d. ?! B; G8 u  }& K4 x2 P( D4 ~7 z2 L
以这种方式,你可以通过注册表中的解析器创建相互引用并互相依赖的链下合约。那么,要是想让我们上述例子中的通道运行起来,我们就得通过注册合约来部署支付通道,在多签钱包的条件支付中解析出支付通道的地址。3 u/ O% Q9 Q8 U4 V9 Y; ~' C

3 m6 e* v  |8 C& h1 \8 G' u; B###依赖
  A6 Z8 V: a5 h' p0 v2 a% R! m1 f9 x6 X+ z0 ~: c
注册合约允许我们做的就是可以建立互相依赖的链下合约,就像合约 A 依赖于合约 B,只有在 B 最终确定之后,A 才能确定(条件层级确定性)。( P8 a3 {3 C* ]  H* m

' S7 m( G- B% U: B* g-以上我们可以看到,除非 Nonce 合约确定了,否则 PC 合约无法确定。-* @4 l: d+ {: f. b7 |
9 {$ ~" E" w# ^; L* d
你看,上面是一个比较基础的例子,我们要求当前合约基于另一个合约的布尔条件值。我们可以扩展这个条件,允许所谓的“原子状态转换”。' G: I# D, v) C8 `

2 Q1 K% Q4 B: `0 }; m7 c###原子状态转换
8 |& t* \1 ?5 Z- L3 t; F
, u# z) h9 A. P/ _+ l根据这种层级的依赖结构,我们可以进行原子状态转换,转换的同时,伴随着一些合约生效,一些合约失效。下面例子表明,一个 10 ETH 的支付通道,基于 nonce 值,转换为一个 8 ETH 的支付通道,加一个 2 ETH 的扑克游戏。3 g7 m8 E; s( E, U9 |4 K

, F! h+ d' p5 b* W5 {-合约的有效性基于 nonce 值-) H" D5 R( J/ s: |# U- v7 [
/ l3 w4 C% i% K# m4 x; J3 `
如果支付通道的双方都同意用支付通道里的 2 ETH 来创建一个扑克游戏,他们可以签署支付通道的余额更新变化,从(5,5)到(4,4),同时签署一个内置 2 ETH 的扑克合约,nonce 合约的 nonce 值是 4 的时候,这两个合约才会生效。1 q6 x! C2 U( a/ X% W

/ e9 R+ o) |) M, Z8 G-基于新 nonce 值的原子状态转换-
4 P% a# j2 A# ?; t* M8 ^& d
9 e0 i. [- B$ y! o2 {3 p2 c当支付通道的双方都签署了支付通道和扑克合约的条件更新之后,他们可以签署 nonce 合约,使得 nonce 值加 1。一旦 nonce 值更新为 4,旧的支付通道状态就会失效,同时扑克合约和新的支付通道状态就会生效。
6 X4 B5 V5 T$ h
: V1 ]/ N8 f# v# G' }- o2 \! H! L3 Q; p有原子状态转换,代码升级就会变得容易。如果之前支付通道的参与双方想修复代码中的 bug,他们可以在更新余额的时候修复代码。当更新 nonce 值后,之前有 bug 的代码就失效了。$ ]# z5 Q( Z1 Y: c5 e7 M
  A- R1 g/ `% j1 v
下面有个例子,这就是基于“根 nonce”合约的一系列反事实合约:
) p# u# o( O" P, b- \1 @
' B, E$ l. |& J. G1 t1 ~2 `根据这种架构,我们可以通过一个“根 nonce”合约有条件地更新所有链下合约的有效性。这允许我们可以根据参与方的需求,迭代地从状态通道中添加和删除链下合约。$ b5 l4 ^. M3 R# k
5 ~4 \. v. f" M3 r
配置通道
: H4 }6 U5 [& E9 g" n
8 @/ I3 t- t# ]* S/ {( Z$ p假设我和阿剑想玩四子连珠的游戏。我们将会这样做:2 n# g: m  [4 k1 w

% v' _! M: g; D- q+ }6 v部署根 nonce 合约、ETH 支付通道(PC)、ETH 条件支付通道(CPC)和四子连珠智能合约( `$ {5 |9 O+ `) n% ^

2 [& B  k/ q0 Z向四子连珠游戏提交最新的签过名的状态8 k  L0 \" k, ~
& Z) V2 f' g, Z7 Y) [; [
基于四子连珠的游戏规则确定 CPC
: G( H# F6 D3 Q! I, d( J$ @0 D- D4 f& a2 |- ?" d
基于 CPC 确定 PC  x. [% q  P/ I# K4 P/ }& w. p! V8 }
: i+ Q6 [: z/ \, W
向多签钱包提交已签名的条件支付(基于 PC 的最终确定状态进行支付)
7 ]7 E* b  {- Q) A6 R1 ~5 V$ S. A( p" Z
因此,我们可以一直开启其他状态通道,甚至允许我们重用已经部署在链上的四子连珠游戏的代码。下一次我们想要玩游戏的时候,我们只需要对游戏状态进行签名,然后提交到已经部署好的智能合约上。唯一需要实现的是取消现有链上代码的确定性,这是一个实现细节。# D/ d2 T' \5 Q% F" P7 A9 \5 L1 R

& K# a. H9 H. c1 O7 Y###注意:你不需要像我展示的四子连珠、CPC 和 PC一样,为你的合约加上这么多的依赖。无论你希望怎么做,这都取决于你和你状态通道中的伙伴。/ {6 K. S+ G" x4 r
% Q" D+ a# H+ z& I3 Y! l8 j
现在,假设阿剑的朋友 Hunter 想跟阿剑玩四子连珠游戏,但是他只跟我开了一个状态通道,这时候 Metachannels 就可以派上用场啦。
# r1 S, d4 `- P. c6 C! F
6 ?9 B! U6 u6 i$ s###Metachannels% E% g' u9 Z  v; q- s8 l- r7 g" c
, W1 x$ B- m$ R  ?, }! e4 ~! R
Metachannels 是状态通道上的虚拟通道(参见本系列 Part-4)。要创建一个 Metachannels,你需要两个想交互的参与者,他们各自有一个状态通道,并且通道的另一方是同一个人。两个参与者同意创建一个新的合约,通道另一方(即共同的中心)会与他们一起创建一个代理合约,指向两个参与者的新合约。看起来就像下面这张图:
  A1 i: h6 U. o* l6 ?; u, O
/ t. m! y9 Y& s5 e$ e- E  g+ Z-广义虚拟状态通道 = Metachannels !-9 C1 Z: i8 P- j/ [0 ^  c/ {
9 g, S1 }7 X! x/ m" q
我们可以无限地扩展这个模型,让我们想跟谁玩四子连珠,就能跟谁玩。0 \9 s6 [; M4 l2 w) _7 g" p9 F$ X
) g( n$ L/ l* N, i& d7 A% ^
###广义状态通道的优点* V$ J. M0 [( T* Y% c' y/ _

* D7 b. M; q$ {引导——因为我们所需要的只有一个多签钱包,我们可以很容易在链上现有的多签钱包中选择一个开始开发。2 A: Z6 o2 e+ m! }9 z) K

0 Q$ s+ b% U9 u# S% ^; r2 D1 a隐私——除了参与者之外,没有人知道状态通道内发生了什么,对于外部世界来讲,参与者之间只有一个多签钱包。2 i4 N9 K4 z! j/ }$ V

/ I% z) F2 F2 {可升级——如果链下代码中有 bug,所有参与者可以通过链下的操作修复 bug,不需要进行任何链上操作。, n/ T3 j. n# `4 F2 S; b

0 j: v$ a# ]0 O4 L3 ^% Q可重用——这种方法有效地鼓励了通用链上库的形成,让所有状态通道都可以引用。
! q% {7 F/ _5 o1 h2 r5 W, a' U$ X$ |1 N! l* `$ F& L8 G3 l9 A! `+ }
###Part-6:反讹诈  V; f, B; e* q: l+ r+ h# ^5 r! c5 T" U

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

本版积分规则

成为第一个吐槽的人

fzny61226 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    22