资讯专栏INFORMATION COLUMN

【许晓笛】EOS 数据库与持久化 API —— 架构

piglei / 2880人阅读

摘要:与数据库交互的被官方称为,中文可以叫做持久化。下图为数据结构。所有对数据的操作必须通过迭代器完成。迭代器会移动到需要的数据对象上。相关文章和视频推荐许晓笛数据库与持久化实战圆方圆学院汇集大批区块链名师,打造精品的区块链技术课程。

EOS 数据库结构详解

在 EOS 中,智能合约执行完毕后,所占用的内存会释放。程序中的所有变量都会丢失。如果智能合约里要持久地记录信息,比如游戏智能合约要记录每位用户游戏记录,本次合约执行完毕后数据不能丢失,就需要将数据存储到 EOS 数据库中。与数据库交互的 API 被官方称为 Persistence API,中文可以叫做持久化 API。下图说明了 EOS 智能合约在执行 Action 时,与数据库的交互过程。

为了方便智能合约与 EOS 数据库的交互,EOS 仿造了 Boost 库中的 Multi-Index Containers,开发了 C++ 类:eosio::multi_index(以下简称 multi_index`),中文可以叫做多索引列表类。

multi_index 头文件地址:
https://github.com/EOSIO/eos/...

在 EOS 见证人硬盘中,为每个账户都预留了数据库空间(大小与代币持有量有关),每个账户名下可以建立多个数据表。智能合约无法直接操作存储在见证人硬盘中的数据表,需要使用multi_index作为中间工具(或者叫容器),每个multi_index实例都与一个特定账户的特定数据表进行交互(取决于实例化时的参数)。EOS智能合约与EOS数据库的数据交互如下图所示。

数据表

multi_index是一个非常方便的数据库交互容器,可以存储任何 C++ 数据类型。每一个multi_index都相当于传统数据库的一个数据表(table),但将传统数据库的行与列的形式改为了单纯的列。也就是说multi_index是一个线性排列的表,只有一列,每一行都只存储一个对象。但是一般来说multi_index存储的对象都是结构体或者类,里面含有多个成员变量,所以multi_index存储数据的灵活性也是不亚于传统数据库的。

我们使用官方的“汽车维修店”示例,我们建立一个数据表,储存每个汽车维修店客户的账户名、保养时间、车辆里程。那么multi_index数据表储存的项目中,每个都是如下的结构体:

struct service_rec {
    uint64_t        pkey;           // 主键
    account_name    customer;       // 车主用户名
    uint32_t        service_date;   // 维修保养时间
    uint32_t        odometer;       // 车辆里程
};

在传统数据库中,需要建立一个 4 列的数据表,用来储存每个用户的这个 4 个数据,而multi_index的每个数据表只有一列,只存储每个用户的 service_rec 整个结构体即可。下图为multi_index数据结构。

多索引

首先,每个数据表要有一组主键,主键必须是无符号 64 位整数类型(64-bit integer),这就是上面的service_rec结构体中第一个变量为uint64_t类型的原因。在数据表中,所有的对象就是按照主键升序排列的,小的在前,大的在后。主键可以是有意义的,也可以是没有意义的,让系统产生一个在这个数据表中没有被使用的主键即可。为了设置主键,我们需要在之前的service_rec结构体添加一个叫做primary_key()的成员函数函数的返回值为主键。

    auto    primary_key()const { return pkey; }

这样就将pkey这个变量设置成了主键。

multi_index从字面上看就是能使用多个索引的数据表。EOS 中,每个multi_index或者说每个数据表都可以设置最多16个索引。索引相当于使用特定的方式给数据表中的对象重新排序。比如在我们经常使用的 windows 文件管理器中,可以按照文件名排序、按照文件修改时间排序、按照文件大小排序,这就有了3个索引。EOS 数据库索引更加灵活,可以多带带按照结构体中的某个变量索引,也可以将变量之间的运算结果(函数输出)进行索引。如果我们想使用车主用户名进行索引,需要在结构体中添加一个get_customer()成员函数,函数的返回值为索引变量。

account_name    get_customer()const { return customer; }

这样就将customer这个变量设置成了数据表的一个索引,下图右侧为customer索引。

迭代器

multi_index是如何操作数据表中的每个对象的呢?答案是 Iterators(迭代器)。大家可以搜索 “C++ 迭代器”或者设计模式中的“迭代器模式”来了解迭代器的设计思路。在 EOS 数据库中,我更愿意将迭代器比喻为一个“电梯”,在整个数据表中上下穿梭。所有对数据的操作必须通过迭代器完成。典型的数据修改过程是这样的:首先使用迭代器的find()方法,在特定的索引中寻找需要的数据,比如在车主用户名索引中寻找某个用户。迭代器会移动到需要的数据对象上。然后就可以使用迭代器的modify()方法修改当前迭代器对应的数据。下图为迭代器指向用户 Sue 的情况。

本篇文章介绍了 EOS 数据库的基本结构,以后的文章会详细介绍 EOS 数据库使用实战,敬请期待。


相关文章和视频推荐

【许晓笛】EOS 数据库与持久化 API —— 实战

圆方圆学院汇集大批区块链名师,打造精品的区块链技术课程。 在各大平台都长期有优质免费公开课,欢迎报名收看。
公开课地址:https://ke.qq.com/course/345101     

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/24412.html

相关文章

  • 晓笛EOS 据库久化 API —— 实战

    摘要:查询数据使用方法和其他迭代器操作查询数据。数据库服务的对象是维修技师和车主。如果查找成功,迭代器就会指向所需的数据对象。 EOS 数据库开发实战 上次的文章详细讲解了 EOS 数据库的架构,本文将以官方示例为基础,详解 EOS 数据库的开发实战。 基本步骤 在智能合约里与 EOS 数据库交互,首先要定义存储的数据: 定义对象:具体就是定义一个 C++ 类或者 C++ 结构体,数据表...

    yck 评论0 收藏0
  • 晓笛EOS 系统架构图解

    摘要:了解系统架构之前我们先看看目前系统的主要组成部分系统的核心进程,也就是所谓的节点。 其实没有那么复杂 相信关心 EOS 系统的同学肯定见过下面这张蓝图。对,目前只是一个蓝图,而且以 BM 的尿性,肯定在心理已经把这张图改的面目全非了(比如图中的 eosd 早就改名了)。所以这张图只能作为未来 EOS 发展方向的参考而已,目前的 EOS 还远没有这么复杂和完善。 showImg(http...

    vibiu 评论0 收藏0
  • 晓笛】听说你买了EOS ,连代码什么样都不知道?

    摘要:说点题外话如果你想提高英语的话,持有一点代币吧,你会急于搞清楚白皮书在讲什么,要是想短时间快速提高英语,持有大量代币吧,别问我是怎么知道的。 最近发现很多人投资了EOS,却并不关心 EOS 目前的开发进度和技术细节,如果你投资了 EOS, 还有一定的技术基础,那就更应该关心 EOS 的开发情况了,下面我们就从 EOS 的源代码说起: Github 是目前最流行的源码管理网站,无数明星项...

    imccl 评论0 收藏0
  • 晓笛】重新理解EOS的系统架构

    摘要:所以想要实现真正实用的智能合约平台,就要脱离比特币系统的架构,寻找新的系统组织形式。比特币和以太坊之所以设计了手续费机制,就是防止大量垃圾交易使得系统拥堵。 区块链系统中,去中心化程度与效率之间天然地存在矛盾关系。 如果区块链智能合约系统想追求类似比特币的去中心化程度,理论上效率就会大打折扣。现实也是这样的:比特币每秒钟只能处理7笔左右的交易,每一笔交易要用至少30分钟才能确认,这种效...

    Alan 评论0 收藏0
  • 晓笛】49行代码就能发币?而且EOS连例子都给你了

    摘要:相关文章和视频推荐许晓笛智能合约案例解析圆方圆学院汇集大批区块链名师,打造精品的区块链技术课程。 Daniel Larimer 在他的博客介绍了EOS新的智能合约架构(EOS团队的开发速度实在是太吓人,根本追不上)。他给出了最简单的一个新币种的智能合约代码,仅有49行就能完成一个新币种的开发,一个新的爱息欧就诞生了。让我们一步一步实现吧。 首先实现私有成员,建立一个 account 结...

    Freeman 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<