Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

EOS纯技术上手学习

罗宾虚汉
132 0 0
EOS.IO 已发布黎明V1.0版本。EOS.IO 黎明V1.0版本是第一个预发布的 EOS.IO SDK(软件开发工具包)。EOS.IO黎明V1.0版本可以让我们体验下EOS一部分区块链特性和简单上手开发、测试。本篇主要是一个快速的review目前EOS黎明V1.0版本的功能上手。
- p6 r  k$ [/ W: x主要内容:
! C' E9 o- i8 g. w# Z2 T! V2 K; r3 e3 t7 [. j8 [
EOS Docker快速部署
# [8 K4 ^3 h3 |' t# o8 f0 u
* |* l: q' R% PEOSC使用% f7 X1 W1 |" F5 X- f
6 B8 U; l3 o. h) f! \) I
创建钱包2 L! o5 o7 B" |# w% v  P5 A
' o7 ]+ ]  j  }5 t5 D
将私钥导入钱包7 I! m3 O( }% W% X( f
' n# s; ^- m8 h, q
锁定和解锁钱包* T) i% F8 P  w3 z9 |
0 B8 ~% K7 l( E3 E8 B$ X
创建账户! S' {, M; a, p
! u1 A) I5 V0 M: a
内置转账$ c8 u$ v' l' n- |6 ^2 B; B' `

9 C4 |2 B* D. _" B  x& E查询交易历史8 S3 d! ~# F5 w9 S
* T3 H$ r; c; u5 @( S9 c
测试合约 - currency
8 J' T8 t5 y; g7 S+ N1 N
6 A/ U+ E  r6 x& G5 k' c' X调用合约# c5 N0 _8 }) W; o* z0 B
1 u( O! P) k+ a/ K- L3 }$ M
查询合约$ T# w! a1 R, w( Y

& R2 O; N0 ]4 f; Y7 N+ k4 v链接特定的节点+ O: Z2 h2 L$ F3 R) @5 |
1 j$ }+ n3 w+ H6 ]
链接独立钱包服务  P$ V" z0 g# I$ k

! ?7 @3 z- U  S2 \; R, V, J: n免签名验证% G) b$ T, f) A

5 s" |( x5 t1 z' x! W  `其他RPC调用8 n, y) ^7 W8 J) E( N

