3.07 EOS資料庫應用
阿新 • • 發佈:2018-12-07
1.EOS資料庫介紹
- 資料庫是輔助智慧合約儲存一些狀態和資料
- 資料庫執行在記憶體中,是KV儲存(區塊鏈就是分散式的KV儲存問題),通過multi_index與資料庫互動建表和操作,multi_index可以理解為一個表
- 資料庫是按不同賬戶分不同空間,Account裡實際上還有scope,scope中有table
- EOS資料庫的重點
- 資料表定義
- 多索引使用
- 迭代器使用
2.資料表
- mulit_index相當於傳統資料庫的一個表
- 但它將傳統資料庫行與列改為了單純的列,只有一個列,並且只儲存一個物件,也就是儲存C++的一個物件
- 物件中可以包含多個屬性,也可以實現類似於傳統資料庫的多列形式
- 官方的“汽車維修店”資料定義例項:
- 這是一個物件,一個物件是表中的一列
struct service_rec{
uint64_t pkey;
account_name customer;
uint32_t service_date;
uint32_t odometer;
}
3.多索引表
- 因為整個是一列,所以訪問資料中的屬性比較麻煩
- 可以在屬性上建立索引,便於操作
- 建立多索引,表必須有主鍵,必須是無符號的64位整型,所有物件按照主鍵升序排序的,小在前,大在後
auto primary_key()const{return pkey;}
- 主鍵本來就是索引,還可以自定義其他索引
- 例如使用車主使用者名稱做二級索引
account_name get_customer()const{return customer;}
- 索引起作用的程式碼:
- multi_index是EOS智慧合約關鍵字,宣告一個index使用
- <>中service是要定義的表名,service_rec是表中物件的struct宣告,indexed_by是宣告index的關鍵字,bycustomer是index的名字
using service_table_type=multi_index<service,service_rec, indexed_by<N(bycustomer),const_men_fun<service_rec, account_name,&service_rec::get_customer>>>;
- 左邊表按pkey排序,然後右邊新的index再次排序,指向前面的關聯資料
4.EOS多索引迭代器
- 例如上面新建立的索引,如果想使用,需要用到索引迭代器
- 最後一句話,呼叫customer_index的find方法,就是去查詢,find是EOS資料庫的API
account_name customer_acct=
eosio::chain::string_to_name(customer_name);
auto cust_itr=customer_index.find(customer_acct);
- 例如查詢Bob,將所有Bob都放到迭代器中,然後從迭代器中去查結果
- 通過定義資料表、index,再通過資料庫API使用index,返回迭代器,最後通過迭代器的遍歷可以訪問資料
- 使用的示例程式碼:
- while迴圈中判斷迭代器是否到最後一個,如果不是,去訪問裡面的customer,去過濾,看是否是想要的customer
while(cust_itr!=service_table.end()&&
cust_itr->customer==customer_acct){
//code
...
cust_itr++;
}
5.資料庫API介紹
- 構造一個multi_table的時候,要呼叫這個建構函式進行初始化
- code就是擁有當前表管理許可權的賬戶
- scope是在這個賬戶名下的一些區域,不同區域是隔離的
- 向表中新增新物件,類似插入的操作,插入一行
- constructor是怎麼構造這一行的Object,是一個lambda表示式
- 通過傳入主鍵,搜尋物件
6.資料庫應用案例
- 啟動網路
- 設定兩個alias
- 生成wast檔案
- 生成abi檔案
- 檢視容器中的合約
- 解鎖錢包
- 部署合約
- 檢視賬戶下的智慧合約
- 插入資料
- 檢視資料
- 再建立一個賬戶插入資料
- 檢視賬戶資訊
- 用新建的賬戶插入資料
- 檢視資料
- 查看錶
- 更新資料
- 再次檢視資料
- 使用自定義索引,當前日誌不列印查詢的內容,需要再開一個會話看日誌
- 用自己賬戶也可以查到eosio的資料
- 使用自定義索引檢視區間資料,然後在日誌中檢視
- 刪除資料
- 關閉網路
7.如何升級非系統合約
- 如果同一個合約有程式碼變動,只需要重新編譯、部署即可升級
- 如果程式碼沒有任何改動重新部署是沒必要的,也會提示此合約程式碼已經存在的錯誤