Ethereumで富豪ごっこをする

この投稿は[SFC-RG Advent Calendar 2017](https://qiita.com/advent-calendar/2017/sfc-rg)の1日目です。

# About
ちゃんとしたタイトルは"gethを用いてEthereumプライベートネットワークでマイニングと送金をしてみる"である。
なお筆者はMonaCoinerである。投げゼニをしてくれ。
```MSHEmtrJ5rWqaiVdF9cPTj55a8fvgc6jkq```

# 環境
macOS
geth v1.7.3

# 事前知識
簡単に基礎知識のおさらい
### Ethereum
ブロックチェーンの１種。スマートコントラクト開発の際のデファクトスタンダード。
### Gas
Ethereumでの送金やコントラクト実行時に必要となる手数料のこと。
### geth
goで書かれたEthereumクライアント。

# 環境構築
## Ethereumのインストール
Homebrewを用いて入れる。

```
$ brew tap ethereum/ethereum
$ brew install ethereum
```

## プライベートネットワークの作成
自分の開発用にパブリックネットワーク(実際に価値を持つお金がある方)でなく、プライベットネットワークを用意する。

1.まずはディレクトリを用意。

```$ mkdir test_eth```


2.Genesisファイルを作成
上で作成したディレクトリにGenesisファイルを安置する。これでネットワークの初期化を行う。今回は公式のREADMEからパクってきたものを使用.

```test_eth/genesis.json
{
  "config": {
        "chainId": 0,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
  "alloc"      : {},
  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x20000",
  "extraData"  : "",
  "gasLimit"   : "0x2fefd8",
  "nonce"      : "0x0000000000000042",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00"
}
```

ここで注意なのが1点書き換える部分がある。

```diff:
  "config": {
-       "chainId": 0,
+       "chainId": 8888, # network idを揃える 
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
```

chainIDをgeth起動時のnetwork idと揃える必要がある。自分の環境では特段network idを設定せずに起動したが、上のように8888に書き換えたら動いた。なお書き換えなかったら後で(送金時)こんなエラーが出る。

```
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")})
Error: insufficient funds for gas * price + value
    at web3.js:3143:20
    at web3.js:6347:15
    at web3.js:5081:36
    at <anonymous>:1:1
```

あとはdifficultyをマイニングが用意な数字に変えても良い。

3.ネットワークの初期化を実行
上で記述したgenesisファイルを用いてネットワークの初期化をする。

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

4.geth起動の確認
以下のコマンドでgethのコンソールが開く。
```$ geth --datadir ../test_eth console```

# マイニングと送金
## アカウントの作成と確認
1.アカウントの作成
金の送金・受け取りするには送信者と受信者の２アカウントが必要になるので作成する。
コマンドはこのように発行。
```> personal.newAccount("任意のパスフレーズ")```
私はこのようにした。

```
> personal.newAccount("shuya")
"0x9ec5dd818510280cc3c6d95e44912fba45bd27ff"
> personal.newAccount("hyde")
"0x39d87264ee89df53d2de89079be680693f320c21"
```

2.アカウントの確認
作成したアカウントは以下のコマンドで確認できる。

```
> eth.accounts
["0x9ec5dd818510280cc3c6d95e44912fba45bd27ff", "0x39d87264ee89df53d2de89079be680693f320c21"]
```

3.報酬を受け取るアカウントの確認
報酬を受け取るアカウントをEtherbaseを呼ぶ。マイニングする前に金がもらえるか確認。

```
> eth.coinbase
"0x9ec5dd818510280cc3c6d95e44912fba45bd27ff"
```

## マイニング
マイニングはとても簡単で１行で行える。

```> miner.start()```

マイニングされているか確認するには

```
> eth.mining
true
```

終える時も同様に
```> eth.stop()```

## 送金
1.残高の確認
無い金は送れないのでアカウントの残高を確認する。

```
> eth.getBalance(eth.accounts[0])
885000000000000000000
```

ようわからんくらい金持ちにになったが、これはweiと呼ばれるEthereumの最小単位で表示されている。etherで表示するのはこれ。(ウェイは小物で覚えよう)

```
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
885
```

2.アカウントロックの解除
送金前に送金を行うアカウントのロックを解除する必要がある。

```
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x9ec5dd818510280cc3c6d95e44912fba45bd27ff
Passphrase: 
true
```

3.送金する
これで晴れて送金できるから送金しよう。

```
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")})
INFO [11-29|19:24:47] Submitted transaction                    fullhash=0x69c7aafa424001e8adab19884a0a50824e97963e44e06a331c2fe74edf271049 recipient=0x39D87264eE89DF53d2de89079Be680693f320C21
"0x69c7aafa424001e8adab19884a0a50824e97963e44e06a331c2fe74edf271049"
```

## 入金の確認
だがしかし、まだ入金はしていない。ブロックチェーン上にトランザクションが承認されていないから。試しに確認してみると、まだ入金はない。

```
> eth.getBalance(eth.accounts[1])
0
```

そこでまたマイニングをして、トランザクションを承認させる。

```
> miner.start()
> miner.stop() #適当に惚れたらストップする
```

もう一度確認すると...

```
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
10
```

やったぜ(現在、10ether = 57万円くらい)