Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

EOS纯技术上手学习

罗宾虚汉
169 0 0
EOS.IO 已发布黎明V1.0版本。EOS.IO 黎明V1.0版本是第一个预发布的 EOS.IO SDK(软件开发工具包)。EOS.IO黎明V1.0版本可以让我们体验下EOS一部分区块链特性和简单上手开发、测试。本篇主要是一个快速的review目前EOS黎明V1.0版本的功能上手。
+ u+ G! {  r, q) ^# e$ L* {主要内容:% a0 T% v3 P% C' K) a& a! T" y: ]
" u4 d# @) w, u' O9 n9 A' J
EOS Docker快速部署* n2 e/ e) i. a

# E6 p" B. J2 T7 jEOSC使用
- P% [: {* u% ]. x
  T& r* [% |. T$ n' ?8 f& h3 N创建钱包
) `* r- h$ T. H) Q6 b& `( I) [( C3 x5 k/ ?
将私钥导入钱包; _: V3 a6 ~" V2 R8 K

; V. z  `; e- v0 H2 ?2 o锁定和解锁钱包+ I; s# D9 I0 _' ~' f6 z) w+ V
5 p# A! n0 e6 e
创建账户
4 o* d5 d2 m/ t$ {
5 }0 }- s" |" t0 j' M1 t内置转账
7 x8 W  D2 ~7 `5 {2 g( J' K4 F' C: ?: M1 }* v
查询交易历史; O5 L4 z- @: M. y" ^

7 R" X" M% c! d) w2 ]: {$ U: `测试合约 - currency: Z- i/ o( F% V6 u4 `4 I8 x2 G
7 f9 b) X5 p* u$ w) c
调用合约
9 o4 b$ f% S' {- o7 }7 I1 N/ Y; v) l
# A( l& I1 Q' ~6 \$ p  {查询合约2 N4 a4 y' ]. K/ D3 L2 V! I: t

) W0 H/ w, P( j0 ]* |+ Y- B链接特定的节点
+ {  m; r5 j, N7 U. y9 N
* }; v+ q  P" F5 J7 g+ {7 i" Y链接独立钱包服务
8 S! E+ Q1 x2 J. j- [* f4 w
! Q- Y5 n) F# K! p免签名验证
+ r, I8 Q; ~3 A* z* C6 p. h! @2 z1 V4 h( t/ I1 e# G' q9 N- b
其他RPC调用* X# \7 r4 ~0 O0 ^3 G4 k; l) U
: @! W" p: q# Q9 D

6 ]6 S! Z- w; _* s  eEOS Docker快速部署
. v1 L: v4 A. S4 `* p, y6 x" S构建eos镜像
4 {, \! A  t0 p3 c% D, ggit clone https://github.com/EOSIO/eos.git --recursive! V. |7 l- X- ?1 `* v) O
cd eos+ I& z. y) ]0 ^# x+ [
cp genesis.json Docker ) P; t# k1 D6 e
docker build -t eosio/eos -f Docker/Dockerfile .0 O4 P& @  J4 M  p+ @2 Z
启动容器; S5 \1 k- ]8 A3 @
sudo rm -rf /data/store/eos # options 9 N6 Z/ q. Q: V% p
sudo mkdir -p /data/store/eos! s( J( n0 v6 J7 I0 x& W
docker-compose -f Docker/docker-compose.yml up
; r- n2 S- Y" {6 u3 X9 z9 g1 ^如果 docker-compose 启动有报错, 可能需要给文件存储目录赋予用户读写权限% s" p; x5 u4 b! f  I
sudo chown -R SYSTEM_USER /data/store/eos
) E9 |) ^. n& V  \7 ?验证,查询区块链状态信息. Q1 s6 Q4 y8 K4 c/ K; d
curl http://127.0.0.1:8888/v1/chain/get_info
0 A! h. K# M! n3 K如果想使用多节点环境,可使用yml文件启动, ?! a* Y  I6 u6 A9 W6 S
version: "2"; G, {+ [1 l$ m! r; i! V8 q
services:, o' ]+ ]/ e; `2 I9 W, q
  node1:- d! U9 [! N3 n1 P
    image: eosio/eos 3 K6 L3 J, p5 i1 E! x9 k
    ports:
! q. Y7 B) ^, h1 c    - "8888:8888"
" s4 @# z! j4 }    - "9876:9876"
4 `+ x/ s" o  F2 t9 n$ {    volumes:
6 d1 ^0 {6 ]& `# r: T; V0 g      - ./node1/data:/opt/eos/bin/data-dir
3 Q/ r0 \$ x, o' r' y0 C  node2:
* _1 E; n! F. C- a1 J1 F    image: eosio/eos " N' f/ S3 a5 ~) N1 n5 _
    ports:1 ~# Q! X+ Y" O4 X
    - "8889:8889"# k5 n1 d$ K9 T
    - "9877:9877"
2 V6 R5 V+ ~, C( ^    volumes:' r8 z7 s1 h5 z7 |
      - ./node2/data:/opt/eos/bin/data-dir
: _# Y; [7 u5 N9 l# }    depends_on:5 `6 m4 Z# T" q% j5 X+ c0 K( m) o
      - "node1"
. T; q" b& T) h# [/ f" D$ LEOSC使用+ q# F$ b4 Q0 c4 R/ \% \/ y! y8 j
EOSC是EOS的核心进程EOSD对外暴露的RESTAPI命令行工具。EOSC的使用会利用到一些内置插件,插件在EOSD的配置文件config.ini中进行设置,如与链的交互需要使用’plugin = eos::chain_api_plugin’。为了签署交易并发送到区块链上,需要使用‘plugin = eos::wallet_api_plugin’。为了查询交易和历史记录,需要使用’eos::account_history_api_plugin’ 。1 F7 \+ I) ?4 L6 K, c
# Plugin(s) to enable, may be specified multiple times% C  Q" R6 a/ a! }+ v1 h
plugin =
: o+ j* C) g4 j; M) g# x4 f2 ]/ Geos::producer_plugin4 j" [" [4 g8 _3 [& S  E$ T
plugin =  D# P0 A" s# b: i* g
eos::chain_api_plugin
  n+ A$ _4 l3 Qplugin =' J7 p/ ?9 C. S" c& ?& f
