上一篇文章使用了nodeos命令来启动eos服务,这一篇文章,就来介绍一下eos提供的相关程序和工具。
-
nodeos
EOSIO的核心守护进程,它可通过插件配置来启动一个节点。 -
cleos
这是一个命令行工具,它跟nodeos开放的REST API接口进行交互。在cleos使用时需要带上 nodeos实例的IP和端口。此外,cleos提供全面的命令行提示,如果不清楚说那个什么参数,可直接输 cleos 回车后会打印出 参数说明。如果需要查看子命令后的参数,也是如此,比如 输入cleos create
ERROR: RequiredError: Subcommand required
Create various items, on and off the blockchain
Usage: ./cleos create SUBCOMMAND
Subcommands:
key Create a new keypair and print the public and private keys
account Create a new account on the blockchain
-
keosd
EOSIO钱包守护进程,它云加载钱包相关插件,比如http接口和RPC API -
launcher
launcher应用程序简化了在LAN和WAN网络上多个nodeos节点的分布 -
eosiocpp
eosiocpp通过检查合约源代码中定义内容的类型,来生成ABI规范文件
为了指示一个类型需要导出到ABI文件,在类型声明上必须加上@abi这个注解, 比如@abi action [name name2 ... nameN] @abi table [index_type name]
要生成abi文件,esoiocpp必须加-g
# eosiocpp -g abi.json types.hpp Generated abi.json ...
eosiocpp也可以生成
helper function
来序列化/反序列化 ABI 文件里声明的类型例如
声明一个
action
#include <eosiolib/eosio.hpp> class example : public eosio::contract { //@abi action void exampleaction( uint64_t param1, uint64_t param2, std::string param3 ) { } }; { "types": [], "structs": [{ "name": "exampleaction", "base": "", "fields": [{ "name": "param1", "type": "uint64" },{ "name": "param2", "type": "uint64" },{ "name": "param3", "type": "string" } ] } ], "actions": [{ "name": "exampleaction", "type": "exampleaction", "ricardian_contract": "" } ], "tables": [], "ricardian_clauses": [], "abi_extensions": [] }
声明一张
table
#include <eosiolib/eosio.hpp> //@abi table my_table struct my_record { uint64_t ssn; std::string fullname; uint64_t primary_key() const { return key; } }; { "types": [], "structs": [{ "name": "my_record", "base": "", "fields": [{ "name": "ssn", "type": "uint64" },{ "name": "fullname", "type": "string" } ] } ], "actions": [], "tables": [{ "name": "my_table", "index_type": "i64", "key_names": [ "ssn" ], "key_types": [ "uint64" ], "type": "my_record" } ], "ricardian_clauses": [], "abi_extensions": [] }
typedef exporting
#include <eosiolib/eosio.hpp> struct simple { uint64_t u64; }; typedef simple simple_alias; typedef eosio::name name_alias; class examplecontract : eosio::contract { //@abi action void actionone( uint32_t param1, name_alias param2, simple_alias param3 ) {} }; { "types": [{ "new_type_name": "simple_alias", "type": "simple" },{ "new_type_name": "name_alias", "type": "name" } ], "structs": [{ "name": "simple", "base": "", "fields": [{ "type": "uint64", "name": "u64" }] },{ "name": "actionone", "base": "", "fields": [{ "type": "uint32", "name": "param1" },{ "type": "name_alias", "name": "param2" },{ "type": "simple_alias", "name": "param3" } ] } ], "actions": [{ "name": "actionone", "type": "actionone", "ricardian_contract": "" } ], "tables": [], "ricardian_clauses": [], "abi_extensions": [] }
使用生成的序列化/反序列化函数并明确用户自定义的apply
#include <eosiolib/eosio.hpp> struct simple { uint32_t u32; }; struct my_complex_type { uint64_t u64; std::string str; simple simple; eosio::bytes bytes; public_key pub; }; typedef my_complex_type complex; //@abi action struct test_action { uint32_t u32; complex cplx; }; extern "C" { void apply( uint64_t code, uint64_t action, uint64_t receiver ) { if( code == N(mycontract) ) { if( action == N(testaction) ) { eosio::print("test_action content\n"); test_action testact = eosio::unpack_action_data<test_action>(); eosio::print_f( "Test action : % %", testact.u32, testact.cplx.u64 ); } } } }
注意,action名和table名都不能使用下划线
使用测试变量来调用合约
cleos push action testaccount testaction '{"u32":"1000", "cplx":{"u64":"472", "str":"hello", "bytes":"B0CA", "pub":"EOS8CY2pCW5THmzvPTgEh5WLEAxgpVFXaPogPvgvVpVWCYMRdzmwx", "simple":{"u32":"123"}}}' -p testaccount
「力场 lichang.io」公链挖矿第一社区!