基于EOS3.0实现todolist上篇-智能合约

环境 ubuntu16.04 64位

一 编写todolist的合约代码

mkdir todo
vim todo.cpp 输入以下合约内容

#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
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<N(todos), todo> todo_table; //声明自定义的多索引容器类型; 
    todo_table todos;
};

EOSIO_ABI(todo_contract, (create)(complete)(destroy))

备注:“typedef eosio::multi_index<N(todos), todo> todo_table; //声明自定义的多索引容器类型;
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 数据库使用指南

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容