eos::wallet_api_plugin
& A% x+ f8 E4 k# {$ V9 pplugin =
' a# J5 N+ }& Beos::account_history_api_plugin
7 x. \% l, X: h  X& M2 \启动eosd后,可以使用EOSC查询当前的区块链状态8 N' l* L( u9 N4 I2 J; @
docker exec docker_node1_1 eosc get info9 F% ^8 o3 O; h& G, F* Q* G
{
3 i6 F( V- G, V3 c& M/ v+ O6 ?  "head_block_num": 23449,0 f- {6 c; f# j* p/ I4 {
  "last_irreversible_block_num": 23432,# ~2 t* h3 I" w! {( Q
  "head_block_id": "00005b996cc85962b28537c3d72696a012d1071638f5e4bad1809cf9afc9abb6",
, ]! z. p5 j8 Q1 S  "head_block_time": "2017-09-29T01:53:33",) Z1 i$ l' e; ~& W+ q
  "head_block_producer": "initi",7 }2 m1 ~; Z3 ^% M2 I6 Z+ c
  "recent_slots": "1111111111111111111111111111111111111111111111111111111111111111",
& c- [$ q: A; C- c' o& h2 b( @  "participation_rate": "1.00000000000000000"
  r- D% J7 t' g' P5 ^}
