2018-05-18

前几天翻译了一篇关于EOS智能合约数据库的内容,今天来演示一下数据库的使用方法。

目录

新增

新增内容往往用到emplace构造函数,来进行数据库对象的新增。

.cpp

void test_da::create(account_name user, string title, string content)

    {

        require_auth( user ); //验证权限

        das datable( _self, user); //定义数据库对象

        datable.emplace(user, [&]( da & d){

            d.title = title;

            d.content = content;

            d.post_id = datable.available_primary_key();

            d.poster = user;

        }); //数据库内容创建

    }

这里需要注意的是:

定义数据库对象, 其中第一个参数是合约的拥有者_self,第二个变量就是数据库的payer,也就是数据库是谁的,数据库存储在谁的账户下。

emplace函数接收两个参数,一个payer,和一个lamada表达式。这个结构是固定的。

那么我们现在来看一下我们的test_da类是怎么定义的。

.hpp

class test_da : public contract {

    public:

          test_da( account_name self ):contract(self){}

          // @abi action

          void create(account_name user, string title, string content);

    private:

          // @abi table data i64

          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> > das;

  };

} /// namespace eosio

所有的智能合约都继承自contract合约。`test_da( account_name self ):contract(self){}

是test_da`合约的构造函数。

下面是对create函数的声明。

接下来是对数据字段的定义。这里我们定义了数据结构da.

primary_key函数是定义主键的函数。

接下来我们定义了辅助主键返回poster。

EOSLIB_SERIALIZE宏的第一个参数是数据结构,其他参数是数据结构中的数据成员。

typedef我们在这里定义了一个名字为das的类型,它用来定义数据库对象。这里我们定义的是一个具有主键及一个辅助键的数据库对象。

.abi

abi 非常重要,错误的abi会导致合约执行失败。

{

  "types": [],

  "structs": [{

      "name": "da",

      "base": "",

      "fields": [{

          "name": "post_id",

          "type": "uint64"

        },{

          "name": "poster",

          "type": "account_name"

        },{

          "name": "title",

          "type": "string"

        },{

          "name": "content",

          "type": "string"

        }

      ]

    },{

      "name": "create",

      "base": "",

      "fields": [{

          "name": "user",

          "type": "account_name"

        },{

          "name": "title",

          "type": "string"

        },{

          "name": "content",

          "type": "string"

        }

      ]

    }}

  ],

  "actions": [{

          "name": "create",

          "type": "create",

        }

  ],

  "tables": [{

      "name": "data",

      "index_type": "i64",

      "key_names": [

        "post_id"

      ],

      "key_types": [

        "uint64"

      ],

      "type": "da"

    }

  ],

  "ricardian_clauses": []

}

接下来来演示一下:

发布合约

cleos set contract eosio test_da   

Reading WAST/WASM from test_da/test_da.wasm...

Using already assembled WASM...

Publishing contract...

executed transaction: 3d6f04278617d3807fe876a33057f1155acf9c9e5a392ac6ed8ad51e79506009  6752 bytes  24679 us

#        eosio <= eosio::setcode              {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d0100000001ad011a60037f7e7e0060057f7e7e7f...

#        eosio <= eosio::setabi                {"account":"eosio","abi":{"types":[],"structs":[{"name":"da","base":"","fields":[{"name":"post_id","...

创建数据

cleos push action eosio create '{"user":"eosio","title":"first","content":"create a first one"}' -p eosio

executed transaction: 830057f270fa499b1d61b82e80ad8cda1774cdc1786c1e786f558a3e0a48974c  216 bytes  17229 us

#        eosio <= eosio::create                {"user":"eosio","title":"first","content":"create a first one"}

下面我们来查一下数据表:

cleos get table eosio eosio data

{

  "rows": [{

      "post_id": 0,

      "poster": "eosio",

      "title": "first",

      "content": "create a first one"

    }

  ],

  "more": false

}

创建信息成功,那么我们用别的账号创建会怎样呢?

cleos push action eosio create '{"user":"eostea","title":"eostea first","content":"eostea create a first one"}' -p eostea

executed transaction: 8542a87e563a9c62b7dbe46ae09ccf829c7821f8879167066b658096718de148  232 bytes  2243 us

#        eosio <= eosio::create                {"user":"eostea","title":"eostea first","content":"eostea create a first one"}

查看数据表:

cleos get table eosio eostea data

{

  "rows": [{

      "post_id": 0,

      "poster": "eostea",

      "title": "eostea first",

      "content": "eostea create a first one"

    }

  ],

  "more": false

}

到这里,相信大家对创建数据已经没有什么疑惑了。

查询

对于数据库,最重要的功能就是查询,如果没有查询功能,数据库里的数据就不能呈现,也就没有意义。查询数据库主要分为两方面,一方面是主键查询,一方面是通过二级索引查询。

这里为了使表中数据多样化我会做一些修改,将所有数据都合到一张表中。

我将以上.cpp中的das datable( _self, user);改为das datable( _self, _self);.这样数据都存在合约账户的表中。

主键查询

这里我添加了一个方法来查询数据并打印:

void test_da::getd(uint64_t post_id){

        das 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());

    }

abi文件也做了相应的调整:

执行:

cleos push action eosio getd '{"post_id":1}' -p eosio

executed transaction: ac8663235462d947c74542af848cca54a059c3991d193237025da7d4767d6725  192 bytes  1724 us

#        eosio <= eosio::getd                  {"post_id":1}

>> Post_id: 1  Post_Tile: first Content: eosio create a first one

二级索引查询

添加二级索引查询代码如下:

auto poster_index = datable.template get_index();

auto pos = poster_index.find( user );

for (; pos != poster_index.end(); pos++)