2 C; \( n, P4 M* ]5 x  X$ u& J& F8 K
, [3 `3 l9 J7 T4 M7 CEOS Docker快速部署1 Z- c# w6 v% h6 v1 t
构建eos镜像
8 j) u3 q- y4 |( Rgit clone https://github.com/EOSIO/eos.git --recursive& X7 b8 \/ \/ a! |. K0 N" U
cd eos2 V5 l8 r7 _- @' w0 x
cp genesis.json Docker * [3 G/ T7 o1 ~" C1 k! c
docker build -t eosio/eos -f Docker/Dockerfile .
8 A: q. t6 {, I, W! t. M8 B  s5 U启动容器* W/ ^  b) n6 L' I
sudo rm -rf /data/store/eos # options
7 Y+ o6 [9 S% X* @7 gsudo mkdir -p /data/store/eos8 i9 ?: H+ A0 M7 p& r( ~
docker-compose -f Docker/docker-compose.yml up
! H+ L6 f0 S" B9 ]如果 docker-compose 启动有报错, 可能需要给文件存储目录赋予用户读写权限
+ C* \; G; n. i! Y, J$ Ysudo chown -R SYSTEM_USER /data/store/eos) T" c9 I& q! V4 P3 R. A
验证,查询区块链状态信息
7 L3 P/ C9 a) z5 g5 Ecurl http://127.0.0.1:8888/v1/chain/get_info! u' t% ~# N# r8 e) q7 j" s8 C
如果想使用多节点环境,可使用yml文件启动
/ [8 u8 x6 C3 aversion: "2"
/ ]3 ~9 p+ w4 ~7 X! f7 m% F' aservices:
# Z3 w. ]! T0 `# @! ~1 T  node1:
9 C  i' d( b: F7 ]    image: eosio/eos
" p5 N+ y+ e/ m+ b1 t" k    ports:
/ L& v' j' D: t' B; g: L    - "8888:8888"# B* A/ x# b/ |% K9 h
    - "9876:9876"! b% p0 K3 F  E+ T
    volumes:0 D/ I# \: Y9 E2 A6 a; V  O% C$ s
      - ./node1/data:/opt/eos/bin/data-dir8 G' @: D  G- h4 r+ a) g
  node2:
* q' b5 t: ?1 p( p$ v5 q+ T! U    image: eosio/eos 9 m" D4 @5 r. ]/ q* ]$ Z& d4 m
    ports:3 Q* b8 J% V6 K; P& I1 I5 R+ N1 t
    - "8889:8889"
9 n9 b- H7 p1 B3 f, b    - "9877:9877"8 r. H( c! n2 D6 y- @' C" y, N
    volumes:7 s) U3 b# ~" g$ s7 Z* i2 v
      - ./node2/data:/opt/eos/bin/data-dir
# X9 ]% n. b9 D    depends_on:8 j' w4 w5 D: F8 ]
      - "node1"
0 u& E% S% j1 ]( W# Z; C0 h5 dEOSC使用
, P; R+ N5 Y0 r, K0 T% V3 LEOSC是EOS的核心进程EOSD对外暴露的RESTAPI命令行工具。EOSC的使用会利用到一些内置插件,插件在EOSD的配置文件config.ini中进行设置,如与链的交互需要使用’plugin = eos::chain_api_plugin’。为了签署交易并发送到区块链上,需要使用‘plugin = eos::wallet_api_plugin’。为了查询交易和历史记录,需要使用’eos::account_history_api_plugin’ 。' {6 x- u- F/ t" m
# Plugin(s) to enable, may be specified multiple times
# m' X: r) H4 B9 p* ^, a0 M/ d6 dplugin =
, T# c7 D: w  weos::producer_plugin
. l. d5 S- G0 W1 d0 iplugin =
- N1 V5 q9 g  D$ Y( _eos::chain_api_plugin
) P4 N( @  R& X- w8 c* i5 Aplugin =+ X4 d. a5 l; M
eos::wallet_api_plugin" r& f* _4 F! o2 m6 G
plugin =
$ h9 S5 l6 F1 y% `8 r4 ]+ q4 E; ^eos::account_history_api_plugin3 |9 k* ~1 `) p8 G4 v, V8 O
启动eosd后,可以使用EOSC查询当前的区块链状态
/ {, @+ d. P" V0 \% k, Tdocker exec docker_node1_1 eosc get info. b/ ^, q9 |$ S, U+ _- V
{
/ ?0 v9 N, |7 Z7 f  "head_block_num": 23449,5 j" j5 k5 R9 b
  "last_irreversible_block_num": 23432,
0 ?: g5 p5 Q" b  "head_block_id": "00005b996cc85962b28537c3d72696a012d1071638f5e4bad1809cf9afc9abb6",) a1 [! A" j, J5 `& |
  "head_block_time": "2017-09-29T01:53:33",3 a; [) l  s" |3 L
  "head_block_producer": "initi",
9 s  _9 U, H/ l  "recent_slots": "1111111111111111111111111111111111111111111111111111111111111111",% I/ x7 \7 n! T% j6 @
  "participation_rate": "1.00000000000000000", }) V/ G; j7 Q1 R# Y& e! {5 e
}" K; F7 M0 S6 u% o; P8 J
创建钱包! h/ U9 c8 U5 t) p0 k6 ]( Z! _( X* B# m
任何发送到区块链的交易都需要由所有者持有的私钥进行签名。首先,我们需要一个钱包来储存和管理私钥,使用EOSC命令创建一个钱包。
6 N/ E& w" L& h$ u5 G$ ndocker exec docker_node1_1 eosc wallet create8 E; V# z! V2 }' y
Creating wallet: default
; R* ^3 }$ \# i7 |1 O7 n0 HSave password to use in the future to unlock this wallet.: e, B) t& M& G' f
Without password imported keys will not be retrievable.
1 |. K+ j$ b$ I"PW5JXSxkHqNEwRKCpG2JUTLqkR8SNCBXofkAwaFDLwQkNdqaSXwC8", _4 z, g( p4 C  X6 V
命令执行完成,会在eos-walletd中创建一个名为‘default’的钱包,并返回钱包密码。
, b, Y* p' g+ d9 X: \% r+ U: L. R这时候可以查看钱包列表
- G! C/ \7 _5 z6 s  T; H+ [docker exec docker_node1_1 eosc wallet list
! I- n; G7 G0 o/ ]Wallets:
& q8 ]  @. @& @[
! ~0 u2 [5 d$ \( X  "default *"
, W6 E) E) ~* N( U# f* V; |( K* M]
2 a( C8 `9 r; L+ r3 a0 [  E如果你没有指定钱包名称,默认都操作的是‘default’钱包
$ {. O" W- [8 f8 k1 W  P. j将私钥导入钱包
& z+ D# K! L+ T如果你想授权某个钱包可以由某人来管理和控制,需要导入该授权者的私钥。
  t! C9 r# a- g" ]docker exec docker_node1_1 eosc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
# a1 F& B+ ?" O# v3 p$ n& n7 `imported private key for:& M' c  b) e1 Q* _
EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV0 }/ T3 Q- K: @
导入后,可以查询钱包已经导入的私钥和对应的公钥
8 q6 G9 K. g" \' ]. }- K. C  _/ Gdocker exec docker_node1_1 eosc wallet keys
7 e* p: D- e- @& n; g* X- T( q[[
4 S& v7 s, Q) j6 L2 U"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
1 u; S, ^$ F! M# e"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"
9 i; Z# W  Q1 P]' N# a5 S  E9 ?1 V, K
]* K( z3 R! X7 ^9 M7 D( W. V
锁定和解锁钱包5 w& E! K: k9 K. r6 l/ W: I
日常使用,为了保证私钥安全,可临时锁定钱包,锁定后查看钱包列表是不可见的2 \) h4 L, P- ~
docker exec docker_node1_1 eosc wallet lock' S! a2 s6 f( {, p) r% r  ]
Locked: 'default'( p9 K! J% x, {" I
当想要使用时,可以用创建钱包时生成的密码来解锁钱包4 Y; |. g; M: T, l( n
docker exec docker_node1_1 eosc wallet unlock --password PW5KVWrn81Y8PLAb52gr2FyXCanVavcrj9d5TC9C3yKhqq1PJYRPk, `) {) z/ q- H6 e
Unlocked: 'default'
$ W' `1 i& A# e/ f0 Y8 S3 z解锁后,可以在列表重新看到default钱包了
  C% b! _1 d+ P; Mdocker exec docker_node1_1 eosc wallet list9 ~% V1 r# R( q4 f" p8 ^2 ]& e
Wallets:
- N# h/ r$ k) v7 A[
: C. m9 L6 w  u$ {  W  "default *"
/ U8 S' r1 r7 c' h3 U+ U]
0 v8 q6 a3 s( t1 @' G: J2 u创建账户
& @0 d7 o+ H( W创建账户需要有两组密钥:owner和active。EOS使用EOSC工具来创建密钥对
$ p( w* ]' @) v# |1)owner key.
! e6 {- y5 Q# d, k# }9 Q) W( i8 C- |Private key:5JRc8XxvodWey4StZ2zzkUhCQhDaHvGMkABtfHzQR2ie4qaUFJ7
& |9 c$ z9 R  A& _' z) y. j# w( X1 ZPublic key: EOS5mFEdAzxvMkHLQXt2v4naUjnBrPGmzMUCikymqhSR6m7QLGSTB  ^, E: J0 ^( h( A: Z
2)active key' ^8 }7 `& Q; y7 d, D( R" k# w
Private key:5KNzFCbToz2a9Hztz9Qen5cyJcM3x5Wpq4GFiTYZgGhzntXdmYo
2 n+ s$ g3 O/ @$ E# iPublic key: EOS5EdsvESpibWLJxupTqod1nswJnbiXQZuUcLiAWEEsqcZskymeB
2 [, n0 J% L4 N: n) J/ b6 iEOSC不会保存生成的私钥
$ @$ _. j% v* V- U0 A因为后续测试智能合约需要,我们创建一个名为currency的账号。目前这个版本,所有的账户都需要用已有账户来创建,所以我们用inita账户的owener key和active key来创建currency。 为了使inita获得发送交易的权限,需要先导入inita的私钥到钱包。(参见私钥导入钱包的步骤)
: x8 _7 [" q$ l# Vdocker exec docker_node1_1 eosc create account inita currency EOS6NpEqWi177VKQkuJQL9V6Y3LqAAp9C2j, R! `! \0 E9 w; \0 |. e" h- K
执行成功,会输出一串json的交易信息,打印账户创建相关内容7 p0 d( t0 \, j! R
我们可以查询inita可以创建了哪些用户
7 U2 O- h+ ?  o: }& c* H1 a& gdocker exec docker_node1_1 eosc get servants inita
& g5 E% N; q8 \: ?) ?1 a) D, l{
9 X, m- _% S9 a  V1 O+ A# z"controlled_accounts": [
7 X3 a. Q! V' {$ j9 |  ~"currency": A( g, f* ?5 e4 [
], K7 ]+ h1 R( t# R. c1 k; f
}) W* v; ?) u  \. b0 ^
内置转账
% J& @8 W) Z1 x( ~6 @$ Y9 L创建账户之后,可以查看当前账户的状态,可以看到创建的测试账号没有余额,这样不少功能无法测试,我们需要试着给创建账户添加一些余额
  g+ U0 o, c7 x1 rdocker exec docker_node1_1 eosc get account currency
, a" \8 U$ I5 W' y8 U{
7 j' g" n- d' w, I6 h& r  "name": "currency",
  \& ~! V5 j, |  "eos_balance": "0.0000 EOS",
0 R' L, @* v+ T  "staked_balance": "0.0001 EOS",
7 T: L3 O5 Y2 N% |: `  "unstaking_balance": "0.0000 EOS",7 ?/ U; n- u2 F3 k& X& m9 m8 j
  "last_unstaking_time": "1969-12-31T23:59:59",9 f7 R/ G4 R  C/ t, i8 W" p
  "permissions": [{$ w7 F. P, E2 [/ W0 s
      "name": "active",  |" y+ D, \7 t, o6 W' X
      "parent": "owner",) E# L* u! |% H/ i/ M
      "required_auth": {! E6 X8 T  f- A7 K  D: Y
        "threshold": 1,
- t1 C: |' L/ ?0 R' h/ F% S$ }        "keys": [{6 c) \* j$ U" r# l( H! T
            "key": "EOS8ff42NMpJUybVj3nwUSnPpc3mMysKxyE4HVJy1E5o3fQv7knWf",4 f; |  r% ~  y/ }/ q
            "weight": 1
5 f5 `7 s/ p& b3 o8 b          }
. R3 R0 V( o1 d' }" u        ],
* w" o; l- |4 k4 B4 R5 V3 W  r0 I        "accounts": []
: Z- l' g+ x( i7 L5 W4 j      }
, f6 U( b* [" ~& F6 D2 P    },{, P) C% m- I+ }- J4 N
      "name": "owner",
0 ?- N8 `/ m- B- I% j1 Q# N2 n4 m      "parent": "owner",, ~, B/ w& ]4 U
      "required_auth": {
/ ?( |+ j5 g' G5 `& @( [        "threshold": 1,
2 a  f  D" }: F! c2 \: w8 o        "keys": [{2 K* |: }! M8 J- p: _! g
            "key": "EOS5fQ4saiHV426EQ7AKrGoD2AVMBYe77bnGSq42JjXBUfipv7o3E",+ i' c" g. p; h
            "weight": 11 h+ o9 Y5 t% B" ?
          }
5 R% g$ S! E+ Y# y' }' U" m        ],- b; e, c- V2 \9 U
        "accounts": []
! `( d7 g$ ?1 A! |2 ^      }
5 ^9 E7 v2 B: H2 m    }
1 s# K  }& Y  E$ b  ]
" ]" }9 ~' t5 c( x) J- i' w: B}. r- P: r+ x+ s2 D# t0 ?  W
保存全网余额的创世账号是eos,查询余额状态) i6 d- z% p" Y8 n  c8 a
docker exec docker_node1_1 eosc get account eos
) Z5 R; A: A3 |, H/ M2 z5 b{
% ~1 m! a3 g; I  ~  "name": "eos",6 M$ r. E0 }; U
  "eos_balance": "69000000.0000 EOS",
. a, C( U6 }1 ]' x$ w. z* q% K  J  "staked_balance": "0.0000 EOS",0 P) I- v- M9 F3 T: E$ p( V% s
  "unstaking_balance": "0.0000 EOS",
( _9 _, N0 o# ]( ?1 C# @7 G  "last_unstaking_time": "1969-12-31T23:59:59",
0 x) F  ^3 L  v: d  W% J  "permissions": [{2 g" k# b# E3 F6 g
      "name": "active",3 p( E# r* [* S4 i7 a
      "parent": "owner",
: H! b- Y6 g9 h: O$ e# j$ a1 z      "required_auth": {
9 e6 C2 Y! z3 q0 k, J, }2 |        "threshold": 1,
0 z6 q* _( C1 I! o) O" Y* Y8 V        "keys": [],
( Q+ L8 W% }0 T: h/ o' u        "accounts": []
! U$ n8 x6 F$ ^" ^, Q, ^# }7 P2 v      }0 X) C5 p( y; S3 W
    },{8 o- e8 ~$ C+ x! N& g4 ^
      "name": "owner",
9 T' p$ r) @) P1 r3 K      "parent": "owner",
  X* X6 X+ \+ W" v% `! I) ]      "required_auth": {8 i9 V6 F; }- O! @" k- c3 n5 H
        "threshold": 1,
  }0 }5 x: T0 J% k4 ~  U        "keys": [],1 X- {# a5 z) p' Z( a, S; n$ \% [
        "accounts": []- J. c# n: d* N# \* }* d* W/ s
      }
' s  g, ^, O6 S  j    }
1 ?) W0 ^) P& L' G  ]! Y  a# j& |' G/ D; F% e
}
! w) b1 N; D8 X我们可以通过创世块定义的创世账户使用EOSC给当前创建的账户转移余额* D% w4 X8 x0 y! Y; b' G
docker exec docker_node1_1 eosc transfer inita currency 100000000( E# e4 a' ?' ?6 f, ~
{
( q4 R+ ?5 C' }* Z# ^, K3 }/ ]  "transaction_id": "59575b8caf08eac7c00eb7483c048f12d0e7abf1ede839c3b2ed41dc6c5c7c5f",' Z. W6 ?. Q3 C. _& ^3 y. f7 j0 @
  "processed": {
! q# V0 N* ^; B+ w  f. |    "refBlockNum": 24199,
- J5 w1 l; A! g) a) C    "refBlockPrefix": 1485651173,
5 M! s" O5 Z: Q    "expiration": "2017-09-29T02:31:03",0 |3 a+ x6 G: T7 N2 `' q
    "scope": [$ D" V! ]$ N1 z$ [5 w$ @5 [  V
      "currency",
6 G" f2 Y& ]3 H8 p      "inita". `  f- d9 n2 C- G1 _
    ],  k( ^7 X5 I4 z8 L/ V. x- p' n# i% n
    "signatures": [9 r3 X. K7 ]$ h" f( F( z* q
      "1f14229bdd4bfb927021bf96ff0651c8b0fa5666e9f5cf423a0270a1b91f2d2f690b573e179d8475ce2c6b160f5cd5507d58a44f8f6cf536348584efa8dd62ade0"
) V+ }& f) t& |, i! V! k& i8 N    ],
* E% H* ?7 ^- w3 Q9 d+ e' T# S# Q    "messages": [{
# E) E" i0 w! x: d2 ^2 S# f        "code": "eos",
/ U" m& w0 ?: j# ]        "type": "transfer",
; G1 Y. f  w  w( C" V! G        "authorization": [{
! |- x! c7 \8 A1 u            "account": "inita",
0 R3 ~$ ?; h! u8 M            "permission": "active"
% p' I% q( Z  M$ f2 Y2 _  Z/ [) E0 x          }) x2 [. D3 I9 A) i  Y
        ],/ B9 I4 }, H, V+ D. x
        "data": {3 x6 T7 u% A8 {& O. _3 J, M
          "from": "inita",
0 Y- A" y; g0 L9 m! U          "to": "currency",
: `" T# _) i5 {: V6 E          "amount": 100000000,
' w0 k$ y  E' W0 u+ _# k: F          "memo": ""
, N- T& r0 m6 d& e        },
: z4 V3 R: n' Y        "hex_data": "000000000093dd740000001e4d75af4600e1f5050000000000"& f7 b- u2 z# c5 {' Q5 x+ z
      }
& }" \) F$ c. p  X0 ^    ],) N0 R0 ^' z" \  e0 ~
    "output": [{! `- Q: F. O2 s3 k! @2 V* E1 n
        "notify": [{/ o  u4 j5 H  d( B3 K% O2 D
            "name": "currency",
0 H" O+ w9 d8 [+ _7 {, B            "output": {
$ l( L" H$ I9 E              "notify": [],
+ o$ d/ i) H& a. R4 h              "deferred_transactions": []& \. u9 `* f6 K, U4 s
            }
$ z/ c& P- Z+ v          },{. O, d% z2 t3 H7 M* e! i0 b% K" p
            "name": "inita",
2 C" g0 k/ X) ?4 u7 A            "output": {
/ Q; C) c+ I  U              "notify": [],% d, ^: S1 a3 w+ Y# W0 U& P  j
              "deferred_transactions": []% M7 C6 N' n, J9 f2 `5 x$ A. _
            }5 M! L0 G* B$ L
          }
! e7 x: w0 Y5 D1 W7 V: C        ],) g6 L: M6 ?. H$ o; k" S+ a
        "deferred_transactions": []
3 Q, r0 Y- ?4 w! p! N$ T& a* a      }9 W) L7 g5 ^% ~
    ]( Q; I8 E3 c8 y9 n
  }, Z) O4 k) S/ Z9 j# O  I+ c( K- s+ t
}) ~) ]0 x+ X  O" s
再通过执行get account 命令,验证余额已经成功转移到创建的账户下5 h  A5 c/ R) d) |% E
查询交易历史0 _, L* G+ k3 L6 h( u
查询交易历史会使用到插件account_history_api_plugin,我们已经在config.ini中定义6 N. S# I+ A' n  T6 N' h+ z
docker exec docker_node1_1 eosc get transaction ; E9 ^) S" |, S5 @! A4 s
如果需要查询一个特定账户最近一次的交易记录# z/ t% x) D+ N# b# w: b
docker exec docker_node1_1 eosc get transaction inita( o! Q3 r% }; S  u# C" {4 X- W
创建智能合约
; F2 n9 J4 h$ ^  r  v官方提供了一个示例合约currency,我们依然使用EOSC来创建并部署智能合约,合约代码位置contracts/currency。- P% G4 B9 u& }4 R: b
1)为合约创建一个所有者账户。前文已经创建了currency账户
8 ]- ?4 M+ ]/ ?2 ?; y2)检查区块链上有无同名合约4 K1 l9 I9 }2 ~, V" T- {4 x( x
docker exec docker_node1_1 eosc get code currency
  I' A! ~3 n$ F% D/ Jcode hash: 0000000000000000000000000000000000000000000000000000000000000000 * R- A: c. u* J/ n0 T
