Develop with pleasure!

福岡でCloudとかBlockchainとか。

Grinで作るAtomic Swapとアウトプットへのタイムロック条件の適用

techmedia-think.hatenablog.com

について整理したので、今回は応用編ということでAtomic Swapや、タイムロックの仕組みをアウトプットと組み合わせた(BitcoinOP_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のブロックチェーン上でセットアップする。

  1. アリスは最初に自分が持っているgrinを、↑のマルチパーティ+タイムロック付きトランザクションを作成しそこに送る。この時払い戻しトランザクションはアリス宛で、その時にセットするタイムロックはTa < TbとなるようなTa
  2. アリスはこのトランザクションをブロードキャストし、コインを2-of-2のマルチシグにロックする。

続いて、交換プロセス。

  1. アリスはランダムなnonce ksを選択し、アリスのランダムファクターの合計rsを計算し、ks*Grs*Gをボブに送る。
  2. ボブはコインを受け取るのに使うランダムなブラインディングファクターrrとランダムなnonce krを選択する。ここで単純にsr = kr + e*rrを計算するのではなく、sr' = kr + x + e * rrを計算しsr``とkrGrrGx*G`をアリスに送る。
  3. アリスはsr'*G = kr*G + x*G + e*rr*Gが成立するか検証する。そしてボブがBitcoinのチェーンでコインをx*Gにロックしているか検証する。
  4. 検証が成功したらアリスは自身の署名値ss = ks + e*rsを計算し、ボブに送る。
  5. ボブは署名を完成させるため、sr = kr + e*rrを計算し、最終的な署名(sr + ss, kr*G + ks*G)を完成させる。
  6. ボブはトランザクションをブロードキャストしgrinを手に入れる。アリスはそのトランザクションの署名値sr + ssからsrを入手し、前にボブから受け取ったsr'を使って、sr' - sr = xを導出する。
  7. アリスはxを使ってBitcoinブロックチェーン上でコインを入手する。

という感じ。BitcoinにもSchnorrが導入されると、Bitcoinサイドも↓みたいにスクリプトレスにできるようになる。

www.youtube.com

アウトプットへのタイムロック条件の適用

前回の記事でトランザクションカーネルlock_heightにブロック高を指定することで絶対的、相対的なタイムロックをトランザクションに施せることは分かった。こういった何の条件もついていないタイムロックの機能に対し、BitcoinではOP_CLTVOP_CSVといったopcodeを使ってトランザクションアウトプットにタイムロック条件を付けることができる。

Mimblewimbleにはそういったスクリプトは無いので、前回の記事に書いた条件の無いタイムロックトランザクションにちょっと変わった仕掛けを組み合わせる。

まず2つの秘密鍵Key1Key2を用意する。そして、2つの秘密鍵を合算して新しい秘密鍵を作る。

Key3 = Key1 + Key2

そして2つのトランザクションTx1Tx2のアウトプットをOut1Out2とし、

  • Out1のブラインドファクターはKey1
  • Out2のブラインドファクターはKey2
  • Tx2にだけロックタイムが付いている

という状況を作る。これは、

  • Tx1はすぐにでもブロードキャストでき、ブロックチェーンに格納される。
  • Tx2はロックタイムが設定されているため、それを経過するまでブロードキャストできない。
  • Key3を使う場合、Out1Out2を同じトランザクションで同時に使用する場合、Tx2のロックタイムを待たなければならない。

という状況が作られることを意味する。

そのため、Key1Key2の情報を知り得ない形でKey3を構成すれば、Out1Out2を個別に使用できないため、タイムロックの期間を過ぎるまで待つしか無い。つまりこういう鍵の公開スコープをハンドリングすることで、アウトプットにタイムロック条件を適用させることができる。

どうやってスクリプトレスなアウトプットにタイムロックのような条件を付与するのかと不思議だったけど、↑みたいに秘密鍵のスコープ調整と組み合わせて実現するのね。スクリプトと比べて手間ではあるけど、よく考えるなー。