. ~4 z* w  L1 f1 y创建钱包$ W- l5 f1 @& v* t$ O
任何发送到区块链的交易都需要由所有者持有的私钥进行签名。首先,我们需要一个钱包来储存和管理私钥,使用EOSC命令创建一个钱包。
! x# a; B0 j! e; K9 V# L* \( V# h, wdocker exec docker_node1_1 eosc wallet create
& ?' f6 T& \, h/ aCreating wallet: default" H8 E3 r$ U5 K/ ~6 d
Save password to use in the future to unlock this wallet.
4 I1 C: g( r$ A$ ~6 J8 GWithout password imported keys will not be retrievable.- q# a7 O( ?* H) A4 R! d  h
"PW5JXSxkHqNEwRKCpG2JUTLqkR8SNCBXofkAwaFDLwQkNdqaSXwC8"
5 F/ j; }2 y! L6 C: [+ t* U命令执行完成,会在eos-walletd中创建一个名为‘default’的钱包,并返回钱包密码。
- h% w' w! m8 m) p2 u% l( g这时候可以查看钱包列表
) j- Q* K4 w+ O  a+ ^docker exec docker_node1_1 eosc wallet list+ k4 L9 k# r0 _) H: u/ Y9 z
Wallets:
% M3 q* N+ k  R1 X[
, M, b+ S" X/ G% T  "default *"/ T) j5 w3 ~8 a3 `- r9 X
]
% i! n+ f' _8 _9 b9 l1 O如果你没有指定钱包名称,默认都操作的是‘default’钱包# B& n/ F. F* g6 P  D' D
将私钥导入钱包/ x% @( Q! ?9 F$ l( }' D& {
如果你想授权某个钱包可以由某人来管理和控制,需要导入该授权者的私钥。+ X& j/ Q1 n7 K( X# e
docker exec docker_node1_1 eosc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD35 p9 Y" l6 n  G+ M" m
imported private key for:
9 v/ C" ]4 E# j+ t$ Q, B; F2 wEOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
4 z9 w. J  N6 G4 f% a8 [导入后,可以查询钱包已经导入的私钥和对应的公钥2 k6 s1 u* E9 ]
docker exec docker_node1_1 eosc wallet keys; P( n  I) c% p  X
[[* {. B0 ?+ e5 z2 t+ P6 _/ V
"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
( C8 f$ T5 l& E3 I5 k; ]"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"
2 x* l2 p5 \6 i8 q8 r  q. U# T]
; r$ |; [8 \0 Z]
3 c, R6 r' z  H4 V# w锁定和解锁钱包
9 R$ \- q* ~% b* W- `日常使用,为了保证私钥安全,可临时锁定钱包,锁定后查看钱包列表是不可见的/ y- N+ V+ i( P7 r+ g
docker exec docker_node1_1 eosc wallet lock/ L- G  s: I+ S, S& p; w4 a/ s+ z
Locked: 'default'
3 D( T* r& @& i- H当想要使用时,可以用创建钱包时生成的密码来解锁钱包
) D5 O. K  M  b  q# e/ t- ^5 Ndocker exec docker_node1_1 eosc wallet unlock --password PW5KVWrn81Y8PLAb52gr2FyXCanVavcrj9d5TC9C3yKhqq1PJYRPk4 d5 `7 _/ |" k# C9 K/ H
Unlocked: 'default'6 @5 t2 Y! K& s4 x- J9 P/ q' R
解锁后,可以在列表重新看到default钱包了
/ [2 h0 T, q7 a: Q' Q! Sdocker exec docker_node1_1 eosc wallet list/ r8 H* ^% H9 h$ m6 P
Wallets:
8 K8 ~; J7 H' D9 P" I[3 ?. ?# o+ B* s5 }$ [' u6 |  }
  "default *"
& O2 I9 j* X" |) c% L]
) {/ d3 K( e5 e创建账户
, I( N9 V7 K: x( }0 J1 H% N创建账户需要有两组密钥:owner和active。EOS使用EOSC工具来创建密钥对
6 g* O3 b! @( |7 w! J1)owner key.! A% V, [, y* O: h, y
Private key:5JRc8XxvodWey4StZ2zzkUhCQhDaHvGMkABtfHzQR2ie4qaUFJ73 j8 D0 A6 B7 ?+ ]
Public key: EOS5mFEdAzxvMkHLQXt2v4naUjnBrPGmzMUCikymqhSR6m7QLGSTB: k: X: ]( L- E0 o
2)active key
$ ~& @) z0 b+ t" ]& N- s  sPrivate key:5KNzFCbToz2a9Hztz9Qen5cyJcM3x5Wpq4GFiTYZgGhzntXdmYo# N* k6 p( a- L* ~# h7 V/ z( i
Public key: EOS5EdsvESpibWLJxupTqod1nswJnbiXQZuUcLiAWEEsqcZskymeB
1 u) n. j/ A- d6 E' }EOSC不会保存生成的私钥" z+ L) r% G) Y) R% u/ I4 R
因为后续测试智能合约需要,我们创建一个名为currency的账号。目前这个版本,所有的账户都需要用已有账户来创建,所以我们用inita账户的owener key和active key来创建currency。 为了使inita获得发送交易的权限,需要先导入inita的私钥到钱包。(参见私钥导入钱包的步骤)2 O) K+ K. t7 X# n. P
docker exec docker_node1_1 eosc create account inita currency EOS6NpEqWi177VKQkuJQL9V6Y3LqAAp9C2j0 q! y) ]# n# z$ {
执行成功,会输出一串json的交易信息,打印账户创建相关内容
# p* `. `7 C. P2 o我们可以查询inita可以创建了哪些用户
: }3 m/ F. O0 }6 d' I/ }7 A% udocker exec docker_node1_1 eosc get servants inita
% A' K* B1 ^/ B! A{9 ]% S' G: i# m5 A$ t% E( c0 R5 g
"controlled_accounts": [
4 q/ z, C5 Z4 v"currency"  c+ ?: I4 y3 F% i
]
7 i. s# N. g& y* f8 _6 d}
, R; F' d/ W6 \, S3 c内置转账
; W  Y6 i3 h) T创建账户之后,可以查看当前账户的状态,可以看到创建的测试账号没有余额,这样不少功能无法测试,我们需要试着给创建账户添加一些余额) u/ w3 a# Q+ N1 E. d" \
docker exec docker_node1_1 eosc get account currency
7 l) T& }1 y* X" ~{9 P, Z" j' V. C! _. G6 M
  "name": "currency",, I4 ~2 c+ ~+ }# ^- T  W7 y
  "eos_balance": "0.0000 EOS",$ I( _- u( R5 E( w& p
  "staked_balance": "0.0001 EOS",
- `; E1 e) m5 z9 j  "unstaking_balance": "0.0000 EOS",
1 Y+ `' b6 d% b; m: d/ o2 [  "last_unstaking_time": "1969-12-31T23:59:59",- j- _1 M8 _  _0 U( }) l
  "permissions": [{) K5 l2 J* T) ]2 Z. V( X
      "name": "active",1 E. I7 y4 Y! t1 g0 ^, {& f6 \
      "parent": "owner",4 H) W" N& ^& ]; |8 I& @
      "required_auth": {/ G7 g* l/ l0 K
        "threshold": 1,
4 J* Z3 {, ~8 p        "keys": [{# K+ w( w+ C2 A
            "key": "EOS8ff42NMpJUybVj3nwUSnPpc3mMysKxyE4HVJy1E5o3fQv7knWf",
8 q/ E: r9 `3 i3 b( N- C' ^            "weight": 1/ j0 p& M: {& Z9 L, X: ]  Y
          }& l. H. h  \- b1 n
        ],% ?+ N* l) t' z; o
        "accounts": []
/ {5 t/ L" ~* Q  g8 D      }/ d* f, B8 l+ ~& o6 ~, ?
    },{
( T3 |) H2 r( r% p8 V& I      "name": "owner",, X  D. ^* B+ y! q& L1 l7 Y! U. w) N
      "parent": "owner"," c/ f' [! T6 ?1 O) b  p  ]# {9 Y
      "required_auth": {
8 S* N* {1 a; F& J; @( H        "threshold": 1,
2 F9 ]- b! z( c2 [2 ^4 c        "keys": [{
4 Z! q* u: x$ k& W+ }            "key": "EOS5fQ4saiHV426EQ7AKrGoD2AVMBYe77bnGSq42JjXBUfipv7o3E",
3 F/ g# @; y: E            "weight": 1
% z: h& A  J/ j8 }2 H3 r8 n          }; M. |, B0 N2 F) L" K! a0 ]
        ],3 X7 A7 M4 q: }) u
        "accounts": []# S% D+ E; B% Q; Z5 ^& g
      }
7 j. h: W6 {2 `" a; G4 H8 |    }
9 l# Q) J* H" N* Y" O  ], P- N2 R+ d8 n! j) R
}
. i) i) E8 U  n! d保存全网余额的创世账号是eos,查询余额状态! m& h7 y+ y$ G. ^3 `
docker exec docker_node1_1 eosc get account eos
6 }- h5 K9 R0 N1 m& C{
% \  L/ ]/ H! _, A  T! c  "name": "eos"," [( v/ j  V4 g; O5 W
  "eos_balance": "69000000.0000 EOS",9 ?& i- r4 k, W- W
  "staked_balance": "0.0000 EOS",
: _6 G, g1 f$ N7 b  "unstaking_balance": "0.0000 EOS",
' b$ N0 h& G% T4 |- O  "last_unstaking_time": "1969-12-31T23:59:59",! i4 a' m. `# ^9 F8 U1 W% E& G2 d, S3 J
  "permissions": [{6 o( G0 P$ G! [* C
      "name": "active",5 ]1 e9 C# Z7 T. s
      "parent": "owner",
8 s, E5 J2 P7 V% Z      "required_auth": {
5 s+ G' x1 C' \& A0 i! s0 ]# F# \        "threshold": 1,' Q* }+ x3 C, E
        "keys": [],4 K) b. @0 O: `' c8 c
        "accounts": []
3 s! D" {8 d7 s      }
6 ]3 r" J$ d) f% B* x/ r/ [    },{
8 T" T/ R3 j& j( t' {. M% H      "name": "owner",
4 M1 p: e$ k3 G9 O4 ?& _: b# q$ `& c      "parent": "owner",) A8 a' _/ N% p: d
      "required_auth": {
9 l. W! {) H2 \* T: D; e0 s        "threshold": 1,
+ f3 C7 X0 N4 N6 T3 p        "keys": [],$ s* V% p( G- N
        "accounts": []
- ^5 f; S7 K% I2 W% c0 }7 G# t      }
! z; B9 _# [( o  i4 G    }
. }6 E, R/ S0 G( X/ ~+ x7 Y9 @% m  ]
7 E1 {, Y3 a' ^* [3 a( r}
: T  }# C0 `: n我们可以通过创世块定义的创世账户使用EOSC给当前创建的账户转移余额
+ K5 B0 j+ `: w) o- Xdocker exec docker_node1_1 eosc transfer inita currency 100000000% i6 D$ g: D7 P
{
* j  m5 v6 x, u# k7 I7 \  "transaction_id": "59575b8caf08eac7c00eb7483c048f12d0e7abf1ede839c3b2ed41dc6c5c7c5f",9 L6 Z* E9 {7 u: E: V* `4 |( d
  "processed": {
' R9 G# @: t) Z+ \* e    "refBlockNum": 24199,/ e# n) z* E0 l( z. E
    "refBlockPrefix": 1485651173,8 c4 _$ e7 s) I; E& P. M8 M: Q
    "expiration": "2017-09-29T02:31:03",
# e& v4 F, C) |. O" O. a9 F+ B    "scope": [2 V' b' U$ q3 O" J
      "currency",
+ S& W& g" E0 e7 i8 m+ h% v" j' }      "inita"
8 y: z2 B$ `2 N$ W    ],7 \1 k5 n5 _  G/ j: m2 n- J- {; y
    "signatures": [
4 S8 f& q( `0 L: u: s      "1f14229bdd4bfb927021bf96ff0651c8b0fa5666e9f5cf423a0270a1b91f2d2f690b573e179d8475ce2c6b160f5cd5507d58a44f8f6cf536348584efa8dd62ade0"
9 M/ e, e% U; g6 l$ Q" K    ],3 K4 l2 \% B9 }# G: }5 Y+ E
    "messages": [{
" U: ~! ?9 {2 ^- {' K        "code": "eos",, Q$ i1 C' v: M5 L
        "type": "transfer",; T8 N& E" r' V% X
        "authorization": [{
8 \8 G7 c6 d/ W            "account": "inita",/ R& q+ ]* {4 T9 w
            "permission": "active"! t: T' m: ?0 x3 k  e7 p
          }; K) Q% e/ y, `7 X5 S
        ],
, V9 ^1 b  G8 J3 r* M. f        "data": {
1 s6 `) O' P  N1 R' {          "from": "inita",, h1 ^$ K- ~/ ~, q
          "to": "currency",
) d+ w( o3 o" }, q# m          "amount": 100000000,
: V9 h, F6 d3 g1 R; Y8 T          "memo": ""
) M6 V' g' Z% x1 s( i        },
) ?, {5 {  g' C  p; O        "hex_data": "000000000093dd740000001e4d75af4600e1f5050000000000"; y9 [; b5 l" Z' J# T0 X
      }: A. ]" Y% q. o/ }  q5 ?
    ],; }& W5 U0 K& ]  _$ _
    "output": [{
0 D8 u9 j& @" T7 g% G5 `: Q$ R5 a        "notify": [{
' b( a; P3 R, `/ k9 Q" \: u1 `            "name": "currency",
$ ?+ ]8 o/ d: w& _; U* k$ w8 C- H- y            "output": {
0 ~& r. n! ^6 Q6 L              "notify": [],
' e. `% r% A3 {. ]7 t& I/ ]) V) E              "deferred_transactions": []
5 M* [; }2 C" R1 d# d            }0 M! m* J2 F( U4 n
          },{1 ]7 @! [8 n. P
            "name": "inita",
9 U0 i4 K5 W3 T' v) Y: s8 e            "output": {# e: M8 r! C/ M9 E/ [
              "notify": [],6 d% ]& e# B3 U1 Y3 y  P' q, Q
              "deferred_transactions": []! a' l$ m3 ]7 G6 O7 |
            }) Y3 {1 o6 D" h8 {; y! M0 O) _1 ^
          }# H' b0 N0 }; y
        ]," L3 n- J. B. ~. x
        "deferred_transactions": []
8 n! n7 U1 K: m% {' S      }
2 p0 b3 `' s* A    ]
+ n. _5 u1 C( N  x. R# K/ ]- B  }
- V1 R0 C; ]" a8 l# T8 `}" O) X: |7 n. h2 m; E
再通过执行get account 命令,验证余额已经成功转移到创建的账户下
9 n  n! C. V* ~- v+ H查询交易历史. @( s. n7 h. C2 L) o! v+ x8 D9 Z! y
查询交易历史会使用到插件account_history_api_plugin,我们已经在config.ini中定义
5 J6 L" b5 Y2 E7 g; Fdocker exec docker_node1_1 eosc get transaction
# ~/ I, f* k4 h, C* \如果需要查询一个特定账户最近一次的交易记录
% W- Q- R0 |( E; d8 R6 ^docker exec docker_node1_1 eosc get transaction inita) M' a* G/ v6 D- \
创建智能合约1 `: X& N7 \" q* z5 P/ ~5 }4 c! F3 z
官方提供了一个示例合约currency,我们依然使用EOSC来创建并部署智能合约,合约代码位置contracts/currency。4 \7 Y6 ?$ t1 v
1)为合约创建一个所有者账户。前文已经创建了currency账户+ N! W! [& a9 u6 h
2)检查区块链上有无同名合约
, Y8 u7 G& v$ _6 xdocker exec docker_node1_1 eosc get code currency 9 T% u* U  {( j+ P6 @
code hash: 0000000000000000000000000000000000000000000000000000000000000000
3 D- F9 G0 Z0 f1 I. I3)为了获得部署权限(发送交易请求)需要将currency的active key导入到钱包中
4 e0 w# h" j5 w( k; B3 V4)部署合约(.wast后缀文件)和他的abi(.abi后缀文件)
+ d% ?/ N" d  i7 Q. S# R- adocker exec docker_node1_1 eosc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi
7 P7 G( O# V' F) C$ J: wReading WAST...( L. k) k$ ~  @3 A' C
Assembling WASM...  W/ m7 |6 y4 \+ A
Publishing contract...
# D5 ^, h5 ^" C+ a屏幕打印部署成功相关的信息,并查询合约hash
  h3 p% C& d$ P' Wdocker exec docker_node1_1 eosc get code currency
8 k  z; ?7 \0 [code hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf, b; G8 ]  ]* f
调用合约
3 d2 j! @' G8 m4 |: a在合约部署到区块链上之后,所有的currency余额会分配给我们创建的currency账户。我们可以调用合约测试做一些转账交易。, x' G+ i) j/ t/ ?5 C
为了更好了解区块链合约的调用方式,我们可以通过.abi查看可以执行的操作列表和消息结构。7 Z& |/ `& Q6 I% S) H% C( h2 s
docker exec docker_node1_1 eosc get code -a currency.abi currency; V4 O; F4 s/ r/ }
code hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf. L. v$ o0 g3 n8 A. o/ T
saving abi to currency.abi# g! `4 X" H2 k( g' {" x
cat currency.abi #查看& V4 }& s- \' L0 M8 M0 m, u" K  U
{
" x( c6 c4 N# ]& |# _  "types": [{! p' r# j  m. `7 ^0 ]5 P( d
      "newTypeName": "AccountName",& N$ M& O. @5 e. W9 O7 ?- h5 f& A
      "type": "Name"
# e0 }. d- j4 J, D    }* y7 k4 U  G6 m5 d
  ],
