Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

EOS纯技术上手学习

罗宾虚汉
166 0 0
EOS.IO 已发布黎明V1.0版本。EOS.IO 黎明V1.0版本是第一个预发布的 EOS.IO SDK(软件开发工具包)。EOS.IO黎明V1.0版本可以让我们体验下EOS一部分区块链特性和简单上手开发、测试。本篇主要是一个快速的review目前EOS黎明V1.0版本的功能上手。
" y' s! H5 d. Q- C, e主要内容:
# c7 Y: k4 W/ H# x' L9 R: w. Z( D# }
EOS Docker快速部署
7 P* K- g3 G- Q5 J$ b$ d
5 C& {: b- M- X3 l! D' qEOSC使用6 K' y$ \$ B9 r- g$ H# K
' J, w6 Y$ T3 }# B( v9 C" M
创建钱包5 b+ Z6 V# H7 F' \" m, h% R
$ L7 A5 ~- @  V* [
将私钥导入钱包$ \5 N$ L/ Y- o  G4 Y
+ Y& o7 ?' y9 H, f1 F
锁定和解锁钱包
# n% ~- \0 T) @7 S' Y( ^
$ C# q- ]( V. s% x% F( C4 }创建账户$ p$ O7 o7 ~. I- R& T8 A, G

) a% y6 e1 m6 G; E% I内置转账
: E# d# b/ k9 U+ [9 @/ |) t" L/ ~# {! [+ O3 C; o/ r/ v9 n8 m% q
查询交易历史- i' y1 g/ f- X2 j) i& E! ^

% y7 F7 C1 X9 K+ ?6 S, `* o) a测试合约 - currency. E; O' j: J0 d. k. s1 ]

: t+ r3 Q1 Y3 s  p+ A" R# P调用合约
+ G  Z5 X: o! v" a& p0 M
1 B+ @; h4 o7 b' [3 [9 @查询合约
4 @  R! n0 u5 G: Z. M3 E* N$ X  X
- X0 V, e2 |1 W, a: l+ r( B链接特定的节点$ s' ~% a# g, P1 s! V. w
2 ^3 f! P, l4 e
链接独立钱包服务8 U* J, ~( w2 g- U; W
# t0 }) q- D2 S# w) ?7 T, {  @1 H; r
免签名验证
+ @4 w+ _& m6 B/ S6 x" Q$ A, ~9 `7 m2 ~" t2 T7 v/ v+ O
其他RPC调用  x7 {6 u) E, Y9 o2 C/ t8 b1 z

1 l2 @7 ?1 f+ s7 V' V
# I$ q$ |: e$ KEOS Docker快速部署
+ ^  C& D/ d6 [  c7 r- ~构建eos镜像( g4 U1 x; Y8 N# o) [
git clone https://github.com/EOSIO/eos.git --recursive
. D1 M0 q  [* |9 q) Jcd eos" J9 M, h. n! U5 P& F+ O9 E6 d4 n7 P$ ^
cp genesis.json Docker
2 @' j. E# B) |6 V$ O5 Z+ Ydocker build -t eosio/eos -f Docker/Dockerfile .
$ I: i  {: I: G! G# L7 x4 v/ o启动容器+ r* n) j3 B" r' [8 w6 l& `- N
sudo rm -rf /data/store/eos # options
' U( ~! P/ [3 }6 t  d  ~. Wsudo mkdir -p /data/store/eos+ q+ M' O5 U* `2 V
docker-compose -f Docker/docker-compose.yml up
9 \* H4 s  u+ \+ ^, N8 [如果 docker-compose 启动有报错, 可能需要给文件存储目录赋予用户读写权限# z0 \* Q4 U) t9 B$ x( U7 D% d3 h
sudo chown -R SYSTEM_USER /data/store/eos
3 t& p; M* h( t5 K  a( ^0 d/ M: U验证,查询区块链状态信息5 F& E* D& B% U, @" Q: j+ Q* ?
curl http://127.0.0.1:8888/v1/chain/get_info6 P1 e/ S4 q% \- W& C  t1 n: A2 K
如果想使用多节点环境,可使用yml文件启动( i, A' G2 Z& u( V
version: "2"
+ q2 h5 A: d4 t  F& F& hservices:
: X" u1 e  `! z* |; y2 A* i" v% O& N  node1:
! `  k6 r1 O, d! t# x! P/ |$ n3 S    image: eosio/eos ' e1 O8 O) `3 R
    ports:
. D. {; G7 v( p# s( X. j5 v    - "8888:8888"6 h) g+ G- g  t8 s/ b
    - "9876:9876"
) D1 ?1 [) v* ~8 p6 N+ v    volumes:
) `# E. J, j. }      - ./node1/data:/opt/eos/bin/data-dir
; b- d( D! |# p3 d3 s  node2:7 C" a$ |9 J' b9 P
    image: eosio/eos
# v5 ]: Q  q7 _. e3 `' y! Q    ports:
# M# k1 Z+ s  E. e5 I& v5 O. k    - "8889:8889"
$ f# y* N  H) R" f* [4 F; j    - "9877:9877"
! f% _+ p# x9 P7 V    volumes:% @8 x' S+ O) e) p% j( H
      - ./node2/data:/opt/eos/bin/data-dir! I+ M6 u( a& K7 Q! t+ _& r& _
    depends_on:
- T# V9 a4 t4 ?3 c7 U      - "node1"
& _! y2 {) U7 {3 d$ @, W+ m- MEOSC使用) j! d2 n$ w+ c* B  g- W
EOSC是EOS的核心进程EOSD对外暴露的RESTAPI命令行工具。EOSC的使用会利用到一些内置插件,插件在EOSD的配置文件config.ini中进行设置,如与链的交互需要使用’plugin = eos::chain_api_plugin’。为了签署交易并发送到区块链上,需要使用‘plugin = eos::wallet_api_plugin’。为了查询交易和历史记录,需要使用’eos::account_history_api_plugin’ 。3 p8 G* G& t2 p- f1 _
# Plugin(s) to enable, may be specified multiple times
2 {! `8 P/ i6 K0 zplugin =0 ]4 X+ l6 {/ n5 L# k
eos::producer_plugin
  x! D' M, A$ j( xplugin =  R$ I* i2 W7 h# f# w
eos::chain_api_plugin
2 x; d' l0 A6 o9 T! o5 T) ~1 Dplugin =
. t- I2 D1 }2 l/ F9 b4 Seos::wallet_api_plugin: T. d. j5 v3 Q: V( P
plugin =
  a/ O, ]* N/ Y0 H) C. neos::account_history_api_plugin
) m5 ^" X8 [& k* r, n8 o启动eosd后,可以使用EOSC查询当前的区块链状态4 Q: `# Y& T* C5 o$ Y- ]* N
docker exec docker_node1_1 eosc get info
0 H( `% f) a: F- X9 K2 e  Y{$ O2 f. Z2 Z) N, s
  "head_block_num": 23449,. T/ c6 o- F3 ?; ^. S, [/ m& e
  "last_irreversible_block_num": 23432,9 K2 e. y* _7 R- ]! S$ b; C4 M
  "head_block_id": "00005b996cc85962b28537c3d72696a012d1071638f5e4bad1809cf9afc9abb6",7 Y+ ^" i% p' R1 E3 f
  "head_block_time": "2017-09-29T01:53:33",
/ b, w# }) \1 D$ v6 S4 U" _  "head_block_producer": "initi",
' G$ ^7 y" S8 @) l  "recent_slots": "1111111111111111111111111111111111111111111111111111111111111111",
# w/ S0 c0 F& D. p7 k$ R, b  "participation_rate": "1.00000000000000000"
5 z+ P5 ^7 V- I9 _9 v}
+ d+ b; R1 i: Q2 o# O创建钱包
; q& A2 w3 _' p* _任何发送到区块链的交易都需要由所有者持有的私钥进行签名。首先,我们需要一个钱包来储存和管理私钥,使用EOSC命令创建一个钱包。: u1 V% h) ~; L. Y3 E/ g  N
docker exec docker_node1_1 eosc wallet create
" {: y& ~( c2 QCreating wallet: default
; j/ k% i3 z9 X5 i1 \8 VSave password to use in the future to unlock this wallet.
+ R$ W; ?4 q7 ^6 ~- Z6 c4 hWithout password imported keys will not be retrievable.
5 u8 G& X  `) j5 ]+ u, F"PW5JXSxkHqNEwRKCpG2JUTLqkR8SNCBXofkAwaFDLwQkNdqaSXwC8"
: z( j3 q! O# M8 k; ^$ r/ U3 [  G命令执行完成,会在eos-walletd中创建一个名为‘default’的钱包,并返回钱包密码。
) e( u) N7 h8 r8 h& \" ?: }这时候可以查看钱包列表; o. Z& ]0 K( S8 j
docker exec docker_node1_1 eosc wallet list
. V& _# T& R& eWallets:
4 D9 o" p3 i( w[
5 s! d1 L& o! G% k  "default *"
  P: |/ ~- \# C/ A1 C]( W* e  c8 |7 w/ {1 a# F& Q; M
如果你没有指定钱包名称,默认都操作的是‘default’钱包
: ]! Q* }2 `& O7 n+ g将私钥导入钱包
8 m, m( n" I3 {% }) I6 V) D如果你想授权某个钱包可以由某人来管理和控制,需要导入该授权者的私钥。7 L* K$ X! s" J2 P+ ~
docker exec docker_node1_1 eosc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
% M1 e1 t2 M  L! g8 F$ Limported private key for:7 X9 V' m( e/ l; O8 t
EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
6 s# m) e# I& S% W( J导入后,可以查询钱包已经导入的私钥和对应的公钥
$ w3 j0 I( \$ E3 Ydocker exec docker_node1_1 eosc wallet keys
; I7 ]0 S) R9 W* M. X' g[[
( R3 x- a; i: ]"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",1 ~' [" Y9 u$ {. T  h
"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"
) O" I, j5 [( y3 }8 |8 q: B]
" A2 O# ]# q" G% S; }; D]
  K6 v; d" o! q0 _" Q# K" I锁定和解锁钱包
+ r7 \$ W( B' w日常使用,为了保证私钥安全,可临时锁定钱包,锁定后查看钱包列表是不可见的9 s) _/ x0 B" B; m# p
docker exec docker_node1_1 eosc wallet lock
! h# o, L8 o* z! k7 ]+ A- @& _1 }! RLocked: 'default'2 N& R. L- U' h% T) k2 ?! y) T6 e
当想要使用时,可以用创建钱包时生成的密码来解锁钱包; _0 j4 G- y2 P- D
docker exec docker_node1_1 eosc wallet unlock --password PW5KVWrn81Y8PLAb52gr2FyXCanVavcrj9d5TC9C3yKhqq1PJYRPk
/ a! f( U- _0 `1 p; T$ [Unlocked: 'default'
# v# m% `7 Q  w; }2 o6 r解锁后,可以在列表重新看到default钱包了: O% d) T8 v1 {# S  i& L8 d! d
docker exec docker_node1_1 eosc wallet list+ [0 [- S# I8 j% v% R$ a! p+ |
Wallets: & R% {: n# \" i0 D! P8 Q
[) x3 x7 y4 z. W- [* [
  "default *"
* I! R  I, H2 A& A9 F]! ]3 X; }" F8 @/ o- D
创建账户+ K  R. N5 |0 X7 S& Y# v' ?( r
创建账户需要有两组密钥:owner和active。EOS使用EOSC工具来创建密钥对! V* N4 h& E8 H8 K1 v3 E( u
1)owner key.! Z4 _. m; ]2 T2 }! d0 }; B8 |
Private key:5JRc8XxvodWey4StZ2zzkUhCQhDaHvGMkABtfHzQR2ie4qaUFJ7
8 }3 ~4 ~6 b6 w9 MPublic key: EOS5mFEdAzxvMkHLQXt2v4naUjnBrPGmzMUCikymqhSR6m7QLGSTB' k( i; ]% n6 _4 a" S0 c' F2 a1 |8 F
2)active key5 b/ j5 `$ i5 u) ?$ v2 f5 U$ E' J
Private key:5KNzFCbToz2a9Hztz9Qen5cyJcM3x5Wpq4GFiTYZgGhzntXdmYo
6 s  z* ~0 n) L1 X% wPublic key: EOS5EdsvESpibWLJxupTqod1nswJnbiXQZuUcLiAWEEsqcZskymeB
1 D7 N$ o3 \8 s& w+ x* |EOSC不会保存生成的私钥
# }! H: v+ M' }# n  x( }; k因为后续测试智能合约需要,我们创建一个名为currency的账号。目前这个版本,所有的账户都需要用已有账户来创建,所以我们用inita账户的owener key和active key来创建currency。 为了使inita获得发送交易的权限,需要先导入inita的私钥到钱包。(参见私钥导入钱包的步骤). h, G( x( N# e* I
docker exec docker_node1_1 eosc create account inita currency EOS6NpEqWi177VKQkuJQL9V6Y3LqAAp9C2j
3 {% z+ V+ C% h" n" J执行成功,会输出一串json的交易信息,打印账户创建相关内容
) T8 g7 u. E$ E$ `& ^+ }) M3 i我们可以查询inita可以创建了哪些用户7 j7 O4 u% E1 S+ H% \
docker exec docker_node1_1 eosc get servants inita5 {; f/ k* q8 }& R( g
{
  K" P) ^0 C8 z+ w0 [  c"controlled_accounts": [1 _; g) A( Z: ~$ H9 ?
"currency"
4 P0 j* @+ m2 Y0 ]5 x6 F$ a]
# K$ k+ }& V9 a; u/ v# N1 y}
5 W2 b  n8 q* s( X# w. e1 h+ @/ o# u内置转账/ H* L2 t1 o9 |9 f6 l
创建账户之后,可以查看当前账户的状态,可以看到创建的测试账号没有余额,这样不少功能无法测试,我们需要试着给创建账户添加一些余额
3 U# V: k8 ^8 e- Q) B3 f5 wdocker exec docker_node1_1 eosc get account currency
/ u9 ?  E( P' b7 o* H{8 ^3 I% a& y7 t5 a4 \$ |" ?
  "name": "currency",
6 X1 N7 `7 ~  X5 U: U" i# d. E  "eos_balance": "0.0000 EOS",& }) j$ c# {7 z% ^6 R
  "staked_balance": "0.0001 EOS",, q1 O/ E' K/ M' G( O8 d( [+ {
  "unstaking_balance": "0.0000 EOS",
( e$ N0 k- B$ N, V2 V  "last_unstaking_time": "1969-12-31T23:59:59",
# C' i) [; T$ k0 R9 _  "permissions": [{& ^$ y8 o- A1 I: z+ G
      "name": "active",5 {1 b* i7 x2 P' p
      "parent": "owner",
1 R- g, n7 Q; p5 t      "required_auth": {0 C! N5 I7 L% [" x1 d0 y) h
        "threshold": 1,6 o% c4 e0 x1 N
        "keys": [{) U2 f( A2 j' n8 g- x
            "key": "EOS8ff42NMpJUybVj3nwUSnPpc3mMysKxyE4HVJy1E5o3fQv7knWf",
$ A) n4 G! M( O7 }% \( \" l            "weight": 1; c! B0 J1 d8 o' Q9 w
          }3 q7 t% K: h" B0 B
        ],, {" J+ ~7 K+ J9 }& @" |1 g
        "accounts": []4 T2 e* L+ m, D6 V8 {4 Z
      }
) z- k% c3 M" u5 u3 o    },{# k9 R; i0 V) l' N1 n, `0 }
      "name": "owner",6 G* H, S6 L$ I" X
      "parent": "owner",1 Z  j- C* N7 o( g
      "required_auth": {
+ c/ n: c7 ~6 j5 {( ?        "threshold": 1,3 V3 Z4 Y& s3 x9 I3 ?
        "keys": [{
1 y6 U. B" K7 |0 v9 t  ?* l8 ]3 W            "key": "EOS5fQ4saiHV426EQ7AKrGoD2AVMBYe77bnGSq42JjXBUfipv7o3E",
: k- t7 G/ `4 a) M            "weight": 1
' F; T$ a. g1 u          }$ a/ L/ ?1 w; q( B3 ?# w
        ],% x8 `. H% F! o: d6 y( P
        "accounts": []
6 p0 k* p8 ^8 h1 s7 k      }
5 [+ H7 y% z6 {/ @    }* ^% q; M, y; G0 I5 j
  ]$ H9 H5 @9 r( S# e2 l/ H2 Q0 [# L
}* Q, \% g% s* }4 ~1 a3 {
保存全网余额的创世账号是eos,查询余额状态
! J% a8 r. B9 \8 P0 Kdocker exec docker_node1_1 eosc get account eos: l6 L: [$ M0 [8 [- Y
{+ ~1 Z9 Z2 }: U) a  i
  "name": "eos",
& n; @0 Q4 F% U& b' l5 E, C7 w  "eos_balance": "69000000.0000 EOS",
9 l$ _2 ^, B. V  "staked_balance": "0.0000 EOS"," Q* H5 F. l# y$ s5 C9 Q8 n5 K
  "unstaking_balance": "0.0000 EOS",3 s* s: I( r5 M3 e6 }
  "last_unstaking_time": "1969-12-31T23:59:59",
4 v; `( a6 T: X% v3 h* r  N  "permissions": [{
3 l- Z- |. t2 W4 K, Z7 z1 Z      "name": "active",
2 F' p7 s6 \/ l) j. r9 X3 Z      "parent": "owner",+ z' I/ q! T. W& }8 i
      "required_auth": {
& @6 {* x  }" f        "threshold": 1,
2 U( n( d. J3 s! D1 x        "keys": [],' @- ~5 v6 O, V
        "accounts": []/ E- V# Y& w0 Y3 K* R& Y
      }
& g2 T9 J) b0 @* P    },{3 F8 W! N  N* q
      "name": "owner",
/ u/ p0 {% I  r! l. o  P" f      "parent": "owner",
3 a1 Y. t- `, b      "required_auth": {
. c' l* T% _, x4 E1 o& h9 c; s; e        "threshold": 1,0 I. m) f& N* g2 P- n* O8 a
        "keys": [],
: x+ f; ]0 n0 v        "accounts": []
: `7 s9 t8 G4 R* N! l, g      }* e  _' r2 U+ d
    }
$ j7 P' m. `; }( t  ]
) q/ T( y' T0 o8 n4 k1 r}
' _* }' t4 M$ V" s, m, H- O; Y我们可以通过创世块定义的创世账户使用EOSC给当前创建的账户转移余额5 ?" D' d) [# {
docker exec docker_node1_1 eosc transfer inita currency 100000000. \5 O3 s. x9 r; x& t5 @) Q3 [! D
{" l: r/ H8 S. r/ W4 K& c& i
  "transaction_id": "59575b8caf08eac7c00eb7483c048f12d0e7abf1ede839c3b2ed41dc6c5c7c5f",
7 f/ U0 k7 z& A  }* A) F2 G  "processed": {& V2 X5 v0 Y) D
    "refBlockNum": 24199,
* [. j6 x5 O: @; B( V9 s    "refBlockPrefix": 1485651173,6 B! r. u# h. t, g/ C, m0 P+ {: E
    "expiration": "2017-09-29T02:31:03",
% X# ~: v$ j8 N% N- y7 c4 o    "scope": [# u# G  q+ d" X& b7 t
      "currency",
. B3 B$ T# y9 S, l# L9 D6 Z      "inita"
8 P9 E- I: p, X' e  X    ],5 R6 O7 @) z7 R
    "signatures": [2 }1 r, {. Y* Y
      "1f14229bdd4bfb927021bf96ff0651c8b0fa5666e9f5cf423a0270a1b91f2d2f690b573e179d8475ce2c6b160f5cd5507d58a44f8f6cf536348584efa8dd62ade0"4 X3 K8 J; _( @+ r' X8 `
    ],
$ L9 J7 A, u* L5 n7 Y" t  U: `    "messages": [{
+ i$ Y/ X" }. q: t        "code": "eos",- F; r6 a% x9 e$ a& \
        "type": "transfer",8 c7 F, e8 `8 ?' D" d
        "authorization": [{
: W, x7 K  t# V/ ^            "account": "inita",7 N. N" b2 u8 _! H! s: D
            "permission": "active"/ v% H6 M: _% @- L) u0 ?/ ^
          }
( c; s* h0 i) g* R/ G        ],, z% ^) D6 L3 v; _
        "data": {, \& t. F% w! E% p
          "from": "inita",
, P1 X% X7 Q8 p+ P+ C' D$ g. e  q          "to": "currency",9 ]3 W2 N$ @0 x: r6 T
          "amount": 100000000,
* a6 f3 I( t( f0 S5 x3 K1 Z1 ~          "memo": ""  h/ H3 R# n6 ~* g' X" f
        },
% U- b7 V, g7 F8 p  O        "hex_data": "000000000093dd740000001e4d75af4600e1f5050000000000"
8 A% |) y# ?* Y      }
7 w# A) r# y% k4 E; B" }# \/ [    ],3 o( S3 T8 y% i' j
    "output": [{, w5 s* Y- `! \$ |2 Z. X+ I" c
        "notify": [{
% c1 P5 R3 a6 V) G6 {* z8 B* K            "name": "currency",6 g  g6 S) v, N  A5 M5 F5 B* H
            "output": {/ S  N" N; J! t- Y' U+ {1 l; v
              "notify": [],
% m8 K2 k4 f, v0 _! c8 R% S8 V              "deferred_transactions": []% @1 R/ z1 h# X1 |
            }* d+ \* _& @1 A. R" S& O
          },{+ b  `5 e+ [4 C- }
            "name": "inita",, y0 Z$ `! S) Y3 u0 R& o
            "output": {- s9 F8 F6 U+ h* B! h4 e( u
              "notify": [],5 t' `, H$ h& H, H9 H
              "deferred_transactions": []/ a0 Z9 E6 k/ v1 c1 T  B
            }5 k& f. P6 R) s. c" {5 W1 {
          }
/ @: I+ i5 L1 q- b* J        ],- A& M1 z3 B; X8 U
        "deferred_transactions": []
' y! W9 V% U. T0 K" A) P8 x  b  A2 }      }- v  B# f3 A* G( ]
    ]
4 |, B) h. |/ t6 O' H  }/ z9 X; }. b* `; ]
}
4 a* y* s  F) }+ o* }* \再通过执行get account 命令,验证余额已经成功转移到创建的账户下
' K# W% W- J2 z$ L. _! P查询交易历史
- r! q6 u; `+ h8 _" I查询交易历史会使用到插件account_history_api_plugin,我们已经在config.ini中定义6 p; u6 a2 c0 N; R) ^
docker exec docker_node1_1 eosc get transaction
; U/ c" j8 [) A1 ^1 Z7 T; ~4 `如果需要查询一个特定账户最近一次的交易记录3 a& _* e8 W8 l- t! G6 \
docker exec docker_node1_1 eosc get transaction inita% Q8 c1 e8 y2 x0 P" }
创建智能合约) a  G7 j1 a3 G! b7 m4 J3 F0 f
官方提供了一个示例合约currency,我们依然使用EOSC来创建并部署智能合约,合约代码位置contracts/currency。& G. c4 E- v( z. T; z; Q6 K
1)为合约创建一个所有者账户。前文已经创建了currency账户  c2 R* u# U# @
2)检查区块链上有无同名合约$ N% ?  d- \# M$ Y
docker exec docker_node1_1 eosc get code currency $ z: U' m- m4 F; T1 f: e$ Y
code hash: 0000000000000000000000000000000000000000000000000000000000000000
4 K+ n+ y5 p% W, ]( j' {3)为了获得部署权限(发送交易请求)需要将currency的active key导入到钱包中
+ V/ p6 m# e6 C$ z4)部署合约(.wast后缀文件)和他的abi(.abi后缀文件)$ {( x/ m$ X! Z
docker exec docker_node1_1 eosc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi7 S4 t, h  m  ?2 N" T
Reading WAST...
  w4 g3 s2 x/ [4 rAssembling WASM...  W$ C! ?+ D7 {1 \& g5 O' ^
Publishing contract...
& B6 d( T) r$ [, [+ Q( g' v$ ?9 c屏幕打印部署成功相关的信息,并查询合约hash
3 ]# e* }3 ~" z2 T5 {/ T- }docker exec docker_node1_1 eosc get code currency
: P5 [( W) o- s' G: E" `7 r# Icode hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf& N0 n4 c7 C  g! X$ A5 L
调用合约
- B" x* p6 H0 B在合约部署到区块链上之后,所有的currency余额会分配给我们创建的currency账户。我们可以调用合约测试做一些转账交易。1 C1 n# f- C% H+ B% e0 ~  c
为了更好了解区块链合约的调用方式,我们可以通过.abi查看可以执行的操作列表和消息结构。& k" M  b, W2 [0 _5 H
docker exec docker_node1_1 eosc get code -a currency.abi currency
1 _2 b5 Z1 [7 D9 K) g9 I7 ~/ a( acode hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf
8 x/ |; U8 ^$ a* U' y; ysaving abi to currency.abi
7 W  V) I3 s) W" e* [, gcat currency.abi #查看
& a4 ~' c2 @) I, N; I* |/ |3 C{
, ~$ n6 v7 W6 W! P/ Q, @3 A  "types": [{( j- I' e0 l2 w
      "newTypeName": "AccountName",
, p- L: T4 s% l& N      "type": "Name"
# \$ k: H0 q) |6 j    }
) I8 d' K5 f' z1 n' ]  ],
+ F- I8 S% c) c) R# |  "structs": [{
+ |9 \3 S  \( l8 \% Z      "name": "transfer",
. v' x: o/ \6 {4 Z3 J+ h      "base": "",4 t( ?2 W$ h; K; J9 l% D7 g/ H
      "fields": {1 ~9 N6 G( {4 k/ E& u7 g
        "from": "AccountName",$ ]  s4 W8 }8 e9 }; X/ P
        "to": "AccountName",
0 g9 {7 D8 x2 z) H* q9 e1 `; Q4 m- H        "amount": "UInt64"
1 c! P- Z% Y. \      }
4 Q4 @% o6 C3 |/ H5 K' ^# {. `    },{! T0 K1 ]4 i6 E
      "name": "account",
; B% F" m. V2 F0 Q9 h, W      "base": "",
8 y. B0 b4 P" q/ @' [1 C, M5 {      "fields": {* ]3 n, Z- Q. N
        "account": "Name",) }0 V& [0 M7 ~; v; C) N, Z
        "balance": "UInt64"1 O+ }* C( y2 A) ^4 }& E
      }; s0 @: z* z+ S5 D- ]7 q
    }
