Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

EOS纯技术上手学习

罗宾虚汉
167 0 0
EOS.IO 已发布黎明V1.0版本。EOS.IO 黎明V1.0版本是第一个预发布的 EOS.IO SDK(软件开发工具包)。EOS.IO黎明V1.0版本可以让我们体验下EOS一部分区块链特性和简单上手开发、测试。本篇主要是一个快速的review目前EOS黎明V1.0版本的功能上手。8 ?9 ]% g" M, F6 W+ Z' a* C
主要内容:
+ A5 {# G( h/ D' @3 |5 s' w
0 x; y2 b2 Y! U' jEOS Docker快速部署
/ U; V( F2 ~7 b2 }* R# e( x0 e/ ?9 z( l
EOSC使用
6 [+ C* l  |5 L1 z1 m2 L2 X
2 x: W: W* X; f( ^( K0 s% ]创建钱包% W" v8 S! ?! t/ L

4 V6 F# ?( v, S4 E3 y6 E6 d将私钥导入钱包7 I5 z+ }" a+ ^4 e* u
0 u! N, y) B5 Y% J
锁定和解锁钱包/ F* ^1 t3 M8 d$ X* b- _

0 a& A! u: d7 v. ]1 ]6 ]: M- I创建账户
$ p1 T, S$ f3 ~3 ]) R5 w% d! H" d
$ a5 i5 {( W9 ~" V% R$ e9 h内置转账
/ k0 @$ J4 t2 t9 c+ E2 N" h9 A
1 E5 B- q9 t$ K  e查询交易历史
8 V) N: t& @9 H* m/ C9 c$ P4 `% e7 E  D( J8 C1 V
测试合约 - currency
$ B: r' D+ O- k% C8 i$ t. @. H0 g* Y) j( G! d. [+ ]
调用合约: v3 G" |+ A7 k, Y$ P* T  B0 D# W

& r; g0 q5 F% v& S查询合约8 Y  Z4 \3 U/ D5 o/ p1 k5 w

7 b% [8 j9 A( k. Z链接特定的节点  f7 K7 h3 f4 L8 m- J: T

) A& S. d3 {: z" w8 i. S0 f链接独立钱包服务
, b1 `$ }, i  t5 J3 d! O6 S( X" A  n* r* b9 U' m. Y: D
免签名验证
2 Y- @' t3 Z2 Z
$ f0 _: D; O: c0 u9 \: L0 i其他RPC调用
  I+ g. U  W% M3 m" m  M. l# `' X0 l

) `/ r5 J3 Q$ q. d  {EOS Docker快速部署
* l9 n# A  \3 i6 U构建eos镜像
4 a; |" H6 p+ ?$ W$ mgit clone https://github.com/EOSIO/eos.git --recursive+ u2 O7 b0 Z9 W- [& L
cd eos
2 F; `- Q$ Q+ dcp genesis.json Docker
! V! i& q' L1 H" W& [' Vdocker build -t eosio/eos -f Docker/Dockerfile .1 K" x( h7 ?5 d7 K6 {. }
启动容器! r" x! H& b: ?4 x9 Q, `" R
sudo rm -rf /data/store/eos # options
6 s& W3 H8 i5 ^4 C  qsudo mkdir -p /data/store/eos
! [" V! H! e% q  E9 k* E# sdocker-compose -f Docker/docker-compose.yml up
7 b6 _2 W; ?6 P3 H5 u1 z1 v如果 docker-compose 启动有报错, 可能需要给文件存储目录赋予用户读写权限% h; V9 T8 `1 x* ?& D
sudo chown -R SYSTEM_USER /data/store/eos
; b% Y- J0 u4 w# p) e, c验证,查询区块链状态信息
4 i% @2 p2 q! k# l( `5 N" u2 }curl http://127.0.0.1:8888/v1/chain/get_info
' s5 }4 V: q8 ]1 G: _: g  x3 @1 m" L  }如果想使用多节点环境,可使用yml文件启动+ a$ N& R4 R+ G6 r
version: "2"
4 r# h/ e$ O! u& P2 q! V! s3 qservices:& R2 V2 D) C/ k- L
  node1:
- n6 D* c7 }3 Q2 f    image: eosio/eos ) s. \' {1 {$ j( x1 ]0 G* k; K- m
    ports:
