Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

EOS纯技术上手学习

罗宾虚汉
146 0 0
EOS.IO 已发布黎明V1.0版本。EOS.IO 黎明V1.0版本是第一个预发布的 EOS.IO SDK(软件开发工具包)。EOS.IO黎明V1.0版本可以让我们体验下EOS一部分区块链特性和简单上手开发、测试。本篇主要是一个快速的review目前EOS黎明V1.0版本的功能上手。" O* A) X: i6 _+ `
主要内容:
" C7 k4 Y' C0 I9 t. @% B
9 @% R" H% Q& _EOS Docker快速部署
) w+ m, W( n9 V$ K- j3 z& I* e' h6 e2 _% Z
EOSC使用! H) b$ c2 W1 N/ W" M; ^

4 `$ V% A- e/ T3 q6 e9 d! o# ~, y2 i创建钱包
1 S8 A. ~4 T& w
. z! P1 |, S6 N/ @/ H6 m将私钥导入钱包3 |7 Z7 k6 B$ z: I6 V
: w4 c1 j, t& c! V: ~
锁定和解锁钱包
% x9 d* v0 o2 i3 b7 L6 u3 U7 W+ g2 G" n+ J( q- }! Z
创建账户2 x3 z) I4 i- D
& A/ L; s/ {* O4 O+ ]
内置转账
% i9 S* f2 ]6 z! P+ M" v6 I, e8 q: O' T# l! Z
查询交易历史
7 N1 z' j! T- _1 x: `9 B+ d9 S: ~7 H( b: G2 ]4 w3 W
测试合约 - currency
/ T9 B& F: F6 @# R% O# M
: P# k: k2 l! W! L  @调用合约! h9 n2 A' g) s1 e1 v4 Y2 x