, F# Q" r# N/ v9 J8 N! m% B+ p$ w! r  "structs": [{
5 S& D" I  l: v      "name": "transfer",+ R- v! M1 v9 E5 u* \- J
      "base": "",4 k3 @8 G$ j/ g4 i4 Z2 v
      "fields": {" O7 t+ L3 o$ x6 f' {
        "from": "AccountName",% u. ]6 t. \  d- z
        "to": "AccountName",
  ^6 v7 R) z! H        "amount": "UInt64"
) S1 x6 ~7 _! k; M) `6 \) L      }; ]5 ^# t1 r" I4 l
    },{
# }; A$ N% @2 _6 N      "name": "account",/ G& e4 v* `2 ^- k. c. ]
      "base": "",
. c5 E! H9 p! k4 X      "fields": {) ^4 h3 Q& r- [7 J# e
        "account": "Name",
. t# \: p& L: W        "balance": "UInt64": H# u0 U7 F; w, a. x- L' b
      }4 T: S4 G, }/ _+ C/ `* Y# y
    }
. C# }+ ]& K# W6 S0 Y  ],( u) Q  J) V( y6 H
  "actions": [{
* D# E1 m( Q  v4 n9 T& Y      "action": "transfer",; Z2 o. i3 b- z/ D4 t1 ~
      "type": "transfer"/ ~- q2 J: k/ k. U6 u$ @( V! j
    }  B2 r. u- X4 Y, [5 s
  ],
7 \4 l, w9 g" K9 w  "tables": [{0 ^+ l3 A8 }( k# {1 B: i
      "table": "account",+ J" K0 o6 r# G% `7 f8 a. H
      "type": "account",3 V# G% U$ i9 \% S: ~6 K- k! A. @7 s
      "indextype": "i64",, y: H- V$ r* V
      "keynames" : ["account"],