' ^2 @- H3 W' f9 ~6 d/ m2 y    - "8888:8888"
; i0 r0 M9 n1 y1 e! T# B    - "9876:9876"
' m2 [4 {$ M1 x+ ^    volumes:: }. X% p+ N6 H; ^5 `
      - ./node1/data:/opt/eos/bin/data-dir5 Y/ l5 Z9 ^* P9 h! w3 V) ^& H. {
  node2:
7 j/ S# V9 X3 ~    image: eosio/eos $ b8 R( ?0 o& ~5 V# d
    ports:# L. X4 p4 C& n. n
    - "8889:8889"
/ p8 z2 O& Z6 t/ ^, g+ l6 P" l$ ?    - "9877:9877"% ~. K- q% v' U2 L1 t1 S# q
    volumes:) j! W% P: y" V: t0 W- P4 p3 M
      - ./node2/data:/opt/eos/bin/data-dir, U4 T# c  u) O
    depends_on:
# [7 a& h$ P  Y' @3 ?      - "node1"# g  }8 G7 c$ L2 ]" @# P
EOSC使用! f- B$ l2 h' F6 _+ \" X
EOSC是EOS的核心进程EOSD对外暴露的RESTAPI命令行工具。EOSC的使用会利用到一些内置插件,插件在EOSD的配置文件config.ini中进行设置,如与链的交互需要使用’plugin = eos::chain_api_plugin’。为了签署交易并发送到区块链上,需要使用‘plugin = eos::wallet_api_plugin’。为了查询交易和历史记录,需要使用’eos::account_history_api_plugin’ 。
: p( [% p  M+ K% ~# Plugin(s) to enable, may be specified multiple times
" J% S9 w5 s6 Q8 y& v3 L3 Cplugin =
; d& |! k2 o! D0 z+ deos::producer_plugin
/ p) f8 q7 G# splugin =
8 ?1 _" Q, F' }& H& \eos::chain_api_plugin
; k9 q" y+ D- x7 D; Y% {plugin =- z6 m% `* ]0 ^5 ?2 h& Z
eos::wallet_api_plugin
$ ]2 t. h' c, Y* S9 c( a% uplugin =
: `2 [  w' y& `* h5 M  ]* Reos::account_history_api_plugin
0 x: \6 Y# x  E启动eosd后,可以使用EOSC查询当前的区块链状态* G2 R+ F1 ?3 \# n
docker exec docker_node1_1 eosc get info
3 b) O3 F' u! v{
- O5 c$ C* ?- E  "head_block_num": 23449,
, c' p& P7 O, H* c) _. d  "last_irreversible_block_num": 23432,0 y) J9 O6 Z8 D. `9 {) E; Z4 @
  "head_block_id": "00005b996cc85962b28537c3d72696a012d1071638f5e4bad1809cf9afc9abb6",
2 G5 E+ s9 V& X9 s) M; t7 _  "head_block_time": "2017-09-29T01:53:33",
4 \7 |( l$ ?9 X  "head_block_producer": "initi",
* U$ k: R) Q: L" M8 g  "recent_slots": "1111111111111111111111111111111111111111111111111111111111111111",9 }- e+ T9 ]+ x2 `/ l1 a: ]
  "participation_rate": "1.00000000000000000"