$ f. K9 W/ Q) v$ Z8 o/ Z( ?0 q+ }  ],
  j9 d3 Y- q8 [6 b7 i  "actions": [{
' y" l$ u0 V3 N      "action": "transfer",5 e" Y5 A/ i1 n6 o* ], e
      "type": "transfer"+ r8 T1 l+ _# H! k5 T) w( h, W
    }/ }5 m+ ?$ U7 \) O/ l: j
  ],) m  L/ g9 |+ C3 H7 B
  "tables": [{
+ h# t5 E5 @# \      "table": "account",3 V# e; ]' x$ B# }9 ~6 F1 o# c% l
      "type": "account",
0 T  O5 p% x" c4 \$ K9 h      "indextype": "i64",+ f0 h8 q2 q$ k6 T( h9 [) I# Q1 y
      "keynames" : ["account"],
' f) e6 }/ v) @      "keytypes" : ["Name"]
: ~7 N9 H% d6 r2 a. g+ w    }
  R) x  u5 ~  d* k  ]
# X3 D' L& F, ^; Q$ [; a}
$ {- c" ^4 N( g  h; X- X通过上面的abi我们可以看到currency合约可以执行transfer操作,消息格式为from,to和amount。我们调用合约从currency账户转移50个余额到inita账户
. a0 d" F- Z* H& F, C1 v4 Kdocker exec docker_node1_1 eosc push message currency transfer '{"from":"currency","to":"inita","amount":50}' --scop' H/ Y6 w8 m" f# P. f
执行完成,我们查询余额验证结果
0 w2 J! R; j8 Q5 I! `docker exec docker_node1_1 eosc get table inita currency account
5 O! J1 Q! Q3 W4 h) h, ]$ Y7 w! E. J{" z; z2 P6 j5 a& U8 B. n
  "rows": [{
9 \8 d8 o7 t, s& T0 \: X2 `      "account": "account",
6 Z2 T3 \* M; h3 k" ^! {$ i      "balance": 50
$ d5 D% o& O5 _* d' U       }9 D- e- e9 @2 J* _# j
    ],
