初心者の僕がつまづいた、Geth起動コマンドの違い

#背景
ブロックチェーン初心者の僕は、gethをインストールしethereumのプライベート・ネットをさぁ立ち上げてみようと意気込んだ、、、が、
見つけたサイトや、書籍ごとにgethの起動方法が違ったため、その違いをまとめてみた。

#動作環境
- macOS High Sierra 10.13.6
- geth 1.8.14

#僕が見つけた起動コマンド色々

コマンド①

```
$ geth --networkid "10" --nodiscover --datadir "{データ保存ディレクトリ}" console
```

コマンド②

```
$ geth  --rpc --rpcaddr "localhost" --rpcport "8545" --rpccorsdomain "*" --rpcapi "eth,net,web3,personal" --networkid "10" --nodiscover --datadir "{データ保存ディレクトリ}" console
```


コマンド③

```
$ geth --dev --datadir "{データ保存ディレクトリ}"
```

コマンド④

```
$ geth console
```


んー、どれを使えば良いのやら。。

ということで軽く調べてみたら、プライベート・ネットに接続するには、大きく以下の２種類の方法があるらしい。

1. `genesis.json`を自分で用意する
2. `--dev` オプションを使用する


##1. `genesis.json`を自分で用意する
プライベート・ネットを構築する際、ゼロからブロックチェーンを作ることになるため、ブロックチェーンの性能などの情報を記載したGenesisファイルが必要になる、らしい。

ここでは、genesis.jsonを用意する具体的な方法は省きます。（知りたい方は以下のサイトを参照してください。）
https://book.ethereum-jp.net/first_use/connect_to_private_net.html

ちなみに用意するgenesis.jsonの中身はこんな感じ。

```json:genesis.json
{
  "config": {
    "chainId": 10
  },
  "nonce": "0x0000000000000042",
  "timestamp": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "",
  "gasLimit": "0x8000000",
  "difficulty": "0x4000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x3333333333333333333333333333333333333333",
  "alloc": {}
}
```

##2. `--dev` オプションを使用する
一方、`--dev`オプションを使用すると、ファイルを用意しなくてもgenesisブロックを自動で作成してくれるみたいです。

##1と2の違い

ん、じゃあ `--dev`オプション使った方が楽じゃね？？`genesis.json`を用意する意味って？？
と思って調べたら、

`--dev`オプションで構築されるデフォルトのgenesisブロックは**採掘難易度（Difficulty）が非常に高く（17,179,869,184）設定されており**、プライベート・ネットでの採掘は非常に困難らしいです。

そのためDifficultyの小さい独自のGenesisファイルを用意してプライベート・ネット内での採掘を容易にすることが慣習になっているとのこと。なるほど。

#各コマンドの意味
##コマンド①
1と2の違いを確認した上で、改めてコマンド①をみてみます。

```
$ geth --networkid "10" --nodiscover --datadir "{データ保存ディレクトリ}" console
```

これは、 **1. `genesis.json`を自分で用意する**　方法を用いた起動方法です。
なお、各オプションの意味は以下にまとめました。

```
--datadir        : gethの動作時のブロックチェーンデータや各種ログの出力先を指定
--networkid "10" : 任意の正の整数のIDを指定することで、パブリック・ネットとは異なるネットワークを立ち上げる。genesisブロックの初期化で指定したchainidと同一の値を指定する必要あり。
--nodiscover     : 自動Peer探索機能を無効。Gethはデフォルトで自動的に（同じネットワークID）のEthereumネットワークのノード（Peer）を探し接続を試みるため、プライベート・ネットでは未知のノードとの接続を避けるためこのオプションを指定する必要あり。
console　　　　　　　　　　　　　　　　　　　　: 対話的にコマンド入力を可能にするコンソールを起動。なお、consoleサブ・コマンドを付加せずに、Gethのプロセスをバックグラウンドで起動させておき、後からそのプロセスのコンソールを起動する事も可能。
```

##コマンド②
続いてコマンド②。

```
$ geth  --rpc --rpcaddr "localhost" --rpcport "8545" --rpccorsdomain "*" --rpcapi "eth,net,web3,personal" --networkid "10" --nodiscover --datadir "{データ保存ディレクトリ}" console
```
これも後半部分はコマンド①と同じであり、 **1. `genesis.json`を自分で用意する**　方法を用いた起動方法です。
しかし、さらにいくつかオプションが追加されていますね。
これらは、**EthereumノードにJSON RPC API経由でアクセスできるようにする**ためのオプションのよう。
なるほど、このオプションを有効にしないと、Node.jsからgethコマンドを呼び出したりすることができないのね。


なお、各オプションの意味は以下にまとめました。

