btc: BIP-341が難しい (5)
2025/01/18
はじめに
こちらのデータで P2TR script path での署名をしようとしている。
ライブラリにするのは諦めた。
sigMsg
key path のとき、1つのトランザクションだと vin[] が同じなので sigMsg もどの vin に対して署名するときも同じだと考えていた。
が、それは全部 vin が key path だった場合だった。
sigMsg の中に spend_type
という値があり、その ext_flag
ビットは key path なら 0、script path なら 1 だった。
そこだけなので自分で作って署名するだけなら難しくはないか。
ライブラリ化を諦めたのは verify するときに仕様を全部実装しておかないとうまくいかなくなるからだ。
よく考えると既に自分で実装していたところも仕様を全部取り込んだわけじゃないので同じことではあるのだが、SIGHASH_SINGLE
や SIGHASH_ANYONECANPAY
などで sigMsg を作り替えたりすることを考えると面倒になってしまったのだ。
計算
あれからいろいろ計算して、ようやく署名データがテスト値と一致した。
スクリプトが 1つしかないこともあり、実装ミスがあったくらいでそこまで苦労はしなかった。
- sigMsg には witness のデータは入らない
- P2W系もそうだったっけ
- key path か script path かの違いは sigMsg に現れるが、どのスクリプトに署名するかは sigMsg に現れない
- 現れないといっても common signature message としての sigMsg に入らないだけで署名データには関わる
OK_CHECKSIG
などは署名する鍵は選べるが署名するデータは選べない- 対象はこのトランザクションでエンコード方法は INPUT になった outpoint のエンコード方法依存
-
署名でなくてもスクリプトが最後に “True” で終われば良い
- commit
終わりに
1つのスクリプトしかない P2TRの outpoint から redeem するトランザクションの例は計算上できた。
key path と比較して時間がかかったのは、BIP-341 に載っている Python らしきコードの読み取りが難しくなったので実実装で確認するようにしたからだ。
再帰があったりして最終的にどういうことになるか想像しづらいのだ、
今回も難しいものから簡単なものまでいろいろと時間がかかってしまった。
まあ、気にしてはいけないのだ。
witness の部分は fee として優遇されていて、script path の部分に画像などを置いたりして Bitcoin 界隈ではいろいろあったのだが、最近は落ち着いてきたのかもしれない。