Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

EOS纯技术上手学习

罗宾虚汉
114 0 0
EOS.IO 已发布黎明V1.0版本。EOS.IO 黎明V1.0版本是第一个预发布的 EOS.IO SDK(软件开发工具包)。EOS.IO黎明V1.0版本可以让我们体验下EOS一部分区块链特性和简单上手开发、测试。本篇主要是一个快速的review目前EOS黎明V1.0版本的功能上手。
8 j3 y9 P$ k6 {  V" T主要内容:: D+ t7 i9 l& f

! i1 T) M, X* p% P3 B. A5 ^EOS Docker快速部署% A) D( R7 N% V! I, `# ~

( }  I2 I/ c) v' OEOSC使用
; b* m9 Z# f4 v& F3 Z/ A1 l) {. |# R/ h0 s( R+ B1 k
创建钱包
2 v5 h/ X! G: s, V! T# S  x
" u/ H; i( G6 I将私钥导入钱包
# x5 o4 `. c+ G6 I  s; j; l) ]* k. M- l- W, c% c
锁定和解锁钱包
  P+ ?/ d7 E: k/ ^
8 a& ~9 \* @2 ?" Z5 p创建账户
2 j7 L: P# S' @' s4 ]1 V- y( J9 a& Y* G+ s8 F6 c" c# i
内置转账) w% h0 g& Z  X5 w

' h$ c# D' M! a. T; f4 T查询交易历史8 B/ Q; c- F# t
; ?0 h+ d# x, x
测试合约 - currency6 j' h; X* @. v$ w) ]5 i. [

