EOS入門指南PART6——別忙著開發(fā)旺隙,先來看看智能合約數(shù)據(jù)是怎么存的

上一章我們學(xué)習(xí)了開發(fā)智能合約之前需要知道的必要概念:

  • 什么是webAssembly以及它在智能合約上下游中的位置邮弹;
  • 什么是ABI以及怎樣使用eosiocpp工具產(chǎn)生ABI和wasm弯洗、wast
  • hello智能合約的簡單入門:部署和調(diào)用

如果說智能合約開發(fā)是一個鎖著門的圖書館耳标,那么之前的學(xué)習(xí)就是鑰匙〕冢現(xiàn)在我們終于可以拿著鑰匙打開大門胜嗓,走進去一探究竟。

摘要

說到智能合約開發(fā)钩乍,大家首先想到的肯定是寫代碼辞州、像solidity開發(fā)一樣教語法。EOS的智能合約是用C++寫的寥粹,基本語法大家可以去買本C++的書变过;這一篇主要介紹EOS智能合約的數(shù)據(jù)存儲,為大家掃清智能合約開發(fā)道路上的最后一道障礙涝涤。

什么是RAM

之前我們在學(xué)習(xí)如何在主網(wǎng)創(chuàng)建賬戶時媚狰,曾經(jīng)接觸到RAM的概念。我們不能像操作以太坊那樣阔拳,憑空生成一個地址作為自己的賬戶崭孤,而是要先有一個賬戶,再去創(chuàng)建另一個賬戶糊肠。其中就涉及到一個關(guān)于RAM很關(guān)鍵的知識點:創(chuàng)建賬戶需要消耗RAM辨宠。

當(dāng)時我們只是很模糊地知道,RAM大概是內(nèi)存的意思货裹。

RAM is used to store data in an in-memory database. DApps will use this to store state information so it is quickly available to their app.

RAM是EOS主網(wǎng)中的內(nèi)存嗤形,用于存儲用戶在EOS中使用頻率高的數(shù)據(jù)(賬戶余額、合約狀態(tài)等)弧圆。

BM對EOS的期望是成為區(qū)塊鏈世界中的【操作系統(tǒng)】赋兵,因此可以把計算機的一些概念對標到EOS中笔咽,其中計算機中的運行內(nèi)存,在EOS中就可以看做是RAM霹期;而硬盤就可以對標EOS區(qū)塊鏈數(shù)據(jù)庫叶组。

所以高訪問量的決策類數(shù)據(jù),例如賬戶余額经伙、智能合約的當(dāng)前狀態(tài)等就會被存儲在RAM中扶叉,并且這部分數(shù)據(jù)將長期占用RAM;而低訪問的費決策性存證數(shù)據(jù)帕膜,例如交易數(shù)據(jù)枣氧,就會存儲在EOS系統(tǒng)的硬盤中,也就是區(qū)塊鏈中垮刹。當(dāng)存儲賬號狀態(tài)的空間不足达吞,即RAM不足時,轉(zhuǎn)賬或部署合約等相關(guān)操作就無法執(zhí)行荒典。

什么是EOS數(shù)據(jù)庫

之前我們曾經(jīng)介紹過transaction和action酪劫,action是智能合約執(zhí)行的基本單元,transaction可以認為是一個或幾個action組成的原子性操作寺董。action在被稱為action上下文的環(huán)境中執(zhí)行覆糟,action上下文提供了執(zhí)行action所需的一些條件,其中一個就是action的工作內(nèi)存遮咖,這是action保存工作狀態(tài)的地方滩字。在處理一個action之前,eosio會先為它清理一次內(nèi)存御吞,因此當(dāng)變量在一個action中被賦值后麦箍,另一個action的上下文是拿不到這個值的。那么在action之間傳遞狀態(tài)的唯一方法就是把它持久存儲到EOS數(shù)據(jù)庫中陶珠,如下圖:

action_and_database

這個持久化存儲就是數(shù)據(jù)庫存儲數(shù)據(jù)挟裂。EOS允許智能合約定義自己的私有數(shù)據(jù)庫表。比如上圖揍诽,Apply Context的內(nèi)容都是一次性的诀蓉,一次action執(zhí)行完成,對象就釋放了,只有存儲到EOSIO database的才被保存暑脆。

什么是multi_index

接著上面介紹的數(shù)據(jù)庫往下說交排, 這個私有數(shù)據(jù)表是通過multi_index來訪問和交互的。EOS的multi_index類似boost的multi_index饵筑,即多索引容器。有了多級索引处坪,智能合約就具備了操作類似數(shù)據(jù)庫模塊的功能根资。

multi_index是一個非常方便的架专、可以和數(shù)據(jù)庫交互的容器。

從字面意思來看玄帕,multi_index就是一個可以使用多索引的數(shù)據(jù)表部脚。

如下圖:

multi_index

每一個multi_index容器都可以理解成傳統(tǒng)數(shù)據(jù)庫中的一張表,但是行和列稍有不同裤纹。和傳統(tǒng)的多列的表不同的是委刘,multi_index只有一列。這一列中的每一行都表示一個對象鹰椒,通常這個對象是struct或者是class類型的锡移,有多個成員變量。因此雖然只有一列漆际,但是multi_index的靈活性絲毫不亞于傳統(tǒng)的數(shù)據(jù)表淆珊。

舉個例子,比如下面的這個struct