( P+ P' P" n$ P# I# X6 G. n( z' ]查询合约
; j  a* c% h1 X: ^
, j* y8 P; M- V! V  g/ C. @  R链接特定的节点
6 x# A; h$ t9 m3 b0 ?6 _' o( A9 ?0 ]1 u$ v  |
链接独立钱包服务2 x2 H+ t  |* f5 a" ]& p2 W
) b& C; |5 m7 a& S( l, @& F
免签名验证: b3 U" u1 z, M0 _" ^  f
- ^$ X8 ?$ j5 n: \0 R& ]$ a/ x! s
其他RPC调用
8 s) V/ K/ d) j, p
$ J1 N% h* V# j, @# i! ~, G# g! g+ a4 x! v2 \+ m
EOS Docker快速部署
3 w! ]. X+ [, J  n构建eos镜像  n7 t% E2 i: D4 E
git clone https://github.com/EOSIO/eos.git --recursive" u) h8 K+ g) U! R  S9 e
cd eos* Z) V: G) j. k( Z7 d- `8 J
cp genesis.json Docker
# X8 O2 c/ x! [9 Odocker build -t eosio/eos -f Docker/Dockerfile .; {7 H* j: q7 B0 ^4 k
启动容器
7 I9 j8 }# R0 P, f# Ssudo rm -rf /data/store/eos # options
( K% q* j( J3 N* `" lsudo mkdir -p /data/store/eos) i  d; F) y8 Q( m) H0 O
docker-compose -f Docker/docker-compose.yml up" Z6 k7 `9 b7 O, L% v) o
如果 docker-compose 启动有报错, 可能需要给文件存储目录赋予用户读写权限
6 p7 d" i: ?+ r+ Vsudo chown -R SYSTEM_USER /data/store/eos) w  l( C! N/ N* d" s
验证,查询区块链状态信息
5 K6 l; N9 ?5 f( V( P. ccurl http://127.0.0.1:8888/v1/chain/get_info
4 P% R9 t. `, G6 N8 G/ h如果想使用多节点环境,可使用yml文件启动/ _0 C% u+ I, r3 |, ^
version: "2"/ i  |3 m% ]5 a1 ?# T3 U7 w' h
services:
; s- a: A" S/ Q1 h! I  node1:
  u# S2 a8 S: f5 Q/ p. M) B    image: eosio/eos " r& H1 K4 j; O( ~6 ]
    ports:7 Q- @& y# q' q: z7 s! {6 q# Y: Z
    - "8888:8888"* {" K. o+ ?9 y$ A2 a+ T
    - "9876:9876"
9 d( z/ x$ Z* e+ k    volumes:) Y$ i! a, h" h, p3 r
      - ./node1/data:/opt/eos/bin/data-dir2 N$ D% T' r7 m
  node2:
% ~2 \* \7 b! b, O% N& y2 ]5 T    image: eosio/eos
: W0 X% O# B( C4 Y    ports:
$ m$ w! G% W* z% v    - "8889:8889"
2 Z" f2 ]2 p. G: D6 o    - "9877:9877"
4 j! V+ R6 P( b7 H* z    volumes:
$ |2 U( L6 Q4 {      - ./node2/data:/opt/eos/bin/data-dir
1 L5 m4 [; s( V5 O4 F$ q# |8 F1 f    depends_on:
" H5 M+ m& C5 x8 ^% `5 l9 t7 J$ ?; j      - "node1"
2 S8 a- Q; u1 v: F! o' Q# I9 g( J2 b( eEOSC使用0 R* t' S( v: F* R: {
EOSC是EOS的核心进程EOSD对外暴露的RESTAPI命令行工具。EOSC的使用会利用到一些内置插件,插件在EOSD的配置文件config.ini中进行设置,如与链的交互需要使用’plugin = eos::chain_api_plugin’。为了签署交易并发送到区块链上,需要使用‘plugin = eos::wallet_api_plugin’。为了查询交易和历史记录,需要使用’eos::account_history_api_plugin’ 。2 I% l7 z# Y3 J# \7 v3 b, m
# Plugin(s) to enable, may be specified multiple times
- w8 u, }+ {+ g: \plugin =- P3 W0 v* E3 B9 P7 d6 P
eos::producer_plugin
6 o) x0 Q* g5 ]# dplugin =( K' ]9 w7 b! N3 A; j3 c
eos::chain_api_plugin. g& X, F9 T  K1 t: Q
plugin =
# E" W! v  |! E6 K, h9 Veos::wallet_api_plugin
, \, X) W" A, v% ?( Lplugin =
% t  F' t8 k% y. G  Seos::account_history_api_plugin+ j  b. t0 M/ x. Y5 ^# ~: s; ?4 P
启动eosd后,可以使用EOSC查询当前的区块链状态
$ ~: m1 i) t9 ?& edocker exec docker_node1_1 eosc get info
) R- G+ T( I6 M+ o5 `{
1 A9 Q# x9 ~* Q) L  "head_block_num": 23449,
! @3 i# F; j! v5 V0 |3 L7 v8 o  "last_irreversible_block_num": 23432,
. _7 ]( H3 }; g. u  "head_block_id": "00005b996cc85962b28537c3d72696a012d1071638f5e4bad1809cf9afc9abb6",
+ P. e2 T! w' {  "head_block_time": "2017-09-29T01:53:33",( J7 ]; q- {8 i! }& A3 D
  "head_block_producer": "initi",4 G0 d9 p. h/ I$ j
  "recent_slots": "1111111111111111111111111111111111111111111111111111111111111111",
: A) o0 z  n0 {  "participation_rate": "1.00000000000000000"9 F+ _( O6 Z4 u
}  X8 x/ R5 S( M% {, K9 `; }. T) e! s/ A
创建钱包5 M8 i6 T$ m$ t, Y- \
任何发送到区块链的交易都需要由所有者持有的私钥进行签名。首先,我们需要一个钱包来储存和管理私钥,使用EOSC命令创建一个钱包。' D: f7 J3 I3 W/ m1 a3 @
docker exec docker_node1_1 eosc wallet create
5 _+ K9 t3 {! o' _( b8 j- rCreating wallet: default
! I7 S# ]5 m2 V+ b7 ^' D- RSave password to use in the future to unlock this wallet.: H- m, u! D$ N9 p( v; d3 }  Y9 I* s
Without password imported keys will not be retrievable.
* j- i) n4 c( y5 Y4 g"PW5JXSxkHqNEwRKCpG2JUTLqkR8SNCBXofkAwaFDLwQkNdqaSXwC8"& t4 o. W1 q' P$ w! J4 t  J  z
命令执行完成,会在eos-walletd中创建一个名为‘default’的钱包,并返回钱包密码。. P2 q" B- Z  I9 S
这时候可以查看钱包列表
, O( s! g8 }% [docker exec docker_node1_1 eosc wallet list: Z/ J5 M3 P" F' ?5 |5 N
Wallets:
/ K; `. m5 o: V, |! c1 l7 E[# B* o3 j$ P- W% Z7 h) I1 s
  "default *"
' z) G' ~! ]3 l3 b- m]
* u( Z# Y' h3 e; O如果你没有指定钱包名称,默认都操作的是‘default’钱包
3 a1 q5 R/ p4 n( k' s& T4 E+ U将私钥导入钱包# S0 j5 E  Q- G  V8 Y, a
如果你想授权某个钱包可以由某人来管理和控制,需要导入该授权者的私钥。' z$ R9 f4 @. u- a% S
docker exec docker_node1_1 eosc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD36 |- i5 b/ J- @( t8 k. F" n5 {
imported private key for:1 @7 [4 k1 g" [1 q
EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV% @( \& s; w9 y3 h+ F; y
导入后,可以查询钱包已经导入的私钥和对应的公钥
3 t' S: u# _: J' o" M  wdocker exec docker_node1_1 eosc wallet keys
; I2 M/ A* x, c/ f5 S[[* r1 P; {$ I) k0 I. }% Q
"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
. W+ Z* o5 C/ e6 A- M6 g"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"1 c/ E# |$ K1 I
]
- s0 R* }0 g2 u' T, s5 H5 R" k]0 A1 O+ m: u% f6 q& ]
锁定和解锁钱包
1 c6 h  F$ `6 S; b6 @+ U" J3 H日常使用,为了保证私钥安全,可临时锁定钱包,锁定后查看钱包列表是不可见的
, C1 w4 t% @) Y8 U" J! t& edocker exec docker_node1_1 eosc wallet lock
/ n; _2 A- O  ~6 `3 \  P' ?- ]# BLocked: 'default'
, B7 i- X, U' L2 Z' ?当想要使用时,可以用创建钱包时生成的密码来解锁钱包
$ C# ~4 Y' J/ A5 ?# c( a( wdocker exec docker_node1_1 eosc wallet unlock --password PW5KVWrn81Y8PLAb52gr2FyXCanVavcrj9d5TC9C3yKhqq1PJYRPk
# U0 \7 x* q  j  q5 @Unlocked: 'default'; h7 o8 L+ @  i7 h
解锁后,可以在列表重新看到default钱包了  y) x$ C6 d* P( V2 t+ h4 ?7 z
docker exec docker_node1_1 eosc wallet list
7 \; k' d8 m7 {0 hWallets:
( c$ o6 N% i5 o: i- o1 n1 H7 O[
4 F) Z) i5 ^0 A' N  G; V  "default *"1 A9 s6 t8 [& `
]2 N- a. r: E' T+ q/ J
创建账户, a7 q( ]7 G. A0 A( J. F) X; V& {
创建账户需要有两组密钥:owner和active。EOS使用EOSC工具来创建密钥对0 o+ t4 ?8 x  Q4 D1 Z$ v( m
1)owner key.
1 a) v) J9 m, Z3 dPrivate key:5JRc8XxvodWey4StZ2zzkUhCQhDaHvGMkABtfHzQR2ie4qaUFJ7
  Q7 `: M  R$ w: RPublic key: EOS5mFEdAzxvMkHLQXt2v4naUjnBrPGmzMUCikymqhSR6m7QLGSTB
3 j' _5 x- l: |- l; p2)active key1 @# A. m* M- k- p
Private key:5KNzFCbToz2a9Hztz9Qen5cyJcM3x5Wpq4GFiTYZgGhzntXdmYo* u6 R" e3 l& h
Public key: EOS5EdsvESpibWLJxupTqod1nswJnbiXQZuUcLiAWEEsqcZskymeB
  _' r. _+ \+ j+ P  g0 s" xEOSC不会保存生成的私钥1 A# M1 k1 \, t3 Y
因为后续测试智能合约需要,我们创建一个名为currency的账号。目前这个版本,所有的账户都需要用已有账户来创建,所以我们用inita账户的owener key和active key来创建currency。 为了使inita获得发送交易的权限,需要先导入inita的私钥到钱包。(参见私钥导入钱包的步骤)/ S, Z- L) ]& }% P+ X' c1 ~' y( w. ~  ^
docker exec docker_node1_1 eosc create account inita currency EOS6NpEqWi177VKQkuJQL9V6Y3LqAAp9C2j
' Q' S- J- N2 J. N# _9 }执行成功,会输出一串json的交易信息,打印账户创建相关内容9 g4 i; w% `1 G
我们可以查询inita可以创建了哪些用户% O6 O6 V& L: s& D
docker exec docker_node1_1 eosc get servants inita" a" c* P, c. N( s) ^, E
{
3 Y/ Y" F1 H# e/ b" ?4 n' r6 X"controlled_accounts": [
; q; |1 |$ c# T" g"currency"3 K- J/ K5 `% V5 Z
]
9 ~2 Z" {; |0 J) Z- k}
0 Z) Y" v; a, f* f  `; t& `内置转账
+ n' K4 `) I* e+ l, ~' \- U$ M创建账户之后,可以查看当前账户的状态,可以看到创建的测试账号没有余额,这样不少功能无法测试,我们需要试着给创建账户添加一些余额% J) v$ g$ B! k& A
docker exec docker_node1_1 eosc get account currency3 l, D* {% q4 j7 `
{
% `; O% |5 L9 m( a+ @3 ~+ i9 W; [  "name": "currency",, j7 [) `# B* C; s/ \
  "eos_balance": "0.0000 EOS",
$ s4 m. [$ p" A, G$ d  "staked_balance": "0.0001 EOS",
, ]; `& s7 Y7 ~1 z  Y  "unstaking_balance": "0.0000 EOS",
6 h+ Z8 u+ f; h( i# m  "last_unstaking_time": "1969-12-31T23:59:59",
0 n% w1 U7 D& s6 x  "permissions": [{! x/ f4 {6 `# y+ h' C
      "name": "active",4 d2 v' T" k& h  M
      "parent": "owner",
+ ^. Z3 S! @, s% G2 X+ ~6 C2 u      "required_auth": {) n  F6 A4 N% r& u
        "threshold": 1,
( P! t, R% w  B# N  L9 R        "keys": [{
8 f  z2 b, l* a$ r2 D, h6 v            "key": "EOS8ff42NMpJUybVj3nwUSnPpc3mMysKxyE4HVJy1E5o3fQv7knWf",& O3 n* [$ I3 \1 A3 E, f5 u& G: `7 I
            "weight": 1+ r( h' b7 t+ d+ ]4 T$ k4 u
          }6 O* ]2 \) y8 s# {
        ],6 R1 C. q5 S/ e" l
        "accounts": []: g8 K- _) X  U0 ]' a7 U' T0 }/ n
      }- }; a4 n  f# r3 b0 P2 _
    },{4 x  i& e- m# s* |
      "name": "owner",
# p- ]0 i; e' h; f7 U+ q! r      "parent": "owner",; q: Y# Q% Y7 x5 r8 b( C# p
      "required_auth": {6 g5 _( j! a  h% M1 Q. T
        "threshold": 1,+ L7 t# b- e# ~9 q1 I- y. Y
        "keys": [{
9 W4 r, j/ P+ v            "key": "EOS5fQ4saiHV426EQ7AKrGoD2AVMBYe77bnGSq42JjXBUfipv7o3E",6 d  ~" v; B- C6 A. Z3 k" C1 H/ X, j
            "weight": 1" A, Y+ K7 `3 T1 }3 j2 h" m3 y0 h
          }
; }& g# u0 k$ s0 u! f% `        ],! v. l$ O( g& Z$ |! T
        "accounts": []
5 @! N, @4 ?. \4 d      }
: R! M# i" T, W. }3 A    }0 a* Z( s8 N& N- a1 `& @8 S1 j; p/ u
  ]- s. e: ]! R* U. @: ]
}1 K' y2 N) y% w- |6 u9 M
保存全网余额的创世账号是eos,查询余额状态
* p$ ^$ {; }* b0 o8 Rdocker exec docker_node1_1 eosc get account eos
6 j+ U; \+ p5 D$ E& e$ [* u' J{" U0 o) B! H! t5 m8 P: z1 y
  "name": "eos",1 N; x2 O) L) ^+ k* p7 P$ _% X& A
  "eos_balance": "69000000.0000 EOS",: R- ]! g$ X3 V
  "staked_balance": "0.0000 EOS",