( m" }4 {) {/ c& b" `8 S( S2 y调用合约
7 Y' P" G3 [: e' b, H9 U3 t2 G3 x  m% }5 [; u5 I
查询合约
  q4 k7 V- N" J+ t4 ]+ Y" c2 b" g1 ^1 p, `
链接特定的节点3 W3 u6 |4 P, o: R& h

7 r. P4 q3 q. H  h链接独立钱包服务) N" I4 `% E* x+ H$ u  |
: ]; p; W9 u1 a! g4 @( z
免签名验证7 j7 u$ i6 |" u, s6 t

( m2 v( M5 o0 x; B1 N1 y$ f其他RPC调用
9 X7 r. i, t: j* V) r
% I) \; P; {/ Y9 B4 M, g! }3 d, G3 C6 P! B$ p/ a3 g
EOS Docker快速部署
8 U" q* |3 T3 G0 {# o+ g2 B构建eos镜像7 w/ A2 H8 r" X7 K  D  u
git clone https://github.com/EOSIO/eos.git --recursive3 v' ]6 O7 a5 C6 l" J& l
cd eos
3 U; C7 \7 O- O0 h* Dcp genesis.json Docker
  ?2 z3 d6 P3 T2 adocker build -t eosio/eos -f Docker/Dockerfile .
+ i. A, B5 O' s* j启动容器
9 A$ U7 O9 `. V1 z  Osudo rm -rf /data/store/eos # options
6 C) c1 L( T0 I% `" f  d3 L3 @7 Isudo mkdir -p /data/store/eos6 J* s' x& N* A4 _6 x9 t
docker-compose -f Docker/docker-compose.yml up+ _* u1 K5 Z* \; x( S: _: n
如果 docker-compose 启动有报错, 可能需要给文件存储目录赋予用户读写权限
) B2 W( [% t# v! \  K5 c4 @sudo chown -R SYSTEM_USER /data/store/eos' A9 c$ u6 i8 m6 T
验证,查询区块链状态信息4 b- n/ X+ Z4 [  R
curl http://127.0.0.1:8888/v1/chain/get_info
3 D! {# p# t% F& I9 m0 t如果想使用多节点环境,可使用yml文件启动' Y  ^/ u/ S: y: c& J0 d" A6 @
version: "2"
& ~$ t" O8 O7 m+ Q4 Nservices:
0 o$ G' w# U" L9 g; n  node1:2 D+ |0 u% S! A0 H. a) @; ?
    image: eosio/eos & N( K! E7 |8 N. X1 B# j: d
    ports:
! h2 |9 u4 k! v8 a3 g% m8 h) {    - "8888:8888"" g: U3 E4 K& a5 [% N/ B7 I9 B
    - "9876:9876"' v! l; G2 {" N& d
    volumes:5 h0 K0 W; D3 D/ `3 m7 k2 r9 U
      - ./node1/data:/opt/eos/bin/data-dir
! t8 J6 i. V- p6 C9 t5 q3 _& d  node2:
- ]4 `& d2 g3 a* R9 ~+ l: G: |/ o    image: eosio/eos . k. a2 G$ O- o$ n% B  ~
    ports:
; F: O, A, R0 I" a, x8 r    - "8889:8889": P9 V  G. V: N& `1 O; [
    - "9877:9877"2 G  W4 k) X  I
    volumes:
' @* Q1 ?0 k9 V7 l) m7 G      - ./node2/data:/opt/eos/bin/data-dir
) ]* a" Y1 r: l& o' K    depends_on:+ R4 D7 D$ |# k
      - "node1"
+ X- h! p; [2 P& |EOSC使用
: ^' m$ e  j- G5 k( ]& I. nEOSC是EOS的核心进程EOSD对外暴露的RESTAPI命令行工具。EOSC的使用会利用到一些内置插件,插件在EOSD的配置文件config.ini中进行设置,如与链的交互需要使用’plugin = eos::chain_api_plugin’。为了签署交易并发送到区块链上,需要使用‘plugin = eos::wallet_api_plugin’。为了查询交易和历史记录,需要使用’eos::account_history_api_plugin’ 。
  X7 J, M0 S3 m# Z, D+ p2 U& p- [* q# Plugin(s) to enable, may be specified multiple times" g4 ~8 V- D5 P5 p3 r" e
plugin =
: `8 W' w/ ~$ ~+ b( Yeos::producer_plugin
. J4 r# y; g- K6 N' g5 Nplugin =
2 L1 p9 |/ G2 u8 W1 ^1 w. |) o& Ueos::chain_api_plugin9 k( b1 w2 w  A4 Z7 Z
plugin =" G# p) e9 [, Z% j
eos::wallet_api_plugin% E% b5 p* _) w6 _- K8 R
plugin =2 ?* [( t8 z) z! n  X4 U
eos::account_history_api_plugin
# r6 l/ d% b$ H7 {8 b" ]启动eosd后,可以使用EOSC查询当前的区块链状态
% K& b' t! k/ ~, o' _docker exec docker_node1_1 eosc get info
- z& n- N) r; w5 l3 [3 s+ M{, T3 q9 h( `9 \- W1 E
  "head_block_num": 23449,
! Y: X! f: z' r  "last_irreversible_block_num": 23432,2 Y2 X3 E$ _! s- b/ k
  "head_block_id": "00005b996cc85962b28537c3d72696a012d1071638f5e4bad1809cf9afc9abb6",
' x- [" L0 U# N$ Z. K! {1 Q4 V: w  "head_block_time": "2017-09-29T01:53:33",3 C6 N0 ~) c& B' ?. ?4 }& X
  "head_block_producer": "initi",
, ~; N2 x& S$ Q+ N; N! R) T  "recent_slots": "1111111111111111111111111111111111111111111111111111111111111111",
2 O! p* I5 s. K, h% i, B  "participation_rate": "1.00000000000000000"/ a2 F  h: u9 f1 c" q* _
}
0 U* |# e# }. l; @# [创建钱包4 `2 u3 A) `. ]( t4 Y* o
任何发送到区块链的交易都需要由所有者持有的私钥进行签名。首先,我们需要一个钱包来储存和管理私钥,使用EOSC命令创建一个钱包。
2 ]8 P5 L0 C# [1 p% R5 `docker exec docker_node1_1 eosc wallet create
( c& }+ n9 _" N( HCreating wallet: default
* n$ Y+ C, }- l1 }; X# d2 ]) e' W3 aSave password to use in the future to unlock this wallet.
3 V6 M7 _9 q7 m0 {Without password imported keys will not be retrievable.
' U; B9 |% Z: s5 u) K"PW5JXSxkHqNEwRKCpG2JUTLqkR8SNCBXofkAwaFDLwQkNdqaSXwC8") G  L# L( `7 v1 m
命令执行完成,会在eos-walletd中创建一个名为‘default’的钱包,并返回钱包密码。4 A! S; D1 v9 X; O! f
这时候可以查看钱包列表
1 j# A) T4 l* v# w5 ]% d8 h# Fdocker exec docker_node1_1 eosc wallet list
" n/ R: {" b. h" P4 G' y) TWallets:
; n' Y  q# Z' n7 I[
% F7 B2 A& ?- u  "default *"3 Z: z0 o" Q3 N5 ^) m
]2 _; U; _* b7 `' q8 w4 h1 H8 V
如果你没有指定钱包名称,默认都操作的是‘default’钱包
1 U; ^. V. |' i: E0 G: _' F4 w8 v将私钥导入钱包
- X' t' n* Z; O4 k( M  c如果你想授权某个钱包可以由某人来管理和控制,需要导入该授权者的私钥。) O+ T! }/ L7 O7 T9 T( A9 F$ k
docker exec docker_node1_1 eosc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
3 C3 E$ q% o6 k0 f* Wimported private key for:9 U$ b* }3 F. U; }2 V9 D( R9 b
EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
0 r# d. Z7 E% Z# ]导入后,可以查询钱包已经导入的私钥和对应的公钥
6 ~! `8 g$ ~, N; J3 b) w/ adocker exec docker_node1_1 eosc wallet keys
% ~5 a5 y/ {8 X+ Y[[  d) l! j% z  |/ E# U
"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
( D) Q6 Y9 o) U2 m1 e1 e* }"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3": K* j' `0 @6 ~: W4 z2 N
]1 H: Z& j& C4 q- M. p
]
: x- v3 K) [7 ~8 B# M锁定和解锁钱包, o$ X/ g2 `; M, L# T
日常使用,为了保证私钥安全,可临时锁定钱包,锁定后查看钱包列表是不可见的
0 ^& j! |& k4 n* h6 W! _docker exec docker_node1_1 eosc wallet lock7 q/ ~% F2 }/ p- y. J
Locked: 'default'6 D! g- _; ^+ i3 \; f$ k2 V
当想要使用时,可以用创建钱包时生成的密码来解锁钱包
: \$ y9 Y! o+ `0 B0 N2 @docker exec docker_node1_1 eosc wallet unlock --password PW5KVWrn81Y8PLAb52gr2FyXCanVavcrj9d5TC9C3yKhqq1PJYRPk8 t* T7 n; i$ @" H
Unlocked: 'default') ^$ d- j% I8 e$ E
解锁后,可以在列表重新看到default钱包了
9 D2 X7 Q! i; m1 G3 ^0 ydocker exec docker_node1_1 eosc wallet list
7 R4 Q. y3 i" k; p7 {! LWallets: : q, A  S$ M! X8 v4 j& ?
[% B+ j/ Q: I, T( k& w" j. v
  "default *"+ [! l" D' t  F9 J! ~$ l0 f
]
, i; x% g5 K7 s7 \创建账户0 O1 Z) b3 j2 G" L  Z! ^
创建账户需要有两组密钥:owner和active。EOS使用EOSC工具来创建密钥对$ y9 E3 I' Y& m8 o% l) s6 T) n
1)owner key.5 _7 K: }! t8 N
Private key:5JRc8XxvodWey4StZ2zzkUhCQhDaHvGMkABtfHzQR2ie4qaUFJ73 G1 F. H3 B! o$ z5 q
Public key: EOS5mFEdAzxvMkHLQXt2v4naUjnBrPGmzMUCikymqhSR6m7QLGSTB
  [) \- W0 G( l- |3 B1 e* ?8 q2)active key$ _9 }& _' A& [# @
Private key:5KNzFCbToz2a9Hztz9Qen5cyJcM3x5Wpq4GFiTYZgGhzntXdmYo
! H, P2 S; x5 _1 n6 NPublic key: EOS5EdsvESpibWLJxupTqod1nswJnbiXQZuUcLiAWEEsqcZskymeB
  W6 m$ U  ?; D- y4 JEOSC不会保存生成的私钥
9 a* u& P1 }* Y4 ]. W+ \% V因为后续测试智能合约需要,我们创建一个名为currency的账号。目前这个版本,所有的账户都需要用已有账户来创建,所以我们用inita账户的owener key和active key来创建currency。 为了使inita获得发送交易的权限,需要先导入inita的私钥到钱包。(参见私钥导入钱包的步骤); g- ^1 L1 G# l1 |0 E
docker exec docker_node1_1 eosc create account inita currency EOS6NpEqWi177VKQkuJQL9V6Y3LqAAp9C2j
0 H) H6 K- d& E" i! i# t执行成功,会输出一串json的交易信息,打印账户创建相关内容6 [' b3 {& }4 e! w' {/ o
我们可以查询inita可以创建了哪些用户6 E' h: |6 @3 O' O- M
docker exec docker_node1_1 eosc get servants inita  b. }4 n! }' N) f2 D/ B# q: j4 Q
{( x1 Q/ b  |# x* N. ]; Y0 d
"controlled_accounts": [1 D1 Q' E0 p3 n; k
"currency"0 P' Y$ a2 F8 w8 l1 e7 X
]6 V5 H: w' d8 l5 a# f
}
) g8 V, @" q+ v. {$ l内置转账; d  ?1 ~. V% f5 {
创建账户之后,可以查看当前账户的状态,可以看到创建的测试账号没有余额,这样不少功能无法测试,我们需要试着给创建账户添加一些余额
3 E4 w/ I7 Z$ H2 M, H! T& Rdocker exec docker_node1_1 eosc get account currency$ Z+ P- L, c" P( O
{5 m" d% U, P2 _# w& w
  "name": "currency",
  S9 t! M- F0 v$ U4 J  "eos_balance": "0.0000 EOS",
8 k) y# ~4 K2 y* H  "staked_balance": "0.0001 EOS",
3 d4 X1 {6 H5 R: g: K6 I' |, a  "unstaking_balance": "0.0000 EOS",
/ w4 r0 f, r/ m/ h+ ~: w  "last_unstaking_time": "1969-12-31T23:59:59",
8 W8 w9 R- C( r, r" N5 t6 E+ c' }+ m  "permissions": [{. j! a% G1 I: _6 U1 G* o5 F; z/ b
      "name": "active",
6 s# m" r( s# ]3 f9 e" S      "parent": "owner",
0 f  P0 ^4 }6 g      "required_auth": {
  V9 j; z- H+ p# I& e        "threshold": 1,( l1 \# G0 ?" ]$ h
        "keys": [{  d. b/ v8 ]. D& O" S
            "key": "EOS8ff42NMpJUybVj3nwUSnPpc3mMysKxyE4HVJy1E5o3fQv7knWf",: J' b7 @/ s4 \0 Q9 }: m0 }7 z
            "weight": 1
* R. k7 f2 Z: _/ D& W          }
: p9 X- p% E& G' z" V        ],  U3 X7 A1 @+ Q8 d/ ]8 c/ I$ e
        "accounts": []
  W" T3 C" l; Y& v: d3 |% N- U      }
; @: c$ m9 Y* w2 _7 l    },{; T4 \" j$ ]! E5 m# T1 Z
      "name": "owner",
0 e. }- ~7 i" g      "parent": "owner",1 [/ a8 y& q" w% j+ p( ^! ?) c
      "required_auth": {
, o- d! c! {3 j- V. p+ F! ?        "threshold": 1,+ D3 L) Y" P6 J$ p( O9 h) i
        "keys": [{$ o. `; i1 j, u; N: b3 s" w
            "key": "EOS5fQ4saiHV426EQ7AKrGoD2AVMBYe77bnGSq42JjXBUfipv7o3E",
