06 使用substrate構建kitties鏈

1 說明

本節分兩部分,一是介紹如何構建kitties pallet,包括建立與kittes互動的功能;另一部分是介紹開發前端UI,與我們第一部分的鏈進行互動。

本課程內容較長,可以分幾次來學習。

2 本節目標

本節涉及的內容主要如下:

學習構建和執行substrate節點的基本模式。

編寫自定義框架pallet並整合到執行時。

瞭解如何建立和更新儲存項。

編寫pellet相關輔助函式。

使用PolkadotJs API將substrate節點連線到自定義前端。

2。1 kitties功能

為了方便學習,我們的kitties subside chain只能做以下事情:

可以透過一些原始來源或者透過使用現有小貓進行繁殖創造。

以其所有者設定的價格出售。

從一個所有者轉移到另一個所有者。

2。2 未完善的工作

本教程中不會考慮以下方面:

為pallet寫測試。

使用正確的weight值。

3基本步驟

3。1 安裝template-node

安裝kickstart

kickstart是一個命令列工具,可以用來方便的命名我們的node template,安裝命令如下:

然後執行如下命令:

敲下回車,當出現如下提示時:

這樣我們就成功的將node和pallet的名字分別改為了node-kitties和pallet-kitties。

kickstart命令修改的目錄如下:

修改runtime/src/lib。rs: 找到:

將其中的:

改為:

3。2 寫pallet_kitties的腳手架

substrate中的pallets是用來定義runtime的邏輯的。在本例子中,我們將定義一個簡單的pallet來管理substrate kitties應用的邏輯。

每個FRAME pallet都會有:

frame_support 和 frame_system依賴的集合;

要求的屬性宏。

對於pallets中的內容,我們先做如下操作:

在/pallets/kitties/src/lib。rs中貼上如下內容:

執行下面的命令先編譯一下:

編譯後,我們得到如下錯誤:

解決此問題需要在/pallets/kitties/Cargo。toml中新增:

3。3 新增儲存

此處我們使用StorageValue。

在pallets/kitties/src/lib。rs中, 我們替換如下部分:

替換成如下程式碼:

3。4 新增餘額實現

在runtime/src/lib。rs新增如下程式碼:

編譯一下檢查是否有錯:

4 相關資料結構與儲存

4。1 定義kitties struct

定義我們的kitties結構體如下(用如下程式碼替換pallets/kitties/src/lib。rs中的註釋“TODO Part II”):

同時還需要在pallet頂部新增:

此時我們的程式碼還編譯不過,因為Gender型別還未定義。

4。2 自定義型別Gender

Gender用來生成kitty,包含兩部分:

定義列舉型別,表示性別;

實現一個helper函式。

4。2。1 定義型別

用如下程式碼

寫在pallets/kitties/src/lib。rs中的註釋“TODO Part II: Enum and implementation”之下。

因為使用了反序列化的庫,因此我們需要在pallets/kitties/Cargo。toml中新增如下:

在pallet頂部新增:

4。2。2 實現函式

在註釋“TODO Part III: helper functions for dispatchable functions”下面加入如下程式碼:

4。3 實現鏈上隨機數

下面我們要定義KittyRandomness。我們將使用frame_support的 Randomness trait來實現。為實現Randomness trait,我們將:

在pallet的config trait中新增:

在runtime中新增:

生成隨機DNA

在pallet中新增如下, 在gen_gender下新增:

4。4 實現storage

4。4。1 理解邏輯

我們使用使用一個唯一的ID作為儲存專案的全域性金鑰,也就是說有一個唯一的key指向我們的kitty物件。為了保證新小貓的ID始終是唯一的,我們可以定義一個儲存項來儲存從ID到kitty物件的對映。從排程函式內部,我們可以使用以下程式碼進行衝突檢查:

我們的runtime需要注意以下兩點:

特定的資產、如通證或者kitties,這些將由名為kitties的storage map維護。

資產的所有權,如賬戶ID,這些將由storage map KittiesOwned來處理。

4。4。2 使用StorageMap

Kitties定義如下:

KittiesOwned定義如下:

將上述兩段程式碼放在pallets/kitties/src/lib。rs中的註釋“TODO Part II: Remaining storage items。”下面。

我們還需要在config trait中新增一個新型別MAxKittyOwned,因此我們在新增如下程式碼:

