准备工作
创建钱包
$ cleos wallet create
Creating wallet: default
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5JjbXbzQ9FKZ36AEAgwUrkXYzpmFEzWHTwtHe4FiWTqxia5TV5y"
导入私钥
$ cleos wallet import 5KG314q9BWCdb9yoXK2vioCaf6cmYBoC27kmooNCNsMHe22kgVV
imported private key for: EOS67C9QroNTsJg4bWFoQqXkzVaWsysDb5cqgz8vcnBX2QhSwoETs
导入BIOS合约
$ cleos set contract eosio contracts/eosio.bios -p eosio
Reading WAST...
Assembling WASM...
Publishing contract...
executed transaction: f8e889e5d09ee3828f3c856446ad57ab0a5d8f33d8ce6bed892238ffb7dd6633 3288 bytes 2200576 cycles
# eosio <= eosio::setcode {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d0100000001581060037f7e7f0060057f7e7e7e7e...
# eosio <= eosio::setabi {"account":"eosio","abi":{"types":[],"structs":[{"name":"set_account_limits","base":"","fields":[{"n...
添加生产账号
在config.ini
中配置了多个producer
private-key = ["EOS67C9QroNTsJg4bWFoQqXkzVaWsysDb5cqgz8vcnBX2QhSwoETs","5KG314q9BWCdb9yoXK2vioCaf6cmYBoC27kmooNCNsMHe22kgVV"]
producer-name = eosio
producer-name = morea
producer-name = moreb
producer-name = morec
创建这些账号
$ cleos create account eosio morea EOS67C9QroNTsJg4bWFoQqXkzVaWsysDb5cqgz8vcnBX2QhSwoETs EOS67C9QroNTsJg4bWFoQqXkzVaWsysDb5cqgz8vcnBX2QhSwoETs
...
...
新建setprods.json
文件
{
"version": 1,
"producers": [{
"producer_name": "morea",
"block_signing_key": "EOS67C9QroNTsJg4bWFoQqXkzVaWsysDb5cqgz8vcnBX2QhSwoETs"
}, {
"producer_name": "moreb",
"block_signing_key": "EOS67C9QroNTsJg4bWFoQqXkzVaWsysDb5cqgz8vcnBX2QhSwoETs"
}, {
"producer_name": "morec",
"block_signing_key": "EOS67C9QroNTsJg4bWFoQqXkzVaWsysDb5cqgz8vcnBX2QhSwoETs"
}, {
"producer_name": "eosio",
"block_signing_key": "EOS67C9QroNTsJg4bWFoQqXkzVaWsysDb5cqgz8vcnBX2QhSwoETs"
}]
}
设置生产者账号
$ cleos push action eosio setprods "$(cat setprods.json)" -p eosio
executed transaction: 7d12d373084708d148b133f72844c6ed10a86fc4ce3273f2ff694727bccc48cd 312 bytes 107520 cycles
# eosio <= eosio::setprods {"version":1,"producers":[{"producer_name":"more","block_signing_key":"EOS5pNnmCXmRNacqmv3pJ7uGGzcwF...
日志中可以看到这些生产者在轮流出块
部署Token合约
创建合约用户
$ cleos create key
Private key: 5J8tcyswr57zZtmui9REGc1MRMGS16DtCQ9TRnzjDAcLNiQ4vvg
Public key: EOS6M8Tdn1BNVuqt9CJU7MoW28K1XhRBDvBsFQhF6LPfeYgVrWPYi
$ cleos create account eosio eosio.token EOS6M8Tdn1BNVuqt9CJU7MoW28K1XhRBDvBsFQhF6LPfeYgVrWPYi EOS6M8Tdn1BNVuqt9CJU7MoW28K1XhRBDvBsFQhF6LPfeYgVrWPYi
$ cleos wallet import 5J8tcyswr57zZtmui9REGc1MRMGS16DtCQ9TRnzjDAcLNiQ4vvg
导入合约
$ cleos set contract eosio.token contracts/eosio.token -p eosio.token
发布Token
首先需要运行create action
$ cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 EOS", "can_freeze":0, "can_recall":0, "can_whitelist":0}' -p eosio.token
然后发行token
$ cleos push action eosio.token issue '["eosio","1000000000.0000 EOS","deposit started"]' -p eosio
获取余额
$ cleos get currency balance eosio.token eosio
1000000000.0000 EOS
转账
首先创建一个测试用户
$ cleos create key
Private key: 5Jcc9Fm6ZPBUs8iYWR5eMUHWCeF19GmAKMAiRQHFpmCJvDjkbfR
Public key: EOS6xP5M1QaUbDqHq9SVm711ApidsYeLjUYSTFvMdwtoen8Mzt4co
$ cleos create account eosio tester EOS6xP5M1QaUbDqHq9SVm711ApidsYeLjUYSTFvMdwtoen8Mzt4co EOS6xP5M1QaUbDqHq9SVm711ApidsYeLjUYSTFvMdwtoen8Mzt4co
向其转账100 EOS
$ cleos push action eosio.token transfer '{"from":"eosio","to":"tester","quantity":"100.0000 EOS","memo":"transfer to"}' -p eosio
查看余额
$ cleos get currency balance eosio.token eosio
999999900.0000 EOS
$ cleos get currency balance eosio.token tester
100.0000 EOS
第一个智能合约
Hello World
contracts
中新建文件夹hello
,编写文件hello.cpp
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
using namespace eosio;
class hello : public eosio::contract {
public:
using contract::contract;
void hi(account_name user) {
require_auth( user );
print("Hello, I'm ", name{user});
}
};
EOSIO_ABI(hello, (hi))
生成wast
和abi
文件
$ eosiocpp -o contracts/hello/hello.wast contracts/hello/hello.cpp
$ eosiocpp -g contracts/hello/hello.abi contracts/hello/hello.cpp
创建合约账号并部署
$ cleos create key
Private key: 5J5eiQtGkMZHeJjrpLemQies93rzNVfhnR8wQCQc6WDjkqSMH3k
Public key: EOS6ghTFAieviETGYmPeefvSwYBPAgMgLsgSfHG2i8etUJk41Cbhu
$ cleos create account eosio hello EOS6ghTFAieviETGYmPeefvSwYBPAgMgLsgSfHG2i8etUJk41Cbhu EOS6ghTFAieviETGYmPeefvSwYBPAgMgLsgSfHG2i8etUJk41Cbhu
$ cleos wallet import 5J5eiQtGkMZHeJjrpLemQies93rzNVfhnR8wQCQc6WDjkqSMH3k
$ cleos set contract hello contracts/hello -p hello
运行Action
$ cleos push action hello hi '{"user":"eosio"}' -p eosio
executed transaction: 0ec6e00144140f50e55e77750949a501d4fedd945e35668b72fe5e77242ea35e 232 bytes 102400 cycles
# hello <= hello::hi {"user":"eosio"}
>> Hello, I'm eosio
合约进阶
新建一个包含数据表的合约
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
using namespace eosio;
using namespace std;
class basics : public contract {
using contract::contract;
public:
basics( account_name self ) :
contract(self),
_statuses(_self, _self){}
// @abi action
void test( name sender, string status ){
require_auth(sender);
auto iter = _statuses.find(sender);
if(iter == _statuses.end()) _statuses.emplace( sender, [&]( auto& row) {
row.sender = sender;
row.status = status;
});
else _statuses.modify( iter, 0, [&]( auto& row) {
row.status = status;
});
}
private:
// @abi table
struct statuses {
name sender;
string status;
name primary_key() const { return sender; }
EOSLIB_SERIALIZE( statuses, (sender)(status) )
};
multi_index<N(statuses), statuses> _statuses;
};
EOSIO_ABI( basics, (test) )
部署合约
$ cleos set contract basics contracts/basics -p basics
数据表变化
运行一次test
Action
$ cleos push action basics test '{"sender":"eosio","status":"resting"}' -p eosio
查看table
$ cleos get table basics basics statuses
{
"rows": [{
"sender": "eosio",
"status": "resting"
}
],
"more": false
}