Substrate #4

성시완·2022년 5월 15일
0

Tutorial 4 (Workshop)

#3 나머지는 나중에 정리할 겁니다 개발팀장님

Build the Substrate Kitties Chain

What we learn!

  • 로컬 머신에 basic substrate 노드를 돌리는 법
  • Substrate에서 사용되는 Rust의 기본
  • NFT를 다루는 custom pallet 제작법
  • runtime에 new pallet 추가하는 법

개념 확인
1) frame_system : pallet를 runtime에 추가하고, pallet끼리 상호작용하는 것을 돕는 시스템 기능 제공
2) frame_support : call, storage, event, error 등에 관한 유틸리티 제공
3) 자료형

  • Enum : 새로운 자료형 정의
  • Struct : 여러 종류의 자료형 묶음

4) Traits : 인터페이스
5) Macros

Configuring pallet

// Your Pallet's configuration trait, representing custom external types and interfaces.
#[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>;

    /// The maximum amount of kitties a single account can own.
    #[pallet::constant]
    type MaxKittiesOwned: Get<u32>;

    /// The type of Randomness we want to specify for this pallet.
    type KittyRandomness: Randomness<Self::Hash, Self::BlockNumber>;
}

Custom Types

  1. Kitty의 gender를 enum으로 정의
  2. Kitty structure -> (dna, price, owner)
    ※ price가 None이면 판매용이 아님

Custom Storage

  1. CountForKitties(StorageValue)는 pallet에 존재하는 kitties의 total number를 나타낸다. 이는 ValueQuery 값으로 no value일 때 None이 아닌 0을 returen 한다.

  2. kitties(StorageMap)은 kitty의 특성을 담은 매핑이다.

  • dna를 이용하여 중복 생성 방지
  1. KittiesOwned(StorageMap)은 유저와 그들이 보유한 kitty의 매핑이다.
  • Key값은 AccountID
  • BoundedVec을 사용(맥시멈 length 제한 보장, Easier searching)

Create Kitty

  1. Error Enum
  • 개인 소유 kitty 제한
  • kitty 복제 불가능
  • kitty 오버플로우
  1. Created Event
  2. Dna 생성과 kitty minting

Transfer Kitty

Set Price

가격 설정 function 실행 전 확인해야 하는 것
1. caller가 signed origin이어야 한다
2. 존재하는 kitty여야 한다
3. caller가 kitty owner여야 한다

Buy kitty

  1. do_buy_kitty : 내부 함수, Transfer를 진행하고 Balance를 업데이트한다.

  2. buy_kitty : callable 함수

pub fn buy_kitty(
    origin: OriginFor<T>,
    kitty_id: [u8; 16],
    bid_price: BalanceOf<T>,
) -> DispatchResult {
    // Make sure the caller is from a signed origin
    let buyer = ensure_signed(origin)?;
    // Transfer the kitty from seller to buyer as a sale.
    Self::do_buy_kitty(kitty_id, buyer, bid_price)?;

    Ok(())
}

cargo build

 Compiling node-template-runtime v4.0.0-dev (/mnt/c/Users/User/substrate-node-template/runtime)
  error[E0119]: conflicting implementations of trait `core::convert::From<pallet_template::Event<Runtime>>` for type `Event`
     --> /mnt/c/Users/User/substrate-node-template/runtime/src/lib.rs:312:1
      |
  312 |     construct_runtime!(
      |    _^
      |  _|_|
      | | |
  313 | | |     pub enum Runtime where
  314 | | |         Block = Block,
  315 | | |         NodeBlock = opaque::Block,
  ...   | |
  330 | | |     }
  331 | | | );
      | | |_- in this macro invocation
  ...   |
      |
      = note: this error originates in the macro `frame_support::construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info)   

  error[E0119]: conflicting implementations of trait `core::convert::From<pallet_template::Call<Runtime>>` for type `Call`
     --> /mnt/c/Users/User/substrate-node-template/runtime/src/lib.rs:312:1
      |
  312 |     construct_runtime!(
      |    _^
      |  _|_|
      | | |
  313 | | |     pub enum Runtime where
  314 | | |         Block = Block,
  315 | | |         NodeBlock = opaque::Block,
  ...   | |
  330 | | |     }
  331 | | | );
      | | |_- in this macro invocation
  ...   |
      |
      = note: this error originates in the macro `frame_support::construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info)   

  error[E0119]: conflicting implementations of trait `core::convert::TryInto<pallet_template::Event<Runtime>>` for type `Event`
     --> /mnt/c/Users/User/substrate-node-template/runtime/src/lib.rs:312:1
      |
  312 |     construct_runtime!(
      |    _^
      |  _|_|
      | | |
  313 | | |     pub enum Runtime where
  314 | | |         Block = Block,
  315 | | |         NodeBlock = opaque::Block,
  ...   | |
  330 | | |     }
  331 | | | );
      | | |_- in this macro invocation
  ...   |
      |
      = note: this error originates in the macro `frame_support::construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info)   

  error[E0119]: conflicting implementations of trait `sp_api_hidden_includes_construct_runtime::hidden_include::traits::IsSubType<pallet_template::Call<Runtime>>` for type `Call`
     --> /mnt/c/Users/User/substrate-node-template/runtime/src/lib.rs:312:1
      |
  312 |     construct_runtime!(
      |    _^
      |  _|_|
      | | |
  313 | | |     pub enum Runtime where
  314 | | |         Block = Block,
  315 | | |         NodeBlock = opaque::Block,
  ...   | |
  330 | | |     }
  331 | | | );
      | | |_- in this macro invocation
  ...   |
      |
      = note: this error originates in the macro `frame_support::construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info)   

  For more information about this error, try `rustc --explain E0119`.
  error: could not compile `node-template-runtime` due to 4 previous errors

안돼~~ 아마 이전 pallet들 관련 코드를 초기화하지 않고 업데이트해서 충돌하는 듯 하다

profile
메모장 // 화이팅

1개의 댓글

comment-user-thumbnail
2022년 5월 16일

ㅋㅋㅋㅋㅋㅋㅋㅋ웬만한 개발자보다 러스트 잘 하시네요....👍좋습니다~~

답글 달기