接下來,我們在runtime使用我們定義的型別,修改程式碼如下:

然後,我們可以編譯一下來檢查是否有錯:

我們發現會報如下錯誤:

5 排程函式,事件和error

前面我們定義了相關的資料結構和儲存,下面我們就可以使用這些結構來實現我們的相關函式。主要如下:

create_kitty(): 允許一個賬戶建立一個kitty的函式

mint():更新我們的pallet的儲存和error檢查的函式,會被create_kitty呼叫。

pallet Events:使用FRAME的#[pallet::event]屬性

5。1 公有和私有函式

此處create_kitty為公有函式,會呼叫私有函式mint。

5。2 寫create_kitty排程函式

在substrate中的排程函式都是一種結構,就是在#[pallet::call]宏下面的implement Pallet {}程式碼塊中。

5。2。1 weights(權重)

權重是substrate開發中很重要的一部分,它會強制開發者思考自己的函式的複雜度(所以,從這句話其實可以推測出weight實際上是類似於以太坊中gas相關的東東)。關於weight相關資料此處我們不展開,建議看下substrate官方文件。此處我們所有的排程函式都將weight設定成100。

在pallets/kitties/src/lib。rs檔案中註釋“TODO Part III: create_kitty”新增如下程式碼:

因為我們此處使用了log,所以要新增log相關的依賴:

5。3 建立mint函式

我們在註釋“TODO: increment_nonce, random_hash, mint, transfer_from”下新增如下函式:

5。4 實現pallet事件

在我們的程式碼中給Event的定義新增如下程式碼:

此時,我們在前面建立的creat_kitty函式中新增呼叫該事件的程式碼:

5。5 錯誤處理

substrate使用#[pallet::error]定義錯誤,我們在Error中新增如下程式碼:

現在,我們可以編譯檢查一下是否存在錯誤:

發現還是會報錯,因為我們還差很重要的一部分,就是configuration。

6 和kitties進行互動

下面我們將實現和kitties互動相關的函式。

6。1 為kitty設定價格

為kitty設定價格分為兩步,分別如下:

檢查Kitty的所有權 我們用如下程式碼實現所有權檢查:

is_kitty_owner函式程式碼如下:

更新kitty物件的價格:在mint函式中,我們將kitty的價格欄位(price)設定為0。因此,我們在set_price函式中要更新此值。因此,我們需要在set_price函式中新增如下程式碼:

發出事件 做完動作後要發出事件提醒使用者,因此還需在函式中加上如下程式碼:

所以設定價格的完整程式碼如下:

6。2 交易kitty

交易kitty的函式分為兩部分實現,一部分是transfer函式,一部分是transfer_kitty_to函式。

transfer函式的程式碼如下:

transfer_kitty_to的程式碼如下:

6。3 購買kitty

購買kitty分為兩步,一是檢查是否可以購買,二是支付

檢查kitty是否可以購買 購買kitty時我們需要從兩個方面確認可以購買:1、這隻kitty的狀態是要等待購買;2、當前這隻kitty是否在使用者的預算之類,並且使用者有足夠的餘額

支付 支付時直接使用Currency::transfer進行,完了後轉移kitty的所有權到買家,最後發出事件。

所以整個buy_kitty函式的完整程式碼如下:

同時,我們還需要在頂部引入“transactional”,如下:

6。4 繁殖小貓

繁殖小貓的函式比較簡單,程式碼如下:

在transfer_kitty_to函式下面新增如下程式碼:

6。5 初始化配置

substrate frame中使用#[pallet::genesis_config]來進行初始化配置:

為了讓我們的genesisConfig生效,我們需要修改node/src/chain_spec。rs,我們需要新增如下程式碼:

我們還需要在chain_sepc。rs頂部新增如下:

6。6 編譯執行

使用如下命令:

7 使用Polkadot-JS Apps UI進行測試

使用6。6執行我們的鏈

執行Polkadot-js Apps UI 使用如下地址:

在介面上,我們找到 “Settings” -> “Developer”,然後輸入如下json:

在介面上,我們可以對小貓進行一些列的操作。

8 完整原始碼地址

完整的實驗原始碼地址:https://github。com/anonymousGiga/substrate-tutorials

9 參考文件

https://docs。substrate。io/tutorials/v3/kitties/pt1/#tutorial-objectives

TAG: Kitty如下kittiespallet函式