Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

EOS纯技术上手学习

罗宾虚汉
154 0 0
EOS.IO 已发布黎明V1.0版本。EOS.IO 黎明V1.0版本是第一个预发布的 EOS.IO SDK(软件开发工具包)。EOS.IO黎明V1.0版本可以让我们体验下EOS一部分区块链特性和简单上手开发、测试。本篇主要是一个快速的review目前EOS黎明V1.0版本的功能上手。" s! J% k* c8 j! h
主要内容:" ~3 c" m3 ?* ^4 X
( c( U% U0 x  R' K$ t3 X; Z
EOS Docker快速部署
9 G4 `0 z6 E" t/ ]- @* [8 R
0 g5 m, x: {5 f, Z; a  cEOSC使用" z2 Q% Y! A' _# A9 K) B0 R& S' t

9 @; [+ B+ Z' |3 {, M9 K创建钱包
9 ~4 I6 r0 r4 Q: {: l
* y4 `' `3 L  @8 ?将私钥导入钱包! X& G' w6 S3 T2 ?6 W8 g

, @( T5 j4 z. E0 K: w" i5 v锁定和解锁钱包( R8 `+ q& q3 t  W% u% g! X% l

. P6 I- \7 ?3 F4 D' F0 H创建账户
9 a- b, z( n- K: A. p+ `. c  P; a
内置转账9 ]% `1 d  {* J% L9 k/ o, v8 b# C  N
; z% Q' C" `" c: z2 T; y" G
查询交易历史0 F5 t( \2 `# t, E5 G- h5 ~! y. R

+ b) P% i9 R& u6 C; @- V9 R测试合约 - currency! f& c' g. b0 G$ f

: ^# u7 ^2 V  K# S调用合约) ]6 F% J1 ~+ c& K6 n7 U5 i, }
* J% Y4 F: p8 r1 w- ]- X4 }$ B5 G
查询合约: j% W$ C& \& S: z

; C/ k7 A- T* c( M/ W链接特定的节点
  W' s/ ?& f) U3 J) B. o! G) @4 _; U" ^& k# y
链接独立钱包服务
! M9 E/ [! L% M! u6 r) T* Y+ Z5 y( s: i) y
免签名验证
; V9 j9 {9 U# `
% Y3 {2 C, i& _5 R其他RPC调用
  H. D, {' ]* ?  Q2 E
1 d/ k8 [* {1 i. E" Q" W+ o' P' n  M: M8 U
EOS Docker快速部署
: l3 i, _  e1 N# X构建eos镜像
, `% g+ d1 U* i2 `- \2 Q! Bgit clone https://github.com/EOSIO/eos.git --recursive
: i- w# w% q0 m$ [& Y$ ccd eos
% F+ v- v  X5 M0 T  c9 rcp genesis.json Docker
, g8 p: S/ z7 m" fdocker build -t eosio/eos -f Docker/Dockerfile .* L& Y1 ^% x6 p) v
启动容器
$ C# E8 r* J- x3 t6 ksudo rm -rf /data/store/eos # options ; }) J8 |2 V; b0 u2 l  \
sudo mkdir -p /data/store/eos' O* @  }- N$ W! {$ v1 q; M2 P
docker-compose -f Docker/docker-compose.yml up
# [2 M" h* F: M8 x" `如果 docker-compose 启动有报错, 可能需要给文件存储目录赋予用户读写权限% ]' a! n% ^% O( P) f
sudo chown -R SYSTEM_USER /data/store/eos
1 W, u- m: T  b8 e验证,查询区块链状态信息: J7 _+ r1 U! r; b* }5 Q; ^
curl http://127.0.0.1:8888/v1/chain/get_info
) o" W1 R1 C2 W& w6 i* R如果想使用多节点环境,可使用yml文件启动
& o, b8 X9 z5 \$ l8 y9 dversion: "2"& L* C: q# U" D
services:2 k* j# _- m9 @8 b
  node1:; s( d4 H+ u8 {6 r$ N5 H% O- ]
    image: eosio/eos 1 l, ^' d) W+ S  b% b
    ports:
/ m; j6 w3 C) r! n  f    - "8888:8888"
) R! @/ F& ^$ V- g, G    - "9876:9876"
) @. \5 E5 F5 R/ U; x: u  W! G    volumes:
7 |+ {3 r" _0 `1 e0 z  C      - ./node1/data:/opt/eos/bin/data-dir! }+ ^+ G1 q6 o
  node2:  X( p! h; l' A
    image: eosio/eos
6 G1 e, ]' _/ b& [    ports:
4 g9 o4 D0 H+ k! t    - "8889:8889"
* C% z1 ^5 G# X( c- @    - "9877:9877"3 _$ D) q9 F5 g5 `2 R( E
    volumes:
  W* B* ^) E8 h      - ./node2/data:/opt/eos/bin/data-dir
/ o% a: Z5 H. t! r" [! D    depends_on:
" C% n8 X6 e9 p# {; d2 P: u/ o      - "node1". l8 P4 J: Y( ~- ~# e. @7 L
EOSC使用
1 S( U5 x* @* j% {3 u, f, O) TEOSC是EOS的核心进程EOSD对外暴露的RESTAPI命令行工具。EOSC的使用会利用到一些内置插件,插件在EOSD的配置文件config.ini中进行设置,如与链的交互需要使用’plugin = eos::chain_api_plugin’。为了签署交易并发送到区块链上,需要使用‘plugin = eos::wallet_api_plugin’。为了查询交易和历史记录,需要使用’eos::account_history_api_plugin’ 。
8 e* u& ?4 A9 _) Q& H' u# f& G# Plugin(s) to enable, may be specified multiple times
; |7 x5 [$ H; }' |6 Pplugin =
6 c- t; f( U1 k+ X* T$ keos::producer_plugin
' A+ K; G$ l2 g1 [' |plugin =
* {# ~; |; {% M& Teos::chain_api_plugin
; `+ m9 j" e  j2 g2 Tplugin =; t- e' K, x: I* h) D$ f
eos::wallet_api_plugin
4 \" ~  h) {! h7 n& ]& K) `# ~plugin =5 i4 Q* c' A$ \) x8 K1 m+ H
eos::account_history_api_plugin) O1 g) Q3 R8 R1 v
启动eosd后,可以使用EOSC查询当前的区块链状态$ j' Z* g3 v+ v' I1 ]3 `
docker exec docker_node1_1 eosc get info: ]  ?8 L6 y! l
{
7 O" Z4 t8 N+ a! e; Q8 U' O& s  "head_block_num": 23449,
9 s: b1 f: ~2 O% h  "last_irreversible_block_num": 23432,6 {8 n2 y1 Z2 P; N
  "head_block_id": "00005b996cc85962b28537c3d72696a012d1071638f5e4bad1809cf9afc9abb6",# D& ], s8 j' [- \: ]( W
  "head_block_time": "2017-09-29T01:53:33",
% a& }! K! ^( R' b+ W+ L& a: c( t2 S  "head_block_producer": "initi",
7 ?( }. L' `: `1 B  "recent_slots": "1111111111111111111111111111111111111111111111111111111111111111",
/ g) K6 _8 ~: J6 N, ^$ w  "participation_rate": "1.00000000000000000": u. K0 ^" s7 B0 I# @, R
}
+ Z7 E" G& k3 o4 g/ ~; I创建钱包
& }% O6 E4 l6 }& D) M6 Z任何发送到区块链的交易都需要由所有者持有的私钥进行签名。首先,我们需要一个钱包来储存和管理私钥,使用EOSC命令创建一个钱包。
  A" `3 j5 K( {$ p5 K0 Q8 k  q% adocker exec docker_node1_1 eosc wallet create/ q- j7 |; V, {" k, v) ^4 n2 M- J
Creating wallet: default
* X0 F+ J4 r+ E9 ?! ~Save password to use in the future to unlock this wallet.) l  _, g/ M0 t& b1 P& C, g+ F
Without password imported keys will not be retrievable./ T) T; j' n; k- F" I- f  R, g
"PW5JXSxkHqNEwRKCpG2JUTLqkR8SNCBXofkAwaFDLwQkNdqaSXwC8"! Z3 J6 Y* G& U! y2 \/ V+ E: a
命令执行完成,会在eos-walletd中创建一个名为‘default’的钱包,并返回钱包密码。, ~% u, U* p$ ]
这时候可以查看钱包列表3 U$ q* K  w4 H, C7 y
docker exec docker_node1_1 eosc wallet list
. D; X3 f0 I3 s# S( @Wallets: 4 U; ^2 d" H" c' ], o& i
[* {% P6 L+ {4 b& B  o$ g
  "default *"
; O; x3 p  g& j" ]  }]
$ m  i+ p0 I, c, n! \2 Y& N如果你没有指定钱包名称,默认都操作的是‘default’钱包0 O5 x6 K0 m+ C# i
将私钥导入钱包& t5 ^0 L/ Z6 F9 B
如果你想授权某个钱包可以由某人来管理和控制,需要导入该授权者的私钥。
* X3 d# u! N. k) A: V3 udocker exec docker_node1_1 eosc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD37 W* r4 ^) P. [3 k
imported private key for:
, b, n6 X0 x0 B/ W. z9 k" Q0 MEOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV) r6 g  S7 a- [' ^
导入后,可以查询钱包已经导入的私钥和对应的公钥% i4 v; _9 R3 a+ W) Q3 W5 R
docker exec docker_node1_1 eosc wallet keys
- M9 M0 D- B3 x) r: m[[8 f- L& S# ~% h9 C8 l- H
"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",  p+ L$ ~2 n/ y6 H/ Z' b, x+ o. {
"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"5 ?2 z% }% r7 H* j' T, d3 A
]
6 J5 q8 c# h# q" g]6 {4 l5 I1 E8 Q( S2 ^
锁定和解锁钱包
" T8 D. ?5 l( }& ~% l$ f日常使用,为了保证私钥安全,可临时锁定钱包,锁定后查看钱包列表是不可见的8 _, ]& H+ T/ |3 r+ L5 l
docker exec docker_node1_1 eosc wallet lock
2 `) z, g5 M6 R0 e2 W6 y% RLocked: 'default'$ `* w$ @  O2 o1 J
当想要使用时,可以用创建钱包时生成的密码来解锁钱包
( E0 E, p" ~+ h( ]  c3 k5 vdocker exec docker_node1_1 eosc wallet unlock --password PW5KVWrn81Y8PLAb52gr2FyXCanVavcrj9d5TC9C3yKhqq1PJYRPk7 l; Q) G, S6 r4 W& t
Unlocked: 'default'' g9 m9 e1 [' F0 u/ [3 s
解锁后,可以在列表重新看到default钱包了" r2 U+ }# c" I1 `; A$ b
docker exec docker_node1_1 eosc wallet list
$ H1 F  K5 l7 KWallets:
0 b; E$ [6 u3 y  t5 S[2 }: H) u2 j' |& t/ G/ c
  "default *"
* G# x" b/ N" ?3 ^9 h8 Q]
$ F% u/ C6 H! b' H1 N创建账户$ f0 Q) `  L4 w( p/ q3 P1 _
创建账户需要有两组密钥:owner和active。EOS使用EOSC工具来创建密钥对
) f7 {5 `8 w# m1)owner key.
, w- ^8 e( F1 TPrivate key:5JRc8XxvodWey4StZ2zzkUhCQhDaHvGMkABtfHzQR2ie4qaUFJ7" G: r, x# I* H
Public key: EOS5mFEdAzxvMkHLQXt2v4naUjnBrPGmzMUCikymqhSR6m7QLGSTB7 E9 Z# H4 w' k
2)active key/ o& f$ V) A& S# ^" L1 J/ V
Private key:5KNzFCbToz2a9Hztz9Qen5cyJcM3x5Wpq4GFiTYZgGhzntXdmYo
: ?% v7 |( M& C+ W$ [& J- FPublic key: EOS5EdsvESpibWLJxupTqod1nswJnbiXQZuUcLiAWEEsqcZskymeB
6 l. e  z5 n( |- V, I' D4 NEOSC不会保存生成的私钥
- L* G& j9 b  s6 t因为后续测试智能合约需要,我们创建一个名为currency的账号。目前这个版本,所有的账户都需要用已有账户来创建,所以我们用inita账户的owener key和active key来创建currency。 为了使inita获得发送交易的权限,需要先导入inita的私钥到钱包。(参见私钥导入钱包的步骤); q* d1 x# @( R, w
docker exec docker_node1_1 eosc create account inita currency EOS6NpEqWi177VKQkuJQL9V6Y3LqAAp9C2j$ {: g, x, {! |, n( T" ~& S
执行成功,会输出一串json的交易信息,打印账户创建相关内容
; y" j" ]8 _9 D我们可以查询inita可以创建了哪些用户  d: W4 D! u: s7 T7 J
docker exec docker_node1_1 eosc get servants inita
- {( Y5 F3 e/ F. J8 }{6 `* M- B: C3 E
"controlled_accounts": [& q6 j/ h2 u2 F# z! x' Q2 U2 p0 \
"currency"
8 i4 W( k( D; j% f]
+ \2 s( e& }  B9 d* n1 _/ l: ?- d}* r6 [% T, s# K6 Y. S
内置转账4 z  @! u1 O+ q0 {% `6 }* p/ f
创建账户之后,可以查看当前账户的状态,可以看到创建的测试账号没有余额,这样不少功能无法测试,我们需要试着给创建账户添加一些余额
5 p0 L! s( D+ |" x9 t* Fdocker exec docker_node1_1 eosc get account currency  @. F9 H- Q) q# ~! ~+ E. l
{
- G8 p* ?" r2 t* M0 V  "name": "currency",, v7 P# h* |! J: b
  "eos_balance": "0.0000 EOS",' m/ s% j( P) K9 Q
  "staked_balance": "0.0001 EOS",
2 S. v) `( O4 J" J5 a/ N  "unstaking_balance": "0.0000 EOS",& w! P# H1 y% x
  "last_unstaking_time": "1969-12-31T23:59:59",9 r" Z+ q3 X* v3 F
  "permissions": [{
0 O% }' |/ l1 ~* k) j* J. o      "name": "active",$ f7 o/ K; Y$ l1 `
      "parent": "owner",
8 f1 a5 y, O: Q* ]& f. J      "required_auth": {, f4 p3 \% o3 Q5 }/ J
        "threshold": 1,
) w! h! V& u( \% u0 G1 O        "keys": [{- V# o+ T+ T* i2 ^& R0 K
            "key": "EOS8ff42NMpJUybVj3nwUSnPpc3mMysKxyE4HVJy1E5o3fQv7knWf",
3 C$ n7 Z6 b; E' L( C            "weight": 1
3 ^  K! E* c5 e& W8 p# C          }! @: Q% k$ r* m6 s& f. k# i$ e% V7 b2 |
        ],5 \1 u( E- c+ u2 [4 j7 J
        "accounts": []
) V  M" x( _6 Y$ j! @* G  X      }& m& G# h6 n& n* D! d$ a& _' c5 L/ Y
    },{
. \" L" |2 C, w      "name": "owner",, U" b2 X- I6 D& S$ C
      "parent": "owner",
4 i1 l1 r6 ?. c' R  W6 m      "required_auth": {
% m8 d( Y+ ]0 X, A        "threshold": 1,
5 G# @7 [6 _: C& ~1 `        "keys": [{2 j7 w& |0 L7 p; W
            "key": "EOS5fQ4saiHV426EQ7AKrGoD2AVMBYe77bnGSq42JjXBUfipv7o3E",9 |# I2 b! m6 M3 r3 D7 L# Y
            "weight": 1
' o( W5 _* Z5 W- h/ [          }
2 S$ O1 N- j. C' l5 h$ M$ H        ],
/ ]- r& f8 M0 Q% b2 }' O. e/ Q        "accounts": []/ J: Y' N8 U3 r+ @
      }
1 ~/ R" ]* I5 `( \9 f7 z    }
8 |0 D3 k" W+ N# B  ]7 Q5 z1 n; H4 i0 \+ ?: `
}3 |5 h$ Y. u8 I0 V& E. l
保存全网余额的创世账号是eos,查询余额状态
  \) [: I! E& U& H, G, }docker exec docker_node1_1 eosc get account eos" E' s. B3 \- e: E
{
9 S5 R# L2 J* `" ~  "name": "eos",
6 q7 a' N5 \+ c7 O5 C' b  "eos_balance": "69000000.0000 EOS",/ r% R8 ]+ a$ ~: g0 {$ V; W
  "staked_balance": "0.0000 EOS",
  }/ k6 X4 d6 t6 l: ?% b" W- e  "unstaking_balance": "0.0000 EOS",2 a3 R; ], Q2 h& q2 a& Z) b
  "last_unstaking_time": "1969-12-31T23:59:59",6 w2 P8 ?, I3 v) E; F" f, |
  "permissions": [{
  ~3 _' q% S2 C0 H2 W9 H5 Q+ {      "name": "active",
$ E, u; o  y: ~/ S) i3 F, S$ Z      "parent": "owner",% e' a  X" S7 ~$ S* g
      "required_auth": {' o) ^6 }' X6 H3 {( O) Y
        "threshold": 1,
( n7 B% a0 `/ a3 O0 ^8 l        "keys": [],( Y$ a/ ]( ?8 S/ t# p: M  c$ ]
        "accounts": []0 D* ]; j, h) s: U: d. p% H
      }* L: H0 _- D  ]. B) n
    },{# b) d. [* p& `/ v
      "name": "owner",% u3 ?* N  v& {
      "parent": "owner",
3 e! i, k. L- a1 |5 O      "required_auth": {' w% S9 n. a, [, {
        "threshold": 1,: }* m; g' S2 l& o9 N) t- Y
        "keys": [],- h7 Z0 y) P4 ]! R  E
        "accounts": []
" A/ _# q' z2 J5 a! P! {: e8 C* ~; d      }
& ~3 S2 U6 s2 y7 e8 Y    }  L& v& x3 [+ d3 X" B( ]# A
  ]! S5 h5 o! b8 ~5 A
}2 y7 D; t( g+ O0 @* Z1 o
我们可以通过创世块定义的创世账户使用EOSC给当前创建的账户转移余额
) m/ r; R) u. f* p+ h2 u/ }* I# j7 Wdocker exec docker_node1_1 eosc transfer inita currency 1000000008 O* r! a! ?/ `% K5 i: ?; j" `
{, J; T8 e& b% E. T" C
  "transaction_id": "59575b8caf08eac7c00eb7483c048f12d0e7abf1ede839c3b2ed41dc6c5c7c5f",
' O: g$ o' w6 a, J# `  "processed": {
- f0 n, j3 I* z, p9 [4 w, _$ C    "refBlockNum": 24199,$ I* e1 W$ N7 U( {9 \7 M
    "refBlockPrefix": 1485651173,- _9 {3 ~7 A% s# |- q
    "expiration": "2017-09-29T02:31:03",
5 \* H) H. e/ \' z8 b* t* H+ [( @    "scope": [
, G) b' G, O3 _" v9 t4 [# G      "currency",, Z! J& Z" z' J
      "inita"% F5 I; l# s% B1 F
    ],
* W1 K1 u# w0 O' S. e+ V    "signatures": [
* v% D5 P& }0 k- f7 B: y$ j4 d/ u, j      "1f14229bdd4bfb927021bf96ff0651c8b0fa5666e9f5cf423a0270a1b91f2d2f690b573e179d8475ce2c6b160f5cd5507d58a44f8f6cf536348584efa8dd62ade0"
; E2 t8 Z) G1 f9 d! S    ],, b' t& Z# @* m' b& L6 \  @
    "messages": [{
2 {3 S1 B5 N$ ^7 h        "code": "eos",0 D% _5 }, N1 O
        "type": "transfer",1 b7 a0 C' h! g/ n
        "authorization": [{* S- [" l0 R/ d7 Y, l: G  U
            "account": "inita",5 z' \0 X8 C1 ^! _" h
            "permission": "active"- m3 m5 Q# k1 l' B
          }$ r% c$ S. w9 A# b9 C1 I: H# f
        ],& K2 i' y- s) |, B5 Y/ D- p% I- Y" ~
        "data": {
9 m( j/ [% U3 O8 C  y) `0 [4 ]          "from": "inita",
" ?6 E3 K- w" y1 c. \          "to": "currency",: ], H# X8 R% Q* \
          "amount": 100000000,- E7 v* G2 e1 W7 j2 ~
          "memo": ""
% n" y. z* y9 p2 G) N. l        },
3 |2 A& I* t( u' V2 A9 E        "hex_data": "000000000093dd740000001e4d75af4600e1f5050000000000"
- b9 y: D/ Y. e. z. @% `      }9 x& `! l# R' B) ?; _
    ],' M$ z1 s: ^% C7 G: z$ D
    "output": [{
0 ]( H2 v1 P7 l+ J7 U        "notify": [{
' y" W$ u# Y$ G! n7 W            "name": "currency",
% b* p4 I) ]: ~) Q: W( o* R2 _7 r            "output": {( K+ u! G8 X  s( N* R: H6 q# W
              "notify": [],  o. O" x7 P9 s% d+ Z% ^
              "deferred_transactions": []; U! F  O; x' I$ y, F; u3 k# A: ?
            }# }7 {# G) f  }+ U2 j; o
          },{
1 ]; ^3 l0 g" C# F6 \4 M4 F            "name": "inita",
0 z# b7 h% J3 n# Y2 ~7 x7 S: @            "output": {/ B% v( U- z4 h4 Q
              "notify": [],
. e+ Y, v! V# P' L              "deferred_transactions": []
, A; N2 f" [2 Z5 B- H            }) d# n5 a4 }2 Q7 W' k$ d/ G" V5 d
          }
) H0 r! V9 v* g" Q+ x. U        ],
" U- v/ c" t  p0 b4 S7 k        "deferred_transactions": []
% {5 X; R: r7 m1 b* Q: f7 Q      }) C" G+ @0 z% Y; @& K
    ]! X8 g% V* \4 T& Y' y
  }. ?7 }( K! R: R" Y# W
}
1 k0 E. l$ x- b0 K再通过执行get account 命令,验证余额已经成功转移到创建的账户下
) O, B" z- W% F: L  f+ V查询交易历史
3 q5 E, @; a, x! |& \% r查询交易历史会使用到插件account_history_api_plugin,我们已经在config.ini中定义# z& i  z8 X, }" l' ]4 K; n
docker exec docker_node1_1 eosc get transaction 8 I" K; |% _  k/ R8 g- t" a% j: d
如果需要查询一个特定账户最近一次的交易记录  J$ g: z, V  U
docker exec docker_node1_1 eosc get transaction inita
, J& x* V" D+ l. U/ i& Q0 ?创建智能合约! ]7 Z: e4 h4 `" Y: f- u1 P
官方提供了一个示例合约currency,我们依然使用EOSC来创建并部署智能合约,合约代码位置contracts/currency。
8 `" s* ^. ^" V1)为合约创建一个所有者账户。前文已经创建了currency账户
: p0 }. k7 I& Q2 X. @- V, M3 x2)检查区块链上有无同名合约' p0 Z: @5 q. c6 Y
docker exec docker_node1_1 eosc get code currency
/ C" h8 I% W# s6 Scode hash: 0000000000000000000000000000000000000000000000000000000000000000
  j/ r# b" B- @3)为了获得部署权限(发送交易请求)需要将currency的active key导入到钱包中
- f, U7 L& z( R( J7 G! s4)部署合约(.wast后缀文件)和他的abi(.abi后缀文件)7 }% `  y5 ^" z9 x
docker exec docker_node1_1 eosc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi
9 V, `% x! }6 C! C$ K7 c2 uReading WAST...8 v& [8 {+ `( m; I$ [/ D' H! j. M& K% c
Assembling WASM...9 Q6 I% ^9 U* j1 p
Publishing contract...
( F, e5 X. Q. u) D* c% M屏幕打印部署成功相关的信息,并查询合约hash  f" i/ M% q- N# a; m0 _
docker exec docker_node1_1 eosc get code currency 3 X( W8 z  g8 a+ r3 ^8 k0 l
code hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf
  |5 O0 E# ~4 F# J7 R调用合约/ j1 w) R* r! r0 @
在合约部署到区块链上之后,所有的currency余额会分配给我们创建的currency账户。我们可以调用合约测试做一些转账交易。7 p. U& O: |; j# l: ~1 g- l9 d8 l
为了更好了解区块链合约的调用方式,我们可以通过.abi查看可以执行的操作列表和消息结构。
0 T. u) l  T+ {& [. Bdocker exec docker_node1_1 eosc get code -a currency.abi currency
8 v/ |- o4 ]0 t- ^$ ~: Fcode hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf2 G. g# J6 Z# s0 W+ j
saving abi to currency.abi/ Z  u9 B6 s& d+ {9 u6 Y
cat currency.abi #查看; E: b5 Q1 I* H0 E# U
{8 y9 g" {. i  X2 A; [( a
  "types": [{
7 y& C. L+ C7 E* y$ b7 T. q      "newTypeName": "AccountName",7 U( R2 v6 \- i' w
      "type": "Name"
% H6 q7 g+ W# {: @4 z& q4 y, R    }6 X, G# X' |' \8 h. e9 n
  ],
* ^  j: y: N  \  "structs": [{% \9 `' N' d9 V- t  b
      "name": "transfer",$ e! K: W, d# F% b5 c+ n4 f) h0 z( Q
      "base": "",
2 n. @2 }' j6 `      "fields": {) _* F1 d2 T+ {! A6 F
        "from": "AccountName",
# E$ L* W" Y8 e! f  m        "to": "AccountName",, t, ]2 Q+ t7 ?2 m: ?* V- y: V+ `
        "amount": "UInt64"; [% r% u% L. \: f
      }
3 [* J& v+ I9 l6 `# ~/ w4 J3 F& r    },{: A8 o; p2 Q) T- X. s/ H
      "name": "account",
) h1 t( j9 F" d3 Z/ c0 v6 Z  A9 H      "base": "",
) I  d9 R  J6 {; Y4 o      "fields": {
. _* u( g% D6 v! g. ]        "account": "Name",) W* a2 e3 F( y2 z% \
        "balance": "UInt64"
9 I$ P9 i, g  }- _      }
, q" u3 O4 x) D4 R' T, Z8 E: @    }- g, F0 z. e% j# S  B' {3 c
  ],
# r, n3 t0 z  p7 u5 p! n  "actions": [{+ w: Z$ b& ]( B% x2 u  u# O. ]" n
      "action": "transfer"," j3 M4 X1 @* A3 D# D1 h  M
      "type": "transfer"2 N3 {9 k  X/ z* c% @. L9 y
    }
" T: }, I  ?$ c( a- X  ],! j5 T+ {1 u8 L' x' g' _9 K
  "tables": [{
: K$ I7 j6 e3 H1 X7 a      "table": "account",
- y9 {) R4 {$ }( H9 z/ G      "type": "account",
5 N! l8 Q/ _5 e9 M! x/ a      "indextype": "i64",% P" Q6 `, I: {/ U# ~+ t
      "keynames" : ["account"],
: u# J; t& }( q$ m, ]  H$ z      "keytypes" : ["Name"], I3 f0 Z" _) y
    }# }0 k6 G5 X7 V0 `8 {
  ]: x- L) s' A  _/ J. ?9 J
}
2 V1 ^7 w5 M6 G: I8 s通过上面的abi我们可以看到currency合约可以执行transfer操作,消息格式为from,to和amount。我们调用合约从currency账户转移50个余额到inita账户- X( P/ i: O4 \) E3 _$ w8 z) ^
docker exec docker_node1_1 eosc push message currency transfer '{"from":"currency","to":"inita","amount":50}' --scop
& N  h/ }' Y! q4 u9 h2 @执行完成,我们查询余额验证结果
$ B# s& G& E  S3 D& J/ kdocker exec docker_node1_1 eosc get table inita currency account
/ E) S+ @8 @" a# g! |{
- [6 d; h9 }. q  "rows": [{
! u' d& C: S( s7 P      "account": "account",2 P" t7 H1 W% c4 j/ }/ T* {
      "balance": 50 , I! `" s3 l7 f' f% h0 Q
       }  v0 s3 U! l; D. e- u
    ],! h' X2 |- [" p7 A+ |
  "more": false
$ |& B* S! t" j}5 _) O3 |+ F, n5 \2 Q
docker exec docker_node1_1 eosc get table currency currency account1 d- [6 k- Z" k2 m9 S5 K$ H5 V' K
{
9 r5 j# }/ ]- l9 w1 \! h/ l  "rows": [{- t* ~- m: y' ]# }$ A$ }
      "account": "account",/ x5 K: v1 {/ p3 X7 t# T7 N
      "balance": 9999999508 q. a9 ~; @. {
    }
) I* C! n) f- j8 t" ]  ],, G- V2 l! v9 |8 H0 m+ @* \! n4 X- H
  "more": false- h  e9 A) Z3 H# J, h& e
}
$ L$ x% d- Z, n- C5 \# T) v* Y余额不足的账户尝试转账,会提示失败
7 v/ t3 R  V+ X0 Pdocker exec docker_node1_1 eosc push message currency transfer '{"from":"tester","to":"inita","amount":50}'-S inita -S tester -p tester@active
/ E# Z" ?3 p3 W# \% ^; x/ u3543610ms thread-0 main.cpp:271 operator() ] Converting argument to binary...0 A& T* T8 H$ v: N% M4 o9 a
3543615ms thread-0 main.cpp:311  main ] Failed with error: 10 assert_exception: Assert Exception
3 i' s5 V0 `4 }4 J" ?status_code == 200: Error : 10 assert_exception: Assert Exception4 ~4 ^) t  q% o# D+ W4 D
test: assertion failed: integer underflow subtracting token balance
* q1 S/ m) W8 w4 D* g6 C1 I7 e! Y{"s":"integer underflow subtracting token balance","ptr":176} thread-1 wasm_interface.cpp:248 assertnonei32i32 [...snipped...]' d+ Z+ r/ i% E6 S
查询合约# W. n8 o2 s! g+ h7 L7 Y' U9 d
如上文验证步骤,在调用完合约后,可以通过查询表来验证每个帐户持有的余额。8 u! m% m0 S1 N. J
docker exec docker_node1_1 eosc get table currency currency account
: T& Y& ]1 F2 K/ m5 }, V% @' W连接特定节点/ j4 X, X0 S& e# }: L9 S, O
默认情况下,EOSC连接本地端口8888的节点。可以通过指定主机地址和端口来连接其他EOSD节点。同样的,钱包服务也可以指定特定的主机地址和端口。
/ T  }" x/ m4 j' Cdocker exec docker_node1_1 eosc --host  --port 1 k/ v, E9 R8 T
链接独立钱包服务( v9 A2 Z, n0 X4 \& K' J. v* K
除了使用EOSD内置的钱包服务,也可以独立部署钱包服务
& Y: k8 {; d& P. x2 ?- Wdocker exec docker_node1_1 eos-walletd --http-server-endpoint host:port% @6 A+ I5 i4 \4 G- j
调用独立钱包服务需要添加如下选项7 |8 G' u, n* A, `" I
docker exec docker_node1_1 eosc --wallet-host --wallet-port
3 d7 `! s# s! i$ a* l免签名验证, d* E6 X* F6 A: s  s
开发者如果需要快速测试功能,可以跳过节点签名的步骤,这样可以解耦密码学的问题而关注应用功能, N0 g) Q' q. M
启动时使用特定参数
# a. R% u# Y( \9 V5 l- L/ S% X3 c4 teosd --skip-transaction-signatures
" t# o, W$ H  o8 zEOSC调用时添加-s 选项
4 ?& R$ m* D7 D# @' E( Hdocker exec docker_node1_1 eosc   -s 3 I- ]* N3 q1 h' ?& _- K
其他RPC调用
' u9 l/ x( C  R! b( @3 Z" REOSD RPC 包含通过HTTP RPC与eosd和注册其上的插件进行调用的方式.
9 I& O" a" O/ ~' p# q; `1)区块链API 配置" R: N8 N# y5 ]' D
想要查询eosd信息需要启用plugin = eos::chain_api_plugin插件并添加至config.ini中
7 B  B5 a3 N7 C! _1 q! p+ D1 Y; ~4 m+ C2)get_info接口用于查询区块链的基础信息8 g* y1 A$ X; d; Y. D+ v3 B
curl http://127.0.0.1:8888/v1/chain/get_info
" L1 L6 T3 @, p* b8 q返回结果如下:; `6 T; e& F/ E9 A# K% B- t  e
{"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"}# B- _0 `7 s- \
get_block接口用于查询区块相关信息
: T9 J( s, K5 z5 @5 W8 l( \; F2 Y0 I1 R, z& n; h  Y; b( w
curl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":5}'
9 j0 v$ ~3 `9 H+ g: v7 U: r* v) Zcurl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":0000000445a9f27898383fd7de32835d5d6a978cc14ce40d9f327b5329de796b}'
1 W. J' S3 R0 T3 _3 c返回结果如下:1 L5 e5 O8 q) E0 l; u7 t9 C
{"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}- w1 l3 L! L# _* j2 K
4)push_transaction接口,调用合约交易
: P: C: y# y8 \7 U1 i0 g5 A该调用为JSON格式并会将结果更新到区块链上
2 l  l; m1 `, K& [* E4 h( Z执行正确的结果返回
- u4 b5 F- K% ~/ P+ ^5 p8 ]0 C4 C" Q返回 HTTP 200 和交易ID号; H$ G) o, u6 g" L
{
1 C6 P. p* @' ]1 E8 B'transaction_id' : "..." 5 w) |/ ^) a; O  _5 j* }. U4 C& h
}
: S7 s+ y  H6 {, I, x执行错误的结果返回,一般为400错误(参数错误)或者500错误. w/ r: \# M4 Z$ B* T9 _
HTTP/1.1 500 Internal Server Error
% d( Z: P% K# e3 p) V7 f# U+ ^$ sContent-Length: 1466' D  M3 P: ^  ]7 r) ~: G
...error message..2 h+ f/ o" W" T; D
push_transaction 调用方法
* t8 z" |# C$ Vcurl  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":[]}'
! G# t( N: }( }5 Z此示例模拟一个转账交易。 refBlockNum和refBlockPrefix使用的前例block查询的结果
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

罗宾虚汉 初中生
  • 粉丝

    3

  • 关注

    0

  • 主题

    16