仮想通貨の初心者が１時間でマイニングを始めるまで

## はじめに
**ブロックチェーン**の勉強用に仮想通貨の**マイニング**を始めてみた。
マイニングは誰でも行うことが可能で、マイニングする人を**マイナー**（採掘者）と呼ぶ。
マイナーは、他のマイナーよりも早く**ナンス**（後述）を見つけることで新しい**ブロック**を生成し、手数料と報酬を得ることができる。

マイニングを始めるには次の３つが必要になる。

1. コンピュータ
2. ウォレット
3. マイニングツール

Qiitaの読者ならコンピュータは当然持っているとしても、ゲーマーでも無ければ高性能なグラフィックボード（GPU）まで積んでいるケースは少ないだろう。PCでの仮想通貨マイニングは**GPUマイニング**が主流だが、**Monero**という仮想通貨なら、CPUでの処理に適したアルゴリズムを採用しているので、GPUに頼らない**CPUマイニング**が可能だ。

## 通貨 Monero（XMR）の特徴
MoneroなどのCryptoNight系コインが採用する**PoW**（プルーフ・オブ・ワーク）アルゴリズムは、CPUマイニングができる暗号通貨であり、匿名性が高く、取引に個人情報が不要という特徴がある。メールアドレスすら要らない。
その特徴ゆえマネーロンダリングの懸念があり、国内で取り扱っている取引所は無い。**ダークウェブ**の決済手段に採用されることも多く、レートが公的機関の動きに影響され易い。

特定用途向け集積回路**ASIC**を積極的に排除するという考え方を持っていて（ASICが開発されると**ハードフォーク**してアルゴリズムを変更する）、**ハッシュレート**（後述）が低く、CPUやGPUでもマイニングできる。

なお、Moneroの匿名性は**リング署名**という技術で実現している。実装レベルで興味がある人は[【Moneroのリング署名。理論を噛み砕いて実装。】](https://qiita.com/ABmushi/items/80adb1256a0085382301)の記事が面白いと思う。

## ウォレット
ウォレットとは文字通り財布だ。仮想通貨の保管はもちろん、他のウォレットへの送金や受取時にも使う。ウォレットがあれば取引所を介さずとも個人間で送金できる。

仮想通貨が海外では暗号通貨（crypto currency）と呼ばれている通り、**公開鍵**と**秘密鍵**をペアにする**公開鍵暗号基盤（PKI）**がベースになっている。
送金データを秘密鍵で電子署名し、公開鍵と一緒に**P2Pネットワーク**に送信することで、送金者本人が作成したものか検証できるようになっている。秘密鍵が分かれば誰でも自由に通貨を送付できるわけだから、秘密鍵を盗まれることはコインを盗まれることと同じなのは理解いただけると思う。過去のコイン流出事件の殆どは取引所などからの秘密鍵の流出である。ブロックチェーン技術そのものに欠陥があるわけではない。秘密鍵は厳重に保管されなければならない。
秘密鍵をオフライン環境に保管することを**コールドウォレット**と言う。コールドウォレットはインターネットから完全に切り離されているため、不正アクセスによって盗まれる危険性は無い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/bf25c6cb-fa88-ce48-bc5e-4616e7225b1a.png)
:small_red_triangle: コールドウォレットのひとつであるペーパーウォレットのイメージ画像
（https://www.bitaddress.org/ で作成。もちろん秘密鍵やビットコインアドレスは架空である）

