NISのデータベースの中身を見てみる

NEMと付き合い始めてもうすぐ2年、元々データの分析や集計に興味があって、以下のようなものを作成しています。

- Twitter bot NEM Harvest Summary
https://twitter.com/NEM_Harvest
- NEM Transfers Dashboard
http://nemdashboard.com

どんなものかというと、日々のハーベストの平均や１日あたりのトランスファーの数を可視化しています。なかなかに便利だと思うので、是非フォロー、ご贔屓にお願いします。  

さて今回の記事で取り扱うのは、扱われるデータをどうやって取得しているかについてです。トランスファー数とかハーベストの平均値とか、一体どうやって計算しているかという話です。  

## データの在り処：NISを建てよう

NIS(NEMのノード)を立てると、packageフォルダと同一階層にnemというフォルダが作成されます。  
そのフォルダの内部にH2データベースが作成されます。このデータベースには、NEMのいろいろな情報が詰まっています。ここからトランスファー数や送信者、受信者の情報を抽出しデータ集計をかけてTwitter botへのつぶやき、ダッシュボードへの反映を行っています。   

基本的にはNISを入手してシェルスクリプトを起動するだけで、難易度は決して高くありません。気をつけるべき点としては高負荷に耐えるためメモリ割り当てを十分に行うことくらいでしょうか。
NISのダウンロードはこちらから
https://nem.io/downloads/

構築手順は44_ukさんの記事が参考になります。(リンク切れ、2022/4/8確認)
http://blog.44uk.net/2017/03/20/nem-setup-on-raspberrypi-to-harvest/

## H2コンソールで接続する

私が使っているUbuntu 16.04では以下の手順で起動します。jarやDBのパスは適宜変更してください。

```{}
cd /home/ubuntu/h2/bin/
java -cp h2-1.4.196.jar org.h2.tools.Server -webAllowOthers
```

以下のようなログイン画面がブラウザ上で起動します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/309172/50af1d64-ae45-21ae-0811-eb300ea7d91d.png)


## テーブル一覧

以下に示す通り、ACCOUNTSからTRANSFERSまで18のテーブルが存在します。特にNEMの特徴であるモザイク、マルチシグ、ネームスペースに関するテーブルが多くあります。
リレーション図はかなり複雑になってしまうので省略し、各テーブルがどんなデータを保持しているか簡単に説明します。特にマルチシグ関連は中々に複雑なので実際に活用を検討する際はテストネットなどを活用することをおすすめします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/309172/c44e038d-e937-781e-69ab-012ff06a1cb7.png)

### ACCOUNTS
アドレスと公開鍵の組み合わせ

### BLOCKS
各ブロックの情報
ハーベストフィーなどはここから取得しています。

### IMPORTANCETRANSFERS
委任ハーベスト開始宣言のトランスファーの履歴

### MINCOSIGNATORIESMODIFICATIONS
マルチシグの最低連署者数の変更履歴

### MOSAICDEFINITIONCREATIONTRANSACTIONS
モザイク作成時のトランスファー履歴

### MOSAICDEFINITIONS
モザイクの定義
作成者、名前、説明、levyなど

### MOSAICPROPERTIES
モザイクの設定
最初の発行量、移動可能か、量の変更が可能か、小数点以下の設定など

### MOSAICSUPPLYCHANGES
モザイクの発行量変更履歴

### MULTISIGMODIFICATIONS
マルチシグの設定変更履歴

### MULTISIGRECEIVES
マルチシグトランザクションの受信者

### MULTISIGSENDS
マルチシグトランザクションの送信者（署名者）

### MULTISIGSIGNATURES
マルチシグの署名履歴

### MULTISIGSIGNERMODIFICATIONS
マルチシグの署名者の変更履歴

### MULTISIGTRANSACTIONS
マルチシグトランザクションの履歴

### NAMESPACEPROVISIONS
ネームスペースレンタル（トランスファー）履歴

### NAMESPACES
ネームスペース名、所有者など

### TRANSFERREDMOSAICS 
モザイクのトランスファー履歴

### TRANSFERS
各トランスファーの詳細
誰から誰へ、数量、メッセージはあるかなど。

## 実際のbot、ダッシュボード運用

組み込みモードのH2データベースには、一つのプロセスしか接続できないという制約があります。NISが動いているときには、データベースへと接続できません。  
また、bot運用ではいちいちGUIのコンソールを開いてデータベースに接続してデータ抽出などやっていられません。

そのため、NEM Harvest SummaryとNEM Transfers Dashboardでは以下のような運用をしています。  

(NISを起動させておく)
1. データベースをコピー
2. コピーしたデータベースに接続、必要なデータをCSVで出力
3. CSVをもとに、Rでデータ集計。集計結果をCSVで出力
4. 集計結果CSVをベースにpythonでbotツイート/AWS CLIでS3へダッシュボードファイルのアップデート

コツとしてはデータベースをコピーするステップでしょうか。  
正直スマートさのかけらも感じられない方法ではあるのですが、意外と問題なく運用できています。

2のデータベースに接続してデータを取得するステップに関しては、こちらのサンプルコードを参照して下さい。

https://github.com/fmhk23/NEM_Harvesting_Summary/blob/master/CsvCreator.java

BLOCKSテーブルからハーベストに関する情報、TRANSFERSテーブルからトランスファー数やネットワークに参加したアドレスの数を計算しています。

## 終わりに

私はデータ分析という、NEMとは直接関係ない目的でNISを立ててデータベースを参照していますが、実際にNEMを使うアプリケーションやサービスなどでもNISを立ててデータベースを参照するというアプローチは有効になり得ます。
API経由でいろいろできるのがNEMの良いところの一つですが、古いデータが重要な場合や大量のデータを参照したい時、また取得すべきデータの内容によってはデータベースへのアクセスも選択肢になります。

NEMの今後のアップデートによりテーブルの構成などは変わっていくものかとは思います。（なのでNIS依存のアプリケーションを今から作るのはあまり良くないかも）

そんな状況ではあるのですがしばらくはこのまま役に立つと思いますし、データベースを活用するというアプローチの紹介になるので、少しでも参考になれば幸いです。