Open9

substrateに入門する

hhattohhatto

substrateノードのテンプレートリポジトリをcloneする

$ ghq get substrate-developer-hub/substrate-node-template
$ cd substrate-developer-hub/substrate-node-template

で、最新にしておもむろにビルド

$ git checkout latest
$ cargo build --release
hhattohhatto

次はフロントエンド側。

$ ghq get substrate-developer-hub/substrate-front-end-template
$ cd substrate-developer-hub/substrate-front-end-template

で、これも最新にしてビルドしてみる。

$ git checkout latest
$ yarn install

一旦準備は完了

hhattohhatto

またノード側に戻ってノード起動。

$ ./target/release/node-template --dev
$ ./target/release/node-template --dev
2021-12-25 00:25:35 Running in --dev mode, RPC CORS has been disabled.
2021-12-25 00:25:35 Substrate Node
2021-12-25 00:25:35 ✌️  version 4.0.0-dev-b74af51-aarch64-macos
2021-12-25 00:25:35 ❤️  by Substrate DevHub <https://github.com/substrate-developer-hub>, 2017-2021
2021-12-25 00:25:35 📋 Chain specification: Development
2021-12-25 00:25:35 🏷 Node name: upset-month-3323
2021-12-25 00:25:35 👤 Role: AUTHORITY
2021-12-25 00:25:35 💾 Database: RocksDb at /var/folders/b_/lxz21x891450bdx5s921z9_40000gn/T/substrateJEBTaz/chains/dev/db/full
2021-12-25 00:25:35 ⛓  Native runtime: node-template-100 (node-template-1.tx1.au1)
2021-12-25 00:25:35 🔨 Initializing Genesis block/state (state: 0x4dfc…78c9, header-hash: 0xfc9d…b862)
2021-12-25 00:25:35 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
2021-12-25 00:25:35 ⏱  Loaded block-time = 6s from block 0xfc9d3b5dd066f2969d606d78c2258b2e3249096d856a19a649f1cc9aea29b862
2021-12-25 00:25:35 Using default protocol ID "sup" because none is configured in the chain specs
2021-12-25 00:25:35 🏷 Local node identity is: 12D3KooWLo9WmUQnvkHBQX5vkV2ajnf5mJekhjQPuWtRGKZX6faV
2021-12-25 00:25:35 📦 Highest known block at #0
2021-12-25 00:25:35 〽️ Prometheus exporter started at 127.0.0.1:9615
2021-12-25 00:25:35 Listening for new connections on 127.0.0.1:9944.

普通にPolkadotノード的な感じで起動する。まぁそりゃそうかという感じ。

hhattohhatto

またフロントエンド側に戻って、フロントエンド側のアプリ立ち上げる。

$ yarn start

http://localhost:8000 にアクセスすると以下のようなノードの状態が見れるようになる。

整ってる。

hhattohhatto

Rustからノードにアクセスできるか試してみる。

$ ghq get paritytech/subxt
$ cd paritytech/subxt

CMakeが必要みたいなので、Homebrewでインストールする

$ brew install cmake

で、examplesディレクトリにあるfetch_all_accounts.rsを動かしてみる

$ cargo run --example fetch_all_accounts
   Compiling test-runtime v0.1.0 (/Users/hattorihideo/ghq/github.com/paritytech/subxt/test-runtime)
error: failed to run custom build command for `test-runtime v0.1.0 (/Users/hattorihideo/ghq/github.com/paritytech/subxt/test-runtime)`

Caused by:
  process didn't exit successfully: `/Users/hattorihideo/ghq/github.com/paritytech/subxt/target/debug/build/test-runtime-ba4e2c3285356ab0/build-script-build` (exit status: 101)
  --- stderr
  thread 'main' panicked at 'Cannot spawn substrate command 'substrate': No such file or directory (os error 2)', test-runtime/build.rs:58:13
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

なんか substrate コマンドが無いと言われる。

hhattohhatto

別のRustのクライアントがあるみたいなので、そちらを試してみる。