6 c! C' M' q/ a( G$ w& V! b}# W& u6 j  D* h5 W' s: T/ f! _9 h  I
创建钱包
. \9 W/ ]' p; a4 v任何发送到区块链的交易都需要由所有者持有的私钥进行签名。首先,我们需要一个钱包来储存和管理私钥,使用EOSC命令创建一个钱包。
7 l# x& ^+ g& O- ^8 R# {9 Ddocker exec docker_node1_1 eosc wallet create2 i7 |" F" H  D) a9 ~2 v2 J9 `# U. f
Creating wallet: default9 I- N8 Q8 i3 b/ J
Save password to use in the future to unlock this wallet.
, B3 ~( g7 L8 L7 m$ ZWithout password imported keys will not be retrievable.
" t: W; \9 N$ q( H1 q"PW5JXSxkHqNEwRKCpG2JUTLqkR8SNCBXofkAwaFDLwQkNdqaSXwC8") @  p; t+ }' l0 @
命令执行完成,会在eos-walletd中创建一个名为‘default’的钱包,并返回钱包密码。
+ h- j! K7 w6 _1 x这时候可以查看钱包列表
. O& k. Z7 K# Vdocker exec docker_node1_1 eosc wallet list4 ^  u% f9 k3 B4 N& S, y
Wallets:
. D# `3 V" B5 k, N[0 q4 A# }. R- Y# @( N: q
  "default *"- Q6 y3 u" \+ I
]
# ?6 r6 H0 m& E如果你没有指定钱包名称,默认都操作的是‘default’钱包
# u1 J1 G. r8 k将私钥导入钱包
" u' m+ e0 Q& N" E6 n% H3 }: ~如果你想授权某个钱包可以由某人来管理和控制,需要导入该授权者的私钥。
" D# S, \4 ?; Tdocker exec docker_node1_1 eosc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
# m8 ?- d" f" c, Fimported private key for:' [' O% s. h% C8 j* Z
EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
, F- ~8 X# J. H4 |导入后,可以查询钱包已经导入的私钥和对应的公钥0 c. R7 F' A5 E6 E, u( D$ B1 n: x
docker exec docker_node1_1 eosc wallet keys
: m4 E+ z: r4 x. M4 R# k% j6 g/ v2 ~[[
; c. g2 t6 Q0 F5 y2 M# N! X, a. m"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",4 [+ T% F  z  H/ ]% w& a+ i
"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"
" X! d/ g1 g& Y) h]
) }- X& u- F. `2 ~( l2 f]) `/ p' o5 M* a
锁定和解锁钱包; u+ L7 W, d% w5 ~. N
日常使用,为了保证私钥安全,可临时锁定钱包,锁定后查看钱包列表是不可见的
% M4 [. k9 a! e) Kdocker exec docker_node1_1 eosc wallet lock) @: R9 S& @! D7 j: l2 M
Locked: 'default'  ^0 J  d1 E. l; U5 C6 G
当想要使用时,可以用创建钱包时生成的密码来解锁钱包
" @0 M- _* b! B" J- udocker exec docker_node1_1 eosc wallet unlock --password PW5KVWrn81Y8PLAb52gr2FyXCanVavcrj9d5TC9C3yKhqq1PJYRPk
1 P7 n' t: G$ EUnlocked: 'default'
7 N* Y" d8 B; {' U解锁后,可以在列表重新看到default钱包了  _# \! f! d# _. O' ^7 F" F! Z
docker exec docker_node1_1 eosc wallet list9 _4 s- e+ Q; W% W/ t* h
Wallets: * }$ b9 b  |) p: o( i3 Z8 g
[
& A: g9 p6 r) a- U  "default *"# L6 A1 u9 Q. b+ w4 ^% \  |
]: T5 s# R% W( s$ E
创建账户( d/ D3 ?- S% b  Z/ I
创建账户需要有两组密钥:owner和active。EOS使用EOSC工具来创建密钥对
% C9 E' i) U/ E4 V1)owner key.
: `( H2 j: l- I6 w! X& ~$ h" dPrivate key:5JRc8XxvodWey4StZ2zzkUhCQhDaHvGMkABtfHzQR2ie4qaUFJ7
: H% ~7 i, g9 S7 aPublic key: EOS5mFEdAzxvMkHLQXt2v4naUjnBrPGmzMUCikymqhSR6m7QLGSTB
! ^# D7 C  t) N6 t$ O2)active key
" J1 v% R) d' ?Private key:5KNzFCbToz2a9Hztz9Qen5cyJcM3x5Wpq4GFiTYZgGhzntXdmYo
) I- i9 _, t* t/ qPublic key: EOS5EdsvESpibWLJxupTqod1nswJnbiXQZuUcLiAWEEsqcZskymeB
: H( R$ i7 f! ~% ]( o2 mEOSC不会保存生成的私钥  W; ]: s% n) k3 G
因为后续测试智能合约需要,我们创建一个名为currency的账号。目前这个版本,所有的账户都需要用已有账户来创建,所以我们用inita账户的owener key和active key来创建currency。 为了使inita获得发送交易的权限,需要先导入inita的私钥到钱包。(参见私钥导入钱包的步骤)
' w! q, J$ B2 J: U! Zdocker exec docker_node1_1 eosc create account inita currency EOS6NpEqWi177VKQkuJQL9V6Y3LqAAp9C2j5 t# V/ Q# \& F& o6 E1 p8 F
执行成功,会输出一串json的交易信息,打印账户创建相关内容' A: [- f6 o, E% w$ ~4 M- ~" O0 O2 u' B
我们可以查询inita可以创建了哪些用户
' J, o4 C1 z- h! K5 Wdocker exec docker_node1_1 eosc get servants inita& Z2 N& f4 i- [# e' v* F
{
) ^) C3 |* m# ?! S; U"controlled_accounts": [! W: @' E  j. @: P* M( M8 ~
"currency"
1 a5 P$ v2 \/ G" f]
' h9 K  z# O7 ~9 G7 e1 ?}
5 m$ q" \0 a* A" ]1 T% Y$ _1 Z内置转账4 g3 J1 ~/ o" [: Z
创建账户之后,可以查看当前账户的状态,可以看到创建的测试账号没有余额,这样不少功能无法测试,我们需要试着给创建账户添加一些余额
' o7 O. Y; {. U* m7 w! Kdocker exec docker_node1_1 eosc get account currency
- l; f. j8 q0 S) g8 d8 P{/ F8 N4 n, c2 A+ L- C
  "name": "currency",
% @# j* U1 U" o0 a) }1 K) A  "eos_balance": "0.0000 EOS",& r9 N+ h6 F9 e, B
  "staked_balance": "0.0001 EOS",  D9 l" w0 S/ ]" J
  "unstaking_balance": "0.0000 EOS",& ~4 p, I3 G8 [6 p
  "last_unstaking_time": "1969-12-31T23:59:59",
( K5 I. k: y8 H# Y8 r/ b8 _  "permissions": [{0 l: J# o  V( P
      "name": "active",- {0 F- @1 O1 i
      "parent": "owner",  y  E. W& p; E2 N4 z5 x/ \
      "required_auth": {
9 ]( a; D3 K) Z0 w        "threshold": 1,
$ ^2 q/ L$ B! ~  _1 D9 i2 ~        "keys": [{! z/ h  D5 \8 E! U0 G4 x3 a/ \
            "key": "EOS8ff42NMpJUybVj3nwUSnPpc3mMysKxyE4HVJy1E5o3fQv7knWf",
- T3 q; I& Z4 D+ k  x" a( e! I6 W            "weight": 1
" y/ o6 X7 I" ^, _          }' q. L% Y2 U" ?3 S! q& A* G- c
        ],
7 \: C# x/ j# d. o6 x& m# t        "accounts": []
$ u% i5 d" m0 I8 K      }1 m9 K" p& q6 R$ G  e" L6 r& n
    },{8 d2 E/ x. `# Q" a
      "name": "owner",
4 P8 L( E4 s. G1 b% V      "parent": "owner",
& c# X1 K. m( F7 I: z      "required_auth": {
9 q$ R% J3 O! D5 m/ M        "threshold": 1,
' d% K1 m  d# p% T        "keys": [{! H* V0 i! {' y4 {! w
            "key": "EOS5fQ4saiHV426EQ7AKrGoD2AVMBYe77bnGSq42JjXBUfipv7o3E",
/ G) d0 }3 U# }. X% d9 T3 L( ^, N* s            "weight": 1
( {+ y$ ?. J0 p) y8 ]          }1 t* t( r: s* ?; Z
        ],4 x9 V, ^+ P( e# p  A6 c* y: n
        "accounts": []4 h% ~) r4 B" b' k3 z
      }