{

    eosio::print("content:", pos->content.c_str(), " post_id:", pos->post_id, " title:", pos->title.c_str());

}

获取二级索引并获取数据,这里我只用了find查询,其他查询就不在一一介绍。

执行getd操作:

cleos push action eosio getd '{"post_id":2,"user": "eostea"}' -p eosio

executed transaction: 2370e1fb1ee8a581f7321f02fb40645e51269e579d183c33ef470dba0b3afdbc  200 bytes  5403 us

#        eosio <= eosio::getd                  {"post_id":2,"user":"eostea"}

>> Post_id: 2  Post_Tile: eostea first Content: eostea create a first onecontent:eostea create a first one post_id:2 title:eostea first

数据库中数据如下:

cleos get table eosio eosio data

{

"rows": [{

    "post_id": 0,

    "poster": "eosio",

    "title": "first",

    "content": "eostea create a first one"

  },{

    "post_id": 1,

    "poster": "eosio",

    "title": "first",

    "content": "eostea create a first one"

  },{

    "post_id": 2,

    "poster": "eostea",

    "title": "eostea first",

    "content": "eostea create a first one"

  }

],

"more": false

}

更改

更改数据库内容。

这里我们先看一下目前的数据库内容。

cleos get table eosio eosio data

{

"rows": [{

    "post_id": 0,

    "poster": "eosio",

    "title": "first",

    "content": "eostea create a first one"

  },{

    "post_id": 1,

    "poster": "eosio",

    "title": "first",

    "content": "eostea create a first one"

  },{

    "post_id": 2,

    "poster": "eostea",

    "title": "eostea first",

    "content": "eostea create a first one"

  }

],

"more": false

}

写一个更改数据的action代码如下:

void test_da::change(account_name user, uint64_t post_id, string title, string content)

    {

        require_auth(user);

        das datable( _self, user);

        auto post = datable.find(post_id);

        eosio_assert(post->poster == user, "yonghucuowu");

        datable.modify(post, user, [&](auto& p){

            if (title != "")

                p.title = title;

            if (content != "")

                p.content = content;

        });

    }

1. 前几行代码已经之前讲解过,现在直接说modify方法,他的第一个参数是你查询出的要更改的对象,第二个参数是payer,其他的不用多说。

下面我们执行一下命令:

cleos push action eosio change '{"user":"eosio","post_id":1,"title":"change","content":"change action"}' -p eosio

executed transaction: 8cb561a712f2741560118651aefd49efd161e3d73c56f6d24cf1d699c265e2dc  224 bytes  2130 us

#        eosio <= eosio::change                {"user":"eosio","post_id":1,"title":"change","content":"change action"}

下面我们看一下数据库:

cleos get table eosio eosio data

{

  "rows": [{

      "post_id": 0,

      "poster": "eosio",

      "title": "first",

      "content": "eostea create a first one"

    },{

      "post_id": 1,

      "poster": "eosio",

      "title": "change",

      "content": "change action"

    },{

      "post_id": 2,

      "poster": "eostea",

      "title": "eostea first",

      "content": "eostea create a first one"

    }

  ],

  "more": false

}

post_id=1的记录已经被改变,说明我们成功了。

删除数据

删除数据我又加了一个action,如下所示:

void test_da::dele(account_name user, uint64_t post_id)

    {

        require_auth(user);

        das datable( _self, user);

        auto post = datable.find(post_id);

        eosio::print(post->title.c_str());

        eosio_assert(post->poster == user, "yonghucuowu");

        datable.erase(post);

    }

这里调用了erase方法删除数据,参数为一个数据对象。下面我们来看一下执行结果:

cleos push action eosio dele '{"user":"eosio","post_id":1}' -p eosioexecuted transaction: 3affbbbbd1da328ddcf37753f1f2f6c5ecc36cd81a0e12fea0c789e75b59714e  200 bytes  2383 us

#        eosio <= eosio::dele                  {"user":"eosio","post_id":1}

现在再来看一下我们的数据库:

cleos get table eosio eosio data

{

  "rows": [{

      "post_id": 0,

      "poster": "eosio",

      "title": "first",

      "content": "eostea create a first one"

    },{

      "post_id": 2,

      "poster": "eostea",

      "title": "eostea first",

      "content": "eostea create a first one"

    }

  ],

  "more": false

}

post_id=1的数据已经被我们删除。

到这里,数据库的增删改查已经讲解完毕。

本文内容为原创内容,如需转载请联系作者。谢谢!!!

原文链接: https://eosfans.io/topics/484深度强化学习在指代消解中的一种尝试-博客-云栖社区-阿里云

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

推荐阅读更多精彩内容

  • 清宫绘本《昇平樂事圖册》十二开,18.5×24.3厘米。台北故宫博物院藏。 《昇平樂事圖》共計十二開...
    江南跛叟阅读 1,796评论 0 1
  • 学理财首先应该先学的是省钱!你没有多下来的钱怎么理财都是空的。 生活中有很多省钱的方法,不是需要我们全部做到,如果...
    赢在青年阅读 693评论 0 1
  • 孩子,看着照片上你两岁小身板上刮痧的印痕,爸爸和妈妈都心痛的睡不着觉,无奈我们都不在你身边。闭上眼就听见你疼痛的...
    爱吃火锅的茶叶蛋阅读 177评论 0 2
  • 我们原生开发的应用需要集成另一个公司的一个项目进来,集成的过程中遇到不少问题,在此记录总结一下: 官方的集成方法 ...
    木子小易呀阅读 1,805评论 0 0
  • 没有快乐,也没有悲伤,平静如水,很想活在只属于我的世界,没有你我没有他,就没有心痛的复使,前世欠的债,又何以还的清...
    大白糖宝阅读 234评论 0 9