```
--rpc            : HTTP-RPCサーバを有効にする。
--rpcaddr        : エンドポイントのホストアドレスの指定。無指定の場合、"localhost"。
--rpcport        : エンドポイントのポート番号の指定。無指定の場合、8545。
--rpcapi　　　　　　　　　　　　　　　　　　　: APIで受け付けるHTTP-RPCインターフェースの種類の指定。インターフェース名をコンマ区切りのリストで記述する。無指定の場合、"eth,net,web3"。
--rpccorsdomain  : JavaScriptのクロスドメイン制限を回避。*はドメイン制限なし）
```

ちなみに、HTTP-RPCにはアクセス制御がないため、他のホストからアクセスされた場合、無制限に制御されてしまう恐れがあるそうで、--rpcaddrで"localhost"以外を指定することはまず無いそうです。


##コマンド③
そしてコマンド③。

```
$ geth --dev --datadir "{データ保存ディレクトリ}"
```

これは、 **2. `--dev` オプションを使用する**　方法を用いた起動方法です。


##コマンド④
さて、これでコマンド①、②、③の違いは分かりました。
じゃあ最後のコマンド④、これは何？


```
$ geth console
```

このコマンドはよく見ると、**コマンド①で指定していたオプションを全て外したもの**です。
ではそれはどういう意味か。それはコマンド①で指定したオプションに答えがありました。

```
--networkid "10" : 任意の正の整数のIDを指定することで、パブリック・ネットとは異なるネットワークを立ち上げる。genesisブロックの初期化で指定したchainidと同一の値を指定する必要あり。
```

そう、これは**パブリック・ネット**に接続するためのコマンドだったんですね。危ない、危ない。（正直何が危ないのかよくわかっていませんが。）



#まとめ

というわけで、僕が今回見つけた4つのgeth起動コマンドの違いをまとめると、

コマンド①は、`genesis.json`を自分で用意し、**プライベート・ネット**に接続するコマンド。（JSON RPC APIは**使用不可**）

```
$ geth --networkid "10" --nodiscover --datadir "{データ保存ディレクトリ}" console
```

コマンド②は、`genesis.json`を自分で用意し、**プライベート・ネット**に接続するコマンド。（JSON RPC APIは**使用可能**）

```
$ geth  --rpc --rpcaddr "localhost" --rpcport "8545" --rpccorsdomain "*" --rpcapi "eth,net,web3,personal" --networkid "10" --nodiscover --datadir "{データ保存ディレクトリ}" console
```

コマンド③は、`--dev`オプションを用いて、**プライベート・ネット**に接続するコマンド。(採掘を容易にするためにコマンド①②を使用するのが慣習)

```
$ geth --dev --datadir "{データ保存ディレクトリ}"
```


コマンド④は、**パブリック・ネット**に接続するコマンド。

```
$ geth console
```

---

もちろん今回使用していないオプションを使用した起動方法もあるかと思いますが、あくまで僕が見つけたコマンドを元に違いをまとめさせていただきました。

何か記述に誤りなどがございましたらご指摘いただけると幸いです。

#参考
##各種ネットワークの違い
以下リンクより引用。
https://book.ethereum-jp.net/first_use/connect_to_private_net.html

> パブリック・ネットワーク：
>>不特定多数のノードのノードが参加し、かつその参加に制限が全くないネットワークです。参加ノードはそのネットワーク上で共有管理されたブロックチェーンに対して自由に、読み取り、トランザクションの発行、マイニングが可能です。仮想通貨としてのEthereumや、多くのパブリックなdAppはこのパブリックネットワーク上で運用されています。

> コンソーシアム・ネットワーク：
>>あらかじめ参加を許されたノードのみが参加することが可能なネットワークです。参加を許されるノードは一つの組織のみに管理されたものとは限らず、複数の利害関係が一致しない組織がそれぞれのノードを管理することが通常です。例えば国際送金の管理を行うブロックチェーンを構築したい場合、予め参加を許された複数の金融企業がそれぞれ管理するノードをこのP２Pのネットワークに参加することで、一つの企業にのみ管理されたシステムではない半非中央集権なシステムが構築可能になります。

> プライベート・ネットワーク：
>>一つの組織のみに管理されたノードのみが参加することが可能なネットワークです。ネットワークは自身の管理下に置くことが可能になり、中央集権的なP２Pシステムが可能になります。

#参考リンク・書籍
**リンク**
[「Ethereum スマートコントラクト入門：geth のインストールから Hello World まで」](https://qiita.com/amachino/items/b59ec8e46863ce2ebd4a)
[「プライベート・ネットワークに接続する」](https://book.ethereum-jp.net/first_use/connect_to_private_net.html)
[「Ethereum入門」を Geth 1.6.7 で進めてみた（インストールからetherの送金まで）](https://qiita.com/shora_kujira16/items/ab05f9d4a58bfa05a96c)
[「EthereumノードにJSON-RPC API経由でアクセスする」](https://qiita.com/kanehara/items/5f09401813b52a326ac5)
[「ブロックチェーンEthereum入門 2」]
(http://www.intellilink.co.jp/article/column/ethereum02.html)
**書籍**
- 「堅牢なスマートコントラクト開発のためのブロックチェーン「技術」入門」