【許曉笛】EOS 數(shù)據(jù)庫與持久化 API —— 架構(gòu)

EOS 數(shù)據(jù)庫結(jié)構(gòu)詳解

在 EOS 中娜睛,智能合約執(zhí)行完畢后,所占用的內(nèi)存會(huì)釋放卦睹。程序中的所有變量都會(huì)丟失畦戒。如果智能合約里要持久地記錄信息,比如游戲智能合約要記錄每位用戶游戲記錄结序,本次合約執(zhí)行完畢后數(shù)據(jù)不能丟失障斋,就需要將數(shù)據(jù)存儲(chǔ)到 EOS 數(shù)據(jù)庫中。與數(shù)據(jù)庫交互的 API 被官方成為 Persistence API笼痹,中文可以叫做持久化 API。下圖說明了 EOS 智能合約在執(zhí)行 Action 時(shí)酪穿,與數(shù)據(jù)庫的交互過程凳干。

為了方便智能合約與 EOS 數(shù)據(jù)庫的交互,EOS 仿造了 Boost 庫中的 Multi-Index Containers被济,開發(fā)了 C++ 類:1eosio::multi_index(以下簡稱multi_index`)救赐,中文可以叫做多索引列表類。

multi_index 頭文件地址:
https://github.com/EOSIO/eos/blob/master/contracts/eosiolib/multi_index.hpp

在 EOS 見證人硬盤中只磷,為每個(gè)賬戶都預(yù)留了數(shù)據(jù)庫空間(大小與代幣持有量有關(guān))经磅,每個(gè)賬戶名下可以建立多個(gè)數(shù)據(jù)表。智能合約無法直接操作存儲(chǔ)在見證人硬盤中的數(shù)據(jù)表钮追,需要使用multi_index作為中間工具(或者叫容器)预厌,每個(gè)multi_index實(shí)例都與一個(gè)特定賬戶的特定數(shù)據(jù)表進(jìn)行交互(取決于實(shí)例化時(shí)的參數(shù))。EOS智能合約與EOS數(shù)據(jù)庫的數(shù)據(jù)交互如下圖所示元媚。

數(shù)據(jù)表

multi_index是一個(gè)非常方便的數(shù)據(jù)庫交互容器轧叽,可以存儲(chǔ)任何 C++ 數(shù)據(jù)類型。每一個(gè)multi_index都相當(dāng)于傳統(tǒng)數(shù)據(jù)庫的一個(gè)數(shù)據(jù)表(table)刊棕,但將傳統(tǒng)數(shù)據(jù)庫的行與列的形式改為了單純的列炭晒。也就是說multi_index是一個(gè)線性排列的表,只有一列甥角,每一行都只存儲(chǔ)一個(gè)對象网严。但是一般來說multi_index存儲(chǔ)的對象都是結(jié)構(gòu)體或者類,里面含有多個(gè)成員變量嗤无,所以multi_index存儲(chǔ)數(shù)據(jù)的靈活性也是不亞于傳統(tǒng)數(shù)據(jù)庫的震束。

我們使用官方的“汽車維修店”示例怜庸,我們建立一個(gè)數(shù)據(jù)表,儲(chǔ)存每個(gè)汽車維修店客戶的賬戶名驴一、保養(yǎng)時(shí)間休雌、車輛里程。那么multi_index數(shù)據(jù)表儲(chǔ)存的項(xiàng)目中肝断,每個(gè)都是如下的結(jié)構(gòu)體:

struct service_rec {
    uint64_t        pkey;           // 主鍵
    account_name    customer;       // 車主用戶名
    uint32_t        service_date;   // 維修保養(yǎng)時(shí)間
    uint32_t        odometer;       // 車輛里程
};

在傳統(tǒng)數(shù)據(jù)庫中杈曲,需要建立一個(gè) 4 列的數(shù)據(jù)表,用來儲(chǔ)存每個(gè)用戶的這個(gè) 4 個(gè)數(shù)據(jù)胸懈,而multi_index的每個(gè)數(shù)據(jù)表只有一列担扑,只存儲(chǔ)每個(gè)用戶的 service_rec 整個(gè)結(jié)構(gòu)體即可。下圖為multi_index數(shù)據(jù)結(jié)構(gòu)趣钱。

多索引

首先涌献,每個(gè)數(shù)據(jù)表要有一組主鍵,主鍵必須是無符號 64 位整數(shù)類型(64-bit integer)首有,這就是上面的service_rec結(jié)構(gòu)體中第一個(gè)變量為uint64_t類型的原因燕垃。在數(shù)據(jù)表中,所有的對象就是按照主鍵升序排列的井联,小的在前卜壕,大的在后。主鍵可以是有意義的烙常,也可以是沒有意義的轴捎,讓系統(tǒng)產(chǎn)生一個(gè)在這個(gè)數(shù)據(jù)表中沒有被使用的主鍵即可。為了設(shè)置主鍵蚕脏,我們需要在之前的service_rec結(jié)構(gòu)體添加一個(gè)叫做primary_key()的成員函數(shù)函數(shù)的返回值為主鍵侦副。

    auto    primary_key()const { return pkey; }

這樣就將pkey這個(gè)變量設(shè)置成了主鍵。

multi_index從字面上看就是能使用多個(gè)索引的數(shù)據(jù)表驼鞭。EOS 中秦驯,每個(gè)multi_index或者說每個(gè)數(shù)據(jù)表都可以設(shè)置最多16個(gè)索引。索引相當(dāng)于使用特定的方式給數(shù)據(jù)表中的對象重新排序挣棕。比如在我們經(jīng)常使用的 windows 文件管理器中汇竭,可以按照文件名排序、按照文件修改時(shí)間排序穴张、按照文件大小排序细燎,這就有了3個(gè)索引。EOS 數(shù)據(jù)庫索引更加靈活皂甘,可以單獨(dú)按照結(jié)構(gòu)體中的某個(gè)變量索引玻驻,也可以將變量之間的運(yùn)算結(jié)果(函數(shù)輸出)進(jìn)行索引。如果我們想使用車主用戶名進(jìn)行索引,需要在結(jié)構(gòu)體中添加一個(gè)get_customer()成員函數(shù)璧瞬,函數(shù)的返回值為索引變量户辫。

account_name    get_customer()const { return customer; }

這樣就將customer這個(gè)變量設(shè)置成了數(shù)據(jù)表的一個(gè)索引,下圖右側(cè)為customer索引嗤锉。

迭代器

multi_index是如何操作數(shù)據(jù)表中的每個(gè)對象的呢渔欢?答案是 Iterators(迭代器)。大家可以搜索 “C++ 迭代器”或者設(shè)計(jì)模式中的“迭代器模式”來了解迭代器的設(shè)計(jì)思路瘟忱。在 EOS 數(shù)據(jù)庫中奥额,我更愿意將迭代器比喻為一個(gè)“電梯”,在整個(gè)數(shù)據(jù)表中上下穿梭访诱。所有對數(shù)據(jù)的操作必須通過迭代器完成垫挨。典型的數(shù)據(jù)修改過程是這樣的:首先使用迭代器的find()方法,在特定的索引中尋找需要的數(shù)據(jù)触菜,比如在車主用戶名索引中尋找某個(gè)用戶九榔。迭代器會(huì)移動(dòng)到需要的數(shù)據(jù)對象上。然后就可以使用迭代器的modify()方法修改當(dāng)前迭代器對應(yīng)的數(shù)據(jù)涡相。下圖為迭代器指向用戶 Sue 的情況哲泊。

本篇文章介紹了 EOS 數(shù)據(jù)庫的基本結(jié)構(gòu),以后的文章會(huì)詳細(xì)介紹 EOS 數(shù)據(jù)庫使用實(shí)戰(zhàn)催蝗,敬請期待切威。


相關(guān)文章和視頻推薦

【許曉笛】EOS 數(shù)據(jù)庫與持久化 API —— 實(shí)戰(zhàn)

圓方圓學(xué)院匯集大批區(qū)塊鏈名師,打造精品的區(qū)塊鏈技術(shù)課程生逸。 在各大平臺(tái)都長期有優(yōu)質(zhì)免費(fèi)公開課牢屋,歡迎報(bào)名收看且预。
公開課地址:https://ke.qq.com/course/345101

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末槽袄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子锋谐,更是在濱河造成了極大的恐慌遍尺,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涮拗,死亡現(xiàn)場離奇詭異乾戏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)三热,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門鼓择,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人就漾,你說我怎么就攤上這事呐能。” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵摆出,是天一觀的道長朗徊。 經(jīng)常有香客問我,道長偎漫,這世上最難降的妖魔是什么爷恳? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮象踊,結(jié)果婚禮上温亲,老公的妹妹穿的比我還像新娘。我一直安慰自己通危,他們只是感情好铸豁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著菊碟,像睡著了一般节芥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上逆害,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天头镊,我揣著相機(jī)與錄音,去河邊找鬼魄幕。 笑死相艇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纯陨。 我是一名探鬼主播坛芽,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼翼抠!你這毒婦竟也來了咙轩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤阴颖,失蹤者是張志新(化名)和其女友劉穎活喊,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體量愧,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钾菊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了偎肃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片煞烫。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖累颂,靈堂內(nèi)的尸體忽然破棺而出滞详,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布茵宪,位于F島的核電站最冰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏稀火。R本人自食惡果不足惜暖哨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凰狞。 院中可真熱鬧篇裁,春花似錦、人聲如沸赡若。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽逾冬。三九已至黍聂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間身腻,已是汗流浹背产还。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嘀趟,地道東北人脐区。 一個(gè)月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像她按,于是被迫代替她去往敵國和親牛隅。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容