ubuntu 20.04 + Geth環境のアカウント設定とether採掘

ubuntuにGethを導入後、アカウントを作成し採掘を行うまでの手順を開設する。

環境構築をまとめた前回の記事はこちら。

https://qiita.com/kanazwk/items/76ffda7b4d6b7dc1ba27


# EOAアカウント作成
このノード内で作成されたEOAのリストを表示する。初期は空の状態なので、空白が表示される。

```
> eth.accounts
[]
>
```

作成は`personal.newAccount(パスワード文字列)`で実行する。ここではアカウントを2つ作成する。

```
> personal.newAccount("p@ssw0rd01")
"0x911e18204582a6de08dd2b1f7540b9167ce93b67"
>
> eth.accounts
["0x911e18204582a6de08dd2b1f7540b9167ce93b67"]
```

```
> personal.newAccount("p@ssw0rd02")
"0x911e18204582a6de08dd2b1f7540b9167ce93b67"
>
> eth.accounts
["0x911e18204582a6de08dd2b1f7540b9167ce93b67", "0x634c921bfbad7756c7988ea74e4bdf5e5387620d"]
```

EOAアカウントとは、**Externally Owned Account**。トランザクションを発生さえるユーザーアカウントで、他のアカウントへのetherの送金やコントラクトコードの実行を行う。etherのマイニングもこのアカウントで行う。

Ethereumのアカウントは2種類あり、もう一方のアカウントは**Contract**と呼ばれる自動エージェントである。EOAから発行されたトランザクションがをトリガーにして、このContractアカウントが持つ**コントラクトコード**が実行される。実行後、Contractアカウントのデータフィールドも更新される。

# etherbase（coinbase）のアドレス確認
`eth.coinbase`コマンドを実行すると、作成したEOAアカウントの一つが表示される。これをetherbase（coinbase）という。etherbase（coinbase）とは、各ノードでマイニングを行う際に、その報酬を紐づけるEOAのアドレスである。

```
> eth.coinbase
"0x911e18204582a6de08dd2b1f7540b9167ce93b67"
```

etherbase（coinbase）は、`eth.accounts[0]`コマンドの実行結果（プライマリアカウントのアドレス）に紐づいている。

```
> eth.accounts
["0x911e18204582a6de08dd2b1f7540b9167ce93b67", "0x634c921bfbad7756c7988ea74e4bdf5e5387620d"]
>
> eth.accounts[0]
"0x911e18204582a6de08dd2b1f7540b9167ce93b67"
> eth.accounts[1]
"0x634c921bfbad7756c7988ea74e4bdf5e5387620d"
>
```

このアドレスは変更することが出来る。変更は`miner.setEtherbase(new_adress)`コマンドを以下のように実行する。

```
> miner.setEtherbase(eth.accounts[1])
true
> eth.coinbase
"0x634c921bfbad7756c7988ea74e4bdf5e5387620d"
>
```

# etherの採掘
etherコインの採掘は、`miner.start(thread_num)`で行う。`thread_num`には実行するCPUスレッド数を指定する。指定しない場合は、動作環境のCPUコア/スレッド数で自動実行する。

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

採掘を開始すると、CPU使用率(%usr)は一気に高騰する。

```
$ dstat -tc
----system---- --total-cpu-usage--
     time     |usr sys idl wai stl
27-12 22:14:34|  0   0 100   0   0
27-12 22:14:35|  0   1  99   0   0
27-12 22:14:36|  0   0 100   0   0
27-12 22:14:37|  0   0 100   0   0
27-12 22:14:38|  0   0 100   0   0
27-12 22:14:39|  0   0 100   0   0
27-12 22:14:40|  0   0 100   0   0
27-12 22:14:41|  1   0  99   0   0
27-12 22:14:42|  0   0 100   0   0
27-12 22:14:43|  0   0 100   0   0
27-12 22:14:44|  0   0 100   0   0
27-12 22:14:45|  0   0 100   0   0
27-12 22:14:46|  0   0 100   0   0
27-12 22:14:47|  0   0 100   0   0
27-12 22:14:48|  0   0 100   0   0
27-12 22:14:49| 58   1  41   0   0
27-12 22:14:50|100   0   0   0   0
27-12 22:14:51| 99   1   0   0   0
27-12 22:14:52|100   0   0   0   0
27-12 22:14:53| 98   2   0   0   0
27-12 22:14:54| 99   1   0   0   0
27-12 22:14:55| 98   2   0   0   0
27-12 22:14:56| 99   1   0   0   0
27-12 22:14:57| 98   2   0   0   0
```

dstatコマンドが導入されていない場合は、以下のコマンドでインストールしよう。

```
$ sudo apt install dstat
```

採掘が開始されていることの確認は、`eth.mining`コマンド。trueが表示されていれば採掘が実行中で、falseが表示されれれば停止中の状況だ。

```
> eth.mining
true
>
```

採掘したetherはブロックを形成する。ブロックチェーンに何番目までブロックが連なっているかを`eth.blockNumber`コマンドで確認することが出来る。