+ T/ _1 ~" _- K* E1 r% E      "keytypes" : ["Name"]
6 K, x4 h0 k. \/ F4 y# i5 }    }
) G+ o8 @5 ]& l; s6 e/ V3 i4 d  ]0 ~0 _2 {/ u; C" c
}
4 s4 Z( r: d/ C! ^通过上面的abi我们可以看到currency合约可以执行transfer操作,消息格式为from,to和amount。我们调用合约从currency账户转移50个余额到inita账户
5 J% U; N. E7 _docker exec docker_node1_1 eosc push message currency transfer '{"from":"currency","to":"inita","amount":50}' --scop
! s+ j3 G& y4 T. b( @7 ^执行完成,我们查询余额验证结果
4 D+ C# D; `( L8 Q6 d0 Hdocker exec docker_node1_1 eosc get table inita currency account8 b: A$ P8 x; X; Z6 H& U( Q2 m
{4 g! p/ ]! H5 q
  "rows": [{
) J, }# F  n! J      "account": "account",& A5 }) U. g: _7 m1 m
      "balance": 50 8 d1 V4 c& R- X4 J- |: D) f8 \
       }
' U' y  c+ K9 i- `9 e, T    ],8 `( ~4 V% A+ B- y% G8 {0 z0 i
  "more": false
! j) g4 H. i) u1 O}6 {2 o/ G. ^6 @
docker exec docker_node1_1 eosc get table currency currency account' c) {" \% e" N  K
{
$ p2 Q, F) g- e  "rows": [{3 U" s9 f9 V! O0 O* [9 Z
      "account": "account",* ]2 ^+ _6 J) i2 C6 c
      "balance": 999999950
$ e! ^) c* T% S! A+ L    }5 N! h. M7 k) j7 Q6 e: C, ?
  ],
