hiro99ma blog

rust: rust-bitcoin と BDK (8)

2025/10/08

BDK をメインで使うことに決めたので、ちまちまと気付いたことを書いていこう。
あとでまとめページを作ることを前提にしているので、メモ程度で良いのだ。

正直なところ DeepWiki 先生がいればだいたいのことは尋ねるとわかる。
わかるだろうけど、こういうサービスも急に使えなくなるかもしれないので、記録しておくとよいこともあるだろう。

The Book of BDK の v2.2.0 対応

Cookbook がまだ v1 系だからなあ、と思っていたら更新されていた。

ウォレットの新規作成

ウォレットを作るとなると、BIP-32 としては master private key を作ることになる。
今は descriptor というかハードコーディングした xprv を使ってウォレットの復元をしているので ストレージなりなんなりに保存しなくてはならん。

ウォレットの DBファイルがあれば Wallet::load() の経路が成功するので、 失敗したときのルートで行えば良かろう。

bip32::Xpriv::generate(()) が最も簡単ということでお任せした。
一応 RNG は使われているそうなので最低ラインはクリアしているだろう。
心配ならカスタマイズすることもできるそうだ。

永続化

ウォレットは作ることができて、ファイルも生成された。
しかし、新しくアドレスを振り出しても次回開くとそのアドレスを忘れてしまっている。
これは .persist() して更新的なことをしないといけなかった。 mut じゃないとできないメソッドを呼び出したら .persist() する感じかな。

ブレークポイントに止まらない(vscode)

ブレークポイントに止まらない。。。
どうやら、シンボリックリンクのパスが挟まっているとダメらしい。
回避案がこちらにあって、やったらうちでも止まった。

シンボリックリンクのディレクトリの中にあるディレクトリをさらにシンボリックリンクして。。。とかだと正式名称?がわからなくなってくる。
readlink -f <ディレクトリ名> などで正式名称が取得できるので "sourceMap": {"<readlink -f . したパス>": "pwd したパス"} などでよいのかな。

cargo の後ろにオプションが付けられる

“spend” というコマンドをテストしたかったので cargo run spend .... のような感じで実行するので launch.json もそう書いた。
しかしなぜか “spend” という名前までわかっているのに失敗する。
理由は、コマンドラインオプションで “spend” のときに取る引数の数をチェックして不一致だと失敗させているのだが、 vscode のデバッガが最後の方に --message-format=json とか引数を追加していたのだ。
どうしようもないらしく、cargo の方ではなく普通に program として実行するしかなさそうだ。

署名できない

ブレークポイントを設定したかったのは、署名に失敗したからだ。
エラーではなく .sign()false が戻ってくる。
PSBT の finalize の過程で失敗しているところまではわかった。

デバッグが始まらない(vscode)

vscode でブレークポイントに止まらない現象は sourceMap を書くことで対応できた。
その後、別の PC で引き続き作業をしようとしたのだが、そちらではデバッグが始まらない。
デバッグ開始のボタンを押すと、エラーにもならずプログレスバーっぽい青いマークが流れ続けるだけになる。

image

わからない。。。

翌日、動いている環境と並べて比較しよう!とやったのだが・・・動いた・・・。
CodeLLDB の再インストールがよかったのだろうか。

まだ署名できない

ブレークポイントに止まるようになったので、状況を確認できるようになった。
それについて DeepWiki に質問しながら進めている。

いろいろ変更して、builder.only_witness_utxo()SignOptions.trust_witness_utxo = true を追加している。
しかし、まだ署名できない。

今は desc.satisfy() で L.2054 の Err の方に流れていて false が戻っている。
せめて Err(_) の中身が分かればよいのだが、確認できるんだろうか?
Arm 系なら r4 だろうけど、あれは C/C++ だけ? そもそも戻り値といってもアドレスになりそうだ。

たどり着いたのが、bitcoin-miniscript の get_satisfaction()
ここで Error::CouldNotSatisfy を返している。

if let Witness::Stack(stack) = satisfaction.stack { って、Rust は if の中に代入文を書けるのか。

しかし CodeLLDB は gdb みたいなものっぽくて、C/C++ のデバッグをしているような $variants$ みたいな表示になっていてつらい。
なんかありそうな気はするのだけど、わからんのよね。

writer: hiro99ma

 < Top page

コメント(Google Formへ飛びます)

GitHub

X/Twitter

Homepage

About me