• EOS 数据库与持久化 API —— 架构


    在 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/blob/master/contracts/eosiolib/multi_index.hpp

    在 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 的情况。

    转自:https://blog.csdn.net/yuanfangyuan_block/article/details/80403360

    总会有不期而遇的温暖. 和生生不息的希望。
  • 相关阅读:
    VS2008编写MFC程序--使用opencv2.4()
    November 02nd, 2017 Week 44th Thursday
    November 01st, 2017 Week 44th Wednesday
    October 31st, 2017 Week 44th Tuesday
    October 30th, 2017 Week 44th Monday
    October 29th, 2017 Week 44th Sunday
    October 28th, 2017 Week 43rd Saturday
    October 27th, 2017 Week 43rd Friday
    October 26th, 2017 Week 43rd Thursday
    October 25th, 2017 Week 43rd Wednesday
  • 原文地址:https://www.cnblogs.com/devi1/p/13486423.html
Copyright © 2020-2023  润新知