| 知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
為了方便調試合約
找到config.ini中的配置項contracts-console = false 改為 true
[root@netkiller ~]# vim ~/.local/share/eosio/nodeos/config/config.ini # print contract's output to console (eosio::chain_plugin) contracts-console = true
這樣 eosio::print() 輸出的內容才會顯示在控制台上。
例如我們需要這樣一個資料結構
{
id,
description,
completed
}
結構體定義如下
struct todo {
uint64_t id;
std::string description;
uint64_t completed;
uint64_t primary_key() const { return id; }
EOSLIB_SERIALIZE(todo, (id)(description)(completed))
};
primary_key() 相當與數據中的主鍵。
定義一個表
typedef eosio::multi_index<N(todos), todo> todo_table; todo_table todos;
void create(account_name author, const uint32_t id, const std::string& description) {
todos.emplace(author, [&](auto& new_todo) {
new_todo.id = id;
new_todo.description = description;
new_todo.completed = 0;
});
void complete(account_name author, const uint32_t id) {
auto todo_lookup = todos.find(id);
eosio_assert(todo_lookup != todos.end(), "Todo does not exist");
todos.modify(todo_lookup, author, [&](auto& modifiable_todo) {
modifiable_todo.completed = 1;
});
eosio::print("todo#", id, " marked as complete");
}
void destroy(account_name author, const uint32_t id) {
auto todo_lookup = todos.find(id);
todos.erase(todo_lookup);
eosio::print("todo#", id, " destroyed");
}
#include <eosiolib/eosio.hpp>
#include <string>
namespace eosio {
using std::string;
class netkiller : public contract {
public:
netkiller( account_name self ):contract(self){}
void create(account_name author, string title, string content);
void change(account_name author, uint64_t post_id, string title, string content);
void remove(account_name author, uint64_t post_id);
void find(uint64_t post_id, account_name author);
private:
struct da {
uint64_t post_id;
account_name poster;
string title;
string content;
uint64_t primary_key()const { return post_id; }
account_name get_poster() const { return poster; }
EOSLIB_SERIALIZE(da, (post_id)(poster)(title)(content))
};
typedef eosio::multi_index<N(data), da, indexed_by<N(byposter), const_mem_fun<da, account_name, &da::get_poster>> > article;
};
}
#include "netkiller.hpp"
namespace eosio {
void netkiller::create(account_name author, string title, string content)
{
require_auth( author );
article datable( _self, _self);
datable.emplace(author, [&]( da & d){
d.title = title;
d.content = content;
d.post_id = datable.available_primary_key();
d.poster = author;
});
}
void netkiller::change(account_name author, uint64_t post_id, string title, string content)
{
require_auth(author);
article datable( _self, author);
auto post = datable.find(post_id);
eosio_assert(post->poster == author, "netkiller");
datable.modify(post, author, [&](auto& p){
if (title != "")
p.title = title;
if (content != "")
p.content = content;
});
}
void netkiller::remove(account_name author, uint64_t post_id)
{
require_auth(author);
article datable( _self, author);
auto post = datable.find(post_id);
eosio::print(post->title.c_str());
eosio_assert(post->poster == author, "The author is invlide");
datable.erase(post);
}
void netkiller::find(uint64_t post_id, account_name author){
article datable(_self, _self);
auto post_da = datable.find( post_id);
eosio::print("Post_id: ", post_da->post_id, " Post_Tile: ", post_da->title.c_str(), " Content: ", post_da->content.c_str());
auto poster_index = datable.template get_index<N(byposter)>();
auto pos = poster_index.find( author );
for (; pos != poster_index.end(); pos++)
{
eosio::print("content:", pos->content.c_str(), " post_id:", pos->post_id, " title:", pos->title.c_str());
}
}
}
EOSIO_ABI(eosio::netkiller, (create)(change)(remove)(find))
nodeos -e -p eosio --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin --plugin eosio::wallet_api_plugin
這裡我們創建一個賬號,用這個賬號部署合約,該賬號是合約所有者。
創建秘鑰對
[root@netkiller ~]# cleos wallet unlock [root@netkiller ~]# cleos create key Private key: 5HxCWNbTEADKbvdRBgeENXhxReHMQbVuPL5mumDqGCzmkPo5yy3 Public key: EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4
導入私鑰
[root@netkiller ~]# cleos wallet import 5HxCWNbTEADKbvdRBgeENXhxReHMQbVuPL5mumDqGCzmkPo5yy3 imported private key for: EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4 [root@netkiller ~]# cleos wallet keys | grep EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4 "EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4",
創建賬號 neo
[root@netkiller ~]# cleos create account eosio contract.cms EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4 EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4 executed transaction: f04ba09f633dffbf97321c6d2e021192082383908fa690dc40032cd98a1bfd89 200 bytes 390 us # eosio <= eosio::newaccount "0000000000ea305590af0119999b274501000000010003588ecdc868696f500c7782dbf0da3b298830e67ea9b810469819d... warning: transaction executed locally, but may not be confirmed by the network yet
contract.art 就是我們合約賬號,我們使用 contract 首碼來區分他是合約賬號。
[root@netkiller eos]# cleos wallet unlock password: Unlocked: default [root@netkiller eos]# cleos set contract contract.cms cms Reading WAST/WASM from cms/cms.wasm... Using already assembled WASM... Publishing contract... executed transaction: 8a72e29389e170807daaf41e9c9e70ac4eff2f2f129ca22ef55ca9443768dedf 7176 bytes 1311 us # eosio <= eosio::setcode "80250219999b27450000c3770061736d0100000001b2011b60037f7e7e0060027f7e0060057f7e7e7f7f0060047f7e7f7f0... # eosio <= eosio::setabi "80250219999b27459d020e656f73696f3a3a6162692f312e30000506637265617465000306617574686f72046e616d65057... warning: transaction executed locally, but may not be confirmed by the network yet
cleos push action contract.cms create '{"author":"contract.cms","title":"hello","content":"helloworld!!!"}' -p contract.cms
[root@netkiller eos]# cleos push action contract.art create '{"author":"contract.art","title":"hello","content":"helloworld!!!"}' -p contract.art
executed transaction: b6cab608fb4e7fa17a7f893848f3516e1bfd231769ad7d7226b0a099f309a771 120 bytes 899 us
# contract.art <= contract.art::create {"author":"contract.cms","title":"hello","content":"helloworld!!!"}
warning: transaction executed locally, but may not be confirmed by the network yet
[root@netkiller eos]# cleos push action contract.cms create '{"author":"neo","title":"hello","content":"helloworld!!!"}' -p neo
executed transaction: 90cb81b11386514b450e1a609f0e1e2633f6a4e40d453c127811e5cd33b46a5a 120 bytes 755 us
# contract.art <= contract.art::create {"author":"neo","title":"hello","content":"helloworld!!!"}
warning: transaction executed locally, but may not be confirmed by the network yet
下面我們來查詢一下剛剛插入的數據:
find
[root@netkiller eos]# cleos push action contract.cms find '{"id":0}' -p contract.cms
executed transaction: b3cba4d001fcb49a88926be208fa7bee59d557b0ed8a2bd12e65bdd3ff69c61e 104 bytes 486 us
# contract.cms <= contract.cms::find {"id":0}
>> id: 0 Tile: hello Content: helloworld!!!
query
[root@netkiller eos]# cleos push action contract.cms query '{"author":"contract.cms", "id":0}' -p contract.cms
executed transaction: c81a0d21634f4942f7d65dd49efcf5cf7cd739a049968b5f9b0eaad7de4c688c 112 bytes 583 us
# contract.cms <= contract.cms::query {"author":"contract.cms","id":0}
>> Post_id: 0 Post_Tile: hello Content: helloworld!!!content:helloworld!!! id:0 title:hello
修改表中的數據
[root@netkiller eos]# cleos push action contract.cms change '{"author":"contract.cms","id":0,"title":"word","content":"china"}' -p contract.cms
executed transaction: 073205e4e3e30699a81394ee622aa84d568958919801b364d809ff34f4ca8412 120 bytes 553 us
# contract.cms <= contract.cms::change {"author":"contract.cms","id":0,"title":"word","content":"china"}
檢查數據修改情況
[root@netkiller eos]# cleos push action contract.cms find '{"id":0}' -p contract.cms
executed transaction: 300fe2c93cf2cfebcdd0524e0629a96b3011b0592be2119d001f38807c1c378b 104 bytes 498 us
# contract.cms <= contract.cms::find {"id":0}
>> id: 0 Tile: word Content: china
[root@netkiller eos]# cleos push action contract.cms remove '{"author":"contract.cms","id":0}' -p contract.cms
executed transaction: eeee8ff799c58d5e3a246ccec8d80c47599ad947d4581611d9a668abee53c0b5 112 bytes 770 us
# contract.cms <= contract.cms::remove {"author":"contract.cms","id":0}
>> word
檢查被刪除的數據,提示 Error 3070002: Runtime Error Processing WASM 表示找不到該記錄。
[root@netkiller eos]# cleos push action contract.cms find '{"id":0}' -p contract.cms
Error 3070002: Runtime Error Processing WASM
#include <eosiolib/eosio.hpp>
using namespace eosio;
class vehicle : public eosio::contract {
public:
/// @abi table
struct service_rec {
uint64_t pkey;
account_name customer;
uint32_t date;
uint32_t odometer;
auto primary_key() const { return pkey; }
account_name get_customer() const { return customer; }
EOSLIB_SERIALIZE(service_rec, (pkey)(customer)(date)(odometer))
};
typedef multi_index<N(service), service_rec> service_table_type;
using contract::contract;
/// @abi action
void exec(account_name owner, account_name customer) {
service_table_type service_table(current_receiver(), owner);
uint64_t pkeyf;
service_table.emplace(owner, [&](auto &s_rec) {
s_rec.pkey = service_table.available_primary_key(); // 主鍵自增
pkeyf = s_rec.pkey;
print(pkeyf);// 打印主鍵內容
s_rec.customer = customer;
s_rec.date = 2000;
s_rec.odometer = 100;
});
print("Hello, ", name{customer});
service_rec result = service_table.get(pkeyf);
print("_", result.pkey);
print("_", result.customer);
print("_", result.date);
print("_", result.odometer);
}
};
EOSIO_ABI(vehicle, (exec))