btc: miniscript (3)
はじめに
miniscript の使い道にお悩み中。
が、難しく考えることでもないかと思い始めた。
Bitcoinスクリプトを作るために使う
ここに miniscript が生まれた背景が書いてあった。
xpub は自分の残高を見るためくらいにしか使ってなかったけど、
BTCPayServer みたいな受け取りメインのアプリでも使えるのだね。
結局のところ Bitcoinスクリプトを作るための miniscript なのだから、 そういう風に使えばよいだけなのだ。
例えば BIP-112 に出てくる HTLC はありがちなスクリプトだろう。 期間内に相手が受け取ってくれれば良し、そうでなかったら別の人に受けとる権利も出てきますよ、というようなスクリプトだ。
HASH160 <revokehash> EQUAL
IF
<Bob's pubkey>
ELSE
"24h" CHECKSEQUENCEVERIFY DROP
<Alice's pubkey>
ENDIF
CHECKSIG
これを解くトランザクションには、Bob が受け取るなら Bob の署名と HASH160 したら <revokehash>
になるデータを積む。
そうすると IF(OP_IF)
のルートを通って署名検証される。
ELSE(OP_ELSE)
の方は <revokehash>
にならない値なら何でもよいが、その代わりトランザクションが confirm してから 24時間以上経っていないと Alice の署名があろうとなかろうと無視される。
(実際は 24時間の代わりにブロック数で 144 を使うだろう。)
わかってしまえば難しくないのだが、いきなりこれを書くのはきつかろう。
見慣れた出力になるとは限らない
ただ、Bitcoinスクリプトを見慣れている人からすると、 miniscript で出力したスクリプトが思ったような形ではないので かえって悩んでしまうかもしれない。
たとえば sipa/miniscript にある “The BOLT #3 to_local policy” は
Lightning Network BOLT#3 の to_local
Output だろう。
署名と OP_IF
か OP_ELSE
かを指定するフラグのようなデータをスタックに積めば良いとわかる。
OP_IF
<revocationpubkey>
OP_ELSE
`to_self_delay`
OP_CHECKSEQUENCEVERIFY
OP_DROP
<local_delayedpubkey>
OP_ENDIF
OP_CHECKSIG
これが miniscript を通して Bitcoinスクリプトになるとこう。
先に <key_local>
で署名検証して、ダメだったら OP_NOTIF
のルートを通って <key_revocation>
で検証して終わり。
OP_ELSE
は <key_local>
で検証が成功したルート。1008 は 0x3f0
なのでこの数値はリトルエンディアンか。
<key_local>
で失敗させたいときはデータを載せなければ良いので、上のスクリプトとそこまで変わらないだろう。
<key_local> OP_CHECKSIG OP_NOTIF
<key_revocation> OP_CHECKSIG
OP_ELSE
<f003> OP_CHECKSEQUENCEVERIFY
OP_ENDIF
いやあ、読み慣れていないと難しい。
この手のスクリプトは、redeem で先に署名を載せて次にフラグのようなデータを置くのが多かったので、むむ、となってしまう。
念のため libwally-core でもやってみたが同じスクリプトが生成された。
bitcoin-cli decodescript
で HEX文字列のスクリプトをデコードできるので便利だ。
おわりに
miniscript は Bitcoinスクリプトにまではしてくれるが、どうスタックを作ると解けるのかまでは説明してくれない。
それくらいはわかってないと困るよというか、わからないのにスクリプトを作ったらいかんやろうということかもしれないが、
心配なので答え合わせをしたい。
sipa/miniscript で出力される逆アセンブルした Bitcoinスクリプトは誰向けなんだろうか?
エンディアンをリトルにしているところからすると人間向きではないのかしら。
それに、WebAssembly にわざわざしてあるってことは、WebAssembly として使いたい要望が結構あるのだろうか。
リトルエンディアンなのもそこら辺に理由があるとか?
わからぬ、わからぬのだが構造的に Bitcoinスクリプトを書く言語というだけでもよいのだと思っておこう。 あとは、必要が出てきたときに分かるだろう。