はじめに
Monacoin に限らず、Bitcoin 由来の暗号通貨(いわゆるオルトコイン)のサービス開発入門者が陥ってしまう罠に 「フルノード 1 を立ち上げようとする」 があります。
これをやってしまうと、外部公開する際に VPS や VMインスタンスを調達する必要が生じ、保守コストが跳ね上がります。お勧めできません。
お勧めは Heroku や Azure Web のような PaaS を使うことなのですが、なぜか必要な情報を見かけないので、具体的なコードでコツを説明していきます。
筆者の個人的趣味で Node で例示しますが、Python 2 や Ruby などでも同じ方針で実装可能です。
monacoind の代わりに何を使うのか
インターネットに公開されているブロックチェーンエクスプローラやウォレットのバックエンドを使います。
Monacoin の場合は Insight や Multi Block Explorer など複数のエクスプローラが存在しています。
ウォレット・バックエンドなら後述する ElectrumX が強力です。
これらの後ろには結局フルノードが存在するのですが、より抽象化された API によりフルノードを隠蔽してくれます。
この戦略を使う場合、UTXO の収集やトランザクションの生成や署名は、サービス内で行う必要があります3。そのあたりのソースコード量が増えるのが欠点とはいえますが、運用コストからすれば微々たるものです。
ソースコード例
「ソースコードを見たほうが早いんじゃ」という方はこちらを御覧ください。
これに Web なり Chatbot へのインタフェースを付け、やたらとアクセスしてくる、いわゆる「乞食」を弾く処理を加えれば faucet の完成です4。もちろん送付先を MA375uccLzk4w5MmsGuex24iHs11tYtdsL
から変更しないといけません。(変更しないと筆者が儲かります)
「ソースコードだけじゃわからんぞ」という方に向けていくつかコツを記します。
coininfo は神
魔改造が施されすぎたいくつかの例外はあるものの、Bitcoin 由来のオルトコインは Bitcoin のライブラリをそのまま流用できます。その際に必要な作業として core の chainparams.h
に記述されているようなパラメータの追加が必要になります。
npm パッケージ coininfo はこの辺りの記述を容易にしてくれます。
const network = coininfo('MONA').toBitcoinJS();
network.messagePrefix = ''; //hack
事前に上記のようにしておき、WIF (Wallet Import Format) 形式の秘密鍵から鍵ペアを作成する際や
const keyPair = bitcoin.ECPair.fromWIF(wif, network);
未署名トランザクションを生成する際に
let txb = new bitcoin.TransactionBuilder(network);
など指定します5。
あとの処理フローは Bitcoin の豊富な情報をそのまま使えます。
Electrum-client も神
const ElectrumClient = require('electrum-client');
const cli = new ElectrumClient(50001, 'electrumx.tamami-foundation.org', 'tcp');
これだけで electrum サーバとお話できるようになります。
Monacoin は有志による ElectrumX サーバ群が充実しており、Android ウォレット Coinomi もバックエンドは ElectrumX であることから、安定した運用を期待できます。
もしそれらが全滅したら(たぶん無いと思いますが)、自前で立てるしか無いですが、Kubernetes 環境へデプロイするためのスクリプトが公開されており、最近のクラウド環境を使えば保守の手間はかなり減らせます。
まとめ
フルノードを立てるので疲弊するのはもうやめよう。作りたいのはWebサービスだったはず。サービスに集中!
お詫び
JPYマイニングに追い立てられていて、アドベントカレンダ遅刻しました (平伏)