```
> eth.blockNumber
20
>
```

ハッシュレートを確認すると、下記の通り数値が表示される。ハッシュレートとは、1秒あたりの計算力、採掘速度のことで、単位は`hash/s`。この数値が表示されている限り演算が続いている。

```
> eth.hashrate
2455
>
```

# etherの採掘停止

採掘の停止は以下のコマンドで行う。

```
> miner.stop()
null
```

コマンド実行後、即時に採掘が停止しないことがある。採掘開始時も同様で、即座に処理は開始されないが、これらの動きはDAGファイル生成に伴った初回だけの動作のようだ。

**DAG**という1GBの巨大なファイルを作成しているためであり、DAGファイルは、ブロックチェーンのハッシュ計算のために使用されるデータファイルである。このDAGファイル生成の間、採掘処理の開始・終了処理が実行される。AMD Ryzen 7 で10分程度要した。

DAGファイルは実行ユーザのホームディレクトリ直下`.ethash`フォルダ内に作成されていた。

```
$ ls -lh /home/kana/.ethash
合計 2.1G
-rw-rw-r-- 1 kana kana 1.0G 12月 27 22:24 full-R23-0000000000000000
-rw-rw-r-- 1 kana kana 1.1G 12月 27 22:35 full-R23-290decd9548b62a8
```

# 採掘したブロックの確認
採掘したブロックの内容を表示する。`eth.blockNumber`コマンドの表示結果をもとに、任意のブロックを`eth.getBlock(number)`コマンドで確認する。

```
> eth.getBlock(19)
{
  difficulty: 132160,
  extraData: "0xd883010919846765746888676f312e31352e36856c696e7578",
  gasLimit: 131749155,
  gasUsed: 0,
  hash: "0xf38872f5d72d585f6c8ba761b14d2e1c2445686c0fa04a0e13904bf772a7e918",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x634c921bfbad7756c7988ea74e4bdf5e5387620d",
  mixHash: "0x29b6d7cd55847d90b0d91853093ece9ded53babc5308dbedfc60f4af52c77168",
  nonce: "0x3de0229868f19a05",
  number: 19,
  parentHash: "0x02af21c8c989e4d2ac63846c3acb8ef708c16d86006a0367994ca585b0c35c3e",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 537,
  stateRoot: "0x9cdf5e057662eafa56503ed8d8fedb7580605d22961a5591665d1f5beea20618",
  timestamp: 1609075546,
  totalDifficulty: 2516544,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}
>
> eth.getBlock(20)
{
  difficulty: 132224,
  extraData: "0xd883010919846765746888676f312e31352e36856c696e7578",
  gasLimit: 131620495,
  gasUsed: 0,
  hash: "0xb53bf57600f78f9f4d0015b9e15f0901b99049d23e65ebc9dfa6460eba8e83ae",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x634c921bfbad7756c7988ea74e4bdf5e5387620d",
  mixHash: "0xd62344a2afbd419ce1e7c38c8664fcdeb35340a4de57fba2c2e5e7e94bdf42fc",
  nonce: "0x45064ec15863ac8d",
  number: 20,
  parentHash: "0xf38872f5d72d585f6c8ba761b14d2e1c2445686c0fa04a0e13904bf772a7e918",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 537,
  stateRoot: "0xd59b4f9158a04312b607464ac5c331142fa2c18f1d324b512f310791b7010a18",
  timestamp: 1609075547,
  totalDifficulty: 2648768,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}
> 
> eth.getBlock(21)
null
>
```

20ブロック目の`parentHash`には、19ブロック目のハッシュ値が記されている。`parentHash`には、親ブロックのブロック・ヘッダ・ハッシュを指す。19ブロックの子が20ブロック目であるという意味である。

このようにブロックが連なるように台帳に記録される。ブロックチェーンと呼ばれる分かりやすい部分だ。

# 採掘報酬の確認
採掘した報酬の確認は`eth.getBalance(eth.accounts[Number])`コマンドで、EOAアカウントを指定する。`eth.accounts`コマンドでEOAアカウント情報を確認し、それぞれ実行してみると、coinbaseである[1]番目のアカウントにetherの持ち高が表示される。採掘に成功していると判断できる。「wei」の単位 で持ち高が表示されるコマンドだ。

```
> eth.coinbase
"0x634c921bfbad7756c7988ea74e4bdf5e5387620d"
>
> eth.accounts
["0x911e18204582a6de08dd2b1f7540b9167ce93b67", "0x634c921bfbad7756c7988ea74e4bdf5e5387620d"]
>
> eth.getBalance(eth.accounts[0])
0
> eth.getBalance(eth.accounts[1])
100000000000000000000
```

単位を「ether」で表示するには`web3.fromWei(eth.getBalance(eth.accounts[Number]),"ether")`コマンドを用いる。

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

丁度100ether。

# まとめ
CPU負荷を見ながら操作すると、採掘（マイニング）の処理負荷を実感できるので、ぜひやってみてほしい。