* H  h* u4 ^# D4 u6 g3 c  "more": false  V+ j, \$ m. a, g. y% r
}. j+ y8 T5 {8 y$ j, q0 q
docker exec docker_node1_1 eosc get table currency currency account
3 m' A, k8 J2 |# V& K{0 W7 G* N& W; A) U# i- @* E5 y
  "rows": [{' X: z* Q' x5 A" J% F2 z
      "account": "account",
. K8 }! Q1 s, E8 x, J      "balance": 999999950! g9 O. {) |; x; P. D: q. k
    }
% i8 j) p" K* V  ],. k5 U, P: N; W0 S
  "more": false, z! j! X. q# p3 }! L5 c4 K
}
% x, J! |- s5 `2 K: {" l余额不足的账户尝试转账,会提示失败
8 a0 `: H. H7 a) q+ Odocker exec docker_node1_1 eosc push message currency transfer '{"from":"tester","to":"inita","amount":50}'-S inita -S tester -p tester@active
0 M1 }# A9 G3 E0 _1 }2 u) c3543610ms thread-0 main.cpp:271 operator() ] Converting argument to binary...+ x* I. t4 @! a
3543615ms thread-0 main.cpp:311  main ] Failed with error: 10 assert_exception: Assert Exception5 S% h" V0 a, P; {  c1 }
status_code == 200: Error : 10 assert_exception: Assert Exception' H$ p8 B* B& {, W- \2 Z5 B3 x# J
test: assertion failed: integer underflow subtracting token balance
9 ^0 G7 |# Z1 ?, K+ r{"s":"integer underflow subtracting token balance","ptr":176} thread-1 wasm_interface.cpp:248 assertnonei32i32 [...snipped...]
, t" t' m/ y: J$ i0 r% \6 _查询合约/ L, d7 k( \& p1 A% ~& y4 t# ]8 k$ [% d
如上文验证步骤,在调用完合约后,可以通过查询表来验证每个帐户持有的余额。
. }1 Q' M4 t# Pdocker exec docker_node1_1 eosc get table currency currency account
8 @3 _1 v4 q+ h* [4 M) p连接特定节点
' I; W* p- P( c) c2 S默认情况下,EOSC连接本地端口8888的节点。可以通过指定主机地址和端口来连接其他EOSD节点。同样的,钱包服务也可以指定特定的主机地址和端口。& Z/ j) h& B9 g% k& S% m* y
docker exec docker_node1_1 eosc --host  --port 7 Q, h  t$ [9 y, l- @
链接独立钱包服务
9 j& Z0 s! e( H3 f除了使用EOSD内置的钱包服务,也可以独立部署钱包服务# |2 w1 j) c4 p( V
docker exec docker_node1_1 eos-walletd --http-server-endpoint host:port
- X# Q; A7 a2 t" M调用独立钱包服务需要添加如下选项
1 }' H+ V; S- V5 n  w5 sdocker exec docker_node1_1 eosc --wallet-host --wallet-port
  A0 Y: F- E3 L0 }2 C8 q1 k免签名验证
