LoginSignup
4
3

More than 3 years have passed since last update.

ブロックチェーン開発フレームワーク「Substrate」とは?

Last updated at Posted at 2019-06-01

この記事は、Substrate Tutorial
https://www.shawntabrizi.com/substrate-collectables-workshop/
を実行する上で、知っておくと進めやすそうな情報を要約する趣旨である。

Substrateとは?

新しいブロックチェーンをカスタムして作ることが出来るフレームワークである。言語はRustが用いられている。
Webアプリを作る時にExpressなどを用いてサーバーの実装が簡単に出来るように、ブロックチェーンを作る際にP2P通信やデータストレージなどの低レイヤーな概念を気にせずに実装できる。

Substrateの構成

大雑把に言うと、Substrate Coreの上にSubstrate Runtime Module Libraryが乗っかっていて、これらを用いてブロックチェーンを作る。

Substrate Core

ブロックチェーンを作る上での最低限の機能が実装されている。暗号関数やp2p通信、コンセンサスなど。

参考:https://coinchoice.net/describe-the-components-of-substrate/#Substrate_Core

Substrate Runtime Module Library

Substrate Coreに組み合わせることで、様々な機能を付与する。暗号通貨の残高を管理するアカウント機能や、スマートコントラクト機能など色々ある。

参考:https://coinchoice.net/describe-the-components-of-substrate/#Substrate_Runtime_Module_LibrarySRML

スクリーンショット 2019-06-01 10.52.19.png

Substrate Runtimeの構成は上の図のようになっており、Substrate Runtime Module Libraryを組み合わせてRuntimeを作成する。(construct_runtime!マクロで行う)

また、RuntimeのみのUpdateであれば、管理者ユーザーによって既存のチェーンを壊さずに行える(ハードフォークしない)

カスタムモジュールの定義

チュートリアルでは、既存のSRMLも利用して自らモジュールを定義することになる。
よく出てくるマクロについて解説する。マクロなので、通常のRustとは違う構文になることに注意。

decl_storage!

ブロックチェーンに保存するデータを定義する。

基本的な構文は以下のようになる。値を使うことも、mapを使うこともできる。(それぞれuse support::StoreValue,use support::StoreMapが必要である)

decl_storage! {
    trait Store for Module<T: Trait> as MyStore {
        MyValue : u32;
        MyMap: map u32 => u32;
    }
}

wasmコンパイルされると、javascriptからは

runtime.mysrml.myValue
runtime.mysrml.myMap(1)

のように呼び出せる。先頭が小文字になるので注意。

decl_module!

ユーザーが最終的に呼び出すことになるpublicな関数を定義する。(Polkadot UIで言うExtrinct)

基本的な構文は以下のようになる。これはdecl_storage!で定義したMyValueとMyMapに値を設定する関数である。

decl_module! {
  pub struct Module<T: Trait> for enum Call where origin: T::Origin {
    fn set_my_value(origin, my_value: u32) -> Result {
      let _sender = ensure_signed(origin)?;
      <MyValue<T>>::put(my_value);
      Ok(())
    }

    fn set_my_map(origin, key: u32, val: u32) -> Result {
      let _sender = ensure_signed(origin)?;
      <MyMap<T>>::insert(key,Val);
      Ok(())
    }
  }
}
  • pub struct〜の定義はおまじないのようにほぼそのまま書くことになると思われる。
  • originは関数を実行しているアカウントを指すので、関数を定義する際に必要となる。関数定義にoriginの型指定がないが、(Rustでは関数定義の際に必要)これはマクロなのでなんか上手いことやってくれいてる。

というのも、マクロが展開されると内部的にはCallというenumが作られ、それを呼び出すことになる。

pub enum Call<T: Trait> {
    set_my_value(u32),
    set_my_map(u32,u32),
}

wasmコンパイルされると、javascriptからは

call.mysrml.setMyValue(1)
call.mysrml.setMyMap(1,2)

のように呼び出せるようになる。(命名規則に注意)

参考記事

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3