环境 ubuntu16.04 64位
一 编写todolist的合约代码
mkdir todo
vim todo.cpp 输入以下合约内容
#include
#include
using namespace eosio;
class todo_contract : public eosio::contract {
public:
todo_contract(account_name self)
:eosio::contract(self),
todos(_self, _self)
{}
//@abi action
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;
});
eosio::print("todo#", id, " created");
}
//@abi action
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");
}
//@abi action
void destroy(account_name author, const uint32_t id) {
auto todo_lookup = todos.find(id);
todos.erase(todo_lookup);
eosio::print("todo#", id, " destroyed");
}
private:
//@abi table todos i64
struct todo{
uint64_t id; //结构体id
std::string description; //todolist的描述信息
uint64_t completed; //todolist的完成情况,0未完成 1完成
//主键函数
uint64_t primary_key() const {return id;}
//声明序列化宏,第一个参数todo为结构体名称 (id)(description)(completed)为结构体内的对象
EOSLIB_SERIALIZE(todo, (id)(description)(completed))
};
typedef eosio::multi_index todo_table; //声明自定义的多索引容器类型;
todo_table todos;
};
EOSIO_ABI(todo_contract, (create)(complete)(destroy))
备注:“typedef eosio::multi_index
todo_table todos;”声明完成后,可以使用以下功能:
todos.emplace(scope, [&]( auto& g ) { ... }) 添加数据;
todos.find(primary_key) 用关键字查找;
todos.modify(itr, scope, [&]( auto& g ) { ... }) 修改数据;
todos.erase(itr) 删除
todos.begin() 数据起始
todos.end() 数据末尾
二 运行eos客户端,启动私有网络
nodeos -e -p eosio --plugin eosio::wallet_api_plugin --plugin eosio::chain_api_plugin --plugin eosio::account_history_api_plugin
eosio generated block bcc817bc... #637 @ 2018-05-10T09:22:13.000 with 0 trxs, lib: 636
eosio generated block 527d07ae... #638 @ 2018-05-10T09:22:13.500 with 0 trxs, lib: 637
三 编译合约
eosiocpp -o todo.wast todo.cpp && eosiocpp -g todo.abi todo.cpp
In file included from todo.cpp:1:
In file included from /usr/local/include/eosiolib/eosio.hpp:7:
In file included from /usr/local/include/eosiolib/action.hpp:7:
In file included from /usr/local/include/eosiolib/datastream.hpp:9:
In file included from /home/li/opt/boost_1_66_0/include/boost/container/flat_map.hpp:26:
In file included from /home/li/opt/boost_1_66_0/include/boost/container/new_allocator.hpp:24:
/home/li/opt/boost_1_66_0/include/boost/container/throw_exception.hpp:56:21: warning:
address of array 'msg' will always evaluate to 'true'
[-Wpointer-bool-conversion]
BOOST_ASSERT(!msg);
~^~~
/home/li/opt/boost_1_66_0/include/boost/assert.hpp:60:36: note: expanded from
macro 'BOOST_ASSERT'
# define BOOST_ASSERT(expr) assert(expr)
^~~~
/usr/local/include/musl/upstream/include/assert.h:8:28: note: expanded from
macro 'assert'
#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, ...
^
In file included from todo.cpp:1:
In file included from /usr/local/include/eosiolib/eosio.hpp:7:
In file included from /usr/local/include/eosiolib/action.hpp:7:
In file included from /usr/local/include/eosiolib/datastream.hpp:9:
In file included from /home/li/opt/boost_1_66_0/include/boost/container/flat_map.hpp:26:
In file included from /home/li/opt/boost_1_66_0/include/boost/container/new_allocator.hpp:24:
/home/li/opt/boost_1_66_0/include/boost/container/throw_exception.hpp:64:25: warning:
address of array 'msg' will always evaluate to 'true'
[-Wpointer-bool-conversion]
BOOST_ASSERT_MSG(!msg, str);
~^~~
/home/li/opt/boost_1_66_0/include/boost/assert.hpp:61:46: note: expanded from
macro 'BOOST_ASSERT_MSG'
# define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg))
^~~~
/usr/local/include/musl/upstream/include/assert.h:8:28: note: expanded from
macro 'assert'
#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, ...
^
In file included from todo.cpp:1:
In file included from /usr/local/include/eosiolib/eosio.hpp:7:
In file included from /usr/local/include/eosiolib/action.hpp:7:
In file included from /usr/local/include/eosiolib/datastream.hpp:9:
In file included from /home/li/opt/boost_1_66_0/include/boost/container/flat_map.hpp:26:
In file included from /home/li/opt/boost_1_66_0/include/boost/container/new_allocator.hpp:24:
/home/li/opt/boost_1_66_0/include/boost/container/throw_exception.hpp:72:25: warning:
address of array 'msg' will always evaluate to 'true'
[-Wpointer-bool-conversion]
BOOST_ASSERT_MSG(!msg, str);
~^~~
/home/li/opt/boost_1_66_0/include/boost/assert.hpp:61:46: note: expanded from
macro 'BOOST_ASSERT_MSG'
# define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg))
^~~~
/usr/local/include/musl/upstream/include/assert.h:8:28: note: expanded from
macro 'assert'
#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, ...
^
In file included from todo.cpp:1:
In file included from /usr/local/include/eosiolib/eosio.hpp:7:
In file included from /usr/local/include/eosiolib/action.hpp:7:
In file included from /usr/local/include/eosiolib/datastream.hpp:9:
In file included from /home/li/opt/boost_1_66_0/include/boost/container/flat_map.hpp:26:
In file included from /home/li/opt/boost_1_66_0/include/boost/container/new_allocator.hpp:24:
/home/li/opt/boost_1_66_0/include/boost/container/throw_exception.hpp:80:25: warning:
address of array 'msg' will always evaluate to 'true'
[-Wpointer-bool-conversion]
BOOST_ASSERT_MSG(!msg, str);
~^~~
/home/li/opt/boost_1_66_0/include/boost/assert.hpp:61:46: note: expanded from
macro 'BOOST_ASSERT_MSG'
# define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg))
^~~~
/usr/local/include/musl/upstream/include/assert.h:8:28: note: expanded from
macro 'assert'
#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, ...
^
In file included from todo.cpp:1:
In file included from /usr/local/include/eosiolib/eosio.hpp:7:
In file included from /usr/local/include/eosiolib/action.hpp:7:
In file included from /usr/local/include/eosiolib/datastream.hpp:9:
In file included from /home/li/opt/boost_1_66_0/include/boost/container/flat_map.hpp:26:
In file included from /home/li/opt/boost_1_66_0/include/boost/container/new_allocator.hpp:24:
/home/li/opt/boost_1_66_0/include/boost/container/throw_exception.hpp:88:25: warning:
address of array 'msg' will always evaluate to 'true'
[-Wpointer-bool-conversion]
BOOST_ASSERT_MSG(!msg, str);
~^~~
/home/li/opt/boost_1_66_0/include/boost/assert.hpp:61:46: note: expanded from
macro 'BOOST_ASSERT_MSG'
# define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg))
^~~~
/usr/local/include/musl/upstream/include/assert.h:8:28: note: expanded from
macro 'assert'
#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, ...
^
5 warnings generated.
Generated todo.abi ...
四 部署合约
cleos set contract bytemaster ../todo -p bytemaster
Reading WAST...
Assembling WASM...
Publishing contract...
executed transaction: d1713c2589a8fffe5a54b7312dc10aff3b9e45cc74ec8f9556616213a86d7747 4712 bytes 2200576 cycles
# eosio <= eosio::setcode {"account":"bytemaster","vmtype":0,"vmversion":0,"code":"0061736d01000000017e1460047f7e7f7f0060037f7...
# eosio <= eosio::setabi {"account":"bytemaster","abi":{"types":[],"structs":[{"name":"todo","base":"","fields":[{"name":"id"...
注意:
(1)如钱包锁定,请使用命令解锁“ cleos wallet unlock --password 钱包私钥”,不然提示
Error 3030002: signatures do not satisfy declared authorizations
Ensure that you have the related private keys inside your wallet and you wallet is unlocked.
(2)用户用上一章创建的bytemaster,如未创建,参考《使用EOS3.0发行代币》创建用户。(https://www.jianshu.com/p/596593bd308f)
五 调用合约create action
cleos push action bytemaster create '["bytemaster", 1, "hello world Message"]' -p bytemaster
executed transaction: fa3b73feba3475e444be13992403f31161bc39c678f00bdb060ae26e30dce8ff 256 bytes 106496 cycles
# bytemaster <= bytemaster::create {"author":"bytemaster","id":1,"description":"hello world Message"}
>> todo#1 created
获取数据
cleos get table bytemaster bytemaster todos
{
"rows": [{
"id": 1,
"description": "hello world Message",
"completed": 0
}
],
"more": false
}
六 总结
(1)了解多索引容器使用,了解数据增删改
(2)了解智能合约编写结构
(3)巩固智能合约编写发布流程
七 引用
https://steemit.com/eos/@eos-asia/part-2-building-a-to-do-list-with-eos-or-working-with-persistent-data-in-eos 《Part 2: Building a To-do list with EOS》
https://mp.weixin.qq.com/s/QVzKIrhYpw7JdrWe38TEJw 《[EOS智能合约]第二节:用EOS开发一个To-do List小应用》
https://github.com/EOSIO/eos/wiki/Persistence-API 《Persistence-API》
https://eosfans.io/wiki/eosiodb 《EOSIO 3.0 数据库使用指南
》