' I8 f" T; ]2 ], u/ Y* ?/ |7 Q& {  "more": false( M) H* x( b6 q- B
}
' Z2 ]1 X) Z; o; x余额不足的账户尝试转账,会提示失败! J! Y; ?) P9 n0 K
docker exec docker_node1_1 eosc push message currency transfer '{"from":"tester","to":"inita","amount":50}'-S inita -S tester -p tester@active5 @- y( W! Y$ `* @# A
3543610ms thread-0 main.cpp:271 operator() ] Converting argument to binary...! a! Y6 b" Z# m/ W  N
3543615ms thread-0 main.cpp:311  main ] Failed with error: 10 assert_exception: Assert Exception
* }9 [0 q" C% _9 K2 A3 h5 jstatus_code == 200: Error : 10 assert_exception: Assert Exception
& c4 ?1 j. l; J* @  B$ ]test: assertion failed: integer underflow subtracting token balance
: V! {$ b2 }" Q8 D* f' u& V{"s":"integer underflow subtracting token balance","ptr":176} thread-1 wasm_interface.cpp:248 assertnonei32i32 [...snipped...]% d5 f$ i4 a+ ]/ Z4 i
查询合约4 v% c* g) a! p. {
如上文验证步骤,在调用完合约后,可以通过查询表来验证每个帐户持有的余额。* \+ _5 F. L. d( I5 d6 a1 o
docker exec docker_node1_1 eosc get table currency currency account
$ w6 ?/ t$ O! |7 g. n5 M连接特定节点
/ g' O' i' v7 t9 }; G9 U. p/ u默认情况下,EOSC连接本地端口8888的节点。可以通过指定主机地址和端口来连接其他EOSD节点。同样的,钱包服务也可以指定特定的主机地址和端口。+ W/ u8 r$ F% j
docker exec docker_node1_1 eosc --host  --port : D4 y; {) [6 a$ F. o
链接独立钱包服务
  k. r; |6 u) s3 K8 [' C除了使用EOSD内置的钱包服务,也可以独立部署钱包服务* i# T0 D  i3 q* J- d, z
docker exec docker_node1_1 eos-walletd --http-server-endpoint host:port
5 u9 a, F  ~+ `9 o" A调用独立钱包服务需要添加如下选项/ V  ~8 z. g$ }+ w, w$ z2 n
docker exec docker_node1_1 eosc --wallet-host --wallet-port
/ V( L. u8 g7 n) W" e8 }! h( L& w免签名验证
/ F. w" l* x5 r* B( @开发者如果需要快速测试功能,可以跳过节点签名的步骤,这样可以解耦密码学的问题而关注应用功能
- I) I  u6 l0 F8 |2 h/ y! V% z% ~启动时使用特定参数7 c/ O6 q3 ]7 ]1 @
eosd --skip-transaction-signatures
  L) U% Q1 J- KEOSC调用时添加-s 选项2 M8 I, i5 @: ?  f" o1 z
