Qtum量子链研究院:Qtum Plasma MVP 技术详解
博客园
发表于 2022-12-3 00:02:12
141
0
0
Plasma MVP以一种非常简单的方式提供Plasma系统的基本安全特性。
8 i6 K J- v' A+ B) ]; b
在Plasma MVP中,用户一旦发现任何不法行为就立即退出,用户的退出申请也是按照UTXOs被创建的时间从早到晚的优先级顺序处理。
& g1 P! B0 ~* W* U, U7 m5 Z7 A& [
Plasma区块链中,区块的创建方法有两种:一种是Plasma链的运营者可以创建区块;另一种是任何用户可以向Plasma链中存入一定资产,这种情况下,合约会在Plasma链上新增一个区块,该区块包含一个创建新的UTXO的交易,UTXO和用户存入资金的价值相等。
8 w s6 n/ d Y% e" P
1 y0 M) y3 ~1 g$ B
如何在Qtum上创建Plasma MVP# X/ h3 ~" A# U% |
6 \/ s4 ~( [/ ~, |
Qtum Plasma MVP 的实现基于以下技术:1 m+ A5 o% r' [) A# p) S' @( ^
Minimum Viable Plasma
Omisego Plasma MVP
1、首先检查你的Python版本:
请使用Python 3.5或更高版本,但我们建议您使 pyenv,并运行3.6.5版。
' j$ D N6 a4 o, u, P5 J O
2、安装Python P/ G% H% u! C9 X
python setup.py install5 I' u; K& o E( z; L
3、运行Qtum Plasma MVP% h" ?, K$ V) c' M6 ]
准备一个镜像docker,其中包含qtumd以及ETH RPC兼容层。
docker run --rm \
--name qtumportal \
-v`pwd`:/ dapp \
-p 3889:3889 \
-p 8545:23889 \
dcb9 / qtumportal
其中:3889为原始的QTUM RPC,8545为ETH兼容的RPC。" o1 |- S$ d& P2 q# F8 l0 s ^ [
4、接下来,设置别名以访问qtum-cli工具:: R; k1 w' J( t/ L6 H
alias qcli='docker exec -it qtumportal qcli'
5、生成600个区块作为测试的初始余额:/ X2 ?5 X& e6 n" K8 L
qcli generate 600" M& r. t& h' @4 Y
9 T/ F0 l; D2 Y" G) T) F
6、设置 Qtum Plasma需要遵循以下步骤:
创建两个Plasma用户
在QTUM上部署根合约
注册Plasma用户2 F6 _& ?2 _ U- N
运行子链
) V! k4 n$ ~& n; b$ i. B! o
7、创建用户, U2 u2 c0 m1 n0 R% T" s% i
你需要准备的事:导入私钥和账户充值
其中导入的私钥为第一个账户用户所有,此用户还充当管理员,用于部署Plasma合约,以及提交子链区块。+ H" b& Z4 |8 q1 s7 W C
# Private Key: g( Y& R; N' Q( h! e; Z! @( I9 Y9 \
00821d8c8a3627adc68aa4034fea953b2f5da553fab312db3fa274240bd49f35
# QTUM Address Hex6 F. y3 ~( Y; s, h( f/ O0 G
0x7926223070547D2D15b2eF5e7383E541c338FfE9' q5 d. f' g6 d% i) E9 U
# QTUM Address Base58
qUbxboqjBRp96j3La8D1RYkyqx5uQbJPoW
# ETH Address
0x6Fd56E72373a34bA39Bf4167aF82e7A411BFED47 m, a* W. ~+ |/ m
请注意,同一私钥的ETH和QTUM地址不同,我们需要知道这两者的区别。获取签名时,ecrecover函数返回ETH格式的地址。0 I5 w5 H9 _! N" n& M d0 l& i
* \% z+ e3 @: E1 ^" A
第二个用户的私钥(没有管理员权限的普通用户):" F% w; h' I$ c
# Private Key
7826adc1127b8cf34c47b2c7909904109d7fe404be04838e323082981c51340e1 p! G9 T6 |. u4 M, B# Q
# QTUM Address Hex6 [6 L' ]( ^& v* c' ~& B+ E
0x2352be3Db3177F0A07Efbe6DA5857615b8c9901D
# QTUM Address Base58( u4 o/ F7 m, m% m9 l; ?4 k- L
qLn9vqbr2Gx3TsVR9QyTVB5mrMoh4x43Uf
# ETH Address
0x0CF28703ECc9C7dB28F3d496e41666445b0A4EAF# z/ D+ b" {! M* E8 Z, f) U& F
导入这些密钥,并为每个帐户充值500 QTUM:
# Admin Userqcli importprivkey \ ~) k2 r x; Q% c1 O- {) l
cMbgxCJrTYUqgcmiC1berh5DFrtY1KeU4PXZ6NZxgenniF1mXCRk8 c5 I% l8 d' J7 i4 Y/ Y& ~, P
docker exec -it qtumportal \
solar prefund qUbxboqjBRp96j3La8D1RYkyqx5uQbJPoW 50000# Normal Userqcli importprivkey \
cRcG1jizfBzHxfwu68aMjhy78CpnzD9gJYZ5ggDbzfYD3EQfGUDZ
docker exec -it qtumportal \
solar prefund qLn9vqbr2Gx3TsVR9QyTVB5mrMoh4x43Uf 50000
部署根链以及注册账户: H1 U* ~. r4 g! N f; B
我们将用管理员用户来创建合约:
make root-chain
如果成功,合约地址将写入文件plasma_core / contract_addr.py:
cat plasma_core/contract_addr.py
ADDR="0x2208595067499452580F54668104Ffb1b8755d79"( M, V7 N/ a4 f$ ~
原始的Plasma MVP不需要用户预先注册。但是,由于上面提到的ecrecover问题,智能合约需要将QTUM地址与ETH地址相关联。4 k! e' `% S/ w
4 E6 d; g, _1 p3 P4 o
注册这两个用户:
omg register 0x7926223070547D2D15b2eF5e7383E541c338FfE9 00821d8c8a3627adc68aa4034fea953b2f5da553fab312db3fa274240bd49f355 g4 X" j( o$ O( k8 K; U0 ]* R+ S% n( K. S
omg register 0x2352be3Db3177F0A07Efbe6DA5857615b8c9901D 7826adc1127b8cf34c47b2c7909904109d7fe404be04838e323082981c51340e: Q4 C" k2 \$ @) e# ?
4 o% g* P3 L% @3 G! p7 A- ]4 T# S
运行子链与充值账户
根链现在准备好了。让我们启动子链,一个Python服务器:% A1 Z+ j7 }+ U: n+ g
make child-chain
4 _9 t: Z# w2 I7 f( _
用户充值至Plasma链中:3 }; }" c# ?: Y C+ o m( j" t
我们使用第一个用户(管理员)将100 QTUM存入根链:0 M4 a0 `9 X3 N+ I) g$ N9 v
omg deposit 10000000000 0x7926223070547D2D15b2eF5e7383E541c338FfE92 d5 y0 d2 ?7 L" d d
Deposited 10000000000 to 0x7926223070547D2D15b2eF5e7383E541c338FfE9
3 Z2 U8 `' L* b* V- t/ ]) s, D" G
当根链确认存款时,应该看到来自子链的以下日志输出:0 j* ?# Q4 F. z4 \
apply_deposit AttributeDict({'depositor':'0x6Fd56E72373a34bA39Bf4167aF82e7A411BFED47','depositBlock':1,'token':'0x0000000000000000000000000000000000000000','amount':10000000000})
这笔存款在侧链上创建了相应的UTXO,Plasma MVP使用简化的UTXO,因此可以有两个VIN和两个VOUT。
3 s0 K" r3 \. p+ G$ L
omg sendtx有点不友好,因为它需要很多参数来创建一笔交易。我们将使用存款UTXO作为VIN1,将VIN2留空,并创建两个每个50个QTUM的VOUT,一个给接收方,另一个作为找零给发送方。; b( O ^6 z, R9 f; R
omg sendtx \ `# vin 1 (blknum, txindex, oindex)` \2 F- Y u6 E0 j% V/ J P: o
1 0 0 \ `# vin 2 (blknum, txindex, oindex)` \
0 0 0 \ `# The type of the (ERC20) token. 0x0 is the "native" token, which is ETH or QTUM.` \! Z3 _9 u* T! Q8 T+ C7 k/ ]6 Z
0x0 \ `# vout 1` \
0x7926223070547D2D15b2eF5e7383E541c338FfE9 5000000000 \ `# vout 1` \, t% {5 C$ h, I+ C& n9 `, X
0x2352be3Db3177F0A07Efbe6DA5857615b8c9901D 5000000000 \ `# Signing key of sender` \/ g/ ]* G- i; T b: r/ x
00821d8c8a3627adc68aa4034fea953b2f5da553fab312db3fa274240bd49f357 [3 F+ R d7 }6 j5 P/ {7 F
. w7 u0 |- J; G- J: q1 D2 n. h) y. L
交易发生在Plasma上,管理员需要将子链区块的merkle根提交到根链,以发布Plasma 交易,供所有人查看:4 r9 v+ J7 b% M; s$ c
# submit a block with the admin's signing keyomg submitblock \
00821d8c8a3627adc68aa4034fea953b2f5da553fab312db3fa274240bd49f35
子链应该输出:
utxo_id: 1000000000blknum: 1from: 0x7926223070547D2D15b2eF5e7383E541c338FfE9block.merkle.root: a2540bf5fef7c09ab916fabd3607385eba19468e6a6e09fced27400254b6ac9blen: 32data: 6bd3991cdfe4d2492b262e178370b74ae7c8eeacc7acb052cd5820e62ac548fa
链的撤销; B1 i# P$ t5 K% J' Q
要使用户2从子链中撤销VOUT,用户1必须为该交易中的每个VIN发送一个确认签名。
前述的sendtx,区块1000上有两个VOUT。, D# F9 Z1 ]! P" Q4 ?, X, r
我们撤销由1000 0 0(块1000,tx 0,vout 0)指定的VOUT,它属于用户1:4 A# o) g8 H `: m r5 [. G
omg withdraw \" v, W9 K, n, }( r$ p& j6 A4 j
1000 0 0 \
`# Use user1's key to create a confirmation sig` \
00821d8c8a3627adc68aa4034fea953b2f5da553fab312db3fa274240bd49f35* u4 ]6 b$ u) C* ~3 H
一旦撤销请求在链上,我们需要等待一个挑战期才能最终确定。在该测试中挑战期设置为30秒,所以只需等待:0 i& D' D1 j2 b. G2 a% N
sleep 30
在挑战期之后,调用finalize来解决链上的所有有效退出:$ H4 x8 N# f% K( `- C
omg finalize_exits% ^! @: N' R) p4 i6 n( U" {
我们应该看到,因为转出500 QTUM UTXO,合同余额现在减少了:
G9 j) a+ l5 G" c+ p% M
bash scripts/getbalance.sh; y, L7 b3 u; c9 o
"balance": 5000000000,; `' w" C- u1 O$ E
如果用户2也想退出,则过程类似:
6 o, U4 B2 j/ s- F9 X) O2 w* t
omg withdraw 1000 0 1 00821d8c8a3627adc68aa4034fea953b2f5da553fab312db3fa274240bd49f35
请注意,CLI工具仅用于测试目的。通常,用户2不知道用户1的私钥,而是直接接收确认签名。
成为第一个吐槽的人