Substrate --chain で指定できるスペック名を追加、ついでに送金手数料を 0 にする

# まえがき

たまってるメモを清書して記事にするというのがおっくうで、、、いつまでも記事にならないので
メモをそのまま投稿していきます。

# やりたいこと

substrate を起動時に chain を指定することができます。
指定できる値は dev, local, staging のいずれかですが、ここで指定できる値を増やして自分専用のものを作りたい
>--chain <CHAIN_SPEC>                         
> Specify the chain specification (one of dev, local or staging)


これができなければ困るということはありません。

```bash
substrate --chain matsuda
```

# やったこと

オプション値を変換するコードを追加、enum に任意の列挙子を追加、スペックを追加
修正、追加するのは runtime/chain_spec.rs 内の3ヶ所です

## enum(列挙型) に MatsudaTestnet を追加

追加する際の文字列は任意です。

```rust:runtime/chain_spec.rs
#[derive(Clone, Debug)]
pub enum Alternative {
	/// Whatever the current runtime is, with just Alice as an auth.
	Development,
	/// Whatever the current runtime is, with simple Alice/Bob auths.
	LocalTestnet,
	/// 追加
	MatsudaTestnet,
}
```
MatudaTestnet を追加しました。

## スペック追加

enum に追加した列挙子に対応するスペックを追加します。
Development の内容をコピーして、中身を修正しました。
Alice ではなく Matsuda にしてみたり、、、、
b"Matsuda（空白）" は seed になる値のため空白を含めて全体の文字数は重要です。
※重要だと思ってますが、、、文字数を変えて試していないので、だれか試したら教えてください


```rust:chain_spec.rs
impl Alternative {
	/// Get an actual chain config from one of the alternatives.
	pub(crate) fn load(self) -> Result<ChainSpec, String> {
		Ok(match self {
			Alternative::Development => ChainSpec::from_genesis(
省略
			),
			Alternative::LocalTestnet => ChainSpec::from_genesis(
省略
			),
/// 追加
			Alternative::MatsudaTestnet => ChainSpec::from_genesis(
				"Matsuda Testnet",
				"matsuda_testnet",
				|| testnet_genesis(vec![
					ed25519::Pair::from_seed(b"Matsuda                         ").public().into(),
				], vec![
					ed25519::Pair::from_seed(b"Matsuda                         ").public().0.into(),
				],
					ed25519::Pair::from_seed(b"Matsuda                         ").public().0.into(),
				),
				vec![],
				None,
				None,
				None,
				None
			),
		})
	}
	pub(crate) fn from(s: &str) -> Option<Self> {
省略
	}
}
```
それぞれの値の意味はいずれ、、、、

## オプションに指定できる文字列を追加

"matsuda" が指定されたら Alternative::MatsudaTestnet を返却するように追加

```rust:chain_spec.rs
impl Alternative {
	pub(crate) fn load(self) -> Result<ChainSpec, String> {
省略
	}

	pub(crate) fn from(s: &str) -> Option<Self> {
		match s {
			"dev" => Some(Alternative::Development),
/// 追加
			"matsuda" => Some(Alternative::MatsudaTestnet),
			"" | "local" => Some(Alternative::LocalTestnet),
			_ => None,
		}
	}
}
```

これの説明は簡単なので
substrate --chain <名前>
<名前> を Alternative::<列挙子> に変換してます。
dev, matsuda, local、指定なし が＜名前＞に指定できるということ staging はどこなんでしょ

## ビルド

```bash
$ ./build.sh
$ cargo build --release
```
過去にビルドしたことがあれば、このビルドは数分で終わります。


## 起動

DBを削除します。はじめて起動する場合は必要ありません。

```bash
$ ./target/release/substrate purge-chain --chain=matsuda
```

起動します。

```bash
./target/release/substrate \
  --chain=matsuda \
  --key=0x4d61747375646120202020202020202020202020202020202020202020202020 \
  --validator

2019-02-27 11:12:25 Substrate Node
2019-02-27 11:12:25   version 0.9.0-c93faf3-x86_64-linux-gnu
2019-02-27 11:12:25   by koichi.matsuda, 2017, 2018
2019-02-27 11:12:25 Chain specification: Matsuda Testnet
2019-02-27 11:12:25 Node name: hideous-kite-8390
2019-02-27 11:12:25 Roles: AUTHORITY
2019-02-27 11:12:25 Initialising Genesis block/state (state: 0x8045…d265, header-hash: 0xda26…c23f)
2019-02-27 11:12:25 Loaded block-time = 10 seconds from genesis on first-launch
2019-02-27 11:12:25 Best block: #0
2019-02-27 11:12:25 Local node address is: /ip4/0.0.0.0/tcp/30333/p2p/QmZm5RZ1QvGqDFr3QTC6AVajxazbHLdP6rhasAvwQt5b5S
2019-02-27 11:12:25 Listening for new connections on 127.0.0.1:9944.
2019-02-27 11:12:25 Using authority key 5FcqSzTdr3zeiMan8S48Rz7yP8fG3YYkzjpD1iaSBAuihkME
```

なんだかオプションが増えてますね
--chain はスペックを指定してます。
--key と --validator を指定しなかったらブロックの生成が行われなかったので追加しました。
今回は動けばいいやということで細かいことは調べてませんがいつか調べます。調べないと自分が困るので

--key に指定した値は subkye で得られます。

```bash
$ subkey restore Matsuda

Seed 0x4d61747375646120202020202020202020202020202020202020202020202020 is account:
  Public key (hex): 0x9d361c06d36e411422e49d14d00f5128662b8f84567400ee26aaeb3cfc8f7f77
  Address (SS58): 5FcqSzTdr3zeiMan8S48Rz7yP8fG3YYkzjpD1iaSBAuihkME
```

--key に指定するのは seed です。Public key ではありません。key という文字だけ見て反射的に Public key を指定して時間を無駄にしたのはワタシです。


Chain specification に chain_spec.rs で指定した文字列が表示される
Using autority key が subkey で得られた Address になってる
タイムスタンプだけのブロック生成が始まる。（コンソールを見ててもブロックの中身は見えませんが、、、、)

# 送金手数料 0

今回は起動オプション chain に指定できる文字列を追加しただけですが、他にもいろいろと設定することができます。
fn testnet_genesis の中をいじるか、独自に作ってしまえば簡単です。

例えば送金で手数料を 0 としたいなら

```rust:runtime/chain_spec.rs
fees: Some(FeesConfig {
			transaction_base_fee: 1,
			transaction_byte_fee: 0,
		})
```

1 を 0 にしてしまうだけです。

# おわりに

Substrate をつかって独自のブロックチェーンを作りたい。そんなことを思いながら Substrate で毎日遊んでます。
勉強会も月に1回渋谷で開催してますので遊びに来てください。

Blockchain Devux - connpass
https://bdevux.connpass.com/