本次研討會(huì)將教您有關(guān)構(gòu)建區(qū)塊鏈的所有知識(shí)茄袖,該區(qū)塊鏈處理稱為Substrate Kitties的不可替代令牌(NFT)的創(chuàng)建和所有權(quán)渺贤。
基本設(shè)置
在我們開始制作Kitties之前雏胃,我們首先需要做一些基礎(chǔ)工作。本部分介紹了使用Substrate node template設(shè)置自定義pallet并包含簡(jiǎn)單存儲(chǔ)項(xiàng)所涉及的基本模式志鞍。
設(shè)置template node
Substrate node template為我們提供了一個(gè)可定制的區(qū)塊鏈節(jié)點(diǎn)瞭亮,包括內(nèi)置的網(wǎng)絡(luò)和共識(shí)層。我們需要關(guān)注的只是構(gòu)建我們的邏輯runtime和pallets.
首先固棚,我們需要設(shè)置項(xiàng)目名稱和依賴項(xiàng)统翩。我們將使用一個(gè)名為kickstart輕松重命名我們的節(jié)node template。
安裝
cargo install kickstart
-
安裝
kickstart
完成后此洲,在本地工作區(qū)的根目錄中運(yùn)行以下命令:kickstart https://github.com/sacha-l/kickstart-substrate
此命令將克隆最新node tampalte的副本厂汗,并詢問您希望如何調(diào)用node和pallet。
-
輸入:
-
kitties
- 作為我們node的名稱呜师。該節(jié)點(diǎn)將被命名為node-kitties
娶桦。 -
kitties
- 作為pallte的名稱。pallet將命名為pallet-kitties
。
這將創(chuàng)建一個(gè)
kitties
目錄衷畦,該目錄使用Substrate node template栗涂, 并且包括我們的node、runtime和pallet相對(duì)應(yīng)名稱的更改祈争。 -
-
在你喜歡的代碼編輯器中打開
kitties
目錄斤程,并將其重命名為kitties-tutorial
-或者你喜歡的任何名稱。注意
kickstart
命令修改的目錄:- /node/ - 此文件夾包含允許node的runtime和 RPC 客戶端交互的所有邏輯菩混。
- /pallets/ - 這是所有自定義pallet所在的位置暖释。
- /runtime/ - 此文件夾是針對(duì)鏈的runtime聚合和實(shí)現(xiàn)所有pallets(自定義“內(nèi)部”和“外部”pallets)的位置。
-
在
runtime/src/lib.rs
中墨吓,您還會(huì)注意到球匕,我們修改后的template pallet名稱的實(shí)例仍然存在。將TemplateModule
更改為SubstrateKitties
:construct_runtime!( // --snip { // --snip SubstrateKitties: pallet_kitties, } );
編寫pallet_kitties
讓我們看一下工作區(qū)的文件夾結(jié)構(gòu):
kitties-tutorial <-- The name of our project directory
|
+-- node
|
+-- pallets
| |
| +-- kitties
| |
| +-- Cargo.toml
| |
| +-- src
| |
| +-- benchmarking.rs <-- Remove file
| |
| +-- lib.rs <-- Remove contents
| |
| +-- mock.rs <-- Remove file
| |
| +-- tests.rs <-- Remove file
|
+-- Cargo.toml
Pallets在 Substrate 中用于定義rumtime邏輯帖烘。在我們的例子中亮曹,我們將創(chuàng)建一個(gè)pallet來管理我們的Substrate Kitties應(yīng)用程序的所有邏輯。
注意秘症,我們的pallet的目錄/pallets/kitties/
與pallet的名稱不同照卦。我們的pallet名稱,正如cargo所理解的那樣pallet-kitties
乡摹。
讓我們通過pallets/kitties/src/lib.rs
內(nèi)部組件的概述來布置pallet的基本結(jié)構(gòu)役耕。
每個(gè) FRAME pallet都有:
- 一組
frame_support
和frame_system
依賴項(xiàng)。 - 必填屬性宏(即配置特征聪廉、存儲(chǔ)項(xiàng)和函數(shù)調(diào)用)瞬痘。
這是我們將在本教程中構(gòu)建的Kitties pallet的最基礎(chǔ)的版本。它包含為本教程的下一節(jié)添加代碼的起點(diǎn)板熊。就像本教程的幫助文件 , 包含 TODO 的注釋框全,指示我們稍后編寫的代碼,以及Action是用于指示將在當(dāng)前部分中編寫的代碼 干签。
-
將以下代碼粘貼到 :
/pallets/kitties/src/lib.rs
#![cfg_attr(not(feature = "std"), no_std)] pub use pallet::*; #[frame_support::pallet] pub mod pallet { use frame_support::{ sp_runtime::traits::{Hash, Zero}, dispatch::{DispatchResultWithPostInfo, DispatchResult}, traits::{Currency, ExistenceRequirement, Randomness}, pallet_prelude::* }; use frame_system::pallet_prelude::*; use sp_io::hashing::blake2_128; // TODO Part II: Struct for holding Kitty information. // TODO Part II: Enum and implementation to handle Gender type in Kitty struct. #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet<T>(_); /// Configure the pallet by specifying the parameters and types it depends on. #[pallet::config] pub trait Config: frame_system::Config { /// Because this pallet emits events, it depends on the runtime's definition of an event. type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>; /// The Currency handler for the Kitties pallet. type Currency: Currency<Self::AccountId>; // TODO Part II: Specify the custom types for our runtime. } // Errors. #[pallet::error] pub enum Error<T> { // TODO Part III } #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event<T: Config> { // TODO Part III } // ACTION: Storage item to keep a count of all existing Kitties. // TODO Part II: Remaining storage items. // TODO Part III: Our pallet's genesis configuration. #[pallet::call] impl<T: Config> Pallet<T> { // TODO Part III: create_kitty // TODO Part III: set_price // TODO Part III: transfer // TODO Part III: buy_kitty // TODO Part III: breed_kitty } // TODO Part II: helper function for Kitty struct impl<T: Config> Pallet<T> { // TODO Part III: helper functions for dispatchable functions // TODO: increment_nonce, random_hash, mint, transfer_from } }
-
請(qǐng)注意津辩,我們?cè)趐allet中使用了
sp_io
。確保在pallet的Cargo.toml
文件中將其聲明為依賴項(xiàng):sp-io = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.19" }
-
現(xiàn)在嘗試運(yùn)行以下命令來構(gòu)建pallet容劳。我們還沒有構(gòu)建整個(gè)鏈喘沿,因?yàn)槲覀冞€沒有在runtime中實(shí)現(xiàn)
Currency
類型。不過我們現(xiàn)在可以檢查pallet中有沒有錯(cuò)誤:cargo build -p pallet-kitties
您會(huì)看到到 Rust 編譯器會(huì)發(fā)出有關(guān)未使用導(dǎo)入的警告竭贩。沒關(guān)系蚜印!只需忽略它們 - 我們將在本教程的后面部分使用這些導(dǎo)入。
添加存儲(chǔ)項(xiàng)
讓我們將最簡(jiǎn)單的邏輯添加到runtime中:一個(gè)在runtime中存儲(chǔ)變量的函數(shù)娶视。為此晒哄,我們將使用StorageValue
睁宰,Substrate的一個(gè)storage API,這個(gè)trait依賴于storage macor.
就我們的目的而言寝凌,我們要聲明的任何存儲(chǔ)項(xiàng)柒傻,我們必須事先包含宏#[pallet::storage]
。了解有關(guān)聲明存儲(chǔ)項(xiàng)的更新詳細(xì)信息點(diǎn)擊這里较木。
在 pallets/kitties/src/lib.rs
中红符,將 ACTION 行替換為:
#[pallet::storage]
#[pallet::getter(fn count_for_kitties)]
/// Keeps track of the number of Kitties in existence.
pub(super) type CountForKitties<T: Config> = StorageValue<_, u64, ValueQuery>;
這將為我們的pallet創(chuàng)建一個(gè)存儲(chǔ)項(xiàng)目,以追蹤現(xiàn)有的kitties總數(shù)伐债。
添加貨幣實(shí)現(xiàn)
在繼續(xù)構(gòu)建node之前预侯,我們需要將 Currency 類型添加到pallet的runtime中。在runtime/src/lib.rs
中峰锁,添加以下內(nèi)容:
impl pallet_kitties::Config for Runtime {
type Event = Event;
type Currency = Balances; // <-- Add this line
}
現(xiàn)在構(gòu)建node并確保沒有任何錯(cuò)誤萎馅。這將需要一點(diǎn)時(shí)間。
cargo build --release
本系列的第一部分已經(jīng)完成虹蒋,待續(xù)糜芳。。魄衅。