$ ghq get scs/substrate-api-client
$ cd scs/substrate-api-client
$ cargo run --example example_get_storage
Interacting with node on ws://127.0.0.1:9944

[+] TotalIssuance is 4611686018302387762
[+] StorageValueProof: Some(ReadProof { at: 0x25d6eb88cf217c96fd9e339eaebd933c6a64397ad150a653bf7c357195c942b3, proof: [Bytes([159, 2, 38, 18, 118, 204, 157, 31, 133, 152, 234, 75, 106, 116, 177, 92, 47, 56, 0, 76, 95, 0, 140, 233, 97, 93, 224, 119, 90, 130, 248, 169, 77, 195, 210, 133, 161, 4, 1, 80, 95, 14, 123, 144, 18, 9, 107, 65, 196, 235, 58, 175, 148, 127, 110, 164, 41, 8, 0, 0, 128, 237, 78, 75, 178, 14, 40, 38, 140, 120, 220, 227, 208, 165, 71, 5, 195, 15, 110, 169, 253, 64, 181, 133, 158, 196, 221, 117, 0, 137, 230, 136, 10]), Bytes([128, 46, 152, 128, 53, 247, 205, 226, 225, 162, 92, 110, 236, 104, 145, 145, 224, 142, 137, 103, 37, 249, 89, 167, 239, 107, 12, 187, 49, 245, 22, 255, 72, 164, 177, 250, 128, 28, 140, 213, 176, 218, 174, 148, 116, 63, 221, 31, 177, 238, 255, 99, 68, 56, 97, 203, 32, 229, 236, 149, 62, 175, 62, 187, 167, 120, 31, 57, 135, 128, 59, 155, 168, 154, 175, 127, 22, 19, 82, 151, 132, 125, 213, 114, 16, 45, 180, 41, 23, 142, 147, 217, 4, 182, 25, 90, 152, 248, 100, 68, 201, 25, 128, 122, 86, 35, 176, 192, 197, 14, 82, 186, 117, 34, 190, 183, 14, 1, 180, 96, 168, 251, 186, 142, 96, 91, 61, 171, 114, 115, 0, 101, 95, 146, 95, 128, 144, 198, 77, 29, 94, 224, 37, 194, 156, 53, 116, 83, 134, 45, 251, 201, 242, 207, 118, 61, 135, 45, 113, 245, 118, 50, 69, 151, 151, 116, 33, 192, 128, 18, 112, 45, 20, 77, 122, 95, 212, 146, 228, 75, 124, 254, 79, 151, 15, 57, 9, 79, 241, 82, 42, 139, 65, 47, 250, 49, 175, 225, 190, 76, 128, 128, 188, 57, 106, 24, 113, 252, 23, 127, 237, 22, 58, 53, 17, 84, 104, 47, 90, 183, 126, 152, 108, 131, 63, 182, 239, 182, 14, 45, 111, 196, 73, 142]), Bytes([95, 7, 200, 117, 228, 207, 247, 65, 72, 228, 98, 143, 38, 75, 151, 76, 128, 64, 50, 166, 140, 248, 255, 255, 255, 63, 0, 0, 0, 0, 0, 0, 0, 0])] })
[+] AccountInfo for Alice is AccountInfoGen { nonce: 1, consumers: 0, providers: 1, sufficients: 0, data: AccountDataGen { free: 1152921504481845758, reserved: 0, misc_frozen: 0, fee_frozen: 0 } }
[+] key prefix for System Account map is StorageKey([38, 170, 57, 78, 234, 86, 48, 224, 124, 72, 174, 12, 149, 88, 206, 247, 185, 157, 136, 14, 198, 129, 121, 156, 12, 243, 14, 136, 134, 55, 29, 169])
[+] Alice's Account Nonce is 1

なんか表示された。
substrateはpalletsと呼ばれる小さなコンポーネントを組み合わせて構築されていて、scs/substrate-api-clientを使うとそこにアクセスして必要な情報を取得できるみたい。
Ethereumでいうところのweb3.jsとかその辺りの感じだろうか。

hhattohhatto

