6
1

More than 3 years have passed since last update.

Cosmos sdkベースのBlockchainにおけるsmart contract実行プラットフォーム CosmWasmについて調べた

Last updated at Posted at 2020-05-06

What is CosmWasm

  • Cosmos sdkで作られるApplication Specific Blockchainでwasm smart contractを構築するためのライブラリ
  • もともとはベルリンのHackatom2019で Gaiansチームがプロトタイピングしたもの
  • CosmWasmはCosmos sdkにプラグインできるモジュールとして書かれている
  • gaiadをフォークしてCosmWasmを実行できるwasmdというsample chainも提供されているので、contractの開発から開始することも可能

NOTE: contract実行に関する最新の情報は以下のページを参考にすべし!
https://www.cosmwasm.com/docs/getting-started/first-demo

Ecosystem

Getting Started

Smart Contract

  • cosmwasm, cw_storage libraryを使用してSmart Contractを実装する。
  • Messageベースでchainとデータのやり取りを行うためCosmos sdkモジュールの開発と同じようにsmart contractが開発できる。

Model

state.rs

  • contractの初期状態を定義する
  • sampleではsingletonのStorageを使用
  • config: write function
  • config_read: read function
state.rs
pub struct State {
    pub count: i32,
    pub owner: CanonicalAddr,
}

pub fn config<S: Storage>(storage: &mut S) -> Singleton<S, State> {
    singleton(storage, CONFIG_KEY)
}

pub fn config_read<S: Storage>(storage: &S) -> ReadonlySingleton<S, State> {
    singleton_read(storage, CONFIG_KEY)
}

msg.rs

  • smart contractが実行するtx, queryのためのMessageを定義する
  • 使用したい構造体があれば、定義する
msg.rs
pub struct InitMsg {
    pub count: i32,
}

pub enum HandleMsg {
    Increment {},
    Reset { count: i32 },
}

pub enum QueryMsg {
    GetCount {},
}

pub struct CountResponse {
    pub count: i32,
}

contract.rs

init function

  • contractを初期化する
contract.rs
pub fn init<S: Storage, A: Api>(
    deps: &mut Extern<S, A>,
    env: Env,
    msg: InitMsg,
) -> Result<Response> {
    // 初期状態を作成
    let state = State {
        count: msg.count,
        owner: env.message.signer,
    };

    // 設定を保存する
    config(&mut deps.storage).save(&state)?;

    Ok(Response::default())
}

handle function

  • txをhandleする
  • Messageのtypeに応じて、実行する関数を分岐する
pub fn handle<S: Storage, A: Api>(
    deps: &mut Extern<S, A>,
    env: Env,
    msg: HandleMsg,
) -> Result<Response> {
    match msg {
        HandleMsg::Increment {} => try_increment(deps, env),
        HandleMsg::Reset { count } => try_reset(deps, env, count),
    }
}

query function

  • queryを実行する
  • tx同様、Messageのtypeに応じて実行する関数を分岐する
pub fn query<S: Storage, A: Api>(deps: &Extern<S, A>, msg: QueryMsg) -> Result<Vec<u8>> {
    match msg {
        QueryMsg::GetCount {} => query_count(deps),
    }
}

NFT-MVP

handle
        HandleMsg::Transfer { recipient, token_id } => transfer(deps, env, &recipient, token_id),
        HandleMsg::TransferFrom { sender, recipient, token_id } => transfer_from(deps, env, &sender, &recipient, token_id),
        HandleMsg::Approve { recipient, token_id } => approve(deps, env, &recipient, token_id),
        HandleMsg::ApproveForAll { owner, recipient } => approve_for_all(deps, env, &owner, &recipient),
        HandleMsg::Mint {} => mint(deps, env),
query
        QueryMsg::Balance { address } => balance(deps, &address),
        QueryMsg::Owner { token_id } => owner(deps, token_id),
        QueryMsg::Allowance { token_id } => allowance(deps, token_id),

Conclusion

  • CosmWasmはCosmos sdkベースのblockchainでwasm smart contractを実行するためのecosystem
  • ドキュメント通りに進めるとsmart contractの実行まで正常に動作することが確認できた
  • Cosmos sdkモジュール開発と同じようにMessageベースでsmart contractを記述していくので、Cosmos sdkの開発経験があれば、比較的簡単に開発できるはず
  • 逆に言えば、Cosmos sdkモジュールの開発経験がない人にはコストが高い?
  • 他のwasm smart contractが実行できるblockchain(substrateのink!やhypermint)はどのような仕組みになっているのか調べてみる必要がある

Reference

6
1
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
6
1