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
-
cosmwasm
- cosmosに対応したwasm smart contractを構築するためのライブラリ
-
https://github.com/CosmWasm/cosmwasm
- cosmwasm-std
- smart contractの構築に必要なbindingと全てのimportを提供するcrate
- https://github.com/CosmWasm/cosmwasm/tree/master/packages/std
- cosmwasm-vm
- wasmerを利用して特定のcontractを実行するためのcrate
- https://github.com/CosmWasm/cosmwasm/tree/master/packages/vm
- cosmwasm-storage
- Storageパターンのためのhelperを提供するcrate
- https://github.com/CosmWasm/cosmwasm/tree/master/packages/storage
- cosmwasm-std
-
wasmd
- cosmos-sdkベースのwasm contractを実行できるブロックチェーン
-
https://github.com/CosmWasm/wasmd
- go-cosmwasm
- wasmerを使って実行するcosmwasm contractへのgo binding
- https://github.com/CosmWasm/go-cosmwasm
- go-cosmwasm
-
cosmwasm-opt
- docker imageとRustコードを受け取り、決定論的にwasmファイルを生成するためのスクリプト
-
cosmwasm-examples
- cosmwasm-templateで構築されたsample cosmwasm contract
- https://github.com/CosmWasm/cosmwasm-examples
-
cosmwasm-template
- cosmwasmシステムと互換性のあるcustom contractを構築するために取得するスターターパック
- https://github.com/CosmWasm/cosmwasm-template
-
serde-json-wasm
- serde-json-core からフォークされたカスタムjsonライブラリ
- https://github.com/CosmWasm/serde-json-wasm
-
cw-storage
- cosmwasm-storageと同様Storageパターンのためのhelperを提供するlibrary。core libraryにはないので、自由にフォークして、自身のcontractのために必要に応じて拡張可能。
- https://github.com/CosmWasm/cw-storage
Getting Started
-
公式ドキュメントの以下のページ通りに進めるとWebAssembly Smart Contractが実行できるApplication Specific Blockchainが実行できる。
https://www.cosmwasm.com/docs/getting-started/using-the-sdk -
以下のページでcosmwasm-examplesのdemoコントラクトが実行できる
https://www.cosmwasm.com/docs/getting-started/first-demo
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
- 公式ドキュメント、サンプルコードを参考にしてNFT用のsmart contractの実装を行った
https://github.com/shiki-tak/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)はどのような仕組みになっているのか調べてみる必要がある