3)为了获得部署权限(发送交易请求)需要将currency的active key导入到钱包中+ ]- E( s2 n; m4 e. d, {: w
4)部署合约(.wast后缀文件)和他的abi(.abi后缀文件)
- X# \. J* q; w8 w0 ydocker exec docker_node1_1 eosc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi
7 D+ F/ d5 n$ G) OReading WAST...
2 F& f* }8 q6 i0 Y- f& RAssembling WASM...
6 P6 T) X6 H3 ?. M- [Publishing contract...
% A5 k) D; i# u4 N2 g" S屏幕打印部署成功相关的信息,并查询合约hash
1 {, p# s. |5 w: m6 G& ~1 `docker exec docker_node1_1 eosc get code currency
- u# Z4 x( l  b! r9 {( l: W8 A) U8 {code hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf  N5 ?7 W+ [1 z" \5 G! @: u' g; M
调用合约( ]5 u4 \" s9 N# H" A4 w% ?
在合约部署到区块链上之后,所有的currency余额会分配给我们创建的currency账户。我们可以调用合约测试做一些转账交易。- y* z7 ~& Q$ m$ J  j
为了更好了解区块链合约的调用方式,我们可以通过.abi查看可以执行的操作列表和消息结构。. z  y- z& Q9 n7 x
docker exec docker_node1_1 eosc get code -a currency.abi currency6 _( z6 {( a" d) @0 U
code hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf
. n+ _( b8 h! f; a" _4 |saving abi to currency.abi/ O, t/ M" g2 K0 k
cat currency.abi #查看8 M$ k5 d2 w  `, [
{
/ T* d6 V  z0 ]2 K' J* w  "types": [{  I  B' v. G3 A" A8 @* J' P
      "newTypeName": "AccountName",
. w, W* q. h: ~3 }, v      "type": "Name") K! V6 H+ ~! |2 e  D
    }
, G( N4 L6 ]3 p* |9 c  ],$ {4 w6 l- _6 H
  "structs": [{
* g4 n( b$ U: B% L( }( f      "name": "transfer",8 N: M; n$ Y1 n9 c9 t
      "base": "",& U9 E* E4 f3 M& |1 l9 f; W
      "fields": {. `2 F. ^" e9 ]8 }2 f7 [6 [
        "from": "AccountName",
1 u; w* `* a( M* U* D' e: B9 z        "to": "AccountName",
6 O, {, u& Q% n$ W% O# u        "amount": "UInt64"
; b- k' _( [% k( U      }6 c1 [8 i8 B, h1 j  F/ T8 q  G  w0 Q
    },{
$ ?$ m( k: ]: G/ d/ z9 J! `6 m' T5 K      "name": "account",
7 Z. D) A/ {' }" S/ [2 e4 [; {      "base": "",. l1 M$ b9 |1 Y
      "fields": {% y" ~: I6 q8 L' a8 }. Q
        "account": "Name",0 D  a$ [: w/ N8 F
        "balance": "UInt64"/ O0 r! E4 F/ C' [$ @
      }6 r6 z& a1 d6 _/ y, r
    }
/ O  K% q7 w' W) T* t0 K  ],
' _! t( N7 o5 |: p( d" M' d3 V  "actions": [{
$ h' T  E3 ?; f- J8 R1 m2 q: |, \2 E      "action": "transfer",# V' a7 m* s( _
      "type": "transfer". k" J, O1 W9 M# x) i
    }
; f% T7 T( e6 u0 S/ G  ],/ O- N2 B0 Y! \: @. s
  "tables": [{; i) U( D! ~4 l0 _+ j/ O  z
      "table": "account",
8 V; \4 [3 v! h! H+ S- y6 e6 u      "type": "account",, i6 @+ w. V- `. p6 e
      "indextype": "i64",3 r+ G. K6 E+ l5 b4 `# R; U0 M
      "keynames" : ["account"],
5 I( c2 E0 R' z1 |  N3 e) g- j      "keytypes" : ["Name"]
4 g! ?9 _0 u1 ~* R" o    }- ?; `4 G4 {8 k
  ]
! E2 W& l8 ?& m}3 H( a. C# p" f$ D
通过上面的abi我们可以看到currency合约可以执行transfer操作,消息格式为from,to和amount。我们调用合约从currency账户转移50个余额到inita账户" }5 @5 F$ A2 o4 ]0 I% C5 d
docker exec docker_node1_1 eosc push message currency transfer '{"from":"currency","to":"inita","amount":50}' --scop
1 j$ d1 A7 ]) T; M* H  w执行完成,我们查询余额验证结果7 u& s7 z. I' H1 f4 m/ k. v
docker exec docker_node1_1 eosc get table inita currency account$ w# z  E+ E  ]' v6 E
{' y. C) K6 J$ P5 C* F6 j
  "rows": [{
' o/ }& |& A; h' l: H# ~      "account": "account",# v. C6 P6 N) T5 a8 F
      "balance": 50 0 V  |2 J- X# ]" k- E% L
       }
1 ^: G- {$ g$ L% d4 y: f" d3 ^    ]," s9 e# N4 G$ x. s
  "more": false
* S) C4 q0 O- {6 L5 N" S}
3 _& o! ^+ U4 y, T8 F8 jdocker exec docker_node1_1 eosc get table currency currency account* e) K: v% v0 t" i& i
{
% n1 ?& h" F- |! k" c  "rows": [{
+ q  I3 i3 n5 u$ u# x      "account": "account",
" F7 m$ s* U. {" _9 z0 C1 V      "balance": 999999950
/ X/ z' H+ A, ]4 g4 l5 E& m2 X    }& J/ p+ l& r3 }1 _1 |8 w
  ],3 m# j' K. G3 H$ H! L+ f: i5 M# V
  "more": false
1 z; U! }$ t3 |, y1 ^! s, a}, P: M) |, s: B# M5 m
余额不足的账户尝试转账,会提示失败/ v7 m+ g$ l7 x$ [# G1 K6 k% r
docker exec docker_node1_1 eosc push message currency transfer '{"from":"tester","to":"inita","amount":50}'-S inita -S tester -p tester@active
3 l& C' o! [8 q8 D3543610ms thread-0 main.cpp:271 operator() ] Converting argument to binary.... e/ O: n. d+ E" [8 y
3543615ms thread-0 main.cpp:311  main ] Failed with error: 10 assert_exception: Assert Exception9 Y3 A, U) [# m. k7 ~2 G
status_code == 200: Error : 10 assert_exception: Assert Exception
- q" R3 U9 \% Q7 f: v+ c* htest: assertion failed: integer underflow subtracting token balance* s5 v1 c" p+ j/ h
{"s":"integer underflow subtracting token balance","ptr":176} thread-1 wasm_interface.cpp:248 assertnonei32i32 [...snipped...]
" C- N1 p1 u5 U# k1 }) `. V# N; Y查询合约$ t0 n$ y( U5 `* G: i
如上文验证步骤,在调用完合约后,可以通过查询表来验证每个帐户持有的余额。2 A! H9 W( W. l
docker exec docker_node1_1 eosc get table currency currency account
, Q, Z( }3 S3 i7 G. L6 b0 b连接特定节点
0 g9 V: Y- E6 t6 w0 i6 o2 w3 K默认情况下,EOSC连接本地端口8888的节点。可以通过指定主机地址和端口来连接其他EOSD节点。同样的,钱包服务也可以指定特定的主机地址和端口。
, [# x$ a4 d/ ]0 ]6 s% udocker exec docker_node1_1 eosc --host  --port
* G$ P+ o8 D4 R链接独立钱包服务
2 B- l( t6 G; W$ l除了使用EOSD内置的钱包服务,也可以独立部署钱包服务
# h6 R9 t+ P" @* E# t( jdocker exec docker_node1_1 eos-walletd --http-server-endpoint host:port
7 }4 k! N6 @( f! v调用独立钱包服务需要添加如下选项
7 W4 d& |& u( }- {0 {  _+ C2 ?  Pdocker exec docker_node1_1 eosc --wallet-host --wallet-port; B8 w9 |2 D7 |1 Y! r1 R
免签名验证( i/ ^$ V0 m4 T
开发者如果需要快速测试功能,可以跳过节点签名的步骤,这样可以解耦密码学的问题而关注应用功能
. N) Z7 e* w1 e; R启动时使用特定参数* h! W2 ~/ \2 Q& ^# ^* u4 l
eosd --skip-transaction-signatures
$ F/ Q3 _, A3 D6 {EOSC调用时添加-s 选项
- Q- G/ d- n2 \, P( jdocker exec docker_node1_1 eosc   -s 4 U' M$ F4 ]& _$ z3 i* n% A
其他RPC调用
/ W' E4 ~( ]& NEOSD RPC 包含通过HTTP RPC与eosd和注册其上的插件进行调用的方式.$ n, Z7 B6 |; x  c
1)区块链API 配置. \1 L- Y9 i9 s- l; ]
想要查询eosd信息需要启用plugin = eos::chain_api_plugin插件并添加至config.ini中, w; x+ D: r" C. H( y( P2 z; g* \7 `
2)get_info接口用于查询区块链的基础信息( w2 ^5 K1 q  P6 I; A( s, t
curl http://127.0.0.1:8888/v1/chain/get_info
" u8 a* t: i4 s2 q# y返回结果如下:4 s. @5 q$ X% h) d0 i
{"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"}
. ~$ ?" o. ?: X* U  r/ zget_block接口用于查询区块相关信息6 D% m" i: W  _( _' i9 J; ?

2 a1 t5 l7 k' [) \1 }curl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":5}'
5 I; ]% q' m7 |( }/ W# @4 Qcurl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":0000000445a9f27898383fd7de32835d5d6a978cc14ce40d9f327b5329de796b}'
; O% R1 C7 k8 g8 ~4 Y3 K返回结果如下:
$ t) s1 K2 \5 L: E/ C0 L2 H{"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}: Y1 r6 b+ G" x! Q* O
4)push_transaction接口,调用合约交易2 N# p, B6 f1 S
该调用为JSON格式并会将结果更新到区块链上" P9 p" Y9 u$ X0 H
执行正确的结果返回, |3 ~0 s, J9 Z: J* u' s
返回 HTTP 200 和交易ID号
2 i! z- @* q" Y  e! l% Z0 k  U. z+ y{ / c- l3 r9 y5 k) p
'transaction_id' : "..." . Y6 R- X$ x% c$ W# w% B9 r
}
1 l  l9 }$ a" s0 v0 O+ t; g" x执行错误的结果返回,一般为400错误(参数错误)或者500错误
% t, `( x/ K& O; Z1 L3 JHTTP/1.1 500 Internal Server Error
, h* o/ g2 r# g6 K% F1 {Content-Length: 1466
4 i. `, B) @5 a  [8 _...error message..
1 }, J% C7 }3 I8 g2 epush_transaction 调用方法
0 [. M9 u$ ^* s. ucurl  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":[]}'
. V9 }& q, u+ z! G6 [' m) E此示例模拟一个转账交易。 refBlockNum和refBlockPrefix使用的前例block查询的结果
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

罗宾虚汉 初中生
  • 粉丝

    3

  • 关注

    0

  • 主题

    16