// @abi table proposal i64
struct Proposal {
  uint64_t id;
  account_name owner = 0;
  string description;
  std::vector<account_name, uint32_t> votes;

  uint64_t primary_key() const { return id; }

  EOSLIB_SERIALIZE( Proposal, (id)(owner)(description)(votes))
};


typedef eosio::multi_index<N(Proposal), Proposal> proposals;

首先看第一行:

// @abi table proposal i64

在部署合約之前奸汇,我們都會用eosiocpp來生成ABI施符,EOS智能合約編譯器可以讀取struct結(jié)構(gòu)體和public方法之前的注。在注釋中我們可以傳入兩種類型:actiontable擂找,ABI就會根據(jù)我們的聲明戳吝,自動在生成的ABI中添加相應(yīng)的方法或者表定義。

第二個proposal就是表名贯涎,而第三個i64就是表的主鍵的類型听哭。在這里主鍵就是id

account_name

注意到第二個成員變量owner:

account_name owner = 0;

這里的account_name是EOS自己定義的類型柬采,也就是之前我們曾經(jīng)創(chuàng)建過的賬戶名欢唾。可以理解成以太坊中的address類型粉捻。

vector

std::vector<account_name, uint32_t> votes;

vector這里可以理解成以太坊中的mapping - 自定義的一個映射集合礁遣。

Primary Keys

 uint64_t primary_key() const { return id; }

eosio::multi_index規(guī)定,每行必須有一個主鍵肩刃,類型為64位的無符號整型祟霍。表中的對象都會根據(jù)主鍵,升序或者降序排列盈包。通過在struct中定義primary_key()方法來獲取沸呐。在這個例子中,Proposal的主鍵就是id呢燥,類型為uint64_t崭添。當(dāng)然主鍵的類型也可以是account_name等。(account_name在eos中被存儲為uint64_int類型)叛氨。

數(shù)據(jù)序列化

EOSLIB_SERIALIZE( Proposal, (id)(owner)(description)(votes))

通過閱讀contracts/eosiolib/serialize.hpp文件可以知道呼渣,它其實是使用了BOOST_PP_SEQ_FOR_EACH宏棘伴。它的作用基本上就是賦予了struct額外的操作,可以把數(shù)據(jù)序列化到multi_index屁置,或者從multi_index中反序列化出來焊夸。

multi_index相關(guān)操作

雖然不想SQL語句那樣豐富,但是multi_index依然提供了一些基礎(chǔ)的操作:

  • 創(chuàng)建:使用.emplace
  • 查詢:使用.find
  • 修改已存在的入口:使用.modify

舉個查詢的例子:

auto itr = proposals.find(proposal_id)

以上語句查詢了特定id的proposal蓝角,它返回的是一個迭代器iterator阱穗。這就涉及到我們?nèi)绾问褂帽碇械臄?shù)據(jù),答案就是迭代器使鹅。

eos_iterator

可以把迭代器想象成一個電梯揪阶,在整個數(shù)據(jù)表中上下滑動(來定位數(shù)據(jù)),任何對數(shù)據(jù)的操作都必須通過迭代器并徘。

結(jié)束語

這一章概念雖然有些多遣钳,但是值得大家仔細研究。這一章我們學(xué)習(xí)了:

  • RAM的概念:存儲用戶高頻使用的數(shù)據(jù)的地方麦乞,比如當(dāng)前狀態(tài)蕴茴;
  • EOS數(shù)據(jù)庫的概念以及如何存儲;
  • multi_index是什么 - 和數(shù)據(jù)庫交互的容器

這一章理論性的內(nèi)容偏多姐直,理解上可能不如之前的幾篇直觀倦淀。下一篇我們將學(xué)習(xí)如何操作multi_index,以此帶大家更加深入地理解multi_index声畏,同時正式開啟我們的智能合約開發(fā)之旅撞叽。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市插龄,隨后出現(xiàn)的幾起案子愿棋,更是在濱河造成了極大的恐慌,老刑警劉巖均牢,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糠雨,死亡現(xiàn)場離奇詭異,居然都是意外死亡徘跪,警方通過查閱死者的電腦和手機甘邀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來垮庐,“玉大人松邪,你說我怎么就攤上這事∩诓椋” “怎么了逗抑?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我锋八,道長浙于,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任挟纱,我火速辦了婚禮,結(jié)果婚禮上腐宋,老公的妹妹穿的比我還像新娘紊服。我一直安慰自己,他們只是感情好胸竞,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布欺嗤。 她就那樣靜靜地躺著,像睡著了一般卫枝。 火紅的嫁衣襯著肌膚如雪煎饼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天校赤,我揣著相機與錄音吆玖,去河邊找鬼。 笑死马篮,一個胖子當(dāng)著我的面吹牛沾乘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播浑测,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼翅阵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了迁央?” 一聲冷哼從身側(cè)響起掷匠,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岖圈,沒想到半個月后讹语,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡幅狮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年募强,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片崇摄。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡擎值,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逐抑,到底是詐尸還是另有隱情鸠儿,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站进每,受9級特大地震影響汹粤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜田晚,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一嘱兼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贤徒,春花似錦芹壕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屁擅。三九已至讨惩,卻和暖如春为狸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背互捌。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工潘明, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人疫剃。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓钉疫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親巢价。 傳聞我的和親對象是個殘疾皇子牲阁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

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