techmedia-think.hatenablog.com
について整理したので、今回は応用編ということでAtomic Swapや、タイムロックの仕組みをアウトプットと組み合わせた(BitcoinのOP_CLTV
使うようなイメージ)条件付きのタイムロック支払いのコントラクトの構成方法についてまとめる。
Atomic Swap
異なるチェーン間でコインをトラストレスに交換するAtomic Swapプロトコルには、よくHTLCsが使われるが、Mimblewimbleにはスクリプトは無いので、Adaptor Signatureを利用して以下のように実現する。
アリスがgrinを持ってて、ボブがbitcoinを持ってて、それぞれを交換するケースを考える。まずボブはBitcoinのトランザクションを作成し以下のいずれかの条件でコインをアンロックできるロックスクリプト宛にコインを送る。
- アリスがハッシュのプリイメージ
x
を知っていれば、アリスの署名でアンロック可能 - 時間が
Tb
経過したらボブの署名でアンロック可能
ただこの時、ハッシュ関数を使うのではなく、代わりにx*G
を使う。つまりスクリプトは以下のような形式になる。
OP_IF 2 <アリスの公開鍵> <x*G> 2 OP_CHECKMULTISIG OP_ELSE <有効期間> OP_CLTV OP_DROP <ボブの公開鍵> OP_CHECKSIG OP_ENDIF
続いてアリスは、ボブがx
を明らかにしたらgrinをボブが入手できるようGrinのブロックチェーン上でセットアップする。
- アリスは最初に自分が持っているgrinを、↑のマルチパーティ+タイムロック付きトランザクションを作成しそこに送る。この時払い戻しトランザクションはアリス宛で、その時にセットするタイムロックは
Ta < Tb
となるようなTa
。 - アリスはこのトランザクションをブロードキャストし、コインを2-of-2のマルチシグにロックする。
続いて、交換プロセス。
- アリスはランダムなnonce
ks
を選択し、アリスのランダムファクターの合計rs
を計算し、ks*G
とrs*G
をボブに送る。 - ボブはコインを受け取るのに使うランダムなブラインディングファクター
rr
とランダムなnoncekr
を選択する。ここで単純にsr = kr + e*rr
を計算するのではなく、sr' = kr + x + e * rr
を計算しsr``と
krG、
rrG、
x*G`をアリスに送る。 - アリスは
sr'*G = kr*G + x*G + e*rr*G
が成立するか検証する。そしてボブがBitcoinのチェーンでコインをx*G
にロックしているか検証する。 - 検証が成功したらアリスは自身の署名値
ss = ks + e*rs
を計算し、ボブに送る。 - ボブは署名を完成させるため、
sr = kr + e*rr
を計算し、最終的な署名(sr + ss, kr*G + ks*G)
を完成させる。 - ボブはトランザクションをブロードキャストしgrinを手に入れる。アリスはそのトランザクションの署名値
sr + ss
からsr
を入手し、前にボブから受け取ったsr'
を使って、sr' - sr = x
を導出する。 - アリスは
x
を使ってBitcoinのブロックチェーン上でコインを入手する。
という感じ。BitcoinにもSchnorrが導入されると、Bitcoinサイドも↓みたいにスクリプトレスにできるようになる。
アウトプットへのタイムロック条件の適用
前回の記事でトランザクションカーネルのlock_height
にブロック高を指定することで絶対的、相対的なタイムロックをトランザクションに施せることは分かった。こういった何の条件もついていないタイムロックの機能に対し、BitcoinではOP_CLTV
やOP_CSV
といったopcodeを使ってトランザクションアウトプットにタイムロック条件を付けることができる。
Mimblewimbleにはそういったスクリプトは無いので、前回の記事に書いた条件の無いタイムロックトランザクションにちょっと変わった仕掛けを組み合わせる。
まず2つの秘密鍵Key1
とKey2
を用意する。そして、2つの秘密鍵を合算して新しい秘密鍵を作る。
Key3 = Key1 + Key2
そして2つのトランザクションTx1
とTx2
のアウトプットをOut1
とOut2
とし、
Out1
のブラインドファクターはKey1
Out2
のブラインドファクターはKey2
Tx2
にだけロックタイムが付いている
という状況を作る。これは、
Tx1
はすぐにでもブロードキャストでき、ブロックチェーンに格納される。Tx2
はロックタイムが設定されているため、それを経過するまでブロードキャストできない。Key3
を使う場合、Out1
とOut2
を同じトランザクションで同時に使用する場合、Tx2
のロックタイムを待たなければならない。
という状況が作られることを意味する。
そのため、Key1
とKey2
の情報を知り得ない形でKey3
を構成すれば、Out1
とOut2
を個別に使用できないため、タイムロックの期間を過ぎるまで待つしか無い。つまりこういう鍵の公開スコープをハンドリングすることで、アウトプットにタイムロック条件を適用させることができる。
どうやってスクリプトレスなアウトプットにタイムロックのような条件を付与するのかと不思議だったけど、↑みたいに秘密鍵のスコープ調整と組み合わせて実現するのね。スクリプトと比べて手間ではあるけど、よく考えるなー。