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