Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

EOS纯技术上手学习

罗宾虚汉
113 0 0
EOS.IO 已发布黎明V1.0版本。EOS.IO 黎明V1.0版本是第一个预发布的 EOS.IO SDK(软件开发工具包)。EOS.IO黎明V1.0版本可以让我们体验下EOS一部分区块链特性和简单上手开发、测试。本篇主要是一个快速的review目前EOS黎明V1.0版本的功能上手。$ A8 f( C$ y7 T
主要内容:1 K1 [( H: L0 z
- R+ \  M$ q/ S. _0 F
EOS Docker快速部署" I/ S  G6 N/ Q1 ^$ B5 z5 Q, O
; W$ Y+ ?/ h' Q. C/ S0 S* ]
EOSC使用) }# p  I; ~, t& l) P" j+ E: R
' s( {9 K: N) x5 W" M$ E
创建钱包
. D# u" \5 R" j' g5 H! U
) U5 n# ]5 g9 N将私钥导入钱包4 ~8 A  c4 f: t: ^8 v8 m' D

1 K4 B: A8 `% b9 a锁定和解锁钱包* Q% y2 V$ s5 n0 b
4 a! y5 p% ^1 M1 F  j+ j/ n7 b% G
创建账户& G, {( K3 w6 b: l& Z

9 c; l1 F* s4 @  i  v: }内置转账, v5 s# ^7 |. j4 a5 ?. F6 ]

+ y- W% g4 T0 G查询交易历史* j, O7 E3 r! C0 e

( |# d* D. u  N& E5 @测试合约 - currency
3 [8 z3 p) b% a7 m/ @2 K! o/ H7 z7 `  G( O' T- z
调用合约
5 [+ a% f* [2 M; Z* ^3 E8 a% |6 f. o1 a; c, q+ S
查询合约
$ W3 a/ H' U* S& g* _; z" {; r" T1 \8 O$ D: m4 F
链接特定的节点
  X! P3 ^7 n6 y0 i  m) f
" j6 U! K; U0 l7 t/ L$ S链接独立钱包服务* y" X6 W* ~% w  I; [( Q; L* t: O8 W+ k
5 r0 b* @& J) S/ v9 J! }  M2 R( l+ `
免签名验证
7 B6 E% n. D* g) K& `% z0 f
. v; t+ C0 n$ ]7 R) e- X其他RPC调用
$ ~% f0 f) d9 O$ a
* z, a. {3 ?8 D- G! ]2 y: N" y2 f0 Z3 _# W5 V+ }
EOS Docker快速部署8 d( Q* U: c6 Q, A/ P1 {
构建eos镜像. P" Y9 R$ {/ C) f0 W' q
git clone https://github.com/EOSIO/eos.git --recursive
3 r" M0 _% W4 q: q" {cd eos9 a0 ?$ t; _. P$ P, Z% Y* w5 r# ^5 _
cp genesis.json Docker 6 v! |# O& S1 J7 W! |9 w
docker build -t eosio/eos -f Docker/Dockerfile .- d; P/ D7 C0 r/ N
启动容器* ^0 O5 [) z: q! u. R- E0 j
sudo rm -rf /data/store/eos # options
/ `1 z% O# l; X1 q2 k# rsudo mkdir -p /data/store/eos
, V; x: M( W1 D+ ?+ @  cdocker-compose -f Docker/docker-compose.yml up0 v& Y0 e! q8 ?; G0 Q/ m
如果 docker-compose 启动有报错, 可能需要给文件存储目录赋予用户读写权限/ `# [. s2 F4 I. @% F8 e; r
sudo chown -R SYSTEM_USER /data/store/eos
; `6 n/ x' ^* D# E验证,查询区块链状态信息* S. S" U" s2 Y& U( s! h- I/ q; P
curl http://127.0.0.1:8888/v1/chain/get_info$ R7 U4 v, J" q1 X
如果想使用多节点环境,可使用yml文件启动1 ], c+ X+ e9 {, d0 k
version: "2"4 D! F; q, x4 [! N  B" E
services:
; r" C; d$ i+ l6 y& y5 b  node1:
1 L. ^5 H& [; g  U    image: eosio/eos
- D+ m. [% M, L& m6 F( t  _: p9 k    ports:* O6 |! {" i! b
    - "8888:8888"8 j" M# l! A) T$ `9 G$ U, @- J- f
    - "9876:9876"5 V6 A) q  b  S# Q1 M9 X
    volumes:
% S$ E0 w  J6 H) U- c* q      - ./node1/data:/opt/eos/bin/data-dir
' V6 C& H5 j4 y' q& K% [" v  node2:
: m3 g" l9 |7 x6 w5 j    image: eosio/eos # q: W+ z! U' e0 J, l1 c
    ports:
; C  y6 T( R* F% q" y5 h, t    - "8889:8889"
' b( ^5 V8 `( L$ h& y1 y    - "9877:9877"8 T& T" O# m+ v2 a3 m6 W0 \
    volumes:
: e" ~$ F" J+ ]! I1 I. C      - ./node2/data:/opt/eos/bin/data-dir8 b5 ?  V: _# o( j
    depends_on:
, R2 F, |" p8 J) W      - "node1"1 T( n9 X0 T) N$ d7 M
EOSC使用7 E* K3 V  i- u, O# `8 z
EOSC是EOS的核心进程EOSD对外暴露的RESTAPI命令行工具。EOSC的使用会利用到一些内置插件,插件在EOSD的配置文件config.ini中进行设置,如与链的交互需要使用’plugin = eos::chain_api_plugin’。为了签署交易并发送到区块链上,需要使用‘plugin = eos::wallet_api_plugin’。为了查询交易和历史记录,需要使用’eos::account_history_api_plugin’ 。* [  B, W, H2 z3 J* |" U8 n/ `
# Plugin(s) to enable, may be specified multiple times
0 _3 M7 V4 f# k6 Gplugin =
. L9 h% T, _& Leos::producer_plugin
/ |- |$ C; C9 U; x% R+ ?' Mplugin =6 S# u; a* G* _5 r+ A7 t" p
eos::chain_api_plugin
7 p: a, |% x. B% |$ D; J( rplugin =
1 a$ }: n$ Q% u' _! xeos::wallet_api_plugin! c' d1 O; _& H) S; @
plugin =
( f1 X, ]* O2 Xeos::account_history_api_plugin
3 @& T1 @  b6 C  V启动eosd后,可以使用EOSC查询当前的区块链状态
& D) i8 B* a3 n3 @8 W* Tdocker exec docker_node1_1 eosc get info8 b. ^: A, R7 Q4 m9 S
{
3 _; k5 I3 j8 |' |& t  "head_block_num": 23449,0 D. Z, v2 A' v$ W0 o$ i
  "last_irreversible_block_num": 23432,* p1 c$ i( g+ E* q
  "head_block_id": "00005b996cc85962b28537c3d72696a012d1071638f5e4bad1809cf9afc9abb6",
- u5 A2 o: ~6 H2 J. Z7 O/ n5 G  "head_block_time": "2017-09-29T01:53:33",9 g4 \  P! X; f% _( k2 H
  "head_block_producer": "initi",& l* R0 n$ N5 h0 k
  "recent_slots": "1111111111111111111111111111111111111111111111111111111111111111",4 h2 l$ p7 X/ u
  "participation_rate": "1.00000000000000000"+ u4 r$ p  @/ K6 u
}6 h/ f  g; q% l9 D
创建钱包) o) @! `/ Y$ J3 t3 [0 A
任何发送到区块链的交易都需要由所有者持有的私钥进行签名。首先,我们需要一个钱包来储存和管理私钥,使用EOSC命令创建一个钱包。
0 G; Q5 ~+ Z, i" E) Cdocker exec docker_node1_1 eosc wallet create
6 t7 a# V- c5 G# Y8 ?. rCreating wallet: default
* C5 R7 [% H1 _7 C. A+ s+ nSave password to use in the future to unlock this wallet.6 S8 s6 I' ^( m
Without password imported keys will not be retrievable.3 t% w9 T$ o6 y6 X5 X; f
"PW5JXSxkHqNEwRKCpG2JUTLqkR8SNCBXofkAwaFDLwQkNdqaSXwC8"
7 }) N+ d- {: N1 D6 N0 Q7 i- F命令执行完成,会在eos-walletd中创建一个名为‘default’的钱包,并返回钱包密码。
6 \; {2 X# }. W这时候可以查看钱包列表2 X, T: [% _! j9 |6 c! u
docker exec docker_node1_1 eosc wallet list+ G5 L3 f$ F2 x7 ?3 s( B1 j
Wallets: & }1 Q2 Z$ T& Q4 i
[
4 ^! _- J% |! f, ]2 m  "default *"7 N9 w1 B0 M, I; D9 w  Y: b
]
; d% H4 n; B! S+ H0 ~0 W0 g如果你没有指定钱包名称,默认都操作的是‘default’钱包
2 \" @6 P* |, P& S3 V8 Q将私钥导入钱包
6 V, f1 k5 X6 f2 O" R9 P3 I如果你想授权某个钱包可以由某人来管理和控制,需要导入该授权者的私钥。8 F# ]: F/ G, C& n6 r
docker exec docker_node1_1 eosc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3$ ?/ e% w9 M& _7 F; A
imported private key for:9 b% @5 I6 a/ r
EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV+ ^6 t. s9 F4 d" P
导入后,可以查询钱包已经导入的私钥和对应的公钥, l8 b0 I# ~& W; B: J3 f8 D
docker exec docker_node1_1 eosc wallet keys
. W: `& e" {: h0 u' X[[3 O- V$ E8 ?! }  m4 S; {# o
"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
/ r& G3 S3 [& x# O/ M# \"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3") F3 p( _: b0 {
]- L4 B4 N( ]+ a1 A( f- K
]
; E) [4 M( K0 W0 R, _" J锁定和解锁钱包
7 `4 e6 n! _% i6 I. ?& S; q日常使用,为了保证私钥安全,可临时锁定钱包,锁定后查看钱包列表是不可见的( I% x" Z3 G  K+ J5 R+ |
docker exec docker_node1_1 eosc wallet lock# V$ k& [) o8 z% q4 \
Locked: 'default'- C3 C. x( D5 t0 N) w
当想要使用时,可以用创建钱包时生成的密码来解锁钱包
, ]" H6 Y1 a6 q7 D- s" L& adocker exec docker_node1_1 eosc wallet unlock --password PW5KVWrn81Y8PLAb52gr2FyXCanVavcrj9d5TC9C3yKhqq1PJYRPk% c; a9 O  D9 }
Unlocked: 'default': |# h5 S" f* ~) |! }" f, j  y' z
解锁后,可以在列表重新看到default钱包了
* ^8 q: j( @# j/ Z- vdocker exec docker_node1_1 eosc wallet list
  q9 Z+ u9 O9 m% p$ V$ \Wallets:
/ P. N3 q& o) C  K( \& o. l[
4 t8 x, w. }# Y$ o- [  "default *"
" T: Z3 O' G. X]
6 S$ q$ @& {* q9 H# h+ ?+ }创建账户
9 O1 q' u+ u; f: m  |1 H创建账户需要有两组密钥:owner和active。EOS使用EOSC工具来创建密钥对
' c% f5 u/ \( w, M% _1)owner key.9 Q+ N0 W4 ?- \, C& R; m
Private key:5JRc8XxvodWey4StZ2zzkUhCQhDaHvGMkABtfHzQR2ie4qaUFJ7
4 h5 T: u' \7 @: |% F% iPublic key: EOS5mFEdAzxvMkHLQXt2v4naUjnBrPGmzMUCikymqhSR6m7QLGSTB9 C; _2 E. A1 C  b! J" g/ `
2)active key
9 H0 l" c* M' C( B9 q0 X9 O, qPrivate key:5KNzFCbToz2a9Hztz9Qen5cyJcM3x5Wpq4GFiTYZgGhzntXdmYo0 ?1 \- h/ C; Z& t* X( j
Public key: EOS5EdsvESpibWLJxupTqod1nswJnbiXQZuUcLiAWEEsqcZskymeB
0 }0 L. H2 B1 x( |; f( R& iEOSC不会保存生成的私钥( r1 T9 ]9 @. `; |2 l! f  k
因为后续测试智能合约需要,我们创建一个名为currency的账号。目前这个版本,所有的账户都需要用已有账户来创建,所以我们用inita账户的owener key和active key来创建currency。 为了使inita获得发送交易的权限,需要先导入inita的私钥到钱包。(参见私钥导入钱包的步骤)
# s$ K4 k1 r& o' @docker exec docker_node1_1 eosc create account inita currency EOS6NpEqWi177VKQkuJQL9V6Y3LqAAp9C2j
2 B2 @+ h8 P" ^) j2 h执行成功,会输出一串json的交易信息,打印账户创建相关内容1 w8 i' o+ h9 x9 c4 D' g
我们可以查询inita可以创建了哪些用户$ u8 I, Y3 s, ~  B9 @% f0 M5 q
docker exec docker_node1_1 eosc get servants inita
/ V4 B) o0 P9 `7 Q9 C! Z{
' V) o6 A% X: o  j0 Y5 z6 x"controlled_accounts": [. ~( A& m# n5 D+ ]( e
"currency"" Z" h+ J1 d/ E8 D. [3 ~
]
6 N$ r" F9 h7 H8 w- n% Y6 _$ I}, l5 ^5 ^3 u2 {3 z# W% {
内置转账
0 O4 X8 s/ T7 ?创建账户之后,可以查看当前账户的状态,可以看到创建的测试账号没有余额,这样不少功能无法测试,我们需要试着给创建账户添加一些余额8 N4 U" M$ |1 b
docker exec docker_node1_1 eosc get account currency
+ t, z2 ^  l. e: h. m4 w4 R9 v{
6 f3 T' J7 t& \% u# t: H' |3 l; q  "name": "currency",
0 Q* M, o3 J5 N& [% s5 ]! N  "eos_balance": "0.0000 EOS",$ |$ }' h3 K8 r1 E  p6 x
  "staked_balance": "0.0001 EOS",
. E4 V, H; _7 u# r2 _4 K  "unstaking_balance": "0.0000 EOS",
; d6 z6 l; y4 x3 t# h  "last_unstaking_time": "1969-12-31T23:59:59",
0 S! T7 r1 A9 n  \  c. J  "permissions": [{
: S8 Z+ |% @, {. T      "name": "active",
; D. z5 b& e9 p4 l1 @0 w      "parent": "owner",# H, F  ~( y) E1 R$ E1 X3 b6 ^' E2 q+ b" @0 j
      "required_auth": {
; x/ F  D( M) q  N        "threshold": 1,9 w+ U5 f( V& f# Y
        "keys": [{) y0 V- |8 M# [
            "key": "EOS8ff42NMpJUybVj3nwUSnPpc3mMysKxyE4HVJy1E5o3fQv7knWf",* m4 J7 R8 I* v8 S3 A
            "weight": 1$ c) d3 w& V! M
          }
" s9 ?; K1 ~4 R( f4 I        ],
+ c0 }' y3 }) A        "accounts": []- I2 [* y4 R" X. M! m) K
      }
2 @( l& R8 N0 A5 t    },{
! M; @9 D+ M# Y7 T, L2 d, D      "name": "owner",
& ~1 g" e6 T" m  Q1 B+ }0 S      "parent": "owner",
( P7 r) ]3 O* q. q      "required_auth": {# s2 b. u3 T6 g% M' U4 o6 J7 F
        "threshold": 1," L" |3 H* W* J' h
        "keys": [{
* Q! ^! R  B. q  J+ P            "key": "EOS5fQ4saiHV426EQ7AKrGoD2AVMBYe77bnGSq42JjXBUfipv7o3E",
2 Y# ?& J# b% I1 F7 ?1 L/ s            "weight": 1) R9 Z1 Z/ a' O  [- I5 I- E: y6 r
          }
, n0 N2 M1 Y/ {+ M        ],9 L1 N7 j$ j5 {+ q) I# `! p
        "accounts": []
5 _. U* f  [1 B6 ~0 p, Z, u      }! h1 |  R! h; ~
    }+ t% i1 A' F" {8 s- b
  ]
3 K, G  F# x+ E* c}: f# j  q9 v/ F
保存全网余额的创世账号是eos,查询余额状态# b+ Q* d  D! Z* d' d; `
docker exec docker_node1_1 eosc get account eos/ x$ X; A  F/ b, ?9 _
{9 c5 w" o. H3 q( F  ]# c  r
  "name": "eos",
3 {: v- e" [: f4 U  "eos_balance": "69000000.0000 EOS",6 Q8 S/ @" u' t" u) G
  "staked_balance": "0.0000 EOS"," _6 w$ B3 T5 m" k  m5 |9 f
  "unstaking_balance": "0.0000 EOS",
$ W# R3 M! }3 T  "last_unstaking_time": "1969-12-31T23:59:59",
) ?) e! s$ C) N# E* n: o  "permissions": [{0 }. _- [* v9 P. N
      "name": "active",2 |7 z4 F& M( U) O9 }/ U+ ?
      "parent": "owner",5 L3 v/ f- B2 p+ h( q
      "required_auth": {
7 |  g- V+ G$ W! I) l0 C        "threshold": 1,9 ?$ ^9 M" o- Z
        "keys": [],+ }) _1 p" n+ B9 J+ D) \+ s: o4 v  Z
        "accounts": []
& a. G2 ?  s3 a1 p2 H- ~# |      }
: o- g( S9 I9 w6 t* }; w+ i" I    },{
: H' V3 M' q# F* ?, F6 z      "name": "owner",
" W+ Y& f  Q6 C& t" g      "parent": "owner",  w. n0 l; g* a; f  o
      "required_auth": {
( T6 ]+ m' Q2 A: h4 @        "threshold": 1,+ \' N7 O' u5 r( c" d5 N5 v5 t
        "keys": [],$ J' q8 k7 f- c' L; y' Y
        "accounts": []) k' m* j$ L) H! J& ?% o: F
      }0 n& w6 }  A8 B) M. d: G
    }
