Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文

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

fzny61226
74 0 0
###什么是广义状态通道?8 _' u9 D3 \- u% g2 ?" @
* O, B( |; r" F4 D" u. C# p4 D
广义状态通道的意思是,用户可以用同一个通道做多种不同的事情。/ E  }0 X2 n+ g5 B4 H: L+ H
: N3 a* k/ l9 Z+ R. @6 |
###广义状态通道有何意义?8 F0 O7 O* l6 t5 G
$ [- N0 r+ A  N- {1 f+ S
没有状态通道,任何以太坊上的 App 都必须承担高额手续费,忍受延迟,因为 App 高度依赖于链上交易。使用 App 定制型状态通道,我们可以创建更经济更高效的 App ,用户只要在启动和关闭 App 时支付就可以了。广义状态通道更进一步地改善了这种情况,用户只需要在关闭 App 时支付。* y% P# U0 \' f7 [

( o. |9 O! Z3 g. R0 v+ h注意:当我说“支付”的时候,我的意思是向链上提交交易。; D  z) t1 P! }$ @. Y; G+ q
- {$ v# _2 R) e7 _3 q5 W& O
###广义状态通道* i1 }8 ~3 V) w* ?) W
. ]! U* E( i% u1 @9 N3 `
在技术上,要开启广义状态通道,所需要求与 App 定制型状态通道一般无二:一个足够强大的多签钱包就足够了,参与者用于锁住状态。区别在于,用户无需为每一个应用都“安装”链上组件——即便要使用多个应用,该多签钱包也将是用户所需的唯一链上组件。1 |+ L5 R+ W2 A0 L% \" T

% f; j8 t1 D' y# t# I; l! AApp 定制型状态通道(回顾)
" p$ v; P" e! T; R7 P- t! U' N8 Z* r) O0 }
鉴于在部署链上组件这一点上差别极大,我们先回顾一下我们在前面的文章中讲到的内容。在前文中,我们遵循下列步骤在多方间打开一个 App 定制型状态通道:! M2 A+ y5 F8 P$ M$ _* Y
) f3 l& M+ S' @
与相关方一起,部署一个多签钱包,把规则集(用来解析发送给钱包的交易)加到链上。
: s5 c! C/ |3 U1 l
5 p3 n! l/ w( j. h, T! c4 |4 g在他们进行不同的操作时,在参与者之间广播已签名的消息。, _5 h# ^- c( U' r/ ~7 `6 a

' V, D% N- A8 _当参与者准备好开启或退出通道时,他们会把所有参与者签名的最新状态提交到多签钱包,多签钱包根据内置的规则集,决定如何在参与者之间分钱。
! u7 a: H) C3 R* ?2 o
8 _0 K- X/ X7 t% Y+ ]这种配置看起来就是下图的样子:$ a" x* U- l6 J5 L

. V4 e8 k9 \" U# A' Q$ e- M3 b$ {-在任何时候,Bob 和 Alice 都可以把双方都签过名最新状态提交到多签钱包,来配置通道。-
, I6 \1 r6 I2 Z% [8 `+ t; Y
/ }% b- V- W! [* C" B6 P9 F注意,上述过程所用的多签钱包只支持符合其内置规则集的 App 。再次强调,广义状态通道通过“反事实实例化(Counterfactual Instantiation)”扩展了 App 定制型状态通道的功能:允许新的 App 安装在现有的状态通道中。
& M! j6 u# S+ E' m! _' _0 I& ^2 X9 C. `; D2 R
###反事实实例化
- {4 |  a- |) ]3 J
: c: j  R1 I7 r/ \反事实实例化是一个通道内成员同意接受链下智能合约约束过程。这是一个比较奇怪的概念,因为它意味着“链下代码即法律”(给 Liam Horne 点小费吧,这是他提出的),一下是一个简单的例子:! r: U0 M0 |# h8 u6 J* [6 a/ [" {" n

