読者です 読者をやめる 読者になる 読者になる

Develop with pleasure!

福岡でCloudとかBlockchainとか。

双方向のPayment Channelの仕組み

Bitcoin Lightning network Payment Channel

Bitcoin MagazineのLightning Networkの記事をベースに双方向Payment Channelの仕組みについて理解する。

bitcoinmagazine.com

双方向Payment Channelの構成要素

  • unconfirmed transaction
    最初のCommitment Transactionを作成する際、入力となるOpening Transactionは署名もブロードキャストされておらずunconfirmedな状態である必要がある。そのため未署名なトランザクションを入力にしたトランザクションが作れる必要がある。
  • 二重使用の防止
    同じ出力(もしくは入力)を持つ2つのトランザクションBitcoinネットワークにリレーされた際、confirmされるのはどちらか1つである。未確認のトランザクションは競合し、どれか1つだけがconfirmされるということに注意する必要がある。
  • マルチシグ
    マルチシグなアドレスが保持するBitcoinを使用するには複数の秘密鍵を必要とする。
  • タイムロック
    将来のある時点までBitcoinをロックする仕組み。タイムロックする方法には2種類あって、1つはCheckLockTimeVerify (CLTV)を使った絶対時間でロックする方法で、もう1つはCheckSequenceVerify(CSV)を使った相対時間でロックする方法。CLTVは実際の時刻までBitcoinをロックする。CSVは実際の時刻の代わりに相対時間を使う。CSVな出力は、それが利用できるまでにその出力がブロックチェーンに記録された時点から指定したブロック経過する必要がある。
  • シークレットとハッシュ値
    コンピュータが計算することが困難な十分な長さの文字列シークレットを用意し、そのシークレットのハッシュ値を取る。元のシークレットを知っていればハッシュを求めるのは簡単だが、ハッシュだけ分かっても元のシークレットを算出するのは非常に難しい。この仕組みを使ってBitcoinをロックする。ハッシュを出力に含め、それを入力にして使用する際はシークレットを必要とするトランザクションを作る。

Channelのオープン

双方向のPayment Channelをセットアップするには、両者がまず最初にOpening Transactionに同意する必要がある。Opening Transactionで、そのChannelにいくらのBitcoinデポジットするかを決める。

Channelを開くには、アリスとボブがそれぞれ5 BTCずつ2-of-2のマルチシグアドレスにBitcoinを送付する。これがOpening Transactionとなる。アリスとボブの両者の署名があればこのマルチシグにデポジットした資金は利用可能になる。

続いてアリスとボブはそれぞれシークレットを作成し、そのハッシュを交換する。

アリスはすぐOpening Transactionを入力にしたトランザクションを作成する。これが“Commitment Transaction”。Commitment Transactionでは、アリスは4 BTCを自分に、残りの6 BTCを新しいマルチシグに送る。このマルチシグが少し変わったマルチシグになっているのがポイントで以下のいずれかの条件でロックが解除される。

  • ボブ自身でロックが解除できるけど、解除するためにはこのコミットメントトランザクションがブロックに含まれてから1000ブロック経過する必要がある(OP_CSVでタイムロックしている)。
  • アリス自身で解除できるが、ボブがアリスに送ったハッシュの元となるシークレットをアリス自身が知っている必要がある。(この時点でアリスはハッシュは知っているが、そのシークレットが何かは分からないので、現時点ではアリスがロックを解除することはできない。)

アリスはこのcommitment transactionに署名し、これをボブに送る。

一方ボブも同様のことを行う。同様にcommitment transactionを作成し、ボブ自身に6 BTC送り残りの4 BTCをマルチシグに送る。そのマルチシグはアリスが1000ブロック待てばロックを解除できる、もしくはボブがアリスのシークレットを知っていればロックを解除できるアドレス。

ボブはこのcommitment transactionに署名し、これをアリスに送る。

