ブロックチェーンアプリ開発基礎の基礎：Gethの基礎、マイニング、送金

#はじめに

[ブロックチェーン基礎の基礎](https://qiita.com/KazukiKawamura/items/68cb6c16a7d95b9c5a02)、[ブロックチェーンの基礎](https://qiita.com/KazukiKawamura/items/79afbc994a92e8d13d5c)では、ブロックチェーンの基本的な事項を確認してきました。しかし、実際に自分で触ってみないと実感が湧かない部分も多いと思うので、実際に**マイニング**や**送金**をやってみます。スマートコントラクト開発のデファクトスタンダードになっているEthereumのクライアントである**「Geth」**を使って実装していきます。

今回の流れは下のようになります。

![Geth.png](https://qiita-image-store.s3.amazonaws.com/0/208575/b42ef50f-35c6-a5ea-8b34-890a48da4627.png)



#Gethのインストール
まずは、Gethをインストールします。

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

インストールが無事終わったかどうかは、

```
$ geth help
```

などで確認することができます。


#Genesisブロックの生成

ブロックチェーンの一番最初のブロック、すなわち0番目のブロックのことを**Genesisブロック**と呼びますが、これを作成していきます。

まずは、自分だけが参加するネットワークとなる**プライベートネットワーク**用にフォルダを作成します。逆に、全世界に公開されたネットワークとして、**メインネット**や**テストネット**といった**パブリックネットワーク**もあります。

```
$ mkdir ~/private_net
```


次に、フォルダ内にGenesisブロックの情報を記述したGenesisファイルを作成します。

```json:genesis.json
{
  "config": {
    "chainId": 42,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "nonce": "0x0000000000000042",
  "timestamp": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "gasLimit": "0x8000000",
  "difficulty": "0x100",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x3333333333333333333333333333333333333333",
  "alloc": {}
}
```

#ブロックチェーンの初期化

続いて、ブロックチェーンを初期化します。

```
$ geth --datadir ~/private_net/ init ~/private_net/genesis.json
```
**「Successfully wrote genesis state」**と出れば初期化成功です。

最後に、Gethを起動します。

```
$ geth --networkid "10" --nodiscover --datadir ~/private_net --rpc --rpcaddr "localhost" --rpcport "8545" --rpccorsdomain "*" --rpcapi "eth,net,web3,personal"  console 2>> ~/private_net/err.log
```
**「Welcome to the Geth JavaScript console!」**と出れば起動成功です。

さっそくですが、Genesisブロックの中身を確認してみましょう。

```
> eth.getBlock(0)
{
  difficulty: 256,
  extraData: "0x",
  gasLimit: 134217728,
  gasUsed: 0,
  hash: "0x83b885bae699c5650394963ed8927f780cf4fea39b55d3abf430e5a95aa305f3",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x3333333333333333333333333333333333333333",
  mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  nonce: "0x0000000000000042",
  number: 0,
  parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 507,
  stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  timestamp: 0,
  totalDifficulty: 256,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}
```
何やら、たくさんの項目がありますが、numberの0はこのブロックが0番目のブロックであることを示しています。

これで、ブロックチェーンの一番最初のブロックを生成することができました。


#新しいブロックの生成
[ブロックチェーン基礎の基礎](https://qiita.com/KazukiKawamura/items/68cb6c16a7d95b9c5a02)で説明したように、新しいブロックを生成することを**マイニング**と呼びました。実際にマイニングをやってみましょう。マイニングを行うと報酬が支払われることも確認してみます。

まず、アカウントを作成します。マイニングを行うだけなら、アカウントの作成は１つでよいのですが、次章で送金を行うので「送信者」と「受信者」の二つのアカウントを作成し、「送信者」の方でマイニングを行います。

```
> personal.newAccount("sender")
"0xfb814cf6d7deae6d68d9dea8f8cef23b9ce63e5f"
```

```
> personal.newAccount("receiver")
"0x9e495cc88b7d99c28918efb641f564f896eec6f5"
```


自分のGethにどんなアカウントがあるかは次のようにして確認することができます。送信者と受信者２つのアカウントがあることが確認できます。

```
> eth.accounts
["0xfb814cf6d7deae6d68d9dea8f8cef23b9ce63e5f", "0x9e495cc88b7d99c28918efb641f564f896eec6f5"]
```

ちなみに、インデックスでアカウントを指定して確認することもできます。1番目に作った送信者のアカウントはeth.accounts[0]で、2番目に作った受信者のアカウントはeth.accounts[1]で指定することができます。

それではさっそくマイニングを始めましょう。

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

しばらくすると、ブロックが生成され、受信者(eth.accounts[0])に報酬が支払われます。アカウントの残高は、次のようにして確認できます。以下の例では、Etherumで使う通貨「Ether」で**25**etherほど残高が生じていることが確認できます。

```
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
25
```
しばらくして、ある程度etherが貯まったことが確認できたらマイニングを中断しましょう。

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

#送金

それでは、マイニングの報酬で得られたetherを送金してみましょう。今、受信者は何もしていてないので残高は**0**etherとなっています。

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

この状態から送信者から受信者に**5**ether送金してみましょう。まずは、誤送金を防ぐために設定されている送信者のロックを解除してやります。

```
> personal.unlockAccount(eth.accounts[0], "sender")
```

ロックが解除できたらいよいよ送金です。**from**は**誰から送金するか**を、**to**は**誰に送金するか**を、**value**は**いくら送金するか**を指定してやります。今は、「**送信者**から**受信者**へ**5ether**送金する」というようにしてみます。

```
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value:web3.toWei(5, "ether")})
"0x02ee9a1765636d9a452f44c987a48b013f3404bec13b584b715c31d7275b856e"
```
送金を行うとトランザクション(取引履歴)のアドレスが返ってきます。しかし、このままでは取引は完了しません。トランザクションはブロックに格納されてはじめて取引完了となるからです。よって、再度マイニングによって新しいブロックを生成してやります。

```
> miner.start(1)
null
```
しばらくすると、取引が完了するので、トランザクションを確認してみましょう。引数には、さきほど得られたトランザクションのアドレスを与えてやります。

```
> eth.getTransaction("0x02ee9a1765636d9a452f44c987a48b013f3404bec13b584b715c31d7275b856e")
{
  blockHash: "0x1d91d02ccde8ae04a53838ace4603bf7efd52a59ce9e20f772fa945d9e2b863e",
  blockNumber: 6,
  from: "0xfb814cf6d7deae6d68d9dea8f8cef23b9ce63e5f",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0x02ee9a1765636d9a452f44c987a48b013f3404bec13b584b715c31d7275b856e",
  input: "0x",
  nonce: 0,
  r: "0x2508ddd4b79fe2fa1b01a86d5114a36fed003ff48d718c3c4c5b0205698ab2c",
  s: "0x6f2270a81fcf878b3e6f7fac80d74c6fe63addc34d3a6e61ee1773be58c3c9bd",
  to: "0x9e495cc88b7d99c28918efb641f564f896eec6f5",
  transactionIndex: 0,
  v: "0x78",
  value: 5000000000000000000
}
```
トランザクションも様々な項目がありますが、blockNumberはこのトランザクションが格納されているブロックの番号を示しており、この場合6番目のブロックであることが分かります。

最後に、受信者の残金が増えているか確認しておきましょう。

```
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
5
```
無事、**5**etherが入金されていることが分かります。これで、送信者から受信者の送金が完了しました。

さいごに、exitでGethを終了しておきましょう。

```
> exit
```