' P, P. J& Y: n! x/ ?4 QSo Easy (作者你是认真的吗?)-
1 }# `( f* m7 k& G0 N+ V
) H  P( n) h; j# [要创建广义状态通道,我们唯一需要的就是一个多签钱包。我跟阿剑各往钱包了存了 5ETH,并且决定要在我们之间创建一个支付通道。所以,我们在链下创建了一个支付通道,并且都对合约代码签过了名,同意在关闭通道时部署它。我们同样也对基于已部署的支付通道的最终状态、发往多签钱包的条件支付请求签了名。* E, C+ d6 T) Z: f5 r/ E+ Z0 ~
- V( s, C$ I2 n/ T( l* n/ {
那么,使用同样的方式——所有参与者都签名,我们不仅能保证状态的可信,也能保证代码的可信。所以,只要我们都签署了代码,我们就可以像该代码已在链上部署的那样,放心地签署相关的状态。两种方式最主要的不同就是,我们只需要在想要结算状态通道时部署代码。, Y& ~0 h2 N* z

5 \' m6 z& S; l3 }0 _4 P- U那么,当我们想结算时的时候,我们需要:. R4 |3 u" j% c3 ~' n
7 E5 N# o6 s9 R, ]9 e
部署支付通道合约) e  a* b* U8 L( H( j

5 ?9 w- M, J& u3 U5 n向该合约提交所有参与者签名的最新状态
) v8 }7 L" Z3 e7 I! `
/ l8 |7 a6 T) S. X3 W: H: [(基于支付通道的余额)将条件支付请求提交给多签钱包, X, s6 S: `2 \% m/ U+ ~) Z/ a2 V9 M8 u
( K) ?1 T# d. z  K# T. T
多签钱包给各参与方支付' H5 u) }8 e8 j/ P/ a) G
' P8 @/ Q6 \, O, T$ V* }. Y2 Y
那么,反事实实例化使我们可以假设链下代码已经被部署到了链上,并据此行动;因为我们可以在任何时候部署上链并提交最新状态。但是,这就有个问题——我们如何在没有链上地址的情况下签署状态转换?这就是注册合约的用武之地!2 g' n) F7 B! T

# ]7 R3 D$ G9 T: B- t###注册
$ L5 l& ~+ u& }4 J- m7 J# H  P
$ _1 f3 |: J  F! V5 z从比较抽象的层面上讲,注册器智能合约允许我们做以下操作:* ]/ U7 S- H  Q7 v2 O2 s$ E4 p, m
& K4 p' ^- J% W9 H! g! @
基于合约字节码,创建一个链下地址(cfAddress)
/ X, X5 k! M/ {9 `9 S3 v0 w& W
2 V5 S+ x" }$ ^4 t8 A+ R3 _部署智能合约,并把 cfAddress 和链上地址进行映射6 x* ~* l7 Y2 a
$ B$ ^( B( v4 f7 D' h/ b/ Z* T5 y
通过 cfAddress 执行链上合约代理调用: h2 A0 A2 O& p7 Z8 n

: x+ X- X1 @( Y注册合约伪代码:' W$ S- F* f3 x5 ]

% K+ W7 m$ e0 i4 p' ^+ icontract Registry {. l! v( i( {) ?$ X& D3 `( r
4 ^9 H2 c4 q5 U+ {, a1 ?+ O; n3 k* r
  mapping(bytes32 => address) resolver;
9 }% c3 e% H, D, R6 L, I4 q5 D. Y% A0 Z3 ?5 l- `: O: I9 {0 X& B4 V
  function cfAddress(bytes code) returns (bytes32) { ... }
& k4 m" X) p" a7 D, O$ B/ w7 U5 u
' w4 `5 ]; g7 q3 \2 J  function deploy(bytes code) { ... }
* J5 B6 O; X( F( j6 Q
5 y$ o% \) {! ^0 C0 C" j  function proxyCall(Registry r, bytes32 addr, bytes data) { ... }
& I: Q: `$ @$ b0 o8 U+ |, s/ ^1 N+ G6 H
}, B# Z6 q7 r  \8 f5 b& G8 O2 _
- A- O) v0 X- ?: r' m7 j
所以,如果你想部署一个合约,你需要用交易调用 deploy 函数,并以合约的 initcode(初始码)作为参数(一般来说,它是与 ABI 编码的构造函数参数连接的合约构造函数字节码)。这个函数把智能合约部署到链上,并且把合约地址加到注册映射表中。
; `+ A! }) V9 O+ I5 q$ n$ ~  X' f8 E; ~7 B, |
以这种方式,你可以通过注册表中的解析器创建相互引用并互相依赖的链下合约。那么,要是想让我们上述例子中的通道运行起来,我们就得通过注册合约来部署支付通道,在多签钱包的条件支付中解析出支付通道的地址。! J: G) ~: o5 W5 H& B! Z: ]9 S
8 x# N! D! h: v5 v. S% H! S7 u3 {
###依赖4 ^& m& ?, ~% T

* q& l9 M/ Q8 g3 W注册合约允许我们做的就是可以建立互相依赖的链下合约,就像合约 A 依赖于合约 B,只有在 B 最终确定之后,A 才能确定(条件层级确定性)。4 v  H: z! s8 U5 c, J1 K, i' \

2 c5 @6 A! n3 ]. v- O% D4 |4 g% K-以上我们可以看到,除非 Nonce 合约确定了,否则 PC 合约无法确定。-
- S, U9 C, u7 n2 u
) @; W% W7 [' J( R1 \+ \你看,上面是一个比较基础的例子,我们要求当前合约基于另一个合约的布尔条件值。我们可以扩展这个条件,允许所谓的“原子状态转换”。$ [% y9 \0 k& t( p, C) ^) G
6 f1 v- S$ t9 L; F: Y; h( N
###原子状态转换/ T0 B  p7 o& S4 @

5 B) b4 J' i& k% }4 {) P根据这种层级的依赖结构,我们可以进行原子状态转换,转换的同时,伴随着一些合约生效,一些合约失效。下面例子表明,一个 10 ETH 的支付通道,基于 nonce 值,转换为一个 8 ETH 的支付通道,加一个 2 ETH 的扑克游戏。( ~# ]& q" y! C
# s2 J3 |9 y6 L6 g4 G
-合约的有效性基于 nonce 值-
' G" w6 b% @" L: B6 I; U% o4 a7 r$ [& W2 s3 Y) l
如果支付通道的双方都同意用支付通道里的 2 ETH 来创建一个扑克游戏,他们可以签署支付通道的余额更新变化,从(5,5)到(4,4),同时签署一个内置 2 ETH 的扑克合约,nonce 合约的 nonce 值是 4 的时候,这两个合约才会生效。
- f' O: ]$ o7 l: q3 _$ k/ x& d$ G% O) u1 `' P
-基于新 nonce 值的原子状态转换-
" F- o6 W+ D1 u, n# |8 ~" O# A# ]0 X$ {# X: Q1 y
当支付通道的双方都签署了支付通道和扑克合约的条件更新之后,他们可以签署 nonce 合约,使得 nonce 值加 1。一旦 nonce 值更新为 4,旧的支付通道状态就会失效,同时扑克合约和新的支付通道状态就会生效。
. z3 |& Z+ l6 z) C. N5 \: Q9 ^9 q3 V6 G* j8 {$ E! C  j0 e
有原子状态转换,代码升级就会变得容易。如果之前支付通道的参与双方想修复代码中的 bug,他们可以在更新余额的时候修复代码。当更新 nonce 值后,之前有 bug 的代码就失效了。
) V/ o, k* F% x6 k8 B% w
8 R* Z2 Z# B0 [, K' ^* e下面有个例子,这就是基于“根 nonce”合约的一系列反事实合约:- ~! f4 A7 w% M1 S# s% H6 ^

