2.创建一个PoE的dapp

创建一个PoE的dapp

这一章我们创建一个PoE的dapp。

名词解释:

开始之前你应该已经完成了章节1中的内容。

安装最新稳定版Node.js:

curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v

Node.js目前最新版是13.x。

安装Yarn,配置仓库:

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

安装Yarn:

sudo apt update && sudo apt install yarn

下载前端模板代码:

# Clone the code from github
git clone -b v2.0.0-alpha.5 https://github.com/substrate-developer-hub/substrate-front-end-template

通yarn命令安装:

# Install the dependencies
cd substrate-front-end-template
yarn install
  • Proof of Existence : 通过文件hash的方式证明文件存在,具体可参考Wikipedia

我们的PoE Pallet暴露两个可以调用的函数:

  • create_claim : 允许用户通过上传文件hash来声明文件的存在。
  • revoke_claim: 允许文件拥有者撤销其所有权。

Substrate的runtime由一系列的Pallets组成,你可以开发自己的Pallet,和已经存在的Pallets组合起来,形成你的runtime。
runtime
接下来我们学习如何创建你自己到的Pallet到你的区块链中。
这里要用到第一章的substrate-node-template工程,看看substrate-node-template的工程结构:

substrate-node-template
|
+-- runtime
|
+-- pallets
|   |
|   +-- template
|       |
|       +-- Cargo.toml    <-- One change in this file
|       |
|       +-- src
|           |
|           +-- lib.rs     <-- Most changes in this file
|           |
|           +-- mock.rs
|           |
|           +-- tests.rs
|
+-- scripts
|
+-- node
|
+-- ...

在pallets/template/Cargo.toml最后加入以下内容:

[dependencies.sp-std]
default-features = false
version = '2.0.0-alpha.5'

在pallets/template/Cargo.toml中修改以下内容:

[features]
default = ['std']
std = [
    'codec/std',
    'frame-support/std',
    'safe-mix/std',
    'system/std',
    'sp-std/std',          <-- 添加行
]

接下来清空lib.rs文件,我们要在lib.rs中编写的代码主要分以下几大块:

// 1. Imports
use frame_support::{decl_module, decl_storage, decl_event, dispatch::DispatchResult};
use system::ensure_signed;

// 2. Pallet Configuration
pub trait Trait: system::Trait { /* --snip-- */ }

// 3. Pallet Events
decl_event! { /* --snip-- */ }

// 4. Pallet Errors
decl_error! { /* --snip-- */ }

// 5. Pallet Storage Items
decl_storage! { /* --snip-- */ }

// 6. Callable Pallet Functions
decl_module! { /* --snip-- */ }

以下是完整内容,请务必仔细阅读每一行,最好是自己亲手写一遍,并理解每行代码的意思。

#![cfg_attr(not(featue = "std"), no_std)]

use frame_support:: {
    decl_module, decl_storage, decl_event, decl_error, ensure, StorageMap
};
use system::ensure_signed;
use sp_std::vec::Vec;

pub trait Trait: system::Trait {
    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}

decl_event! {
    pub enum Event<T> where AccountId = <T as system::Trait>::AccountId {
        ClaimCreated(AccountId, Vec<u8>),
        ClaimRevoked(AccountId, Vec<u8>),
    }
}

decl_error! {
    pub enum Error for Module<T: Trait> {
        ProofAlreadyClaimed,
        NoSuchProof,
        NotProofOwner,
    }
}

decl_storage! {
    trait Store for Module<T: Trait> as TemplateModule {
        Proofs: map hasher(blake2_128_concat) Vec<u8> => (T::AccountId, T::BlockNumber);
    }
}

decl_module! {
    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
        type Error = Error<T>;
        fn deposit_event() = default;

        fn create_clain(origin, proof: Vec<u8>) {
            let sender = ensure_signed(origin)?;
            ensure!(!Proofs::<T>::contains_key(&proof), Error::<T>::ProofAlreadyClaimed);

            let current_block = <system::Module<T>>::block_number();

            Proofs::<T>::insert(&proof, (sender.clone(), current_block));

            Self::deposit_event(RawEvent::ClaimCreated(sender, proof));
    
        }

        fn revoke_claim(origin, proof: Vec<u8>) {
            let sender = ensure_signed(origin)?;

            ensure!(Proofs::<T>::contains_key(&proof), Error::<T>::NoSuchProof);

            let (owner, _) = Proofs::<T>::get(&proof);

            ensure!(sender == owner, Error::<T>::NotProofOwner);

            Proofs::<T>::remove(&proof);

            Self::deposit_event(RawEvent::ClaimRevoked(sender, proof));
        }
    }
}

重新编译:

cargo build --release

运行,运行之前清除链数据:

# Purge chain to clean up your old chain state
# You will be prompted to type `y`
./target/release/node-template purge-chain --dev

# Re-run your node in "development" mode
./target/release/node-template --dev
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值