9 \, _+ ^% R3 l5 H9 U" h% q0 f  "unstaking_balance": "0.0000 EOS",- p5 R" u$ b- W' D, a
  "last_unstaking_time": "1969-12-31T23:59:59"," y( v  N2 K% r0 L& L% P
  "permissions": [{3 G1 N7 m; w3 `0 j3 k0 A
      "name": "active",2 [  w) p% ]( j: P" T* _
      "parent": "owner",
' _) N; y$ J: z& O      "required_auth": {( L0 Y3 ~& N. c5 x) j+ p
        "threshold": 1,
/ L4 p, T6 O4 l5 V: U* K  Z. v        "keys": [],
( M6 A1 {, d: [7 n/ f        "accounts": []
+ y8 _3 B( w5 v. _5 f      }& a/ A' f0 ]$ U# b/ X) E6 i
    },{
0 `6 C4 `, a2 ?3 C7 V# c9 G      "name": "owner",; e& {8 q, U9 q$ V6 r+ G0 b
      "parent": "owner",
: ^" W( z: |7 C/ D      "required_auth": {- L9 o) s4 R+ o6 P; R8 V
        "threshold": 1,1 {: x# [" c( k' S; }( B9 t
        "keys": [],# x; r, j2 \8 f
        "accounts": []
# v8 c0 q% K6 k, p! W# ~& _0 R      }3 d( {5 O& ]( r- ?8 D( }
    }+ D" \  L9 ^: P0 x
  ]/ [3 i# o( `# o% I7 W9 O; q  E
}) T6 `6 t0 X, d9 Z6 q
我们可以通过创世块定义的创世账户使用EOSC给当前创建的账户转移余额
9 j# z" R; Q" y+ f  qdocker exec docker_node1_1 eosc transfer inita currency 100000000
4 a& }: O/ T! l5 X- C! E{9 w1 f8 i3 ~6 p& K
  "transaction_id": "59575b8caf08eac7c00eb7483c048f12d0e7abf1ede839c3b2ed41dc6c5c7c5f",3 R! c, F) b3 k/ [
  "processed": {
# B% t2 h9 [; n- F2 |* t    "refBlockNum": 24199,
) J' e$ q8 z$ J7 h! n0 P- Y& C    "refBlockPrefix": 1485651173,- [" }" e* g  S4 H3 _' G/ P: z
    "expiration": "2017-09-29T02:31:03",
. O5 O/ x" P, K' N0 ]$ m    "scope": [
' }& ~& j3 o8 i5 W' z. R      "currency",$ t! u, o9 I2 _6 U. a1 R3 ?8 e3 \
      "inita"! d; L- y7 R) q- F% j5 E
    ],
* K0 I* m' o7 ]& `, ]    "signatures": [
4 K6 }( t/ O9 i$ A5 v/ A% g: H      "1f14229bdd4bfb927021bf96ff0651c8b0fa5666e9f5cf423a0270a1b91f2d2f690b573e179d8475ce2c6b160f5cd5507d58a44f8f6cf536348584efa8dd62ade0"
/ h3 S' e# j( O( m    ],
5 f. x1 a2 b$ X" e) V    "messages": [{; c2 X/ W" V% c( h7 a0 Z3 }# U
        "code": "eos",  a, D' V; M  Y
        "type": "transfer",
0 \/ b+ v* ^  ^4 X, R5 J' D& G        "authorization": [{& _6 r: D$ U4 ?  p% ~+ m
            "account": "inita",/ x7 m: C% {' t1 Q
            "permission": "active"7 \& c6 h; @4 t3 ]
          }
  U, y$ s5 F2 x, [2 V        ],
) m+ j5 m8 ~; v# s* p) X4 R        "data": {; Q" D" [2 v' \0 P/ x
          "from": "inita",
