btc: bitcoinjs-lib を使う (3)
2025/01/24
はじめに
P2TR を扱うのに node.js で使える bitcoinjs-lib を使ってみよう。
前回は準備だけで終わったので、今回は key path を扱う。
server=1
txindex=1
regtest=1
rpcuser=user
rpcpassword=pass
fallbackfee=0.00001
- 手順
rm -rf ~/.bitcoin/regtest/
bitcoind -regtest -daemon
sleep 5
bitcoin-cli -regtest -named createwallet wallet_name=test load_on_startup=true
addr=`bitcoin-cli -regtest getnewaddress`
bitcoin-cli -regtest generatetoaddress 110 $addr
Node.js と TypeScript と ESM
環境の準備をしているところだが、Node.js / TypeScript / ESM 関係でつまづいている。
“Node.js” ということで調べないと、ブラウザとは状況が違うようである。
私の場合は TypeScript を Node.js(か ReactNative)でしか使わないので、そういう調べ方をせねばならぬ。
昨日、自分のコードから ESM Only な node-fetch@v3
を使う使うために変更し、動作した。
その後、node-fetch@v3
から ky
に変更して、それも動いた。
そこまではよかったのだが、bitcoinjs のサンプルコードを一部持ってきたところ ecpair
が読み込めない(ERR_MODULE_NOT_FOUND
)。
issue にあるようにバージョンを v2 と指定する必要があった。
インストールするパッケージのバージョンは気にしないといかんね。
そこに至るまでいろいろ探していたのだが、こちらのサイトが詳しかった。
多少長いのだが、このくらい説明されないと現在の状況が分からなかったのでありがたい。
Go言語も gomod に落ち着くまでなんだかわからなかったので、そういうものだと思って受け入れるしかあるまい。
ESLint
tweak key
taproot-with-bitcoinjs を見ていて、
tweakSigner()
のような関数を実装しているのが気になった。
P2TR だったらよく使いそうだし、そこそこ面倒なので bitcoinjs にありそうなものだが。
bitcoinjs の taproot.spec.ts にも類似したコードはない。
が代わりに tweak()
という関数を呼んでいる。
これは bip32 の方 に実装されていた。
ただの関数ではなく HDウォレットに紐付いていて、internal public key だけがある状態で呼び出せるものではなかった。
なるほど。
BIP32Factory()
の謎
bitcoinjs-lib ではこう使っている。
- BIP32Factory
import BIP32Factory from 'bip32';
const bip32 = BIP32Factory(ecc);
同じように書いたのだが、呼び出すところで関数じゃないとエラーになる。
こちらのように BIP32Factory.default()
にしても default
はない。
import で {}
で囲むと呼び出せた。
- javascript - Uncaught TypeError: bip32.fromSeed is not a function - Bitcoin Stack Exchange
import {BIP32Factory} from 'bip32';
bip v4.0.0 では defaultではないexports だから {}
がいるということかな?
でも index.ts
では as default も無しもある。
import * as _bip32 from 'bip32';
...
const bip32 = _bip32.BIP32Factory(ecc);
bitcoind から key path アドレスに送金
お金じゃないのだけど「送金」と呼んでしまう(英語で書くときは “transfer” にしている)。
それはともかく、key path から導出したアドレスに bitcoind の JSON-RPC で送金し、confirm するまでポーリングするようにした。
最初は listreceivedbyaddress
でやろうとしてたけど、あれは自分のウォレットしか見ないのね。
名前からしても自分じゃないウォレットだと “received” にはならんから当たり前だ。
tweaked private key などの生成は bip32
に任せている。
今回の目標は、なるべく自分でコードを書かずに任せるである。
key path アドレスから bitcoind に送金
アドレスに送金された outpoint から bitcoind のウォレットに送金する。
サンプル実装ほぼそのままで使えたので楽だった。
一番面倒な tweak 関係の計算を bip32
に任せられたのが大きいな。
おわりに
key path のアドレスを作り、そこへの送金を他に転送するサンプルを作った。
自作のライブラリと比べると、さすがというかかなり楽に使うことができた。
PSBT の概念をきっちり持ち込むことでパラメータもシンプルになったのだろうか。
無駄というと変だが、なくてもなんとかなるような API は持ってなさそうだった。
BTC <–> satoshi 変換とか。
ゴチャゴチャしてしまうからかな?
さて、次は script path か。