4 O; R; o3 R5 s4 ~7 t1 `7 i  N2 Q            "weight": 1
- `, V& R+ H' ]$ ~. A' @          }- @8 ~. C. u0 L* g; _  o: w4 Z
        ],' T$ c1 z# ]* V8 ?' Z/ h( {
        "accounts": []" {3 r1 T: C' c
      }2 o: d$ Y- u/ \( r+ d
    }
1 p% x7 |+ r2 }  ]8 N3 E: ?1 Z5 t# k4 F# J# \
}4 q2 Q6 h8 t" g8 i3 E8 A, i
保存全网余额的创世账号是eos,查询余额状态* y8 ~# v% C' J, v+ f
docker exec docker_node1_1 eosc get account eos; {" ~; a9 r+ a2 a
{
. X1 S4 e. a( H  "name": "eos",
! p& ~0 D/ X1 D6 W  "eos_balance": "69000000.0000 EOS",
" r* o; [( w" Q2 @2 `& y  \  "staked_balance": "0.0000 EOS",
7 z( e' _% d* _  p  "unstaking_balance": "0.0000 EOS",( d+ W- u9 c5 U" R$ j. }2 J
  "last_unstaking_time": "1969-12-31T23:59:59",
( ~4 c! q5 X$ V5 d1 O  "permissions": [{9 K, H. A4 F% b1 V. M
      "name": "active",; n: Q2 q! ]" v0 C" u( u1 C
      "parent": "owner",( f& s' [, j# j$ g/ C' P( B) v
      "required_auth": {+ e/ [( ^5 y+ a, D
        "threshold": 1,( I" l1 N* U+ ?$ j$ i* G
        "keys": [],0 a; c- s4 g$ n
        "accounts": []8 G- Z2 I1 u0 l/ m& C2 w
      }7 O4 H- }+ B# ~# O& s
    },{: M9 o& @) C+ @) E' ~4 I' n
      "name": "owner",
7 A( T6 h7 C! j7 h( E# g1 J3 t      "parent": "owner",
9 I# i6 p8 ^- V  T& e+ b/ O      "required_auth": {$ k( |3 P8 N- y( n0 D
        "threshold": 1,
6 V# I, R; f# H+ J        "keys": [],* e( u9 v& R! b- R  s! s
        "accounts": []2 z, z2 Y9 Z3 M3 k  A$ ^
      }9 r$ p% S( X& }8 x9 P% m7 n
    }
  a9 T/ \: X7 I8 P  ]
7 K# p5 T* G* I1 I7 z: u9 v! }* L}
% V8 ?9 a: R/ K0 _! ^% b我们可以通过创世块定义的创世账户使用EOSC给当前创建的账户转移余额0 j0 `5 l2 I; p: {3 L# m! a5 |
docker exec docker_node1_1 eosc transfer inita currency 100000000# p, |- ]: a& U+ K5 t
{
* i3 U5 E8 E, _% O: n  "transaction_id": "59575b8caf08eac7c00eb7483c048f12d0e7abf1ede839c3b2ed41dc6c5c7c5f",
4 a$ z! p' ^' @* U' f( M- I  "processed": {
4 A8 D9 t9 n6 W% R/ ?% p9 w1 ?    "refBlockNum": 24199,
7 T" J3 S4 e3 k* p2 |- A    "refBlockPrefix": 1485651173,
9 M" x$ A8 H( l% S    "expiration": "2017-09-29T02:31:03",
/ D: J% \+ k6 \$ ]: N5 x) }    "scope": [
; A5 P- r% I* r7 Z      "currency",( d6 Z& E; Y6 c1 F
      "inita", [- I) F4 c- Y& n2 Y+ ?, S$ v
    ],3 O2 O: J: L) X: S% E1 Y8 K: i
    "signatures": [
& K/ M0 X; U1 p1 S      "1f14229bdd4bfb927021bf96ff0651c8b0fa5666e9f5cf423a0270a1b91f2d2f690b573e179d8475ce2c6b160f5cd5507d58a44f8f6cf536348584efa8dd62ade0"
7 s! A  \3 ?& V6 l  n, Z* Q    ],
; I# [  N4 b* V( i) a    "messages": [{
2 n) o, D5 m3 x        "code": "eos",
# w3 c& |8 }: S' L: f' w        "type": "transfer",  T. b6 w1 P2 O( |# w$ Q
        "authorization": [{
/ Y, b* d  V. X! k" R/ R( E            "account": "inita",- |* S- z: t2 ]& y+ W
            "permission": "active"
, y& P4 t. r, }' y          }0 U3 |' K$ D# U* [4 a8 L- C+ H5 h
        ],
3 z4 a( Y1 d+ d( U+ Z        "data": {# ^1 A3 \* Q# Z: d2 n
          "from": "inita",( }4 W' B: ^( x
          "to": "currency",
0 H2 ?9 D% I- @) n          "amount": 100000000,# u+ F1 i: u4 m$ t$ u
          "memo": ""
: r5 @" G3 H/ p, s/ `0 g5 L        },
: U; N& o) x8 I0 j        "hex_data": "000000000093dd740000001e4d75af4600e1f5050000000000"7 r3 \5 P7 w; S, }; l+ h- n
      }
