Node.jsでモナコインの送金がしたい。そのコード例と思しきものを読んでみた。さっぱり理解できなかった。
経緯
モナコインを送金する方法を調べたとき、コメントで以下を紹介してもらった。
今回はこれを調査する。Node.jsでモナコインの送金ができるようになるはず。それができればElectronでも同じことができるはず。ElectronでMpurseが使えなかった(Chrome拡張機能サポートを使用してもダメ)としても送金できるようになるはず、だと思いたい。
これまでの調査
これまでモナコインを送金するプログラムを調査してきた。
- MasteringBitcoin PDFを読んで暗号通貨のトランザクション概念について学ぶ
- Mpurse APIで送金する
- mpchain APIで送金する
- Node.jsで送金する
Mpurse APIならできるが、それ以外はまだわからない。Mpurseは内部でmpchain APIを呼び出しているようだが、その使い方がよくわからなかった。Node.jsでの方法は未調査だったため、今回はそれをやってみようと思う。
本当はフルノードをインストールして基礎となるコマンドから勉強するのがよさそう。でも取引データのサイズが膨大すぎてムリ。そこで軽量ノードであるelectrumのモナコイン版を入れようと思ったが、できなかった。
今回はのこる最後の手がかりNode.jsでの方法を探る。
調査
sample-sending-monacoin/app.js
記事をみるとフルノードいらずでモナコイン授受する方法としてsample-sending-monacoin/app.jsコードがあるという話らしい。
タイトルからして送金処理かと。私にはコードを見てもどこで何をしているのかよくわからなかった。まずは雰囲気で読んでみる。
使用パッケージ
コードでは以下のようなパッケージを利用していた。
const bitcoin = require('bitcoinjs-lib');
const coininfo = require('coininfo');
const coinselect = require('coinselect');
const ElectrumClient = require('electrum-client');
こいつらの役割分担すらわからない。
キーワードで読む
おそらくelectrum-clientを使って、指定サーバに送金処理を依頼している。そのために必要な細かい処理をbitcoinjs-lib, coininfo, coinselectでやっているのだと思われる。
bitcoin
const keyPair = bitcoin.ECPair.fromWIF(wif, network);
const fromAddress = keyPair.getAddress().toString();
coininfo
const network = coininfo('MONA').toBitcoinJS();
coinselect
.then(utxos => coinselect(utxos, targets, feeRate))
electrum-client
const ElectrumClient = require('electrum-client');
const cli = new ElectrumClient(50001, 'electrumx.tamami-foundation.org', 'tcp');
cli.connect()
.then(() =>
cli.subscribe.on('blockchain.headers.subscribe', (v) => console.log(v)))
.then(() => cli.server_version('2.7.11', '1.0'))
.then(console.log)
.then(() => cli.blockchainAddress_listunspent(fromAddress))
.then(utxos => coinselect(utxos, targets, feeRate))
.then(res => {
// .inputs and .outputs will be undefined if no solution was found
if (!res.inputs) throw new Error('No input');
if (!res.outputs) throw new Error('No output');
let txb = new bitcoin.TransactionBuilder(network);
res.inputs.forEach(input => txb.addInput(input.tx_hash, input.tx_pos));
res.outputs.forEach(output => {
// watch out, outputs may have been added that you need to provide
// an output address/script for
if (!output.address) {
output.address = fromAddress;
}
txb.addOutput(output.address, output.value);
});
for (let i = 0; i < res.outputs.length; i++) {
txb.sign(i, keyPair);
}
return txb.build().toHex();
})
.then(hex => cli.blockchainTransaction_broadcast(hex))
.then(console.dir)
.then(() => cli.close())
.catch(console.error);
最後の長い処理が送金処理だと思われる。
- 入力するコインと出力するコインを設定する:
input
,output
- 署名する:
sign
- 送金処理を依頼する:
broadcast
キーワードからそう判断した。
所感
さっぱりわからないので、まずは各パッケージを個別に使ってみることからはじめたほうが良さそう。とくにelectrum-clientとbitcoinjs-libがキモと思われる。