我們上篇文章中講到完成一個Dapp的搭建需要兩個主要的部分塑娇,即智能合約的編寫以及前段的構(gòu)建景用,今天我們首先來一步步看智能合約中主要有哪些內(nèi)容以及是如何編寫的打肝。
在智能合約中娩缰,數(shù)據(jù)的存儲是較為重要的一環(huán)灸撰,我們在做源碼分析的時候都知道數(shù)據(jù)是存儲在Multi-Index(多索引表)里面的,本文將介紹如何創(chuàng)建一個多索引表以及如何通過action來更新表中的內(nèi)容的漆羔,同時我們引入了智能合約中使用的ABI的概念梧奢。
1狱掂、第二課
在元素戰(zhàn)爭游戲中演痒,我們需要存儲玩家的游戲狀態(tài)、細(xì)節(jié)等信息趋惨,在這里我們使用eos系統(tǒng)中的Multi-index來實現(xiàn)鸟顺,對于不太熟悉boost multi-index的朋友們來說,你可以簡單的把multi-idnex想象成一個關(guān)系型數(shù)據(jù)庫器虾,知道他是用來存儲數(shù)據(jù)的就可以了讯嫂。如何來創(chuàng)建一個多索引表呢?
1兆沙、首先讓我們來創(chuàng)建一個用戶信息表user_info,user_info中包含了以下內(nèi)容:
- 用戶名
- 贏的次數(shù)(初始化為0)
- 輸?shù)拇螖?shù)(初始化為0)
用戶名是一個uint64的account_name類型欧芽,而贏的次數(shù)和輸?shù)拇螖?shù)均為int整型。為了查詢我們存儲的數(shù)據(jù)葛圃,我們還需要定義一個類似主鍵的東西千扔,我們稱之為primary_key()。primary_key()需要實現(xiàn)库正,返回當(dāng)前用戶名即可曲楚。
```
? ? // @abi table users
? ? struct user_info {
? ? ? account_name? ? name;
? ? ? uint16_t? ? ? ? win_count = 0;
? ? ? uint16_t? ? ? ? lost_count = 0;
? ? ? auto primary_key() const { return name; }
? ? };
```
2、然后我們typedef一個名為users_table褥符,在這里需要主要user_info要和上一步定義的結(jié)構(gòu)體名一樣龙誊,不然編譯就會失敗。我們的typedef包含兩部分內(nèi)容
- 表名
- 剛聲明的結(jié)構(gòu)體的名
```
typedef eosio::multi_index<N(users), user_info> users_table;
```
3喷楣、聲明一個多索引變量
```
users_table _users;
```
4趟大、在構(gòu)造函數(shù)中初始化這個變量
那么這一系列的操作中主要包含哪些信息呢:
- code(合約賬戶名)鹤树,_users(self,self),提供了code和scope
- scope
- table name护昧,N(user)提供了表名
- primary key魂迄,primary_key()返回了主鍵信息
此處需說明:上面聲明的一個表適用于整個智能合約范圍內(nèi)。
多索引表定義號之后惋耙,我們來嘗試使用login這個action來更新多索引表捣炬,login這個action是為了驗證用戶是否有權(quán)限登陸元素戰(zhàn)爭的,因此我們需要使用require_auth()這個函數(shù)來獲取用戶相應(yīng)的權(quán)限绽榛,如果玩家是第一次玩這個游戲湿酸,我們就需要在多索引表中創(chuàng)建這個用戶的相關(guān)信息。
```
//聲明
void login(account_name username);
//實現(xiàn)
void cardgame::login(account_name username) {
? // Ensure this action is authorized by the player
? require_auth(username);
? // Create a record in the table if the player doesn't exist in our app yet
? auto user_iterator = _users.find(username);
? if (user_iterator == _users.end()) {
? ? user_iterator = _users.emplace(username,? [&](auto& new_user) {
? ? ? new_user.name = username;
? ? });
? }
}
```
接下來再來看ABI灭美,ABI定義了我們智能合約中的數(shù)據(jù)結(jié)構(gòu)和action的信息推溃,因此在部署智能合約之前我們需要創(chuàng)建一個和我們智能合約對應(yīng)的ABI文件,eos官方已經(jīng)提供了一個自動化生成ABI文件的工具--eosiocpp届腐。eosiocpp可以檢測到我們ABI中的信息铁坎,為了規(guī)范我們需要再表名之前寫上@abi table table_name (此處需特別注意),不然就會出現(xiàn)表中數(shù)據(jù)查詢?yōu)榭盏那闆r犁苏,感興趣的朋友也可以試一下硬萍,這和我們平時的注釋內(nèi)容是有區(qū)別的哦。在開發(fā)者指引手冊中有詳細(xì)的介紹ABI的文件生成
[ABI的相關(guān)說明](https://developers.eos.io/eosio-cpp/v1.2.0/docs/abi)
以及如何手寫一個ABI文件
[如何手寫一個ABI文件](https://developers.eos.io/eosio-cpp/v1.2.0/docs/how-to-write-an-abi)
每個action均需使用EOSIO_ABI來包含围详,不然在部署完合約之后使用push action的時候會提示你該action不存在朴乖,如下:
```
EOSIO_ABI(cardgame, (login))
```
然后使用eosiocpp命令來生成ABI文件如下:
```
eosiocpp -g cardgame.abi cardgame.cpp
```
至此,我們便完成了簡單的智能合約的編寫助赞,更多的功能實現(xiàn)會再接下來的文章中介紹买羞,同時智能合約的部署、前端和智能合約之間的通信也會一步步進(jìn)行雹食。
如果你覺得我的文章對你有一定的幫助畜普,請點擊文章末尾的喜歡該作者。
如果你對eos開發(fā)感興趣,歡迎關(guān)注本公眾號,一起學(xué)習(xí)eos開發(fā)群叶。
![3.png](https://upload-images.jianshu.io/upload_images/10941341-89ba713181af805f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
微信公眾號
有任何疑問或者指教請?zhí)砑颖救藗€人微信,當(dāng)然有對eos開發(fā)感興趣或者金庸粉的也可以添加一起交流,備注eos開發(fā)或金庸吃挑。
![4.png](https://upload-images.jianshu.io/upload_images/10941341-c5422f23d565e2a0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 個人微信號?