生活随笔
收集整理的這篇文章主要介紹了
带数据库的智能合约
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
編寫使用數(shù)據(jù)庫的智能合約
前面一直在搗鼓EOS網(wǎng)絡(luò)搭建的相關(guān)東西。然而今天比較不走運(yùn)的是,興致勃勃的把源碼版本升到4.0,在編譯的時(shí)候如我所猜想的出現(xiàn)了一系列問題,正一籌莫展的時(shí)候,導(dǎo)師突然問了我一個(gè)關(guān)于合約如何操作數(shù)據(jù)庫的問題。沒辦法,前面沒怎么關(guān)注這一塊,于是乎吞吞吐吐沒能回答老師的問題。心想,反正現(xiàn)在源碼有問題,搭不了網(wǎng)絡(luò),干脆花點(diǎn)時(shí)間看看合約的內(nèi)容。
于是乎,就有了今天的學(xué)習(xí)筆記,內(nèi)容如下:
直接上實(shí)例合約源碼
addressbook.cpp源碼:
include <eosiolib/eosio.hpp>
include
using eosio::indexed_by;
using eosio::const_mem_fun;
using std::string;
class addressbook : public eosio::contract {
public:
//構(gòu)造函數(shù)
explicit addressbook(action_name self) : contract(self) {}
//添加聯(lián)系人
//@abi action
void add(const account_name account, const string& name, uint64_t phone) {//獲取授權(quán),如果沒有授權(quán),Action調(diào)用會(huì)中止,事務(wù)會(huì)回滾require_auth(account);//eosio::multi_index(多索引表)可以用來讀取和修改EOS數(shù)據(jù)庫//address_index是自己定義的eosio::multi_index//實(shí)例化address數(shù)據(jù)表(multi_index),參數(shù)用于建立對表的訪問權(quán)限//如果訪問自己的合約則具有讀寫權(quán)限,訪問其他人的合約則具有只讀權(quán)限address_index addresses(_self, _self);//multi_index的find函數(shù)通過主鍵(primary_key)查詢數(shù)據(jù),返回迭代器itr//auto關(guān)鍵字會(huì)自動(dòng)匹配類型auto itr = addresses.find(account);//如果判斷條件不成立,則終止執(zhí)行并打印錯(cuò)誤信息eosio_assert(itr == addresses.end(), "Address for account already exists");//添加數(shù)據(jù)//使用存儲(chǔ)需要付費(fèi),第一個(gè)參數(shù)account是付費(fèi)的賬戶addresses.emplace(account, [&](auto& address){address.account = account;address.name = name;address.phone = phone;});
}//修改聯(lián)系人信息
//@abi action
void update(const account_name account, const string& name, uint64_t phone) {require_auth(account);address_index addresses(_self, _self);auto itr = addresses.find(account);//如果沒有找到account,打印錯(cuò)誤信息并終止eosio_assert(itr != addresses.end(), "Address for account not found");addresses.modify(itr, account, [&](auto& address){address.account = account;address.name = name;address.phone = phone;});
}//刪除聯(lián)系人
//@abi action
void remove(const account_name account) {require_auth(account);address_index addresses(_self, _self);auto itr = addresses.find(account);eosio_assert(itr != addresses.end(), "Address for account not found");//刪除addresses.erase(itr);
}//設(shè)置聯(lián)系人為特別關(guān)注
//@abi action
void like(const account_name account) {//無需獲取授權(quán),每個(gè)人都可以調(diào)用like Actionaddress_index addresses(_self, _self);auto itr = addresses.find(account);eosio_assert(itr != addresses.end(), "Address for account not found");//修改相應(yīng)的liked字段addresses.modify(itr, 0, [&](auto& address){//打印提示信息eosio::print("Liking: ", address.name.c_str(), "\n");address.liked++;});
}//功能和like()相同,但通過phone查詢數(shù)據(jù),而不是主鍵
//@abi action
void likebyphone(uint64_t phone) {address_index addresses(_self, _self);//獲取自定義索引auto phone_index = addresses.get_index<N(phone)>();auto itr = phone_index.lower_bound(phone);for(; itr != phone_index.end() && itr->phone == phone; ++itr) {phone_index.modify(itr, 0, [&](auto& address){eosio::print("Liking: ", address.name.c_str(), "\n");address.liked++;});}
}
private:
//定義address表,i64表示索引使用默認(rèn)的uint64_t類型
//@abi table address i64
struct address {
uint64_t account;
string name;
uint64_t phone;
uint64_t liked;
//定義address表的主鍵,address表是一個(gè)multi-index表uint64_t primary_key() const { return account; }uint64_t get_phone() const {return phone; }EOSLIB_SERIALIZE(address, (account)(name)(phone)(liked));
};//默認(rèn)通過主鍵索引,使用indexed_by,可以通過自定義函數(shù)進(jìn)行索引
//這里是get_phone,即通過phone字段進(jìn)行索引
typedef eosio::multi_index< N(address), address,indexed_by<N(phone), const_mem_fun<address, uint64_t, &address::get_phone>>>
address_index;
};
EOSIO_ABI(addressbook, (add)(update)(remove)(like)(likebyphone))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
該合約業(yè)務(wù)邏輯是實(shí)現(xiàn)一個(gè)通訊錄的功能,其中包括增加聯(lián)系人、更新聯(lián)系人信息、刪除聯(lián)系人以及將聯(lián)系人標(biāo)記為特別關(guān)注。
接下來我們來一步步來看該合約是如何實(shí)現(xiàn)的。
創(chuàng)建表格
1)定義結(jié)構(gòu)體
該結(jié)構(gòu)體的成員變量為表的字段,成員函數(shù)primary_key()定義主鍵,get_phone()定義二級(jí)索引,EOSLIB_SERIALIZE宏定義序列化表字段如下:
struct address {uint64_t account;string name;uint64_t phone;uint64_t liked;//定義address表的主鍵,address表是一個(gè)multi-index表uint64_t primary_key() const { return account; }uint64_t get_phone() const {return phone; }EOSLIB_SERIALIZE(address, (account)(name)(phone)(liked));
};
1
2
3
4
5
6
7
8
9
10
11
12
其中宏EOSLIB_SERIALIZE定義如下
#define EOSLIB_SERIALIZE( TYPE, MEMBERS ) template friend DataStream& operator << ( DataStream& ds, const TYPE& t ){ return ds BOOST_PP_SEQ_FOR_EACH( EOSLIB_REFLECT_MEMBER_OP, <<, MEMBERS ); } template friend DataStream& operator >> ( DataStream& ds, TYPE& t ){ return ds BOOST_PP_SEQ_FOR_EACH( EOSLIB_REFLECT_MEMBER_OP, >>, MEMBERS ); }
轉(zhuǎn)載于:https://www.cnblogs.com/xiaocongcong888/p/9892714.html
總結(jié)
以上是生活随笔為你收集整理的带数据库的智能合约的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。