UbuntuでEthereumのプライベートネットを作成するまで

Geth(Go Ethereum)を使って、プライベートネットワークを立てるまでの手順についてまとめました。

## 環境
* Ubuntu 18.04.3 LTS

## Gethのinstall
```
$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get install ethereum
```

```
$ geth --help
```

## 準備
これから作成するプライベートネットワークのデータやログを保管するようのディレクトリを作成します。

```
$ mkdir geth
$ cd geth
```

**これ以降の作業はこのディレクトリの中で行う。**

### Genesisファイルの作成
ブロックチェーンの最初のブロック(Genesisブロック)を作るために必要な情報が記録されたファイル(genesis.json)をあらかじめ作成する必要があります。

ファイル名は`genesis.json`

```json
{
  "config": {
    "chainId": 10,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0
  },
  "alloc": {},
  "coinbase": "0x0000000000000000000000000000000000000000",
  "difficulty": "0x20000",
  "extraData": "",
  "gasLimit": "0x2fefd8",
  "nonce": "0x0000000000000042",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp": "0x00"
}

```

設定する項目がたくさんあって難しそうに見えるが、特に環境とかに依存する部分はないのでコピペで大丈夫です。

* chainId : 任意だが既存のMainnetやTestnetと重複してはいけない
* difficulty : マイニングの難易度(あまり大きくするとマイニングが進まない)

以下に、主なネットワークとそのネットワークのIDを表示する。Genesisファイルのchain_idは以下と重複してはいけません。

Ropsten,Rinkeby,Kovanはテストネットワークの種類

|  chain_id  |  name |
| ---- | ---- |
|  1  |  Mainnet  |
|  3  |  Ropsten  |
|  4  |  Rinkeby  |
|  42  |  Kovan  |


### Gethの初期化

```
$ geth --datadir ./ init ./genesis.json
```

* --datadir : nodeやアカウントに関する情報を保存する場所を指定
* init : 指定したファイル(genesis.json)を利用してgenesisブロックを作成

こんな感じになればOK

```
INFO [12-19|07:54:31.385] Maximum peer count                       ETH=50 LES=0 total=50
INFO [12-19|07:54:31.387] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [12-19|07:54:31.389] Allocated cache and file handles         database=/home/bc/geth/geth/chaindata cache=16.00MiB handles=16
INFO [12-19|07:54:31.398] Writing custom genesis block
INFO [12-19|07:54:31.399] Persisted trie from memory database      nodes=0 size=0.00B time=4.263µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [12-19|07:54:31.399] Successfully wrote genesis state         database=chaindata                    hash=5e1fc7…d790e0
INFO [12-19|07:54:31.400] Allocated cache and file handles         database=/home/bc/geth/geth/lightchaindata cache=16.00MiB handles=16
INFO [12-19|07:54:31.405] Writing custom genesis block
INFO [12-19|07:54:31.406] Persisted trie from memory database      nodes=0 size=0.00B time=2.765µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [12-19|07:54:31.407] Successfully wrote genesis state         database=lightchaindata                    hash=5e1fc7…d790e0
```

## 起動

今回作成するプライベートネットワークは、以下のことができるとします。

* 起動した段階でマイニングを行なっている
* 外部からトランザクションを投げ込むことができる

### 初回起動
初回起動の際にいくつか設定を行います。以下のコマンドを実行します。

```
$ geth --networkid 10 --datadir . 2>> ./node.log console
```

* --networkid : ネットワークIDを指定する。このIDはGenesisファイルのchain_idと一致している必要があります。
* --datadir : Nodeが保持する情報を置くディレクトリを指定します。
* console : Gethのコンソールを開く。


上記のコマンドを実行すると以下のように、コンソールが開きます。

```
Welcome to the Geth JavaScript console!

instance: Geth/v1.9.9-stable-01744997/linux-amd64/go1.13.4
at block: 0 (Thu, 01 Jan 1970 02:00:00 SAST)
 datadir: /home/bc/geth
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

>
```

#### アカウントの作成
* Gethのコンソールでアカウントの作成を行います

```
> personal.newAccount()
```

```
Password:
Repeat password:
"0xe05013205ff323dafd58c6efe511698610839173"
```

パスワードを2回入力すると、アカウントが作成され、アカウントのアドレスが表示されます。

アカウントを作成することで初めてマイニングができるようになります。

ここまでできたら、`exit`で一度コンソールから抜けます。

### 2回目以降

2回目以降からは以下のコマンドでGethを起動させ、プライベートネットを立ち上げます。

```
$ geth --networkid 10 --datadir . 2>> ./node.log --rpc --rpcaddr "<IPアドレス>" --rpccorsdomain "*" --mine --minerthreads 1 --rpcapi eth,net,web3,personal console

```

* --rpc : HTTP-RPC サーバーを有効にする
* --rpcaddr :HTTP-RPC サーバのリスニングインターフェイスを指定する(無指定の場合はlocalhost)
* --rpccorsdomain: クロスoriginリクエストを受け付けるドメインを指定する
* --mine : Gethの起動時からマイニングを行う(アカウント作成済みでないと、指定できない)
* --minerthreads 1 : マイニングに使うCPUスレッド数を指定する(アカウント作成済みでないと、指定できない)
* --rpcapi : 受け付けるAPIを指定する

`--rpcport`でポート番号を指定することもできる。デフォルトでは8545番で待ち受けている。
localhostではなく、外部からGethに繋ぐ時は、Firewallの設定も必要になります。

ちなみに、ここまでの作業を行い、作成したディレクトリの中を見ると以下のようになっています。

```
$ ls
```

```
LOCK  chaindata  genesis.json  geth  geth.ipc  history  keystore  node.log  nodekey  nodes  transactions.rlp
```

#### コンソールを開く
起動させたGethをバックグラウンドで実行させておき、必要な場合のみコンソールに繋ぎたいときには、作成したディレクトリの直下で以下のコマンドを実行します。

```
$ geth attach ipc:geth.ipc
```

コンソールが開く

```
Welcome to the Geth JavaScript console!

instance: Geth/v1.9.9-stable-01744997/linux-amd64/go1.13.4
coinbase: 0xe05013205ff323dafd58c6efe511698610839173
at block: 0 (Thu, 01 Jan 1970 02:00:00 SAST)
 datadir: /home/bc/geth
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

>
```

あとは、Gethコマンドを使って色々遊んだり、外部からトランザクションを投げ込んで遊んだりするだけです。

## まとめ
初めてGethでプライベートネット立ち上げるときに、色々苦戦した記憶があったので、まとめておいた。