创造我们的NFT,使用Substrate 创建KItties 一

kitties-tutorial.png

本次研讨会将教您有关构建区块链的所有知识,该区块链处理称为Substrate Kitties的不可替代令牌(NFT)的创建和所有权。

基本设置

在我们开始制作Kitties之前,我们首先需要做一些基础工作。本部分介绍了使用Substrate node template设置自定义pallet并包含简单存储项所涉及的基本模式。

设置template node

Substrate node template为我们提供了一个可定制的区块链节点,包括内置的网络和共识层。我们需要关注的只是构建我们的逻辑runtimepallets.

首先,我们需要设置项目名称和依赖项。我们将使用一个名为kickstart轻松重命名我们的节node template。

  1. 安装 cargo install kickstart

  2. 安装kickstart完成后,在本地工作区的根目录中运行以下命令:

    kickstart https://github.com/sacha-l/kickstart-substrate
    

    此命令将克隆最新node tampalte的副本,并询问您希望如何调用node和pallet。

  3. 输入:

    • kitties- 作为我们node的名称。该节点将被命名为 node-kitties
    • kitties- 作为pallte的名称。pallet将命名为 pallet-kitties

    这将创建一个kitties目录,该目录使用Substrate node template, 并且包括我们的node、runtime和pallet相对应名称的更改。

  4. 在你喜欢的代码编辑器中打开kitties目录,并将其重命名为kitties-tutorial -或者你喜欢的任何名称。

    注意kickstart命令修改的目录:

    • /node/ - 此文件夹包含允许node的runtime和 RPC 客户端交互的所有逻辑。
    • /pallets/ - 这是所有自定义pallet所在的位置。
    • /runtime/ - 此文件夹是针对链的runtime聚合和实现所有pallets(自定义“内部”和“外部”pallets)的位置。
  5. runtime/src/lib.rs中,您还会注意到,我们修改后的template pallet名称的实例仍然存在。将TemplateModule更改为 SubstrateKitties:

    construct_runtime!(
       // --snip
       {
           // --snip
           SubstrateKitties: pallet_kitties,
       }
    );
    

编写pallet_kitties

让我们看一下工作区的文件夹结构:

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逻辑。在我们的例子中,我们将创建一个pallet来管理我们的Substrate Kitties应用程序的所有逻辑。

注意,我们的pallet的目录/pallets/kitties/与pallet的名称不同。我们的pallet名称,正如cargo所理解的那样pallet-kitties

让我们通过pallets/kitties/src/lib.rs内部组件的概述来布置pallet的基本结构。

每个 FRAME pallet都有:

  • 一组 frame_supportframe_system依赖项。
  • 必填属性宏(即配置特征、存储项和函数调用)。

这是我们将在本教程中构建的Kitties pallet的最基础的版本。它包含为本教程的下一节添加代码的起点。就像本教程的帮助文件 , 包含 TODO 的注释,指示我们稍后编写的代码,以及Action是用于指示将在当前部分中编写的代码 。

  1. 将以下代码粘贴到 :/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
    
       }
    }
    
  2. 请注意,我们在pallet中使用了sp_io。确保在pallet的Cargo.toml文件中将其声明为依赖项:

    sp-io = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.19" }
    
  3. 现在尝试运行以下命令来构建pallet。我们还没有构建整个链,因为我们还没有在runtime中实现Currency类型。不过我们现在可以检查pallet中有没有错误:

    cargo build -p pallet-kitties
    

您会看到到 Rust 编译器会发出有关未使用导入的警告。没关系!只需忽略它们 - 我们将在本教程的后面部分使用这些导入。

添加存储项

让我们将最简单的逻辑添加到runtime中:一个在runtime中存储变量的函数。为此,我们将使用StorageValue,Substrate的一个storage API,这个trait依赖于storage macor.

就我们的目的而言,我们要声明的任何存储项,我们必须事先包含宏#[pallet::storage]。了解有关声明存储项的更新详细信息点击这里

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创建一个存储项目,以追踪现有的kitties总数。

添加货币实现

在继续构建node之前,我们需要将 Currency 类型添加到pallet的runtime中。在runtime/src/lib.rs中,添加以下内容:

impl pallet_kitties::Config for Runtime {
    type Event = Event;
    type Currency = Balances; // <-- Add this line
}

现在构建node并确保没有任何错误。这将需要一点时间。

cargo build --release

本系列的第一部分已经完成,待续。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351