hiro99ma blog

btc: libwallyでP2TR key-pathトランザクションを作るのは大変だ

2025/09/07

過去にも何度かやっている libwally-core を使うシリーズ。

今までは P2TR の計算方法を確認したりしていたが、 スクリプトを作って確認するプログラムを作ろうとすると HDウォレットを採用して秘密鍵を埋め込まないようにしたり、 新しいアドレスを作ってくれたり、指定したアドレスに送信するトランザクションを作ってくれるような機能が欲しくなる。
1つベースを作っておいて、何かしたかったらそれをプロジェクトごとコピーして作業するようにしたい。

そういうわけでここ数週間やっているのだが、なかなか進まない。
ようやくトランザクションを作るところだけできた。まだお釣りもないし、もちろん feerate も未考慮だ。
昔作っていたコードを持ってきただけなので

たったそれだけなのにこんなにコードを書くのだよ。
前半は INPUT のチェックなどだからトランザクションを作るのは 400行目くらいからだが、それでも 180 行くらいはある。
多くない?

libwally-core のドキュメントを眺めてはいるのだが、API しかないのでよくわからない。
なんとなくだが、シングル鍵で INPUT が 1つ、OUTPUT が 2つならトランザクションを作ってあげますよ、みたいな便利 APIはないように思う。
組み合わせればできるんだったら組み合わせればいいじゃないの、というところか。
tweaked public key と tweaked private key なんてまとめて計算してくれればいいのにとは思うのだが、まあ組み合わせればできるのだ。 tweaked private key を求める際には tweaked public key も計算することになるので tweaked public key も返してくれれば良いのにとは思うが。

なので、この部分はたぶんこれ以上は減らないと思う。
せっかくまとめたのだから、これを API にすれば便利かもしれないが・・・汎用にするには引数が多すぎる。
こんな大きい関数を main() に置きたくないから整理はするつもりだが、あまりきれいにならないような気がする。

C++ にしたから減るという感じもしないし、C/C++ でよさげなライブラリも思いつかないし、今やってるのが終わったら探しますかね。

libwally-core には世話になっているが、心の中で文句は言ってよいと思うのだ。
API 引数以外に統一性がなさ過ぎ!
分類が Address なのか Script なのかよくわからないので検索しようとするが、 wally_address_ かと思えば wally_addr_ もあるしで検索もしづらい。

DeepWiki で尋ねるのが一番早そう。 「segwitのアドレスをscriptpubkeyに変換」とかで探してくれるので便利だ。

とはいったものの、名前はともかく分類については明確に切り分けられない API が多いので仕方ないとは思う。
アドレスと scriptPubKey は裏表だし、scriptPubKey はトランザクションでよく使うし、 でもアドレスも scriptPubKey もウォレットのデータから作ると楽だからそっちにも API を置きたい。。。
どこに分類したとしても「わからんでもないけど、そこにしたのか」という気持ちにはなりそう。

配列の初期化を配列で与えられない

struct wally_tx_inputtxhash は配列だ。
他のメンバは固定値なり変数値なりで初期化できるのだが、txhashmemcpy にした。
まあ、動的な値が入っているのでスタックメモリに展開されるだろうから const でなくてもよいのだけど、せっかくなので一箇所で初期化できればとは思う。
1つずつ初期値を与えることはできるので { a[0], a[1], a[2], ... } のように列挙すればできると思うが、さすがにそれは。。。

お釣りが必要か

計算が正しいかどうかの実装をしているときは考慮せず、HDウォレットを使うようにして気がついたのはお釣りの計算だ。
UTXO 方式のチェーンを使う場合、考え方としては「ある金額の塊を別のところに転送し、その手数料は誰かに渡し、残った分はお釣りになる」だ。

1,000 sats あって、そこから 500 sats 支払う場合、小銭が入っているおサイフがあるならなるべく小銭を小さくしてお釣りを無くそうとするかもしれない。
しかし UTXO 方式の場合、イメージとしてはそれぞれの支払いに紙幣で受け取ったようなものである。
紙幣は分割できないのでお釣りをもらうしかない。

それとは別で、お釣りが必要かどうかも考えないといけない。
Bitcoin には dust_limit というものがあり、アドレスのタイプによっては受け付けられないこともある。

writer: hiro99ma
tags: Bitcoin開発    

 < Top page

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

GitHub

X/Twitter

Homepage

About me