Neutrinoで働くブロックチェーンエンジニアのブログ

渋谷の専門特化コワークNeutrinoに入居してブロックチェーン領域のエンジニアとして働いています。(Neutrino運営企業とは直接関係ありません)

NEMのモザイクぜんぶ抜く

池の水ぜんぶ抜く」的な企画です。

NEMの内部データベースはH2dbというRDBでできていて、MySQLOracleと同じようなRDB(リレーショナルデータベース)で格納されています。NEMJavaで書かれていて、データベースもRDBなので、コードや内部データベースを見ると、割と普通の業務システムっぽいなという感覚を抱くことがあります。

データをP2Pで共有して、暗号化してまとめているプロセスがブロックチェーンで、トランザクションを格納するデータベースそのものがブロックチェーンというわけではない、と言えるかなと思ったりします。普通はNEM公式で提供されているAPIを使ってデータを取ったりするのですが、内部データベースを直接いじればごそっとデータが取れるんじゃないか、というのが今回の記事です。

ちなみにこのネタ前から温めていたんですが、似たようなことをやられている方を今月見つけまして、リスペクトとしてこちらの記事を載せさせていただきます。(やや2番煎じ感が)よろしくお願いします。

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

それではやっていきます。

環境

  • NEM: rb2nem v0.6.96
  • Java: java version "1.8.0_131" (古いです)

DockerでNEMノードを立ててデータベース(h2db)を取り出す

とにかくデータベースを同期する必要があります。公式の「Developing NEM Docker」を参考にして進めます。

blog.nem.io

Dockerイメージのビルド

Docker Hubからビルド済みのイメージを落とすのもありですが、せっかくなのでimageをビルドするところから始めてみます。

git clone https://github.com/rb2nem/nem-docker.git
cd nem-docker/
docker build -t nem_image . #権限エラーが出たらsudoで行う

configの設定

NEMの起動コンフィグを設定します。sample configがあるので、それを名前を変えてコピーしてベースを作ります。

cp custom-configs/supervisord.conf.sample custom-configs/supervisord.conf
vi custom-configs/supervisord.conf #編集する

viの編集画面で、nisautostart=trueに設定します。

[program:nis]
user=nem
autostart=true # autostart=false

Dockerコンテナの起動

コンテナを起動します。

mkdir ./tmp/nem # cloneしたリポジトリ内で、データベースをマウントするディレクトリを作成
docker run -d -p 7890:7890 \
           -v "$PWD/tmp/nem:/home/nem/nem" \
           -v "$PWD/custom-configs/supervisord.conf:/etc/supervisord.conf" \
           --name nem \
           nem_image

コンテナができていることを確認します。

docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                  NAMES
1c81a102cdc7        nem_image           "/usr/bin/supervisord"   2 days ago          Up 33 hours         7777/tcp, 7880/tcp, 8989/tcp, 0.0.0.0:7890->7890/tcp   nem

しばらく放置してデータベースができるのを待つ

しばらくするとデータベースができます。

起動ログを見てみましょう。

docker logs nem

/usr/lib/python2.7/site-packages/supervisor/options.py:296: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
  'Supervisord is running as root and it is searching '
2018-12-19 08:32:12,726 CRIT Supervisor running as root (no user in config file)
2018-12-19 08:32:12,768 INFO RPC interface 'supervisor' initialized
2018-12-19 08:32:12,769 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2018-12-19 08:32:12,769 INFO supervisord started with pid 1
2018-12-19 08:32:13,779 INFO spawned: 'perms' with pid 8
2018-12-19 08:32:13,848 INFO spawned: 'nis' with pid 11
2018-12-19 08:32:14,856 INFO success: perms entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2018-12-19 08:32:14,857 INFO success: nis entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

しばらくすると、別のログが出てきます。

update of 400 blocksと出ているのが、同期ログだと思われます。

docker logs nem