1 j2 H' C% M3 L+ H# i          "to": "currency",9 g+ `' m) f  Z8 t7 C* j
          "amount": 100000000,9 m( m) u8 d( `( X3 n& [# Z! w
          "memo": ""
1 `2 x) V6 j) S7 d8 X" g        },
, O" a  ]& @" @# i, H4 Q        "hex_data": "000000000093dd740000001e4d75af4600e1f5050000000000"
6 h/ H- x8 j$ e      }6 h% o  ^4 \" x+ y
    ],
$ C! m. E1 v, M3 J  |6 C! p    "output": [{2 z% z* o8 L$ {, r% K
        "notify": [{
2 W4 S9 c& a7 F, A9 \            "name": "currency",$ M3 `, Y% J1 L2 H" ?9 X1 j( h
            "output": {  \2 J6 j2 P! O5 j: X8 }6 b
              "notify": [],
7 a& k2 u$ R: S3 ~              "deferred_transactions": []$ _) b# g- s; L$ S
            }
- o7 \9 y2 U& K3 T3 h  o; K          },{$ g& V9 M- X  O: k; h# D: M
            "name": "inita",
' h! I8 N+ v8 s( p0 j* r: a/ g" _. ]            "output": {+ S1 S7 ~5 C, ^9 |. r" v  t9 N) s+ G
              "notify": [],1 n% y; ?5 |! f6 R
              "deferred_transactions": []
" o# k  I) S/ S# {            }* |; ^: K6 `8 S% t, s; v, }
          }3 d* p$ z6 K% L) _- `  ~
        ],& I: O& k. [0 f8 @& W$ O
        "deferred_transactions": []  e& u& P5 g4 `2 b/ E1 M* j
      }* H2 q0 H% I, i. {+ k
    ]
6 }& y& r! B* f: e! F6 r4 [  }
  G! o$ K, d' {5 ~}