. Z0 _4 p2 j$ a* l  ]
; P0 e1 R( W2 Z! W# e3 l( n9 g/ s8 H}. g7 s, e( @, q, y- W! k" t
我们可以通过创世块定义的创世账户使用EOSC给当前创建的账户转移余额# }% C4 D3 H* }% [0 E
docker exec docker_node1_1 eosc transfer inita currency 100000000
7 `1 }6 c# f% v! i6 N{6 j* Y; T' v1 q5 C! p
  "transaction_id": "59575b8caf08eac7c00eb7483c048f12d0e7abf1ede839c3b2ed41dc6c5c7c5f",. C8 ]0 v9 w5 F6 |
  "processed": {
& Y9 {5 H! x; g. [! Y    "refBlockNum": 24199,& i# \4 w5 A6 @3 t$ `; ~
    "refBlockPrefix": 1485651173,
# I, b" ~- ~1 U) U: p    "expiration": "2017-09-29T02:31:03",2 `; f0 H$ c. H/ G$ U/ R1 k6 x
    "scope": [
) W* w8 M8 O+ |6 j" e5 j' c: D) u" J1 h      "currency",
5 ^4 h( U" L* M& n; Y* U; g      "inita"
* S; p4 K8 D3 n( m% A: F, m    ],# E& M- F1 T2 [. g. b/ p
    "signatures": [
1 f  Q  e$ {8 L      "1f14229bdd4bfb927021bf96ff0651c8b0fa5666e9f5cf423a0270a1b91f2d2f690b573e179d8475ce2c6b160f5cd5507d58a44f8f6cf536348584efa8dd62ade0"" ^+ P- S. O, h) t
    ],
5 Y, ^& W. M: u1 H( n$ i* n; I    "messages": [{
) b: X8 F. [( Z/ u; Q: @, w        "code": "eos",
$ \# |+ O. S6 I        "type": "transfer",
& ?/ U0 _0 f, w" \  N        "authorization": [{
% d; Y: e& I, Q8 @            "account": "inita",' Q: @5 W! t# F3 ~( R
            "permission": "active"
! Y4 f) r+ @6 r# O          }/ C3 j- t0 K$ f" [& N8 L
        ],
  n! ^4 C. ]" @2 j4 T        "data": {/ l1 |5 v: `  g, k
          "from": "inita",
8 m3 U( Y% [+ D6 G; }- C6 N, Z# u          "to": "currency",
# c2 o. }* e: T          "amount": 100000000,
6 d7 p# R) Y7 H( ~# L5 P: T          "memo": ""
( Q* h. i4 [: F; a( ^" w        },2 F1 l9 `% w6 r  B
        "hex_data": "000000000093dd740000001e4d75af4600e1f5050000000000"
! u$ p/ q$ b, j' h: ^      }
$ d+ @/ n7 H9 A9 n2 K- ?, i    ],) y: ?7 m' p  E" }. a$ _0 b: x% a
    "output": [{7 S6 t: C' F6 `. S6 G
        "notify": [{$ x3 ^: w) H: ?- M# y( |5 [
            "name": "currency",0 X  `) O) \/ ~. j; Q) K+ c' z
            "output": {
8 i- C; F1 T' t1 N! k. x6 D              "notify": [],
& |: ?1 J/ b$ [. O4 ^5 \              "deferred_transactions": []2 M0 h  x( u% L
            }
. I3 d" A- g) \& M% Y2 [7 s          },{
" C" G" X" t" ~5 p2 T            "name": "inita",
) C# Z7 r+ c- @$ a# _. o) z            "output": {# Y% y& v5 E9 E9 H, E' p$ P
              "notify": [],  n' I! C/ O" z7 R9 S
              "deferred_transactions": []
+ E1 h4 q2 T- W8 n4 ]1 ~            }, b8 ~0 U# F. S1 H- [/ a" c# \
          }
. |, z3 f$ i0 _! t- Q        ],% X7 w5 w3 R- f8 R& v7 W- z+ g* m
        "deferred_transactions": []' A- Y) d* A. V& x; d; b3 ~% c
      }& b  C4 h* X8 W1 S" c. W+ _
    ]$ r, B3 S- h- u8 e0 _' ?
  }5 a: ?* [# f" `3 q% _" \' O  P
}
5 z* m, u6 }7 X再通过执行get account 命令,验证余额已经成功转移到创建的账户下( c+ D# u1 f9 K6 H/ {$ ~
查询交易历史2 W: {% n  D, i# x5 [  w
查询交易历史会使用到插件account_history_api_plugin,我们已经在config.ini中定义
, Z8 n4 a" m% Kdocker exec docker_node1_1 eosc get transaction % p* Z2 v/ [% j. x# f
如果需要查询一个特定账户最近一次的交易记录
0 f, P0 N5 W. r" ?docker exec docker_node1_1 eosc get transaction inita
: [% d2 s" V( N/ x  ?2 l, \. g创建智能合约
# `+ c$ A: `7 @  e: g$ I' ~8 D  n官方提供了一个示例合约currency,我们依然使用EOSC来创建并部署智能合约,合约代码位置contracts/currency。
, B: b/ P$ S7 d, P: D: G; B9 M5 S* }1)为合约创建一个所有者账户。前文已经创建了currency账户1 S+ s+ Q  }# P% r' M5 q
2)检查区块链上有无同名合约
/ ]& a  P9 @6 S( bdocker exec docker_node1_1 eosc get code currency
4 J7 l3 o! q3 R, |* H% x& A8 qcode hash: 0000000000000000000000000000000000000000000000000000000000000000 % R) [- K  m0 D
3)为了获得部署权限(发送交易请求)需要将currency的active key导入到钱包中
7 i0 n5 m2 P. j! s4)部署合约(.wast后缀文件)和他的abi(.abi后缀文件)% n' x$ E! d/ E" l7 U; ?
docker exec docker_node1_1 eosc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi  o3 }3 o* d* Y- ]% W* I( Q
Reading WAST...
6 [. y$ z( L5 G) Z7 _! m& V, C1 qAssembling WASM...
0 f/ p7 p: U8 \- R: `Publishing contract...0 G9 I5 b7 P# C  l: @% S* }: D; n
屏幕打印部署成功相关的信息,并查询合约hash' l5 ~5 X9 S2 C9 o1 Y; a
docker exec docker_node1_1 eosc get code currency
4 z* @0 |% F8 F) n( l# Ccode hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf
8 ^5 o6 [  c/ E5 V调用合约/ s1 n( |" ]8 R
在合约部署到区块链上之后,所有的currency余额会分配给我们创建的currency账户。我们可以调用合约测试做一些转账交易。
) D; u! N! k+ a为了更好了解区块链合约的调用方式,我们可以通过.abi查看可以执行的操作列表和消息结构。
; _8 K  a) H9 P  udocker exec docker_node1_1 eosc get code -a currency.abi currency- M) c1 S! D, `3 j
code hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf7 }- @- A: c5 k6 [- W
saving abi to currency.abi" Z- m2 {( `& o# t
cat currency.abi #查看0 ?6 h- b( a; {- ~' \
{: p- T4 r* X2 i4 P) {1 {8 e
  "types": [{
# v: W; i4 P! H3 d$ }      "newTypeName": "AccountName",, `, ~% f6 u8 [) @3 j- q( M! @
      "type": "Name"9 {4 c$ r" ^/ w9 h' r
    }8 m# _0 u& N1 n+ p. Z* l
  ],
3 Z. u  v; d+ a. R3 U  "structs": [{9 W9 I& |5 V. j1 i. J) F$ i. O
      "name": "transfer",
/ h; Z" S6 z7 f5 Z4 r$ O* d6 {, [      "base": "",) c) J8 Y/ e. u; j% ~4 T9 c3 c
      "fields": {# A/ P% o9 i2 L7 N- T) ?
        "from": "AccountName",. e8 ?# B) R6 _  a
        "to": "AccountName",
# s' F$ m: ?$ x        "amount": "UInt64"( K1 a' v; T- w3 D: q- ]
      }  J* n+ C9 L; z* b2 p; c, E
    },{
4 `# O. j9 |* W0 q) ^      "name": "account",( W! c) v3 @1 r- o) K& w
      "base": "",9 L  f- a/ g4 O. t
      "fields": {
8 U  U1 V4 V0 z  ~7 w- g; [        "account": "Name",
8 N3 x7 v& S, ~1 C        "balance": "UInt64"
  g, E- \: p% I8 @      }
+ n7 E2 d9 [3 ~* D$ ?: p    }
) M3 i% b+ Z+ r' e& p- z  ],
5 w3 m, X5 y6 ~! n# u% ~- g  "actions": [{9 a, ]& Z( y( f& A/ M6 @( S, ?
      "action": "transfer",' g& z4 S+ d+ g
      "type": "transfer"# [0 ~% l" `5 d) @5 o" `" E7 C( a
    }
  T6 _+ J& S$ ]5 c9 X1 R+ }( {  ],. P* i/ g3 X) }- U: a7 K) j4 c6 d8 b6 Y
  "tables": [{- H3 D0 ^; [& R/ d9 O
      "table": "account",
4 C$ D  q1 I# P" d: A; g+ g) F0 k      "type": "account",% b) p) ^7 S. J0 v2 O. j5 f& Z
      "indextype": "i64",; z- B* V! |, N) |# B. o" q; W" N* U6 O
      "keynames" : ["account"],8 m/ Q5 g& T# T% A
      "keytypes" : ["Name"]
& u& ?0 F0 \# R+ U* U    }; M% W2 M0 n7 ]
  ]
6 I  s2 t/ L5 i$ y3 D( `}% x1 ~- N  e" Z5 f3 g
通过上面的abi我们可以看到currency合约可以执行transfer操作,消息格式为from,to和amount。我们调用合约从currency账户转移50个余额到inita账户  ~' _& o1 ?/ a
docker exec docker_node1_1 eosc push message currency transfer '{"from":"currency","to":"inita","amount":50}' --scop
. K7 J+ G. Y8 s* t. U9 C! G执行完成,我们查询余额验证结果
7 H- V% e. [+ z  w/ x+ O4 F# [+ _docker exec docker_node1_1 eosc get table inita currency account' D- U! ^- ^/ M( W+ P; L6 y
{
' r! w2 |) F! ~- O7 _* M  "rows": [{
6 c$ U8 A# C- g$ B+ R: D* k      "account": "account",
2 Z; W# a# ~8 T6 K4 v" ~      "balance": 50
6 P  B$ ~0 |- j( M5 X3 s       }9 u$ m+ j6 n( B7 G9 t9 _' K
    ],
& H6 p0 _8 n# ?' w- {/ Z  "more": false
( z) x. d" N5 Q. t}5 V1 q8 ]5 |$ ~  c* h
docker exec docker_node1_1 eosc get table currency currency account8 Y1 B6 }1 X/ Z/ D3 g7 f
{
! |- u  h0 r6 e$ ~  "rows": [{
6 T) t) ?2 i1 [( E3 M      "account": "account",
1 Q; s% ~$ K& x+ z* q8 K! H      "balance": 999999950
, \8 o! u1 p# y* G* n& n5 Q    }! j7 w4 F' @4 [; I3 q/ z9 r; O
  ],7 A0 j7 M9 ]% t! B  E
  "more": false
8 M9 w6 H) ^2 w; I}
" C- X: B$ I8 L+ _! s余额不足的账户尝试转账,会提示失败( \0 |4 X) t/ n. G1 D
docker exec docker_node1_1 eosc push message currency transfer '{"from":"tester","to":"inita","amount":50}'-S inita -S tester -p tester@active
' L9 C9 G. K$ m+ l0 `* R, c3543610ms thread-0 main.cpp:271 operator() ] Converting argument to binary...
/ N7 k: M- o  f$ K3543615ms thread-0 main.cpp:311  main ] Failed with error: 10 assert_exception: Assert Exception
( O! ~- c, Y4 R; ?2 s- j1 c1 [status_code == 200: Error : 10 assert_exception: Assert Exception
2 ~, G2 O; E) C+ ytest: assertion failed: integer underflow subtracting token balance
: i- L3 H" z3 h9 t{"s":"integer underflow subtracting token balance","ptr":176} thread-1 wasm_interface.cpp:248 assertnonei32i32 [...snipped...]
: R8 u. A; F3 S2 R' ~( [3 ?" _/ `6 [查询合约5 `" L6 f1 _- D  f
如上文验证步骤,在调用完合约后,可以通过查询表来验证每个帐户持有的余额。7 G" _5 N) W1 C" \$ X- v
docker exec docker_node1_1 eosc get table currency currency account
0 y1 v* e; u& z5 J连接特定节点
- W* `9 ?- {* {+ t默认情况下,EOSC连接本地端口8888的节点。可以通过指定主机地址和端口来连接其他EOSD节点。同样的,钱包服务也可以指定特定的主机地址和端口。+ t+ K0 a5 i8 W5 ?0 t1 X
docker exec docker_node1_1 eosc --host  --port
; e* V6 q) o; \# V5 u链接独立钱包服务' h6 V5 [% C% m1 g1 t  L
除了使用EOSD内置的钱包服务,也可以独立部署钱包服务
3 @3 t, l4 W# D# Bdocker exec docker_node1_1 eos-walletd --http-server-endpoint host:port
- f# C* s8 X8 ^; F( S! J调用独立钱包服务需要添加如下选项, K6 a- Y' r: D  w" R
docker exec docker_node1_1 eosc --wallet-host --wallet-port4 M3 A; b3 y  r+ O- ?2 L
免签名验证3 X2 D* Z1 B0 |2 K- g/ L
开发者如果需要快速测试功能,可以跳过节点签名的步骤,这样可以解耦密码学的问题而关注应用功能
8 `3 @4 y" s$ s( h" v4 h0 J启动时使用特定参数7 i5 b5 b- u+ ^. O, X
eosd --skip-transaction-signatures
1 P3 }$ y2 C8 [6 Z$ AEOSC调用时添加-s 选项
! C* m2 r, e& J4 s) ]3 Mdocker exec docker_node1_1 eosc   -s
% @% l! b8 z  J4 J其他RPC调用
$ [" K, R- V  O5 d6 vEOSD RPC 包含通过HTTP RPC与eosd和注册其上的插件进行调用的方式.: n. u* a8 [1 v2 U6 p
1)区块链API 配置
0 x+ n3 ^2 ^5 S0 C( L% x, N+ b想要查询eosd信息需要启用plugin = eos::chain_api_plugin插件并添加至config.ini中
8 g4 o/ y/ [7 j7 p2)get_info接口用于查询区块链的基础信息% G" M2 k2 b, h, M3 u, Q7 W9 j
curl http://127.0.0.1:8888/v1/chain/get_info $ f8 m4 Y) @' p' C/ M% v! A
返回结果如下:
4 S7 P5 c  s; \& v0 k; }5 ~{"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"}
; K* l8 A0 X% f+ h$ sget_block接口用于查询区块相关信息+ I" B: L: A' {
. |5 }# M6 K7 E- b
curl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":5}'
% Z6 w+ t4 K  h9 j7 Ocurl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":0000000445a9f27898383fd7de32835d5d6a978cc14ce40d9f327b5329de796b}'
9 Z; t% U- z7 ?: S# h/ @7 F  O返回结果如下:( G8 f/ C6 W6 x  L9 P5 d( t
{"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}7 X; A5 P5 m& Z
4)push_transaction接口,调用合约交易
) w# I# `& @' \; {该调用为JSON格式并会将结果更新到区块链上
" Q! j' I. P6 k( E2 y2 n执行正确的结果返回
7 [% Q* C$ w1 t- T3 v( w返回 HTTP 200 和交易ID号
/ m/ \; D9 d/ \5 o# ^$ ~* n{ , S# h' V: I. b! U, |" [/ `
'transaction_id' : "..."
; Q* E2 J- R8 c7 j}% W. A2 |- E7 h; j& o
执行错误的结果返回,一般为400错误(参数错误)或者500错误  G8 r" I# X7 I
HTTP/1.1 500 Internal Server Error
% {, `  f! N/ |" y9 _. sContent-Length: 1466
* d: W& B4 A# V  s+ p1 r# o...error message..% ~3 N: J5 E+ k4 ^
push_transaction 调用方法7 q$ f; f; G0 E9 _0 a
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":[]}'8 I! t3 T' L' ^- Y4 {
此示例模拟一个转账交易。 refBlockNum和refBlockPrefix使用的前例block查询的结果
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

罗宾虚汉 初中生
  • 粉丝

    3

  • 关注

    0

  • 主题

    16