前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >EOS技术研究:合约与数据库交互

EOS技术研究:合约与数据库交互

作者头像
文彬
发布2018-06-07 14:42:00
7930
发布2018-06-07 14:42:00
举报
文章被收录于专栏:醒者呆醒者呆

智能合约操作链数据库是很常见的应用场景。EOS提供了专门的工具来做这件事(相当于Ethereum的leveldb),专业术语叫做持久化API,本文将完整严密地介绍这个工具以及对它的使用测试。

关键字:EOS,智能合约,链数据库,eosio::multi_index,emplace,erase,find。

需求

首先来看EOS中智能合约涉及到持久化的场景需求。一个action在执行时会有上下文变量出现,包括事务机制的处理,这些内容会应用链上分配的内存资源,而如果没有持久化技术,执行超过作用域时就会丢失掉这些上下文数据。因此要使用持久化技术将关键内容记录在链数据库中,任何时候使用都不受影响。持久化技术应该包括:

  • 记录一些状态持久化到数据库中
  • 具备查询的能力从数据库中获取内容
  • 提供C++ 的API来调用这些服务,也服务于合约开发者

eosio::multi_index

这是模仿boost::multi_index开发的一套库。它使用C++编写,提供了合约与数据库的交互持久化接口。

Multi-Index Iterators:不同于其他key-value数据库,multi_index提供了不同类型的key对应的值也是可迭代的复杂集合类型。

创建表

  • class/struct 定义一个持久化对象。
  • 该对象需要有一个const的成员作为主键,类型为uint64_t
  • 二级主键可选,提供不同的键类型
  • 为每个二级索引定义一个键导出器,键导出器是一个函数,可以用来从Multi_index表中获取键

使用Multi-Index表

一般来讲,对数据库的操作无外乎增删改查,

  • 增加对应的方法是emplace
  • 修改就是modify
  • 删除是erase
  • 查找包括find和get,以及迭代器操作

实战

下面我们通过一个智能合约操作底层数据库的实例,来演示对持久化api,multi_index的使用。过程中,也会展示相应api的定义。

车辆维修跟踪

首先,创建一个service表,用来创建服务记录报告,它包含的字段有:

  • 主键,客户ID不可当做主键,因为一个客户可以有多条记录。实际上,我们并不直接需要主键,所以我们可以让系统为我们生成一个。
  • 客户ID,与账户名字对应
  • 服务日期
  • 里程表,汽车里程表
代码语言:javascript
复制
#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        service_date;
        uint32_t        odometer;

        auto primary_key() const { return pkey; }

        account_name get_customer() const { return customer; }

        EOSLIB_SERIALIZE(service_rec, (pkey)(customer)(service_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) {
        print("Hello, ", name{customer});
        service_table_type service_table(current_receiver(), owner);// 构造器,第一个参数是code代表表的拥有者,目前是current_receiver(),也可以使用contract基类的构造器初始化时的账户名_self,第二个参数是scope,在代码层次范围的标识符,这里就使用传入的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.service_date = 2000;
            s_rec.odometer = 1000;
        });
        service_rec result = service_table.get(pkeyf);
        print("_", result.pkey);
        print("_", result.customer);
        print("_", result.service_date);
        print("_", result.odometer);
    }

};

EOSIO_ABI(vehicle, (exec))

使用eosiocpp工具生成abi文件和wast文件。

代码语言:javascript
复制
eosiocpp -g vehicle.abi vehicle.cpp | eosiocpp -o vehicle.wasm vehicle.cpp

然后在终端中部署该合约,

代码语言:javascript
复制
cleos set contract one work/CLionProjects/github.com/eos/contracts/vehicle 

调用合约的exec方法,并输出结果:

代码语言:javascript
复制
liuwenbin@liuwenbin-H81M-DS2:~$ cleos push action one exec '["one","two"]' -p one
executed transaction: 3a45eaeb06732ad0c53ba7b157003e1c503f74ed447029d82cecbe12926cc9a9  112 bytes  365 us
#           one <= one::exec                    {"owner":"one","customer":"two"}
>> Hello, two13_13_14927180964919508992_2000_1000
warning: transaction executed locally, but may not be confirmed by the network yet

通过输出结果,可以知道主键为13,customer账户名被转为无符号32位整型数据14927180964919508992,服务时间为2000,里程表为1000。我们已经成功将数据存入了multi_index并取了出来。

删除的话可以通过service_table.erase(result);来删除掉对应记录。

find涉及二级索引,迭代器等操作,end判断等multi_index的api操作没有给出具体实例,未来在其他合约使用时会直接说明。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-05-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求
  • eosio::multi_index
    • 创建表
      • 使用Multi-Index表
      • 实战
        • 车辆维修跟踪
        相关产品与服务
        数据库
        云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档