2018-12-19 08:33:15.600 INFO ESC[0;32mchain update of 400 blocks (1 transactions) needed 1000 ms (1000000 ?s/tx)ESC[0m (org.nem.nis.sync.BlockChainUpdateContext fz)

以下コマンドで、同期したブロック高を確認できます。NEMはhttpのgetでAPIが叩けるので便利ですね。

curl http://127.0.0.1:7890/chain/height
{"height":1007865}

このまま同期が完了するまで待ちましょう。

NEMExplorerをトラストする事にして、最新ブロックを確認、そこまで同期が終わるのを待ちます。

H2dbのインストール

H2dbの公式サイトからダウンロードします。

ダウンロードすると、ビルド済のjarファイルが落とせますので、Javaで開きます。

H2サーバーを起動

$ java -cp (ダウンロードしたディレクトリパス)/h2/bin/h2-1.4.197.jar  org.h2.tools.Server #落としたバージョンによってjarファイル名称は変わるので適宜変更

接続画面が出るはずです。

f:id:naomasabit:20181224155022p:plain

h2dbをコピーして接続

 # 現在は~/experiments/nem-experienece/nem-docker/nem-dockerにいる
cp tmp/nem/nis/data/nis5_mainnet.h2.db . # データディレクトリから~/nem-dockerにh2dbをコピーする

各種設定

  • 保存済設定: Generic H2 (Embedded)のままでOKです。これは組み込みモードで1セッションしか接続できないモードですが、今回はこれで十分です。

  • ドライバクラス: org.h2.Driver

  • JDBC URL : コピーしたh2dbを指定します。

 記法は<接続方法>:<データベース種別>:<データベースのパス。ただし.h2.db拡張子はなし>  例:jdbc:h2:~/experiments/nem-experienece/nis5_mainnet - ユーザー:空欄 - パスワード:空欄

接続

接続ボタンを押して、うまく接続できると、NEMの内部データベースが見えます。

普通にRDBです。

f:id:naomasabit:20181224160309p:plain

普通にSQLでデータを見られます。

試しにACCOUNTをSELECTすると、全アドレスを見ることができます。

f:id:naomasabit:20181224160410p:plain

モザイクをSQLで抜いてみる

モザイクが関連するテーブルは主に

  • MOSAICDEFINITIONS
  • MOSAICPROPERTIES
  • MOSAICSUPPLYCHANGES

です。特にコアとなる「MOSAICDEFINITIONS」をSELECTしてみます。

SELECT NAME,DESCRIPTION FROM MOSAICDEFINITIONS LIMIT 50;

f:id:naomasabit:20181224160502p:plain

結果のNAMEがモザイク名。DESCRIPTIONが説明ですね。

上から50件のモザイクを見てみる。

TOP50件のNAME、DESCRIPTIONをとってみましょう

SELECT NAME,DESCRIPTION FROM MOSAICDEFINITIONS LIMIT 50;
NAME DESCRIPTION
red_token This token is to celebrate the release of Namespaces and Mosaics on the NEM system. This token was the fist ever mosaic created other than nem.xem. There are only 10,000 Red Tokens that will ever be created. It has no levy and can be traded freely among third parties.
tokens Super tokens of amazing value!
trollpoints Trolls... you know who you are. Act accordingly, and these rewards can be yours too. Don't forget, this is a very rare asset. Only 42 will ever be created. You will have to be at the top of your troll game if you want to be in this elite club. Will you have one?
names Namespace .doc provides varios names (aka domain). Names mosaic is intended to obtain, transfer (in future) or perform other transactions with doc. names
takaocoin Takao Coin!
pt Reward points for jpbitcoin.com
test test mosaic for ptDivisibility:0Transferable:1Mutable supply:1Requires levy:0
riddle a puzzling question
udon うどんは弾力のある麺と心温まる出汁が融合した世界一美味しい食べ物です。Owner Twitter:@udon_crypto
ocknamo おくなもの秘密を知ったものはそれを誰にも話してはならない
lolcoin lol
shit "Shitshares will be bigger than Bitcoin!" – Milan
test1 small business mosaic.Initial supply:10000 Divisibility:0 Transferable:true Mutable supply:true Requires levy:false
gold CAPLOGUEの基本通貨です。
okome What makes you glad when sent to you, whoever the sender may be.
walkingeyes Walkingeyes
gox Where is our monney? No more GOX.
tanucoin タヌ神が認めた者にのみ送られる何の意味もないコインだが...
medal タヌキップトラストから授与される名誉ある勲章。授与されたものはNEMタヌキップトラストから認められた者として責任ある行動をしなければならない。掟1.NEMの普及に貢献する。掟2.NEMへの愛を忘れない。この掟を破った場合、身の保証は出来ないTanuki Nakamoto
abv This mosaic is ABV
kanna @kanna
sample-mosaic-1234567890 Initial supply:1000Divisibility:0Transferable:falesMutable supply:trueRequires levy:false
toro 寿司のネタ等として使われるマグロの特定の部位の呼称。脂質の含量が高い腹部の身を指す。そのNEM版。
wasabi 地下茎をすりおろしたものは、日本料理の薬味として寿司などに添えられる。そのNEM版。
uni 鮮度が重要視され、生きているものの殻を割ってその場で食べると特に美味。そのNEM版。
jalebi jalebi mosaics description
rkgkcoin らくがきacのらくがきコインです!
act act token test
kycoin Kycoin is one of shitcoins. The issuer guarantees that this mosaic is worthless.
punt Antwerpse A-kaart punten
maruicoin マルイ
soncoin そんさんこいん
is-abc-1 Hash: bfa8baba00a85a195c32b9323dbf6a40bc0eed81db955e9fb4a1f32399f88e07
me A beer tip!
takaocoin たかおこいん
akippa 駐車場空きスペース
kandencoin 関電コイン
chaco “chaco” はすべての人が幸運を手に入れることを願っています。
minarin みなりん*コイン
music 音楽
dancing 踊ること
katio i love you :)
citizen This Mosaic represents a Belgian citizen. An account that has received 1 citizen from Belgium will point to the official account of the citizen.
notary This Mosaic represents a Belgian Notary. An account that has received 1 notary from Belgium will point to the official account of the Notary.
undefined no data found.
hbis-1 Demoasset for Democompany HBIS-1
primarybomb キラークイーンが触れたものを爆弾に変える。
secondarybomb 「熱」に反応して対象を自動的に追尾し、爆発攻撃する。
tertiarybomb 吉良吉影の正体を知る、「スタンド使いでない人間」に憑依して発動する。その間キラークイーンは憑依した人間を完璧にガードし、敵からの攻撃や自殺を防ぐ。
auriga 教授モザイク

日本語モザイクが多くて、NEMが日本向けのマーケティングをしていた事が見えるような気もします。

全モザイクはこちら。

https://docs.google.com/spreadsheets/d/1PAQMx_szaF1QSKAgY_sK5IkFEpzOu6teSgZ8cMwCCD4