; u2 F! i, Z+ L/ |# ^$ s开发者如果需要快速测试功能,可以跳过节点签名的步骤,这样可以解耦密码学的问题而关注应用功能
* D) k0 n2 u  |2 E6 a启动时使用特定参数! e1 w9 M$ W' C
eosd --skip-transaction-signatures6 R4 s* [3 o; E& f; q& Q$ c2 S
EOSC调用时添加-s 选项) z% K+ p# ?2 Z) s& O' e
docker exec docker_node1_1 eosc   -s ) g7 t; h! d( Q: D+ N  V$ v
其他RPC调用
% [: u, d: ^' f: ?( y' |. K! }EOSD RPC 包含通过HTTP RPC与eosd和注册其上的插件进行调用的方式.# M* E- c3 g& t7 b
1)区块链API 配置% C: e$ `* H) j! Q& F
想要查询eosd信息需要启用plugin = eos::chain_api_plugin插件并添加至config.ini中/ q! _6 p; Q' r1 v. C3 F
2)get_info接口用于查询区块链的基础信息6 D7 W  l/ ?3 x; c0 ~
curl http://127.0.0.1:8888/v1/chain/get_info " u6 J7 p& B3 @8 ?. \) ^* u
返回结果如下:* S, X  [8 y# ]; S& t6 `  V5 U3 Y
{"head_block_num":25028,"last_irreversible_block_num":25014,"head_block_id":"000061c443dd3e85932c442a8e5176b7ac822a0f6d09d034298f508e71c5ae6c","head_block_time":"2017-09-29T03:12:30","head_block_producer":"initm","recent_slots":"1111111111111111111111111111111111111111111111111111111111111111","participation_rate":"1.00000000000000000"}
; S1 K; U# M; s- k' f4 o7 oget_block接口用于查询区块相关信息! }. C4 l, R- L# o+ ^
9 M: g6 v- L) M4 Z0 n, T  c' a9 m
curl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":5}'
$ y9 G8 L6 Y6 ^: }& Xcurl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":0000000445a9f27898383fd7de32835d5d6a978cc14ce40d9f327b5329de796b}'& }! {5 B1 D, N" E3 {2 b7 P7 o
返回结果如下:7 R0 Z! V. L: T& |5 k! D
{"previous":"000000047aba47492d2143beebfdfba171192970a0f9248f0408a8614ff42dca","timestamp":"2017-09-28T06:21:21","transaction_merkle_root":"0000000000000000000000000000000000000000000000000000000000000000","producer":"initf","producer_changes":[],"producer_signature":"1f25a5b592b7f605ffdbd1cba90497e94b3e1c0e5805b70851de6875e0f33e20dd1f363cd1fcfd2dc8421fb918d694d260e255956cc7f8f554fa0be01d805a84ed","cycles":[],"id":"00000005bf39fd177fc2ea8ba6540d5f31e8b07218f054016123a34b16d0b30e","block_num":5,"refBlockPrefix":2347418239}
& E: O4 b# i/ [% w3 a" T4)push_transaction接口,调用合约交易
' \, v. x0 [4 Q9 Z! Y( e8 P% T( n该调用为JSON格式并会将结果更新到区块链上
. l3 _( S! r3 E7 a2 J执行正确的结果返回
& ?1 g$ }% k& }+ x返回 HTTP 200 和交易ID号9 ?& D  v0 T( B" t+ Y0 ?( ]
{ 2 `/ b( G4 Y; K8 k5 g& p
'transaction_id' : "..."
( w5 n+ Y" o0 W, H' @}
1 P# V" T* G$ ^" w; M0 d执行错误的结果返回,一般为400错误(参数错误)或者500错误
; q$ V  z( D" }- y+ AHTTP/1.1 500 Internal Server Error
& ?8 Y* e) v& G$ A. A! r/ uContent-Length: 1466
4 [; q& m4 S* F4 @8 g+ i- B...error message..
! T9 Q8 k3 b5 _6 v9 {push_transaction 调用方法8 H# y0 t. }- ?* n/ H7 R3 u. E
curl  http://localhost:8888/v1/chain/push_transaction -X POST -d '{"refBlockNum":"5","refBlockPrefix":"27728114","expiration":"2017-07-18T22:28:49","scope":["initb","initc"],"messages":[{"code":"currency","type":"transfer","recipients":["initb","initc"],"authorization":[{"account":"initb","permission":"active"}],"data":"c9252a0000000000050f14dc29000000d00700000000000008454f530000000000"}],"signatures":[],"authorizations":[]}'
1 c2 q" T3 \9 C/ p% d8 D+ j" o8 K2 F6 ^此示例模拟一个转账交易。 refBlockNum和refBlockPrefix使用的前例block查询的结果
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

罗宾虚汉 初中生
  • 粉丝

    3

  • 关注

    0

  • 主题

    16