### ウォレットの作成
自分のウォレットを持つには、Moneroの公式サイトからもリンクされている [MyMonero](https://wallet.mymonero.com/) が手軽だ。登録にメールアドレスすら必要ない。

サイトの右下にある`Create new wallet`をクリックすると、25の単語からなる *Mnemonic code* が表示されるので、これをメモしておくだけである。秘密鍵は暗号化されており、次回、`Use existing wallet` から *Mnemonic code* を入力すると秘密鍵が復元され、ウォレットに接続できるという仕組みだ。

`My Monero Wallet` をクリックすると**ウォレットアドレス**（公開鍵から生成された16進数字の羅列）が表示される。これがマイニングの報酬を受け取るアドレスになるので控えておこう。

## マイニング
マイニングでは、**ランダムなナンスをハッシュ関数に代入してみて正解かどうかを確認する**という、膨大な量の計算を延々と繰り返す（あまりに非生産的なのでチアなどの地球に優しい仮想通貨も出始めている）。
ナンスとは、Number used once（一度だけ使用される使い捨ての数字）の略で、その実態は32ビットの数値だ。ブロックのハッシュ値が採掘難易度（ディフィカルティー）よりも小さくなれば正解となり新しいブロックを生成できる。

1秒間に何回ハッシュ計算できるかを測る指標が**ハッシュレート**だ。例えば100H/sであれば1秒間に100回の計算がされているという意味になる。その通貨全体でハッシュレートが高いということは、多くのマイナーが参加しているということであり、取引の承認スピードが増すので、通貨の信頼度（価値）も高まるという仕掛けになっている。

マイニングには、1人で行う**ソロマイニング**、複数人で行う**プールマイニング**、マイナーの団体に投資する**クラウドマイニング**がある。
ソロマイニングは成功すると報酬を独り占めできるものの、ブロックチェーン上のすべての情報をダウンロードした大容量の**フルノード**を自分で持つ必要があるのと、機材（**リグ**と呼ぶ）と電気代の負担がのしかかる。
プールマイニングでは、マイニングプールと呼ばれるチームに参加する。プールのメンバーは自分のマシンパワーを提供する見返りに、手数料を差し引いた成功報酬を貢献度に応じて受け取る。

今回はメジャーな[MoneroHash](https://monerohash.com)というマイニングプールに参加してみる。やはり会員登録の必要がなく誰でもすぐに利用できる。

### マイニングツールのインストール
では、いよいよマイニングツールのインストールに取り掛かろう。
導入する環境は次の通り。

```:導入環境
# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.6 LTS
Release:        16.04
Codename:       xenial
```

Moneroのマイニングツールは https://monerohash.com/#getting_started で紹介されている。
どれでも良いと思うが、今回は`xmr-stak`をGitHubからクローンしてビルドする。以前は`xmr-stak-cpu`というのがあったらしいが統合されたようだ。

```:ビルド
apt -y update
apt -y install libmicrohttpd-dev libssl-dev cmake build-essential libhwloc-dev
cd /usr/local/src
git clone https://github.com/fireice-uk/xmr-stak.git
mkdir build && cd build
cmake .. -DCUDA_ENABLE=OFF -DOpenCL_ENABLE=OFF
make install
```

```:セットアップ
cd bin
./xmr-stak

Use simple setup method? (Y/n)
n <== 入力
Please enter:
- Do you want to use the HTTP interface?
Unlike the screen display, browser interface is not affected by the GPU lag.
If you don't want to use it, please enter 0, otherwise enter port number that the miner should listen on
0 <== 入力
Configuration stored in file 'config.txt'
Please enter:
- Please enter the currency that you want to mine: 
        - aeon7
        - bbscoin
        - bittube
        - cryptonight
        - cryptonight_bittube2
        - cryptonight_masari
        - cryptonight_haven
        - cryptonight_heavy
        - cryptonight_lite
        - cryptonight_lite_v7
        - cryptonight_lite_v7_xor
        - cryptonight_r
        - cryptonight_superfast
        - cryptonight_turtle
        - cryptonight_v7
        - cryptonight_v8
        - cryptonight_v8_double
        - cryptonight_v8_half
        - cryptonight_v8_reversewaltz
        - cryptonight_v8_zelerius
        - cryptonight_v7_stellite
        - cryptonight_gpu
        - cryptonight_conceal
        - graft
        - haven
        - lethean
        - masari
        - monero
        - qrl
        - ryo
        - torque
        - plenteum
        - zelerius

monero <== 入力
- Pool address: e.g. monero.miner.rocks:5551
monerohash.com:2222 <== 入力（このポートは Low & mid range CPU 向け）
- Username (wallet address or pool login):
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX <==  MyMonero のウォレットアドレスを入力
- Rig identifier for pool-side statistics (needs pool support). Can be empty:
 <== 何も入力せずにEnter
- Does this pool port support TLS/SSL? Use no if unknown. (y/N)
N <== 入力
- Do you want to use nicehash on this pool? (y/N)
N <== 入力
- Do you want to use multiple pools? (y/N)
N <== 入力
```

すべての質問に回答すると、設定がテキストファイルに保存され、マイニングが始まる。

```:実行
-------------------------------------------------------------------
xmr-stak 2.10.7 fd19a5d

Brought to you by fireice_uk and psychocrypt under GPLv3.
Based on CPU mining code by wolf9466 (heavily optimized by fireice_uk).

Configurable dev donation level is set to 2.0%

-------------------------------------------------------------------
You can use following keys to display reports:
'h' - hashrate
'r' - results
'c' - connection
-------------------------------------------------------------------
Upcoming xmr-stak-gui is sponsored by:
   #####   ______               ____
 ##     ## | ___ \             /  _ \
#    _    #| |_/ /_   _   ___  | / \/ _   _  _ _  _ _  ___  _ __    ___  _   _
#   |_|   #|    /| | | | / _ \ | |   | | | || '_|| '_|/ _ \| '_ \  / __|| | | |
#         #| |\ \| |_| || (_) || \_/\| |_| || |  | | |  __/| | | || (__ | |_| |
 ##     ## \_| \_|\__, | \___/ \____/ \__,_||_|  |_|  \___||_| |_| \___| \__, |
   #####           __/ |                                                  __/ |
                  |___/   https://ryo-currency.com                       |___/

This currency is a way for us to implement the ideas that we were unable to in
Monero. See https://github.com/fireice-uk/cryptonote-speedup-demo for details.
-------------------------------------------------------------------
[2019-09-22 21:43:55] : Mining coin: cryptonight_r
[2019-09-22 21:43:55] : Starting 1x thread, affinity: 0.
[2019-09-22 21:43:55] : hwloc: memory pinned
[2019-09-22 21:43:55] : Starting 1x thread, affinity: 1.
[2019-09-22 21:43:55] : hwloc: memory pinned
[2019-09-22 21:43:55] : Starting 1x thread, affinity: 2.
[2019-09-22 21:43:55] : hwloc: memory pinned
[2019-09-22 21:43:55] : Fast-connecting to monerohash.com:2222 pool ...
[2019-09-22 21:43:55] : Pool monerohash.com:2222 connected. Logging in...
[2019-09-22 21:43:56] : Difficulty changed. Now: 5000.
[2019-09-22 21:43:56] : Pool logged in.
[2019-09-22 21:43:56] : enable cryptonight_r asm 'intel_avx' cpu's
[2019-09-22 21:43:56] : enable cryptonight_r asm 'intel_avx' cpu's
[2019-09-22 21:43:56] : enable cryptonight_r asm 'intel_avx' cpu's
[2019-09-22 21:44:04] : CPU: Share accepted. Pool: monerohash.com:2222
[2019-09-22 21:44:04] : CPU: Share accepted. Pool: monerohash.com:2222
```

設定が正しければ、ほどなくして `New block detected` と表示されるはずだ。

`h`キーを押すとハッシュレートが表示される。

```
HASHRATE REPORT - CPU
| ID |    10s |    60s |    15m | ID |    10s |    60s |    15m |
|  0 |   61.4 |   61.4 |   61.5 |  1 |   62.1 |   62.1 |   62.2 |
|  2 |   62.1 |   62.1 |   62.2 |
Totals (CPU):   185.6  185.6  185.9 H/s
-----------------------------------------------------------------
Totals (ALL):    185.6  185.6  185.9 H/s
Highest:   187.8 H/s
```

`r`キーを押すと結果レポートが表示される。

```
RESULT REPORT
Currency         : monero
Difficulty       : 22335
Good results     : 18 / 18 (100.0 %)
Avg result time  : 146.3 sec
Pool-side hashes : 332286

Top 10 best results found:
|  0 |          1339762 |  1 |           783934 |
|  2 |            91178 |  3 |            59930 |
|  4 |            59417 |  5 |            56694 |
|  6 |            48263 |  7 |            47158 |
|  8 |            38573 |  9 |            34075 |

Error details:
Yay! No errors.
```

ここで、別ターミナルから`top`コマンドで見ると、`xmr-stak`のCPU利用率が100%になっているのが確認できると思う。

```
top - 03:04:18 up 149 days, 13:16,  2 users,  load average: 3.94, 3.91, 3.91
Tasks: 137 total,   1 running, 136 sleeping,   0 stopped,   0 zombie
%Cpu0  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  0.3 us,  0.0 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  8080552 total,   141784 free,   895976 used,  7042792 buff/cache
KiB Swap:  8292348 total,  8292108 free,      240 used.  6751952 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                        
22389 root      20   0  591928   8892   7428 S 299.7  0.1 945:47.00 xmr-stak                                                       
```

`htop`コマンドを使うと色付きで視覚的にも見易い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/a73a0271-1b04-8d88-7696-acca4bd17ee2.png)

サービスとして自動起動させるなら、次のようにする。

```ini:/lib/systemd/system/xmr.service
[Unit]
Description=xmr
After=network.target
[Service]
ExecStart=/usr/local/src/xmr-stak/build/bin/xmr-stak -c /usr/local/src/xmr-stak/build/bin/config.txt -C /usr/local/src/xmr-stak/build/bin/pools.txt --cpu /usr/local/src/xmr-stak/build/bin/cpu.txt
User=root
[Install]
WantedBy=multi-user.target
```

```:有効化
systemctl daemon-reload
systemctl enable xmr.service
```

```:起動
systemctl start xmr.service
```

## 報酬
マイニングプールのサイトでウォレットアドレスを入力すると、引き出し可能な報酬を確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/dce43347-ea07-a5d5-5136-da250915683c.png)
Moneroから日本円への変換ツールは [CoinGecko](https://www.coingecko.com/ja/%E3%82%B3%E3%82%A4%E3%83%B3/%E3%83%A2%E3%83%8D%E3%83%AD/jpy) が便利だ。
このPCの平均ハッシュレートだと１日に概ね10円くらい掘れる感じか。電気代を差し引けばプラスにはならないと思うので、あくまで趣味と割り切るべきだろう。