: M, I/ b( ~9 r+ w2 `7 k8 `  R7 W再通过执行get account 命令,验证余额已经成功转移到创建的账户下3 V; P9 g7 G1 N  c; ?# t: E
查询交易历史
/ ^3 f; f6 }& e4 U0 [查询交易历史会使用到插件account_history_api_plugin,我们已经在config.ini中定义
2 J' q  [% J. `7 @docker exec docker_node1_1 eosc get transaction 0 l; z, t) h) v) }. o, V8 r
如果需要查询一个特定账户最近一次的交易记录
% g( _! H6 }+ y) N5 i& A" \docker exec docker_node1_1 eosc get transaction inita
, I9 i- m! \  g5 W8 q: |0 b7 L创建智能合约/ T: |; z, R. q1 A8 ~" s
官方提供了一个示例合约currency,我们依然使用EOSC来创建并部署智能合约,合约代码位置contracts/currency。
& u; p* j% P& C1)为合约创建一个所有者账户。前文已经创建了currency账户4 H4 H$ D0 ^& X0 b
2)检查区块链上有无同名合约- Z' ]0 n! ?4 h6 y1 G. K4 u1 s# W
docker exec docker_node1_1 eosc get code currency . \  F' l3 _5 \+ e/ s0 m, |" Q' p
code hash: 0000000000000000000000000000000000000000000000000000000000000000
( ?+ \, O$ v: _/ k' e: R% O$ t& O3 H3)为了获得部署权限(发送交易请求)需要将currency的active key导入到钱包中
, f, B: j1 l! }5 k* M" Z4)部署合约(.wast后缀文件)和他的abi(.abi后缀文件)
" l6 e; X4 F* ~docker exec docker_node1_1 eosc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi
# ]- r6 Q5 R2 d" }Reading WAST...& B9 ]1 g, ]; q& A8 i. L
Assembling WASM...; m* u5 ^9 R+ e& ]4 C+ D, G
Publishing contract...
+ v; n$ `3 r/ I/ t2 u1 k8 o屏幕打印部署成功相关的信息,并查询合约hash
: }$ |- V6 G: N( A  i/ @+ Z  |docker exec docker_node1_1 eosc get code currency
! f- V; i, X! a4 ccode hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf2 ^, r1 L; _" a8 v( u' E- P8 e
调用合约& P: f- U* K4 g8 P
在合约部署到区块链上之后,所有的currency余额会分配给我们创建的currency账户。我们可以调用合约测试做一些转账交易。$ n# r% i/ _  ?9 h: V& t9 f9 n
为了更好了解区块链合约的调用方式,我们可以通过.abi查看可以执行的操作列表和消息结构。9 X% x/ ^. p! r  @0 m. D- {
docker exec docker_node1_1 eosc get code -a currency.abi currency
) e8 s; _5 c, o, }* i/ |code hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf
: L/ B9 r. b) e5 Wsaving abi to currency.abi
9 H4 h/ b- l. i% q4 lcat currency.abi #查看  r% ]3 E4 q' S" N& h/ Q
{$ \; r. a! H* s5 h& _
  "types": [{6 n9 }4 m. d; c
      "newTypeName": "AccountName",
7 }; J1 T& `& Z& l/ y6 M- f# N      "type": "Name"% o( U4 J. f/ [7 V/ r9 t& _
    }) s; e9 `# w! I' a9 j5 r6 p/ m8 F
  ],
0 z" m! s$ K% o. [% Z  a% X& Q. B  "structs": [{
( [/ y: M/ u9 f- @  i      "name": "transfer",) r3 Y. R! k% T& }( T: l, I$ ?& }
      "base": "",. }) C7 `8 Y$ ~/ Y. N. f7 E- P& d" j
      "fields": {
+ M* h# r( |0 @# a' O3 k6 g        "from": "AccountName",
0 S2 O4 t& j2 c* l& K        "to": "AccountName",
% w1 S0 q: T, h# i8 L# @6 t        "amount": "UInt64"8 _: \3 n, Q" a; i- `; M) I$ o
      }. ^3 H% M9 }2 ]4 {% _( l2 U& e/ w
    },{4 r4 ~- }/ M% G; k% I
      "name": "account",( \, b" u4 I& J6 I# d. e: [
      "base": "",8 O+ G' E8 D: @" f8 }6 j
      "fields": {
# P8 y4 X. A" z, f        "account": "Name",
+ u  @# i3 w& d3 b% `; d        "balance": "UInt64"" x1 \+ Z$ J* X! D
      }
2 }' ~, J2 c  W3 D    }" ^9 A6 G0 ?8 i8 {/ X
  ],7 H% j4 @% }. Z  s
  "actions": [{" l" q# L  X) }& o6 k- K$ H
      "action": "transfer",  d# g/ B) q) |, w! t7 ?
      "type": "transfer"
5 C: ^1 @& ^5 a7 W5 E    }! a8 y  Z8 ]4 G1 R
  ],
