上一篇文章使用了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 );
}
}
}
}