9 a" C8 h* d# d/ D" J    }4 h/ ^: k3 m4 W* k3 {; a$ l
  ]7 l. O8 U/ _* l6 [) Q( G! D7 N( f
}
; b; A! p* e+ N8 b保存全网余额的创世账号是eos,查询余额状态
4 u- M' {! M3 D- V# P2 [: [docker exec docker_node1_1 eosc get account eos9 O# T" [9 F3 H0 D* [
{( l4 L" H+ |/ y7 F$ r7 Z
  "name": "eos",
( e, M. {8 U. k* [4 ~+ X' z  "eos_balance": "69000000.0000 EOS",
+ Q( r9 L$ |" F, p/ A& N, m  "staked_balance": "0.0000 EOS",( S0 `3 g4 L1 n) f+ X1 M$ I* z2 L
  "unstaking_balance": "0.0000 EOS",
5 @; W+ D, j- [: }) I  "last_unstaking_time": "1969-12-31T23:59:59",
+ ]* P  c0 t9 W( I2 t5 ~; |  "permissions": [{: |3 @5 d/ K6 ]5 ?9 Z$ I- B% h
      "name": "active",5 ]2 Y5 K8 k3 d* C/ I; w$ Z. j# b
      "parent": "owner",
4 d% I3 h& r8 U5 ~0 p      "required_auth": {" i8 e3 `0 K+ B
        "threshold": 1,
( g0 W( q- ?4 H  ^, t  L  I' P        "keys": [],
' }5 a1 u. V9 x2 }) ~2 ~) B        "accounts": []
+ T' Y, W1 I) L. U      }
$ @$ Q! v& X8 W( z, z" x9 \4 u    },{- U3 `4 a. Z) t3 t4 C
      "name": "owner",% q. v- M9 G  ?7 A: E: O* m
      "parent": "owner",
; _- |" I8 l# A' O; _      "required_auth": {
) J6 S/ W5 T6 U        "threshold": 1," ?3 x( `1 W9 f7 T# g: s/ ?- H
        "keys": [],
+ v2 l! G9 m3 U2 E        "accounts": []) `3 J/ V1 L- ^
      }
- ~- k6 Z( j8 d* Y    }
0 Z" M8 P, L$ D# }) j( c. d  ]
) c5 n) P9 `. a}+ r4 `4 V# l# f+ G; o' u
我们可以通过创世块定义的创世账户使用EOSC给当前创建的账户转移余额: e$ G) k% {( V% ?6 X. r* c
docker exec docker_node1_1 eosc transfer inita currency 100000000/ ~5 C1 W3 l4 e
{6 o& c% X' v5 T5 T4 ^
  "transaction_id": "59575b8caf08eac7c00eb7483c048f12d0e7abf1ede839c3b2ed41dc6c5c7c5f",) V, J' C) n% {! w
  "processed": {. ?) z) C5 K# [/ V
    "refBlockNum": 24199,
/ z& B6 A& A# D$ s7 Z5 I/ T    "refBlockPrefix": 1485651173,
5 |+ x- O/ `( Z) B/ |% ]. N0 l  e+ X    "expiration": "2017-09-29T02:31:03",
# e* g( p. Y) D! X  O9 p" W) l    "scope": [
: g8 s) a8 W9 z5 Y3 Y6 C      "currency",
7 g( D% R& l% y. C. ]      "inita"
  J7 f4 Y1 Y/ H  w$ N6 @    ],0 ?( H1 N5 s" j; C. T
    "signatures": [
$ L+ K* w- S, g% ^( V3 t! L      "1f14229bdd4bfb927021bf96ff0651c8b0fa5666e9f5cf423a0270a1b91f2d2f690b573e179d8475ce2c6b160f5cd5507d58a44f8f6cf536348584efa8dd62ade0"3 R. q/ ]3 _* }! l# E
    ],2 u3 V6 v. q. ~. a
    "messages": [{* F1 O1 n0 X8 N$ D8 e
        "code": "eos",
: x0 [8 @/ m! |. g. o# J        "type": "transfer",
9 q8 Q' f* C* m; L) P5 H, @8 y0 w: }        "authorization": [{
4 h) |% t( H5 k            "account": "inita",0 n: B$ S7 k  ]: w: s$ S
            "permission": "active"
' f8 y3 R% V4 p- r% q, G0 I1 ]          }7 S5 I+ D. I, k- l
        ],4 @+ v2 ^* f" s4 [3 ~
        "data": {. s+ S0 s8 m6 K
          "from": "inita",8 [/ _$ s  ~  f% ^5 c8 _- X% r
          "to": "currency",1 B, ~$ L3 S5 ]( a9 h
          "amount": 100000000,9 I0 X$ h( U" m& t/ j7 e8 x
          "memo": ""
/ L$ S2 M' ~$ Q7 @4 ^9 X        },
# U. T/ E) @: g) }) J2 S; g8 s( y7 {        "hex_data": "000000000093dd740000001e4d75af4600e1f5050000000000"$ f5 \/ n1 N( I7 R0 _  U
      }
+ L2 z! O3 O% y5 \$ I( P4 F/ z' i. |    ],9 V0 E5 |! e& B3 s) W( X
    "output": [{
9 u" w1 X! c# f+ `( ?" t" [7 K        "notify": [{' A& l& C6 l, p  T4 ?* \% T
            "name": "currency",
/ ?& x% }; r  L7 I. F! O            "output": {
% i9 p5 N" D4 i! Q              "notify": [],
' K+ ^! O, c3 y3 E2 X              "deferred_transactions": []
1 V8 H4 R* C% I+ z            }# B( }, j: l, ^! x) g
          },{! ^3 `6 o" z' A* {
            "name": "inita",
# P( w) z' Y9 m5 R. H( t; \            "output": {
$ s/ u2 N5 G2 J/ F, I" ]/ V3 Z4 f              "notify": [],, g) f2 x- O# h8 \! w  }6 l" @5 s
              "deferred_transactions": []
& }  L# c1 {# ]# _3 @6 S# ]            }6 h% `8 [9 {& L% K0 {
          }
9 \! T/ d0 S/ [5 A# f. k        ],
- a7 T4 z. c7 \: F8 r; I        "deferred_transactions": [], P" f: n7 {7 }6 L1 }! @* q
      }7 R" S! L1 h' W' w/ B
    ]+ d. [1 M! E: W% m6 d( r
  }. a3 x/ ?9 ]) w" h6 z
}( f' r: V% J: x) c4 g' ~
再通过执行get account 命令,验证余额已经成功转移到创建的账户下5 u) d( z0 r/ g4 i" N' }/ F
查询交易历史- E- m  S' G+ i4 U3 T
查询交易历史会使用到插件account_history_api_plugin,我们已经在config.ini中定义2 q3 T; y6 P* L* l5 m8 @) J" _
docker exec docker_node1_1 eosc get transaction # e* v; W+ n3 _4 u
如果需要查询一个特定账户最近一次的交易记录' Z$ q! ]) _1 n* N. t
docker exec docker_node1_1 eosc get transaction inita6 W- c0 f7 g+ a5 D: L- _8 @
创建智能合约
0 ~. ?3 [7 S' t; L4 w/ i官方提供了一个示例合约currency,我们依然使用EOSC来创建并部署智能合约,合约代码位置contracts/currency。+ N; q& f3 T- y1 R+ K' S8 c1 ?) D$ m
1)为合约创建一个所有者账户。前文已经创建了currency账户( M6 Y( r# E- G5 L1 Z) O
2)检查区块链上有无同名合约
% d' I2 e( h5 z* W, v$ S& {( xdocker exec docker_node1_1 eosc get code currency
3 @( p. c5 ^- Ncode hash: 0000000000000000000000000000000000000000000000000000000000000000
! X! ^- t+ X- }& ^+ n3)为了获得部署权限(发送交易请求)需要将currency的active key导入到钱包中/ {/ U  `; y2 Z- F$ M7 W) o+ H
4)部署合约(.wast后缀文件)和他的abi(.abi后缀文件); F8 Z9 u/ W# m
docker exec docker_node1_1 eosc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi! H& D/ j+ Q) n3 \+ d/ h
Reading WAST...
7 I6 F2 n4 }0 H  W7 ~& _! Q! JAssembling WASM..., S5 ]" i$ @. h$ F& s( U$ j
Publishing contract...& k; d5 }0 A) U; H3 p9 U. A% `5 D
屏幕打印部署成功相关的信息,并查询合约hash
" O+ j% m* x5 B; w6 bdocker exec docker_node1_1 eosc get code currency ; Z- C  f' o- V) v9 H
code hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf
. N" y4 E* X! M- G调用合约2 n2 D" ~- X# k& a. P6 M6 v' w
在合约部署到区块链上之后,所有的currency余额会分配给我们创建的currency账户。我们可以调用合约测试做一些转账交易。- `; h' G" S+ }" g+ g- |" r
为了更好了解区块链合约的调用方式,我们可以通过.abi查看可以执行的操作列表和消息结构。& T" N0 C: Z3 B, d7 E6 P
docker exec docker_node1_1 eosc get code -a currency.abi currency- [" Z  [# C. R2 a' i2 I# S0 S
code hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf
& e4 E3 u6 C% {- x9 csaving abi to currency.abi2 U% O3 [% Q, Y9 {5 \, z& g7 W
cat currency.abi #查看
+ ~! t0 C0 n( _3 Q- }6 N; k% @{+ ^* ^7 J$ Y7 w4 T- u" O
  "types": [{  T# |- r, b3 O; Y0 s
      "newTypeName": "AccountName",
# h" q* D" q! Y3 [2 `) D      "type": "Name"/ S: t% d" J3 G7 P2 E* M9 y1 @, C7 k
    }4 x0 v3 |  e$ ^, @+ u. D
  ],$ t1 G& A7 B0 h) |0 c
  "structs": [{) j" w3 ^2 ?$ x, e  d7 E  o& |
      "name": "transfer",. o8 d8 }2 L4 T7 R' e5 y
      "base": "",, X: U7 V. b4 N- L% Y. Y
      "fields": {
* S# c$ D3 u- V! S8 @, ?" a        "from": "AccountName",& K9 d$ U' d7 Y) n0 o1 o
        "to": "AccountName",
8 g$ V4 W5 {& P" d- d        "amount": "UInt64"
, s: D2 W: I- I& Z3 B      }6 n9 Z- k$ c* b' `: K0 a+ G
    },{
; f6 _* e$ [% n( f      "name": "account",
# \0 r- {# w. Y6 D% w0 U6 X      "base": "",
8 g) O/ o  x) g9 d$ n  J1 i      "fields": {3 |9 ~' x9 t2 E1 g( t. ~
        "account": "Name",
# m  u9 I7 ~: \  R; P  O        "balance": "UInt64"1 M4 c, I" o& W1 |: @: m( i
      }! i5 k9 u: C  E2 _$ @$ q" Y
    }7 c( ?# W0 Z' y/ E2 i% m" _/ r
  ],
# \7 M! N! U+ l* `- t( N0 E  "actions": [{; S4 T, N: N+ s6 `
      "action": "transfer",
' d  _. A' T. ?: u+ X      "type": "transfer", ^6 E* g  Y1 X7 R
    }# o; f5 W$ K4 Q) `: e' q: R7 O
  ],  o0 }5 ?9 |+ F6 b. Z% ~$ r' L
  "tables": [{
3 [7 [2 e9 A* u5 ~6 x% `) K      "table": "account",; K  @# D0 Z+ y( }' u8 ]2 e
      "type": "account",+ Y7 R; J9 a9 G+ V/ k3 Q' R
      "indextype": "i64",. R0 c8 H( t6 i6 F) n" l' E
      "keynames" : ["account"],, o' W: i2 u7 {6 s) f* h* P1 V
      "keytypes" : ["Name"]
7 n! f0 I6 u. q& m) E0 K    }
; p) H7 W+ p8 O9 Q  ]* X* ^8 b6 m' f' N: F
}
- r; c& F/ u+ l. w) R) ~通过上面的abi我们可以看到currency合约可以执行transfer操作,消息格式为from,to和amount。我们调用合约从currency账户转移50个余额到inita账户
! C, F2 W) @8 [$ P* b; cdocker exec docker_node1_1 eosc push message currency transfer '{"from":"currency","to":"inita","amount":50}' --scop% t  [3 c/ X" t  U% [" c9 W/ ~
执行完成,我们查询余额验证结果
9 c  u/ j: B( C0 hdocker exec docker_node1_1 eosc get table inita currency account+ X% R+ ^0 S7 A! P) K4 D* s
{
4 j1 x+ }" v: Q  "rows": [{( s' K3 S/ D$ P! J. Z
      "account": "account",/ L! c5 }$ \4 X9 ~$ _/ }+ q2 L3 `
      "balance": 50 / n4 V+ p$ @7 y* G) m
       }
" }/ r% f' h3 j- z8 y" k    ],
5 `8 ~9 P0 m  ]% ~8 d' Z# R  "more": false
% S  ^( Q7 C8 A' j6 x}
" i) O; |- @6 K7 E. v1 V/ ndocker exec docker_node1_1 eosc get table currency currency account
* U2 `0 l. E0 \0 g" Y5 I{
( K0 C4 g% f9 o' l' f1 R  "rows": [{
2 e, I) K. Z/ @! [* f* [9 s2 G      "account": "account",
7 K. P* r9 [9 W: [8 e' D      "balance": 999999950
! Z) w2 P9 s, K4 t: W6 R    }- [/ y+ v5 R& G2 d1 c) h
  ],. r  G( J8 U8 v8 N) L5 j
  "more": false
5 s5 P: {5 p" Q6 P}
! a- V& ^! E6 g1 P4 E( J' u余额不足的账户尝试转账,会提示失败
9 w! R8 @% E/ e: \: C) Idocker exec docker_node1_1 eosc push message currency transfer '{"from":"tester","to":"inita","amount":50}'-S inita -S tester -p tester@active, C* t( H: |! J, X+ x! n+ n- W& F4 W6 d7 ?
3543610ms thread-0 main.cpp:271 operator() ] Converting argument to binary...3 h# M, \; q/ m; g% R& n! X$ U
3543615ms thread-0 main.cpp:311  main ] Failed with error: 10 assert_exception: Assert Exception% U3 h/ S' P+ r3 t; W: [6 S
status_code == 200: Error : 10 assert_exception: Assert Exception
7 v, r: u& m" d9 W& ftest: assertion failed: integer underflow subtracting token balance
/ n: M  h/ U  a9 D/ Y{"s":"integer underflow subtracting token balance","ptr":176} thread-1 wasm_interface.cpp:248 assertnonei32i32 [...snipped...]% z- w1 N" Q% M
查询合约
0 H# c2 z1 A* [# v/ L2 A如上文验证步骤,在调用完合约后,可以通过查询表来验证每个帐户持有的余额。
6 r" }5 Z) ?& P5 Edocker exec docker_node1_1 eosc get table currency currency account
+ K$ q# J& ~8 [. `/ Z8 B2 Q2 s连接特定节点/ v, Q' x) A/ d' u- O* U+ P4 q
默认情况下,EOSC连接本地端口8888的节点。可以通过指定主机地址和端口来连接其他EOSD节点。同样的,钱包服务也可以指定特定的主机地址和端口。1 s1 ~3 u# Z( _( I2 _" z- B
docker exec docker_node1_1 eosc --host  --port ' g/ n7 v7 D0 u5 k- r9 V& g  |
链接独立钱包服务+ o) R3 T/ A- Q  U
除了使用EOSD内置的钱包服务,也可以独立部署钱包服务
/ D! H% H$ g  }; ?$ ^# v+ z; Bdocker exec docker_node1_1 eos-walletd --http-server-endpoint host:port1 o4 p3 D. J6 t! f
调用独立钱包服务需要添加如下选项
4 v# h1 X8 f: P. Gdocker exec docker_node1_1 eosc --wallet-host --wallet-port+ `$ j6 s3 p: r2 h, ^8 h) U) u
免签名验证( m% _7 k6 v% R/ ]- m
开发者如果需要快速测试功能,可以跳过节点签名的步骤,这样可以解耦密码学的问题而关注应用功能$ D# ?; F6 |; L1 j
启动时使用特定参数4 C" {# v$ m0 k" h  J+ E
eosd --skip-transaction-signatures4 T3 }2 G# y+ d; Q% k7 p' s
EOSC调用时添加-s 选项$ O8 p3 m5 X3 n  g8 M& i
docker exec docker_node1_1 eosc   -s
$ ?7 z7 }) ^! F# |: {) v1 x其他RPC调用0 b9 U9 a4 {2 J# g6 ?) u5 e
EOSD RPC 包含通过HTTP RPC与eosd和注册其上的插件进行调用的方式.
$ ~8 Z* C3 y. I' ]/ z1)区块链API 配置: Y) F  l/ B$ D: j
想要查询eosd信息需要启用plugin = eos::chain_api_plugin插件并添加至config.ini中1 W6 V. o3 g* w* @
2)get_info接口用于查询区块链的基础信息9 d  N2 p) e: h. m8 p; L
curl http://127.0.0.1:8888/v1/chain/get_info
1 w; T0 M; z0 S8 h返回结果如下:
; I3 t! O2 j8 Z8 I5 g: ~{"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"}6 a: V) Q: I+ U3 g. }# `% M
get_block接口用于查询区块相关信息
" e' u# K7 Z, b6 [2 N% o- V, j
% z+ }+ _+ _5 W' z* Zcurl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":5}'
) B! }/ D; E  ]curl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":0000000445a9f27898383fd7de32835d5d6a978cc14ce40d9f327b5329de796b}'
  r, x( F: i' W) ]( ?返回结果如下:
( a- W/ Y/ p3 g{"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}; Y$ ^, d  k/ T% c9 c
4)push_transaction接口,调用合约交易$ L( I" T3 |% J1 q/ J/ t$ |6 _; E+ J
该调用为JSON格式并会将结果更新到区块链上
: Y" t: g( b- @3 A" ~7 v/ I执行正确的结果返回
5 s! V7 X+ ?# w: R) h3 i9 c返回 HTTP 200 和交易ID号% E& U( z) T: O0 Q
{ 1 b9 D( [6 Q6 H6 p1 Z! `. _) N
'transaction_id' : "..."
: Y' T- M- R! j, E, x7 A; `}- k1 b2 X  ^. w
执行错误的结果返回,一般为400错误(参数错误)或者500错误) a0 L* n6 b; w/ }  N0 @
HTTP/1.1 500 Internal Server Error  T+ S- L/ k# M. a
Content-Length: 1466
7 M, p/ [/ H3 m9 t# u3 w...error message.." m1 D- I- M2 A7 {* X
push_transaction 调用方法
0 d" z( P' A. T2 O, M  n: lcurl  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":[]}'. m4 M5 |" l, P& I  u* a8 f$ C
此示例模拟一个转账交易。 refBlockNum和refBlockPrefix使用的前例block查询的结果
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

罗宾虚汉 初中生
  • 粉丝

    3

  • 关注

    0

  • 主题

    16