6 a5 X* S4 e7 @0 v; @) Y  "tables": [{5 V9 j8 A9 v, c$ {: W' d
      "table": "account",
3 ~) O6 U& M+ C" G3 ?% [8 Q      "type": "account",
# r7 o; E2 w; ?6 I      "indextype": "i64",  R% ~) f* E+ x3 o# H
      "keynames" : ["account"],$ S6 n+ m+ g: Y5 Y, J6 y5 E/ D
      "keytypes" : ["Name"]
" ]* x( C$ r) i    }" [" u6 A: K  [# y
  ]
4 w4 }$ s4 p; y: h) V}, Q6 v7 e8 |2 a( L$ g! u6 l2 K
通过上面的abi我们可以看到currency合约可以执行transfer操作,消息格式为from,to和amount。我们调用合约从currency账户转移50个余额到inita账户7 j+ o2 T/ M+ ]/ M: s. u+ ]
docker exec docker_node1_1 eosc push message currency transfer '{"from":"currency","to":"inita","amount":50}' --scop! D9 N7 J% d' e" S1 m2 e3 h
执行完成,我们查询余额验证结果
2 |. U4 A6 R1 p5 ]$ Jdocker exec docker_node1_1 eosc get table inita currency account
# c3 Z* ]2 d7 \# ]  t{  O' \% H  Q$ Z; d  Y6 Z
  "rows": [{
8 ]( E/ b) o& y  d3 J& v5 B5 y8 X      "account": "account",' M# i' s- `$ S
      "balance": 50 # B& |; U* n. |. ~1 r/ e" W
       }
; u& P* l4 e; _" R  t    ],
* R: L; m3 o# k8 P6 t: W" T1 t: a  "more": false  k! K0 K/ F/ f- @  O: s
}
1 C% A5 }$ u$ R- ?; p/ Ddocker exec docker_node1_1 eosc get table currency currency account
) C( N( b! i: a  X! [{2 N8 Q( \) l  m' E
  "rows": [{
6 g: t: z' \+ R      "account": "account",
& X* U; F* P+ A+ I/ z      "balance": 999999950$ q4 ~: A3 D6 q" a0 Q
    }. T: n% B: o& \
  ],! y8 Y  R0 O3 Q& j+ _7 U
  "more": false
9 q  k5 C- ~6 g  M, m: E, Z/ E0 k}8 e5 p5 N5 u6 H5 V7 p) p1 e( D
余额不足的账户尝试转账,会提示失败
, |: f1 }! D' _1 \* o7 p9 adocker exec docker_node1_1 eosc push message currency transfer '{"from":"tester","to":"inita","amount":50}'-S inita -S tester -p tester@active
0 S% k( V) W; s* W  `- N$ e& M& e" v3543610ms thread-0 main.cpp:271 operator() ] Converting argument to binary...
  w3 r: E, z. N9 n3543615ms thread-0 main.cpp:311  main ] Failed with error: 10 assert_exception: Assert Exception