1 |5 Y. ^0 i. ]& r, l8 x根据这种架构,我们可以通过一个“根 nonce”合约有条件地更新所有链下合约的有效性。这允许我们可以根据参与方的需求,迭代地从状态通道中添加和删除链下合约。2 y7 I- J. _7 r+ D! F) U

; S- E( o  _0 g3 b: E6 N配置通道/ L" e! c, g# w6 c/ q

+ Z4 q3 [" Y; I7 l0 p假设我和阿剑想玩四子连珠的游戏。我们将会这样做:$ Y8 U1 ?4 `" e
% L* o% N0 ^* {6 k2 `" T
部署根 nonce 合约、ETH 支付通道(PC)、ETH 条件支付通道(CPC)和四子连珠智能合约
5 b, W) Y! L: \: Q* z
) L2 H# S( T. X  Q+ J$ i: X向四子连珠游戏提交最新的签过名的状态
8 z+ |2 {8 h5 |% o, A
9 X; k9 y2 t4 M0 \: p7 A7 F基于四子连珠的游戏规则确定 CPC
" U) @1 R2 P$ ?1 f8 i9 r  k9 y9 D8 C5 t$ O" K- c! q2 q) x
基于 CPC 确定 PC
- z- R1 M& s, X# R/ {- b# U/ R& g3 `5 Z& y; N
向多签钱包提交已签名的条件支付(基于 PC 的最终确定状态进行支付)) h0 I$ o: c  H& Q
9 p$ }! ~- l3 G
因此,我们可以一直开启其他状态通道,甚至允许我们重用已经部署在链上的四子连珠游戏的代码。下一次我们想要玩游戏的时候,我们只需要对游戏状态进行签名,然后提交到已经部署好的智能合约上。唯一需要实现的是取消现有链上代码的确定性,这是一个实现细节。
# A) s+ ~& U  u1 e! E2 n8 i
& R" h" `' L" W6 P###注意:你不需要像我展示的四子连珠、CPC 和 PC一样,为你的合约加上这么多的依赖。无论你希望怎么做,这都取决于你和你状态通道中的伙伴。
  ~5 Q- o4 w1 [7 P
; V. B& e6 h$ [: b现在,假设阿剑的朋友 Hunter 想跟阿剑玩四子连珠游戏,但是他只跟我开了一个状态通道,这时候 Metachannels 就可以派上用场啦。
6 ^" J. n2 |' x8 \9 I0 d, X2 f' B  t, ^8 R
###Metachannels% u1 W! X5 U  r5 |0 [

5 @! \/ t. L2 ~; _8 W. I1 aMetachannels 是状态通道上的虚拟通道(参见本系列 Part-4)。要创建一个 Metachannels,你需要两个想交互的参与者,他们各自有一个状态通道,并且通道的另一方是同一个人。两个参与者同意创建一个新的合约,通道另一方(即共同的中心)会与他们一起创建一个代理合约,指向两个参与者的新合约。看起来就像下面这张图:3 O0 K8 t$ N" g/ u

1 A6 R7 `; u. u6 T-广义虚拟状态通道 = Metachannels !-
* L. i3 X/ c' h. d+ a+ b3 x* Q3 j# _# J: v, e. a' n
我们可以无限地扩展这个模型,让我们想跟谁玩四子连珠,就能跟谁玩。
* H( F7 s' J4 y& e9 p
/ x- S& {" B2 P* Y5 x/ r###广义状态通道的优点
- a. o1 f- L5 B: [) L  G* ~8 K) l5 J8 u9 `$ e: r
引导——因为我们所需要的只有一个多签钱包,我们可以很容易在链上现有的多签钱包中选择一个开始开发。5 N+ P) |0 p# C9 k0 P3 ~2 U; _

$ X' S2 I6 F; ?6 E- [$ Y隐私——除了参与者之外,没有人知道状态通道内发生了什么,对于外部世界来讲,参与者之间只有一个多签钱包。' K! c% j8 I/ o! @0 p, Z
- y% S7 M; ^; A: q$ k
可升级——如果链下代码中有 bug,所有参与者可以通过链下的操作修复 bug,不需要进行任何链上操作。
1 |- E- z7 K7 c+ M. }) ~: L9 F: T, f, T
可重用——这种方法有效地鼓励了通用链上库的形成,让所有状态通道都可以引用。
; k  {+ |$ o# J6 |2 @3 n7 E  f
7 n. c! b  `: y* H' _  k###Part-6:反讹诈6 H* c5 l# e' G# C8 i; W
' O" G; [/ P4 D; `
在我下一篇博文中,我将会深入讲解状态通道中的反讹诈。讹诈即是说参与者向通道提交一个对自己更有利的较早状态。博文的焦点是 Pisa.
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

fzny61226 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    22