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

kitties-tutorial.png

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

基本设置

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

设置template node

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

首先,我们需要设置项目名称和依赖项。我们将使用一个名为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(_);
    
       /// 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> + IsType<::Event>;
    
           /// The Currency handler for the Kitties pallet.
           type Currency: Currency;
    
           // TODO Part II: Specify the custom types for our runtime.
    
       }
    
       // Errors.
       #[pallet::error]
       pub enum Error {
           // TODO Part III
       }
    
       #[pallet::event]
       #[pallet::generate_deposit(pub(super) fn deposit_event)]
       pub enum Event {
           // 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 Pallet {
    
           // 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 Pallet {
           // 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 = 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

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

你可能感兴趣的:(创造我们的NFT,使用Substrate 创建KItties 一)