! \. x# h% q+ v4 E& w' }# j+ d  b% ?status_code == 200: Error : 10 assert_exception: Assert Exception
8 `( c" x$ G# m3 Vtest: assertion failed: integer underflow subtracting token balance
6 k! J7 L7 E1 e2 @{"s":"integer underflow subtracting token balance","ptr":176} thread-1 wasm_interface.cpp:248 assertnonei32i32 [...snipped...]: ~, ]8 D# n: U7 v2 _
查询合约8 w+ b6 X" E# F' D) `) k  P
如上文验证步骤,在调用完合约后,可以通过查询表来验证每个帐户持有的余额。
; ]: m: D/ W" u3 Tdocker exec docker_node1_1 eosc get table currency currency account
9 ?/ e: y! H2 `* ?0 x3 q* q. q连接特定节点
2 n& O; d2 ]* {0 F默认情况下,EOSC连接本地端口8888的节点。可以通过指定主机地址和端口来连接其他EOSD节点。同样的,钱包服务也可以指定特定的主机地址和端口。
* A2 \" j. l* Q$ G7 {docker exec docker_node1_1 eosc --host  --port 3 H. U1 {6 d! l" E; T; z3 |: I; Z
链接独立钱包服务
- s0 [1 m% g; r7 k( L除了使用EOSD内置的钱包服务,也可以独立部署钱包服务
8 M2 f+ ]: k) R5 \3 w; Udocker exec docker_node1_1 eos-walletd --http-server-endpoint host:port
) H3 c; m7 N4 [( n* i9 I调用独立钱包服务需要添加如下选项
8 y& P3 u! H. ?/ s# idocker exec docker_node1_1 eosc --wallet-host --wallet-port
0 G9 |' a/ t0 I5 R3 E$ z2 b# Y/ z+ i免签名验证+ _: _2 A9 M3 x1 K& O- v% X- o% y
开发者如果需要快速测试功能,可以跳过节点签名的步骤,这样可以解耦密码学的问题而关注应用功能
; ]( }- Y. s  O# T1 m启动时使用特定参数! b* q* v5 L. T9 e+ r; F2 V# \0 d
eosd --skip-transaction-signatures
. `& y' `+ i% \& vEOSC调用时添加-s 选项
* W9 L4 w% b, D$ ], kdocker exec docker_node1_1 eosc   -s . m3 Y' a7 A; G( ?3 s7 H
其他RPC调用# M9 Q  G. O$ Z8 j' t1 [8 s6 ^
EOSD RPC 包含通过HTTP RPC与eosd和注册其上的插件进行调用的方式.6 N! I+ T  [' v7 ^6 x% @
1)区块链API 配置
3 i! v/ P6 @+ i* [3 ~! ^1 g想要查询eosd信息需要启用plugin = eos::chain_api_plugin插件并添加至config.ini中
, F) Q; |3 {* K- a4 m0 T1 V8 R2)get_info接口用于查询区块链的基础信息
2 q( w6 G5 R* N5 x: d# ?curl http://127.0.0.1:8888/v1/chain/get_info
8 K  I. ?8 m  M返回结果如下:
0 ?9 S9 a& G. x( F5 A3 V1 `{"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"}
! R: ?+ q: P3 Gget_block接口用于查询区块相关信息2 e% H( D- n) ]* g, e  J% [

: @0 w1 ~" W' lcurl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":5}'
. s1 c# X6 q" w3 D# g* L4 ~4 xcurl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":0000000445a9f27898383fd7de32835d5d6a978cc14ce40d9f327b5329de796b}'9 b/ H$ @. V6 `" w# r
返回结果如下:
. g# C# B: Z$ S0 Z: p/ p, O{"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}: i2 v3 ^: u) ~) @
4)push_transaction接口,调用合约交易
2 {- a1 M( K2 Q该调用为JSON格式并会将结果更新到区块链上1 D5 w8 d6 _+ {) h- ~, A- {0 P: x
执行正确的结果返回
" J$ F, f: P, K# _( ~返回 HTTP 200 和交易ID号
0 |- ^: g3 d  N8 \( b{ ) t9 f8 H: ]# l. T1 _+ j
'transaction_id' : "..." 6 S3 a* `$ @# b3 D& E) H
}
  e# k  f5 ?3 }& o执行错误的结果返回,一般为400错误(参数错误)或者500错误: v8 H5 j8 x4 w' o9 I# z8 P
HTTP/1.1 500 Internal Server Error3 n% }; }5 q( }# V' }- |4 M* a
Content-Length: 1466
, w7 N/ y* r; d% P( w, r7 b* `...error message..* i2 g; }1 Y" R3 d( k
push_transaction 调用方法; I% [$ L9 b$ ~, X  U1 v! Y
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":[]}'
- a* r: w. H  E此示例模拟一个转账交易。 refBlockNum和refBlockPrefix使用的前例block查询的结果
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

罗宾虚汉 初中生
  • 粉丝

    3

  • 关注

    0

  • 主题

    16