docker exec docker_node1_1 eosc   -s
5 R; ^3 S8 m3 T  _其他RPC调用
, g6 c- ~: p4 f' Q4 C( @, _# ]EOSD RPC 包含通过HTTP RPC与eosd和注册其上的插件进行调用的方式.% y5 [" {! F" ?* d
1)区块链API 配置7 H& k" M, `* r
想要查询eosd信息需要启用plugin = eos::chain_api_plugin插件并添加至config.ini中
% s4 Z! ^- c* o- k. Y# x/ F; q2)get_info接口用于查询区块链的基础信息, T' ~( n+ D" |
curl http://127.0.0.1:8888/v1/chain/get_info - s' s6 K* j9 s+ M/ G, K0 I
返回结果如下:
) z4 @1 O& t9 M. Y/ ?1 p/ |0 Q{"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"}
1 ^5 a- w+ @3 s6 [8 vget_block接口用于查询区块相关信息
2 _( W. \* P4 M+ f( ]! G6 f7 o& ~+ {, l% C
curl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":5}'! [" P* A; U/ E, F4 r, Q$ E
curl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":0000000445a9f27898383fd7de32835d5d6a978cc14ce40d9f327b5329de796b}'
9 A) Q/ f" P8 |& ]返回结果如下:: Q1 H! h. W; H5 e( ~$ n9 @. u
{"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}: i/ f8 q. \, E! r9 D! B5 ^3 m
4)push_transaction接口,调用合约交易. ^! |8 `- w, H' w5 Y; L$ D/ |+ f2 ^
该调用为JSON格式并会将结果更新到区块链上+ L# y1 e' {2 I% A  z& i
执行正确的结果返回4 i0 V4 V9 B1 v/ h! W
返回 HTTP 200 和交易ID号! `# E! V/ @6 r  I
{ 5 d4 B5 ~# W5 m6 \: P; K$ l
'transaction_id' : "..."
, J1 k2 |; M5 u% n0 i' K  e- @}4 [0 \' s5 V4 i. c8 h& K, @
执行错误的结果返回,一般为400错误(参数错误)或者500错误
; `; \8 ]4 ?1 J6 hHTTP/1.1 500 Internal Server Error
- }8 `& h, ]& k4 \Content-Length: 1466! X- Y2 p! [! e' I
...error message..
& R5 e( [$ J, W+ l3 x" [- r! Opush_transaction 调用方法
" X  D6 E% x+ q+ w+ j3 ^7 n( [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":[]}'; }7 Y0 ^/ {8 p. V
此示例模拟一个转账交易。 refBlockNum和refBlockPrefix使用的前例block查询的结果
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

罗宾虚汉 初中生
  • 粉丝

    3

  • 关注

    0

  • 主题

    16