アリスとボブお互いにシークレットのハッシュとCommitment Transactionの交換を終えると、Opening Transactionに両者が署名しブロードキャストする(Opening Transactionは必ずcommitment transactionを交換した後に署名及びブロードキャストする必要がある)。Opening Transactionがブロックチェーンに記録されたことを持って、Payment Channelがオープンしたことになる。

この時点で、アリスとボブ両者はお互いに相手から受け取ったトランザクションに署名してブロードキャストできる。アリスがブロードキャストした場合、ボブはすぐに6 BTCを手に入れる。ボブがブロードキャストした場合は、アリスはすぐに4 BTCを手に入れる。しかし両者共に署名しトランザクションをブロードキャストしない場合は、お互いマルチシグのロックを解除するために1000ブロック待って、残りのBitcoinを取り戻すことになる。

このPayment Channelのキーはどちらも受け取ったcommitment transactionをブロードキャストしないということ。

Channelのアップデート

少しして、ボブはアリスに1 BTCを戻したくなった場合、両者はお互い残高が5 BTCと5 BTCになるようChannelの状態を更新する。これを実現するためアリスとボブは以下の2つの作業をする。

最初に、↑と同様に(※Opening Transactionが既にブロードキャスト済みなのが↑とは異なる)両者ともOpening Transactionを入力にし、アリスとボブそれぞれ自分に5 BTC、マルチシグに残りの5 BTCを送るCommitment Transactionをお互いに作成する。マルチシグの宛先も最初に作ったCommitment Transactionと同様だが、その際アリスとボブは新しくシークレットを作りそのハッシュを交換する。そしてそれぞれ自分が作ったトランザクションに署名し、相手に送る。

続いて、アリスとボブは古い(一番最初に作った)シークレットをお互いに明かす。

この時点で、アリスとボブは相手から受け取ったCommitment Transactionに署名しブロードキャストすることができる。ブロードキャストするとすぐに相手は5 BTCを利用可能になるが自分はブロードキャストされてから1000ブロック待つ必要がある。こうやってChannelを更新する。

しかしここで考えられるのがボブが1つめのCommitment Transactionをブロードキャストしないのか?ということ。1つめのCommitment Transactionはボブに6 BTCを送ることになっていて2つめの5 BTCよりも多い。

その理由はボブの最初のシークレットをこの段階ではアリスが知っているためである。アリスがシークレットを知っているためボブは古いCommitment Transactionに署名してブロードキャストすることができない。もしボブが古いCommitment Transactionに署名してブロードキャストすると、アリスはすぐに4 BTCを受け取り、ボブは1000ブロックまって残りの6 BTCを受け取ることになるが、アリスはボブのシークレットを知っているため、ボブが1000ブロック待っている間にそのシークレットを使って残りの6 BTCもアリスが入手できるようになる。そのためボブが古いCommitment Transactionに署名してブロードキャストすることはない。

そしてボブもアリスのシークレットを知っているので、アリスが同様のことをすると資金は全てボブに渡る。

このため現実的にブロードキャスト可能なのは両者の持つ最新のCommitment Transactionだけとなる。

双方向Payment Channelのフローまとめ

↑の内容を図にすると以下のようなフローになる。

f:id:techmedia-think:20160806212406p:plain

所感

最初のOpening TransactionとCommitment Transactionを作る過程では、Opening Transactionは未署名なのでそれを入力とするにはトランザクションが未署名な状態でトランザクションのハッシュが決まる必要がある。従来のトランザクションハッシュの計算には署名を含んでいたため、Lightning Networkでは新しいSIGHASHタイプとしてSIGHASH_NOINPUTを設けていたのだと思う。ただこれはSegwitのリリースによりトランザクションから署名が分離されれば解決するので、Segwitがリリースされればオフチェーンでトランザクションをやりとりするプロトコルは別にして双方向のPayment Channelは実装できると思う。

シークレットは、最新ではないCommitment Transactionをブロードキャストできないようにするための仕組として必要なのね。

ただ古いシークレットが交換を担保する仕組みって必要ないのかな?