Substrateでブロックチェーンとアプリケーションを作る Runtimeの設定から〜ゲームPlayまで
こんにちは、Stakedの渡辺創太です。
前回こちらの記事で、Substrateのインストールからアカウントの作成までを行いました。この記事はその続きです。Gavin Woodの Web3 Summitでのプレゼンを参考にしています。
Runtimeモジュールを作成する
RuntimeとはSubstrateにおけるブロック処理ロジックなどを決める機能です。State Transaction Functiuonとも言われるときもあり、WebAssemblyバイナリーでオンチェーンに記載さてています。詳しくはScraoboxに記載しています。
前回、substrate-node-template
をインストールしましたが、./runtime/src/demo.rs
のフォルダに記載していきます。
作成したdemo.rs
にいくつかのライブラリーをインストールします。
use parity_codec::Encode;
use support::{StorageValue, dispatch::Result, decl_module, decl_storage};
use runtime_primitives::traits::Hash;
use {balances, system::{self, ensure_signed}};
pub trait Trait: balance::Trait {}
Web3 Summitのプレゼンでは、簡単な賭けゲームを作成していました。ゲームに勝てば、Potに溜まっていた金額を得ることができ、負ければPotに没収されるという簡単な仕組みです。
ライブラリーをインストールしたので、次に、モジュールを宣言する必要があります。(module declaration)
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn play(origin) -> Result{
//ゲームをプレイするロジック
}
fn set_payment(_origin, value: T::Balance) -> Result{
//ゲームのpaymentの仕様
}
}
}
decl_storage! {
trait Store for Module<T: Trait> as Demo {
Payment get(payment): Option<T::Balance>;
Pot get(pot): T::Balance;
}
}
strageモジュールはオンチェーンに載せる情報を定義するために使用します。
次に、モジュール内のロジックを書いていきます。
ゲームをプレイするロジック
fn play(origin) -> Result {
let sender = ensure_signed(origin)?;
//decl_strage!で宣言しているからpaymentが使える
let payment = Self::payment().ok_or("Must have payment amount set")?;
//senderの残高を減少させる
<balances::Module<T>>::decrease_free_balance(&sender, payment)?;
//ハッシュ関数を通してハッシュ値の最初のbyteが128以下であれば勝ち。potにあった金額がSenderに払われる
if (<system::Module<T>>::random_seed(), &sender)
.using_encoded(<T as system::Trait>::Hashing::hash)
.using_encoded(|e| e[0] < 128)
{
<balances::Module<T>>::increase_free_balance_creating(&sender, <Pot<T>>::take());
}
//結果どうあれ、senderが賭けに参加した金額がデポジットされる
<Pot<T>>::mutate(|pot| *pot += payment);
Ok(())
}
ゲーム内のPaymentのロジック
fn set_payment(_origin, value: T::Balance) -> Result {
//イニシャルpaymentがセットされていない場合の処理
if Self::payment().is_none() {
<Payment<T>>::put(value);
<Pot<T>>::put(value);
}
Ok(())
}
変更をアップデートする
上記でModuleを設定しました。変更を実行するために./runtime/src/lib.rs
を編集します。
mod demo;
の追記。
impl demo::Trait for Runtime {}
の追記
Demo: demo::{Module, Call, Storage},
の追記
上記で新しいRuntimeモジュールを作成したので、次にブロックチェーンのアップデートをします。
Substrate-node-templateのディレクトリでビルド
substrate-node-template $ ./build.sh
ビルド後、substrate-uiのnpm run dev
で接続したlocalhost8000にて一番下にRuntime Upgradeができるので、Select Runtimeを押し、
./runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm
を選択する。これでRuntimeのアップデートができました。Developer Consoleでみると動いていることがわかります。
UIを整える
UIを整えるにはsubstrate-uiレポジトリーを編集する必要があります。
./substrate-ui/src/app.jsx
を編集します。
新しく以下のセクションを追加します。
<Divider hidden />
<Segment style={{margin: '1em'}} padded>
<Header as='h2'>
<Icon name='game' />
<Header.Content>
Play the game
<Header.Subheader>Play the game here!</Header.Subheader>
</Header.Content>
</Header>
<div style={{paddingBottom: '1em'}}>
<div style={{fontSize: 'small'}}>player</div>
<SignerBond bond={this.player}/>
<If condition={this.player.ready()} then={<span>
<Label>Balance
<Label.Detail>
<Pretty value={runtime.balances.balance(this.player)}/>
</Label.Detail>
</Label>
</span>}/>
</div>
<TransactButton
content="Play"
icon='game'
tx={{
sender: this.player,
call: calls.demo.play()
}}
/>
<Label>Pot Balance
<Label.Detail>
<Pretty value={runtime.demo.pot}/>
</Label.Detail>
</Label>
</Segment>
同時に、exportの部分にthis.player = new Bond;
を追記します。
................
this.seedAccount.use()
this.runtime = new Bond;
//これ
this.player = new Bond;
}
これでUIを構築することができ、ゲームをPlayすることができます。
Author And Source
この問題について(Substrateでブロックチェーンとアプリケーションを作る Runtimeの設定から〜ゲームPlayまで), 我々は、より多くの情報をここで見つけました https://qiita.com/SotaWatanabe/items/b08c1e5f744cedca0c94著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .