【Ethereum】Gethをプライベートネットワークで起動して操作する

# 1．環境
- Ubuntu v16.04.4
- geth v1.8.8


# 2．Ethereumのインストール
Ethereumでは、いくつかのEthereumのクライアントが存在していて、クライアントを使って操作をしていきます。
今回はその代表的なクライアントである「Geth」のインストールから、Ethereumをコントロールするコマンドまでをご紹介していきます。

「Geth」は「Go-Ethererum」の略称で、Go言語で実装されたCUIクライアントです。
まずはそのインストールを行っていきます。

```bash:ethereum-install
$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get -y install ethereum
```

終了後、versionコマンドで下記のように表示されればインストール完了です。

```bash:geth-version
$ geth version
Geth
Version: 1.8.8-stable
Git Commit: 2688dab48c9b8ae71b8d95c7678817eaa17f2b53
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10
Operating System: linux
GOPATH=
GOROOT=/usr/lib/go-1.10
```



# 3．gethの起動
gethを起動するためにはgenesis.jsonというファイルが必要となりますので、こちらを作成していきます。
ブロックチェーンに積み上がる一番初めのブロックのことをジェネシスブロック（Genesis Block）と呼び、そのジェネシスブロックの情報を記載したファイルとなります。

今回はプライベートネットワークでネットワークを構築するため、ジェネシスブロックは適当な値で設定しています。
メインネットワークに接続したい場合は、すでにジェネシスブロックは存在しているため、この動作（ジェネシスブロックの採掘）は必要ありません。

```bash:make-genesis
$ mkdir private
$ cd private
$ vim genesis.json
```

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

genesis.jsonの作成が完了したら、ジェネシスブロックをコマンドから採掘してgethを起動します。

```bash:geth-start
# genesisブロックの採掘
$ geth --datadir private init private/genesis.json

# 起動コマンド
$ geth --networkid "15" --nodiscover --datadir "/home/vagrant/work/eth/private" console 2>> /home/vagrant/work/eth/geth.log
```


## 補足: gethのバックグラウンド起動について
先ほどの起動コマンドを実行すると、自動でConsoleへ入るのですが、このプロセスからexitしてしまうとgethのプロセスまで終了してしまいます。

そのため、gethを起動する際は基本的にバックグラウンドで起動していくことになるはずです。

```bash:background-start
# オプションを付けながら起動する
$ nohup geth --datadir private --mine --rpc --rpcaddr "0.0.0.0" --rpcport 8545 --rpccorsdomain "*" --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" 2>> private/geth.log &
```

# 4．Consoleからgethを操作する

## 4-1．Consoleに入る
ここでは先ほどご紹介したバックグラウンドでgethを起動しているものとして、説明を進めていきます。
バックグラウンド起動後は、Consoleに入り、Ethereumを操作していきます。
※バックグラウンド起動をしなかった場合、Consoleへ勝手に入りますので、ここ（4-1）は飛ばして大丈夫です。

```bash
# consoleに入る
$ geth attach ipc:private/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.8-stable-2688dab4/linux-amd64/go1.10
coinbase: 0xf339d34141c8f84cb41f522e15932e61a6132404
at block: 1458 (Sun, 17 Jun 2018 12:15:01 JST)
 datadir: /home/vagrant/work/eth/private
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
```

## 4-2．Consoleコマンドについて
Consoleに入ってから、コマンドを叩くことでgethを操作していきます。
ここではその際によく使うConsoleコマンドをご紹介します。


### ＜アカウント情報取得系＞
#### アカウントのアドレスを表示する
eth.accounts

```bash
# 返り値: ノードに存在する全てのEthereumアドレス
> eth.accounts
["0xf339d34141c8f84cb41f522e15932e61a6132404", "0x106cf689445729383eb5b45b6996a266ff400150", "0xe419b76396bdb3b2f0685f2126f5fb1c175d8cd1"]

# 引数: index値
# 返り値: 指定したindex番号のアカウントのアドレス
> eth.accounts[0]
"0xf339d34141c8f84cb41f522e15932e61a6132404"
```

#### 新しいアカウントとアドレスを発行する
personal.newAccount("User名")

```bash
# 引数: 好きなアカウント名
# 返り値: Ethereumアドレス
> personal.newAccount("Account")
"0x345749906435fc04495715eacfc69cd72718faf1"
```

#### 引数で指定したEthereumアドレスの残高を表示する
eth.getBalance("アドレス")

```bash
# 引数: Ethereumアドレス
# 返り値: 指定アドレスの残高（Wei単位で表示）
> eth.getBalance("0xf339d34141c8f84cb41f522e15932e61a6132404")
1.1395e+22
```

### ＜ブロック・トランザクション情報取得系＞
#### 現在のブロック数を表示する
eth.blockNumber

```bash
# 返り値: 現在のブロック数
> eth.blockNumber
154
```

#### 指定したBlock番号のBlock情報を表示する
eth.getBlock("Block番号")

```bash
# 引数: Block番号
# 返り値: 指定したBlock番号のBlock情報
> eth.getBlock(2382)
{
  difficulty: 396051,
  extraData: "0xd683010808846765746886676f312e3130856c696e7578",
  gasLimit: 13095390,
  gasUsed: 21000,
  hash: "0x935a8c4771417814e728f0623876dcc08d5cada52e706003be3e8d63cd4fa4f5",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xf339d34141c8f84cb41f522e15932e61a6132404",
  mixHash: "0x926aae5dc8d3a7bcd340b9b2b98be24d6f691ca3d848ae590e118f8b618f9f64",
  nonce: "0x39fca5458e5dd50f",
  number: 2382,
  parentHash: "0x9e50acf21c8337ae745b71d872997a1b474e2c670010dfb3b2865b0bf2183954",
  receiptsRoot: "0x8227202bce5e79b7f4b0a76c03d53a39ea08b6fd238912b90fdf3a7f63572d22",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 644,
  stateRoot: "0xe5df2b4b15e578a6f312f830ebe5e078f1b007ef10c274d4bf4ffd605542239c",
  timestamp: 1529209512,
  totalDifficulty: 578276739,
  transactions: ["0xa5e7146a89e634808f6ded9ac2bc6127935863a5eff3e12c6d9c74376b3dab2b"],
  transactionsRoot: "0x5ff30b4021d60bf6dc899232c11cd15f623861b29596d88970d2d52c0a99b4a6",
  uncles: []
}
```

#### 指定したTransactionIDを持つ、Transaction情報を取得する
eth.getTransaction("TransactionID")

```bash
# 引数: TransactionID
# 返り値: Transaction情報
> eth.getTransaction("0xa5e7146a89e634808f6ded9ac2bc6127935863a5eff3e12c6d9c74376b3dab2b")
{
  blockHash: "0x935a8c4771417814e728f0623876dcc08d5cada52e706003be3e8d63cd4fa4f5",
  blockNumber: 2382,
  from: "0xf339d34141c8f84cb41f522e15932e61a6132404",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0xa5e7146a89e634808f6ded9ac2bc6127935863a5eff3e12c6d9c74376b3dab2b",
  input: "0x",
  nonce: 0,
  r: "0xe6ce234fb5d2ac1dacb11c2f39f025720b801f8512ca561b1554feab9f90668b",
  s: "0x4611c4f29ecd4beb5c11fe216a0cc2bcfd06cccac9596bd675591bc8e5f688db",
  to: "0x345749906435fc04495715eacfc69cd72718faf1",
  transactionIndex: 0,
  v: "0x1b",
  value: 3000
}
```

### ＜マイニング系＞
#### マイニングを開始する
miner.start()

```bash
> miner.start()
null
```

#### マイニングを停止する
miner.stop()

```bash
> miner.stop()
true
```

#### マイニングが現在、動いているかどうかを表示する。
eth.mining

```bash
# 返り値: boolean（マイニングをしているかどうか）
> eth.mining
true
```

### ＜送金系＞
#### 送金を行うためにアカウントをアンロックする
personal.unlockAccount("Ethereumアドレス")

```bash
# 引数: Ethereumアドレス（自分のノードでないとアンロックは不可）
## Passphrase: Ethereumアドレスを発行する際（Personal.newAccount()）に入力したアカウント名
# 返り値: boolean（アンロックに成功したかどうか）
> personal.unlockAccount("0xf339d34141c8f84cb41f522e15932e61a6132404")
Unlock account 0xf339d34141c8f84cb41f522e15932e61a6132404
Passphrase:
true
```

#### Ethereumを送金する
eth.sendTransaction({from: "送金元Ethereumアドレス", to: "送金先Ethereumアドレス", value: "送金額（Wei）"})
※送金元アカウントはアンロック必須。

```bash
# 引数: 
## from: 送金元Ethereumアドレス
## to: 送金先Ethereumアドレス
## value: 送金額（Wei単位）
# 返り値: TransactionID
> eth.sendTransaction({from: "0xf339d34141c8f84cb41f522e15932e61a6132404", to: "0x345749906435fc04495715eacfc69cd72718faf1", value: "3000"})
"0xa5e7146a89e634808f6ded9ac2bc6127935863a5eff3e12c6d9c74376b3dab2b"
```

# 5．インストールまとめ
大して手間でもないですが、シェルにまとめましたので、インストールする際はこちらをコピペORシェルで実行していただければと思います。
※rootユーザーで叩いてください！

```bash:eth-install.sh
#!/bin/sh

sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get -y install ethereum
```


# 6．参考文献
- [Ethereum入門](https://legacy.gitbook.com/book/a-mitani/mastering-ethereum/details)
- [Gethをインストールする](https://book.ethereum-jp.net/first_use/installing_geth.html)