# `. i9 d+ [( q* r    ],) ?  c9 c5 R3 y4 `/ s" L! \
    "output": [{+ ]. L9 F& C* M
        "notify": [{
& N& w7 S, d" o            "name": "currency",+ x. ~* ?" W/ m2 R
            "output": {% J: ?' j, O4 i/ Y
              "notify": [],
. k2 _% b: t; ]& k9 e9 D, \              "deferred_transactions": []/ N: k; t% {# c/ h* L0 `
            }
* x7 {  w& M/ @9 y: _9 p: k          },{+ }' C" B' Y7 b- Y4 j; z
            "name": "inita",
$ @, H, A+ x( [/ I$ e1 I& u            "output": {+ ?. X5 F! z# K' ]
              "notify": [],
4 \, M* \. z( m8 h              "deferred_transactions": []
/ \/ O  h% {, @. m            }
6 {2 w; h3 \2 n2 f+ r' I% y- q/ n          }
* N  C: y6 J+ v) o3 c        ],, ~; D( Y+ y& s
        "deferred_transactions": []
" R1 Q: X8 f  y4 Q, ^      }, H9 u. }$ a( `. d4 V% A
    ]8 ~* \/ F# n% p" s9 z
  }( u- j# W3 k' d) x. v
}
4 R. {8 n- {" z! D2 |' i1 h再通过执行get account 命令,验证余额已经成功转移到创建的账户下, @$ g4 m" K8 K" @0 d/ n
查询交易历史8 t7 i, d0 `4 }
查询交易历史会使用到插件account_history_api_plugin,我们已经在config.ini中定义
( X0 }$ R; y% Q8 gdocker exec docker_node1_1 eosc get transaction 3 `0 i1 T3 _& c
如果需要查询一个特定账户最近一次的交易记录
! n/ X- E% Y5 l4 ]) b& mdocker exec docker_node1_1 eosc get transaction inita+ g7 z/ |$ A2 q$ {4 i
创建智能合约& s  j) h" I2 g: ?2 ]
官方提供了一个示例合约currency,我们依然使用EOSC来创建并部署智能合约,合约代码位置contracts/currency。
: A3 d& T, J( i4 @) G; M! u2 b1)为合约创建一个所有者账户。前文已经创建了currency账户2 |, H1 b' L7 q- n2 `. p
2)检查区块链上有无同名合约1 i$ f+ `7 \6 _& m! {1 Q
docker exec docker_node1_1 eosc get code currency / a( S+ V& s/ K  @0 `$ L8 q
code hash: 0000000000000000000000000000000000000000000000000000000000000000
1 o2 I! e* V/ P. x- s3)为了获得部署权限(发送交易请求)需要将currency的active key导入到钱包中" S/ u0 S, k2 F( |3 g5 J
4)部署合约(.wast后缀文件)和他的abi(.abi后缀文件)
. w- B8 Q$ i  r$ p- `! \docker exec docker_node1_1 eosc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi
% j2 q+ D" W; b) |" o! HReading WAST...
! b) m/ ^5 ], v: L3 i2 AAssembling WASM...
! B) G9 S# d! B) kPublishing contract...2 h+ g$ J  {) \7 I
屏幕打印部署成功相关的信息,并查询合约hash
6 A1 X+ L. {! r! odocker exec docker_node1_1 eosc get code currency
3 j+ V) g% P" r0 {  m4 X% S, b$ Vcode hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf0 Z" H6 N$ g# {5 V
调用合约
" |, c+ M' z) S% D" |在合约部署到区块链上之后,所有的currency余额会分配给我们创建的currency账户。我们可以调用合约测试做一些转账交易。
/ u4 W( h& P, ]+ v% P为了更好了解区块链合约的调用方式,我们可以通过.abi查看可以执行的操作列表和消息结构。
9 e2 A1 O' \* I1 Z' cdocker exec docker_node1_1 eosc get code -a currency.abi currency3 d) {! T# M( O7 j3 v2 u' }0 p
code hash: c4023f74b3c7a3321d1641e4111b13584078fa7265c6ab12e1c19ff7ee800faf# f+ J. G3 U, @
saving abi to currency.abi
/ l% M" B7 u2 b0 [cat currency.abi #查看
+ Z# s( _- h( }+ `7 u# d: K2 K! m{
: f2 R0 `! ?7 V, m9 G2 k3 E  "types": [{$ v/ F) o' k0 e6 M6 h4 L( N9 u
      "newTypeName": "AccountName",% z. u0 f) F6 G% w
      "type": "Name"! `) j9 k, J' g, g; r
    }
) w" Y  Z8 {$ ^9 K8 s' b0 N5 s  ],: a4 e% A1 z: i/ B
  "structs": [{; h4 D$ e2 n! M2 Y; l: q
      "name": "transfer",
. r# g* y: A9 C  _      "base": "",
5 F" M- R* l4 |: g; O7 L0 ^      "fields": {
. ~" |3 L4 k& _) w0 \        "from": "AccountName",0 \: L- w! S8 Y9 E9 e* A; |
        "to": "AccountName",* Z% p# f# i7 }2 R" V. x- \! a$ M
        "amount": "UInt64"/ E; z, K$ R7 ~* f  c0 b) K
      }" T' f8 i$ n2 ~6 a& a) _
    },{. @: j8 }0 ]. `8 w7 ?& ~
      "name": "account",% Y/ L1 u4 F, T/ G! u2 e
      "base": "",4 f7 T0 p- E3 F0 o' Y
      "fields": {$ }# K3 ?' b+ J- y
        "account": "Name",
/ X/ j4 ?6 `. D& T8 R" S        "balance": "UInt64"8 K, w4 q) R7 h& Z& z
      }
) n* K/ p6 Y  T0 ?5 N    }
4 a' W+ n4 m" _/ @  ],
# Q' L/ x* s2 V8 y& H( }  "actions": [{
; p7 Q$ D# W* g3 S      "action": "transfer",
6 A9 D0 ]$ m% L" V8 S4 g      "type": "transfer"
+ [' L3 K. _4 u, u, m    }/ u$ |" z' k+ ], C- Q% [; ]
  ],! I0 x; n/ a- z' w4 ~$ S5 c% V
  "tables": [{6 S* u" F! I- d' W7 j
      "table": "account",
1 B! _; ?; z6 d5 J2 x2 {      "type": "account",
! _0 R" }. v5 W- b6 Z4 w      "indextype": "i64",
7 S) L: R" K1 m4 p) O2 {      "keynames" : ["account"],3 g! d7 e0 |! i) @
      "keytypes" : ["Name"]
+ J9 y6 P% d/ ]  `5 n/ I, l    }
  k+ g0 s, w6 B- e  y& b8 |  ]5 o, r# z6 N3 q7 @/ ~2 X
}3 _' z8 Z) V$ a; N8 @
通过上面的abi我们可以看到currency合约可以执行transfer操作,消息格式为from,to和amount。我们调用合约从currency账户转移50个余额到inita账户6 L' V! b) p; P1 b/ g. z
docker exec docker_node1_1 eosc push message currency transfer '{"from":"currency","to":"inita","amount":50}' --scop
! @7 t' a' v  c执行完成,我们查询余额验证结果/ N9 S, h/ Q% T+ v7 D
docker exec docker_node1_1 eosc get table inita currency account
- C* G& f% {! q{& Q, d8 l( D8 R0 s
  "rows": [{
5 B, i6 l3 \; a/ H1 l8 T      "account": "account",' }- Q: ]; H+ P. u% q# h
      "balance": 50 1 b3 x6 }2 O- l+ Y$ ~# b0 Z- L
       }
6 P" w  h" D9 u" |& f    ],
" ?* T7 t" K$ ]; l  "more": false- R  _7 M# H4 g5 f0 s, z( D
}
  B9 x9 g7 g& l; [0 P  k2 sdocker exec docker_node1_1 eosc get table currency currency account
4 F# J2 e( z! _3 x{; |; S: p3 ?. i  A$ i
  "rows": [{9 {: w& h$ |0 w+ S
      "account": "account",
9 T0 x& A, G3 z! X# u' Z  C& j0 y      "balance": 999999950* k# P% M$ u8 t% T3 X. n; ?" U
    }
' p7 [$ D" H6 r, s: r3 n  ],: X) d( D$ p2 Y2 B& W$ Y, P
  "more": false
" C' ?6 T* d) r}8 m2 H$ z0 w' V- A( y
余额不足的账户尝试转账,会提示失败
6 q8 F& U5 F; _" V( x/ s1 bdocker exec docker_node1_1 eosc push message currency transfer '{"from":"tester","to":"inita","amount":50}'-S inita -S tester -p tester@active# O6 p& S# c4 W3 s
3543610ms thread-0 main.cpp:271 operator() ] Converting argument to binary..., D, r, ~& w" K  _+ x' C  ~
3543615ms thread-0 main.cpp:311  main ] Failed with error: 10 assert_exception: Assert Exception4 Y; p9 p  s( ^3 O; j* T5 e8 ]
status_code == 200: Error : 10 assert_exception: Assert Exception3 x- F8 D6 v' g
test: assertion failed: integer underflow subtracting token balance
& B3 F5 \% z  ^8 n! ^. s{"s":"integer underflow subtracting token balance","ptr":176} thread-1 wasm_interface.cpp:248 assertnonei32i32 [...snipped...]
& ]' T7 |$ l. w+ R" o! H8 L5 \查询合约' [( n7 g# z, e4 o" ~4 N1 E
如上文验证步骤,在调用完合约后,可以通过查询表来验证每个帐户持有的余额。
1 x$ H% p( g7 P7 a5 T) f: k5 r9 Zdocker exec docker_node1_1 eosc get table currency currency account
* b& c8 v& K) L5 F! z连接特定节点
; n8 v" c1 C; _- Z$ S默认情况下,EOSC连接本地端口8888的节点。可以通过指定主机地址和端口来连接其他EOSD节点。同样的,钱包服务也可以指定特定的主机地址和端口。8 }) \; S% F( z
docker exec docker_node1_1 eosc --host  --port ! N; t7 J- [/ r. L! c! Z
链接独立钱包服务
8 @/ r: n8 [, f2 p% H: e/ e除了使用EOSD内置的钱包服务,也可以独立部署钱包服务/ X8 M$ }  u) j
docker exec docker_node1_1 eos-walletd --http-server-endpoint host:port
( v/ c: L/ A6 K, N  {1 \( B调用独立钱包服务需要添加如下选项
* M8 M4 W+ l4 W+ h! B* Ndocker exec docker_node1_1 eosc --wallet-host --wallet-port* K4 B# N  k" O0 l
免签名验证
% W. ]4 Z" U& `4 j. r1 B开发者如果需要快速测试功能,可以跳过节点签名的步骤,这样可以解耦密码学的问题而关注应用功能
( _" C6 M: P! v& @, ]& U7 `$ E启动时使用特定参数
- j  k" D: p3 s6 w/ \, X( feosd --skip-transaction-signatures
# b, n7 _! x& j) \- j$ S/ @EOSC调用时添加-s 选项
3 g- \9 o3 U4 s' w5 Sdocker exec docker_node1_1 eosc   -s
5 o9 K$ A6 c! G, c其他RPC调用9 }: h! m6 I: s* d2 D
EOSD RPC 包含通过HTTP RPC与eosd和注册其上的插件进行调用的方式.4 \/ X7 B5 a" w; G/ A+ I* Q
1)区块链API 配置
- @7 F2 O9 i7 q4 M想要查询eosd信息需要启用plugin = eos::chain_api_plugin插件并添加至config.ini中# A$ o* E0 [5 Y1 e: P
2)get_info接口用于查询区块链的基础信息
* a. Q/ J$ E, _- h) rcurl http://127.0.0.1:8888/v1/chain/get_info   ~7 y1 S1 l2 U" j+ T; j2 s
返回结果如下:2 s! J9 L8 n: X7 p5 J7 r& 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"}5 J3 ^' ^4 W" e6 s& T9 p/ I
get_block接口用于查询区块相关信息: }7 N7 y7 W  L' L
7 S/ G; n9 C2 p% G0 w% L- N
curl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":5}'
+ t( e9 `! j) ^' jcurl  http://localhost:8888/v1/chain/get_block -X POST -d '{"block_num_or_id":0000000445a9f27898383fd7de32835d5d6a978cc14ce40d9f327b5329de796b}'
- H" P  k3 W6 C; b返回结果如下:* _7 }; A7 K. r7 W6 D
{"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}$ F! O+ ]& z8 `$ `# F
4)push_transaction接口,调用合约交易
$ ^5 Y! O5 E7 z: s. Z该调用为JSON格式并会将结果更新到区块链上
( S  }+ ^( I+ y2 L4 {执行正确的结果返回6 m( V* V9 e4 u& I2 O# c3 Y
返回 HTTP 200 和交易ID号9 p, N( W1 \3 B+ H
{
# r! p& a. z4 O9 b) y'transaction_id' : "..." ' Z0 I! Z- n0 K* B$ ?
}8 }" ~3 |$ ]# E/ o' W  T! d: G
执行错误的结果返回,一般为400错误(参数错误)或者500错误
# ~; N+ R7 V$ M7 Y% M0 E9 NHTTP/1.1 500 Internal Server Error4 d, E. z# Z8 Q/ n: U* |5 }/ q
Content-Length: 1466
2 ^' V" c- e' B...error message..5 x" i9 k' y5 u4 J
push_transaction 调用方法/ Q/ Q! v" f. k8 I# |
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 P. J' t. [3 m
此示例模拟一个转账交易。 refBlockNum和refBlockPrefix使用的前例block查询的结果
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

罗宾虚汉 初中生
  • 粉丝

    3

  • 关注

    0

  • 主题

    16