開発によく使うbitcoin 関連cliツール

joemphilips
GBEC Tech Blog
Published in
8 min readJan 15, 2019

宮本です。

今日は自分が開発時に使う Bitcoin 関連 cli ツールベスト4 を共有します。使用頻度としては docker とか jq とかの方が高いんですが、Bitcoinと直接の関連がないので今回は書いてません。

bitcoinが専門ではないけれども業務で使う必要が出てきたプログラマーの方に役立つと思います。

4位: btcdeb

bitcoinのスクリプトをステップ実行してくれるデバッガです。以下のコマンドで使います。

btcdeb --tx=<hexシリアライズされたtx> --txin=<入力に使われるtxのhex>

トランザクションの input には一つ前のトランザクションの idと index (二つを合わせてアウトポイントと呼びます)が入っているため、どのインプットが `txin` に対応するものなのかがわかり、その input を実行しています。

スクリプトの実行だけなのになぜトランザクション全体を渡すの?と思ったかもしれませんが、これは署名の検証などでトランザクションのデータが必要になるためです。

emscripten で wasm にコンパイルすることもできるみたいですが、今の所利用例は見たことがありません。ブラウザで使いたい場合、現状パフォーマンスが問題になることもそうないので大人しく bitcoinjs-lib を使えば良いのではないでしょうか、そのうち bitcoin-ts が完成してきたらそっちを使えば良いと思います。

ブラウザベースのデバッガは他に色々あるのですが、tx を丸ごと指定するので署名検証が楽という利点がこちらにはあります。ただ、多くの場合は適当なbitcoinライブラリのREPLで十分なので利用頻度は低いです。

3位: bcoin

node.js の bitcoin library です。別に bcoin でなくても良い(bitcoinjs-lib とか python のやつとか) のですが、REPL が付いている言語のライブラリを一つ覚えておくとサッと使えて便利です。

bcoin が嬉しいのはインメモリで wallet なんかも弄れる点にあります。

node --experimental-repl-awaitで起動して使います。 --experimental-repl-await はnode.js 10 以降の機能で、 async/await を使えるようになります。wallet や 、wallet/node に対するクライアント (bclient) を使う場合 async API が大量にあるので、on にしておくと便利です。

自分がよく行う手順は以下みたいな感じです。複雑な例を見せるため、p2sh-p2wsh のマルチシグをinput にもつ tx を作成し、シリアライズしています。

let b = require("bcoin")// 1. 鍵とスクリプトの準備
let k1 = b.KeyRing.generate() // 適当な秘密鍵を生成します。
let k2 = b.KeyRing.generate() // マルチシグ用の鍵も生成
// 2-of-2 のマルチシグスクリプトを作ります。
let script = b.Script.fromMultisig(2, 2, [k1.publicKey, k2.publicKey])
// keyring には input の形式も指定できます。のちの getAddress() に影響します。
k1.witness = true // segwit を使うことを明示します。
k1.nested = true // p2sh-nested-witness であることを明示します。
k1.script = script
k1.refresh() // cache をクリア
// 2. ダミーインプット用のトランザクションを作成
let cb = new b.MTX() // Mutable Transaction クラスを生成。他のライブラリでTransactionBuilder と呼ばれているものに近いです。
// cb は coinbase の略です。
cb.addInput(new b.Input()) // 引数なしで Input インスタンスを生成すると、coinbase トランザクションの input が生成されます。
// value の単位は satoshi です。
cb.addOutput({ address: k1.getAddress(), value: 1000})
// 3. 目的の tx を作成
let mtx = new b.MTX()
mtx.addOutput({b.KeyRing.generate().getAddress(), value: 970})
mtx.addTX(cb, 0) // 一つ前のtxをinputにセットします。第二引数は output の index です。
// scriptSig(あるいは scriptWitness)を構築します。第一引数は input の index です。
mtx.scriptInput(0, cb.outputs[0], k1) // スクリプトの準備です。成功すれば true を返します。
mtx.signInput(0, cb.outputs[0], k1) // 署名します。
mtx.signInput(0, cb.outputs[0], k2) // マルチシグなのでもう一回
let tx = mtx.toTX() // tx へとビルドします。
tx.toJSON().hex // hex string 形式で出力

興味がある人は、この手順を真似した上で最後に出力した hex をbtcdeb に渡してみたり、bitcoin coreの以下の RPC に渡したりして遊んでみましょう。

  • decoderawtransaction
  • converttopsbt

最近は NBitcoin を扱っているので、F# のインタープリタを使うことを目論んでいます。

2位: bitcoin-cli

bitcoin core にrpc コマンドを送信するためのクライアントです。コマンドラインツールと言っていいのか微妙なところですが、bitcoin を扱う限り bitcoind/bitcoin-cli は必ず使うので含めました。bitcoin coreをインストールすれば一緒についてきます。

自分はよく jq や xargs と組み合わせて使います。以下にその例を示します。

./src をつけて相対パスで指定しているのは、自分は様々なバージョンの bitcoin core を扱う必要があるので make install によるグローバルインストールを行っていないためです。 ( git worktreeで適当なバージョンをチェックアウトしてサブディレクトリでコンパイルしていますが、docker を使っても良いと思います。)

# 最新ブロックのcoinbase txのトランザクションIDを取得する例
./src/bitcoin-cli getblockhash 1 | xargs -IXXX ./src/bitcoin-cli getblock XXX 2 | jq ".tx[0].txid"

(もっと良い扱い方があったら教えて欲しい)

1位: bx

libbitcoin-explorer というライブラリのコマンドラインツールです。 libbitcoinはビットコインのライブラリとしてはかなり老舗(多分)ですが、それだけにしっかりと使える状態を保守している印象です。

mac ならbrew で入ります。

brew install bx

bx help でコマンドの一覧を見ることができます。他のツールと比べて低レベルな機能を揃えていることと、explorer を参照する必要がある機能もさっと使えることが魅力です。

適当なmnemonicを作成する例です。

bx seed | bx mnemonic-new

他にも本当に色々あるのですが、多すぎて書ききれません。ヘルプを参照しましょう。

お知らせ

■HashHubでは入居者募集中です!

HashHubは、ブロックチェーン業界で働いている人のためのコワーキングスペースを運営しています。ご利用をご検討の方は、下記のWEBサイトからお問い合わせください。また、最新情報はTwitterで発信中です。

HashHub:https://hashhub.tokyo/

Twitter:https://twitter.com/HashHub_Tokyo

■ブロックチェーンエンジニア集中講座開講中!

HashHubではブロックチェーンエンジニアを育成するための短期集中講座を開講しています。お申込み、詳細は下記のページをご覧ください。

ブロックチェーンエンジニア集中講座:https://www.blockchain-edu.jp/

■HashHubでは下記のポジションを積極採用中です!

・コミュニティマネージャー

・ブロックチェーン技術者・開発者

・ビジネスディベロップメント

詳細は下記Wantedlyのページをご覧ください。

Wantedly:https://www.wantedly.com/companies/hashhub/projects

--

--