チュートリアル用のpallet、nicks palletを追加してみる。

substrate-developer-hub/substrate-node-templateruntime/Cargo.toml に使用するpalletsを定義するので、追加するnicks palletの設定を追記する。

runtime/Cargo.toml
diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml
index 51e89d0..bf64aff 100644
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -12,6 +12,12 @@ repository = 'https://github.com/substrate-developer-hub/substrate-node-template
 [package.metadata.docs.rs]
 targets = ['x86_64-unknown-linux-gnu']

+[dependencies.pallet-nicks]
+default-features = false
+git = 'https://github.com/paritytech/substrate.git'
+tag = 'devhub/latest'
+version = '4.0.0-dev'
+
 [dependencies.pallet-template]
 default-features = false
 path = '../pallets/template'
@@ -210,6 +216,7 @@ std = [
     'frame-system-rpc-runtime-api/std',
     'frame-system/std',
     'pallet-aura/std',
+    'pallet-nicks/std',
     'pallet-balances/std',
     'pallet-grandpa/std',
     'pallet-randomness-collective-flip/std',

依存パッケージのチェックする

$ cargo check -p node-template-runtime
hhattohhatto

nicks pallet用の設定を runtime/src/lib.rsに追加する。

diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs
index 8ecb219..74af058 100644
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -6,6 +6,41 @@
 #[cfg(feature = "std")]
 include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
 
+/// Add this code block to your template for Nicks:
+parameter_types! {
+    // Choose a fee that incentivizes desireable behavior.
+    pub const NickReservationFee: u128 = 100;
+    pub const MinNickLength: u32 = 8;
+    // Maximum bounds on storage are important to secure your chain.
+    pub const MaxNickLength: u32 = 32;
+}
+
+impl pallet_nicks::Config for Runtime {
+    // The Balances pallet implements the ReservableCurrency trait.
+    // `Balances` is defined in `construct_runtime!` macro. See below.
+    // https://docs.substrate.io/rustdocs/latest/pallet_balances/index.html#implementations-2
+    type Currency = Balances;
+
+    // Use the NickReservationFee from the parameter_types block.
+    type ReservationFee = NickReservationFee;
+
+    // No action is taken when deposits are forfeited.
+    type Slashed = ();
+
+    // Configure the FRAME System Root origin as the Nick pallet admin.
+    // https://docs.substrate.io/rustdocs/latest/frame_system/enum.RawOrigin.html#variant.Root
+    type ForceOrigin = frame_system::EnsureRoot<AccountId>;
+
+    // Use the MinNickLength from the parameter_types block.
+    type MinLength = MinNickLength;
+
+    // Use the MaxNickLength from the parameter_types block.
+    type MaxLength = MaxNickLength;
+
+    // The ubiquitous event type.
+    type Event = Event;
+}
+
 use pallet_grandpa::{
 	fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList,
 };
@@ -292,6 +327,7 @@ construct_runtime!(
 		Aura: pallet_aura,
 		Grandpa: pallet_grandpa,
 		Balances: pallet_balances,
+        Nicks: pallet_nicks,
 		TransactionPayment: pallet_transaction_payment,
 		Sudo: pallet_sudo,
 		// Include the custom logic from the pallet-template in the runtime.

また依存関係チェックしてからビルド

$ cargo check -p node-template-runtime
$ cargo build --release

ノードを起動し直す。

$ ./target/release/node-template --dev

すると、Pallet Interactorにnicks palletが選択可能になる。

何回か試してもなんかエラーなるなーって思ってたら、8文字以上32文字以下で無いとエラーになるみたい。
で、この時点でニックネーム設定するpalletってことをやっと理解した。

runtime/src/lib.rs
parameter_types! {
    // Choose a fee that incentivizes desireable behavior.
    pub const NickReservationFee: u128 = 100;
    pub const MinNickLength: u32 = 8;
    // Maximum bounds on storage are important to secure your chain.
    pub const MaxNickLength: u32 = 32;
}

この辺りですね。

適当に8文字で入力したらうまく動いた。

参照もできると。

Substrate面白い!!