エンジニアの光田(@34ro)です。
前回のBIP-148に関するブログは予想を遥かに上回る反響&アクセス数になり、ビットコインに感心を持つ層の広がりを感じます。
今回はSegwit有効後に実現可能になるPayment Channelについてです。
Payment Channelのプロセスをちゃんと理解しようと思いドキュメントを読んでもなかなか理解しづらいものでした。
難しい理由は状態遷移が複雑なのに時系列で図式化されている説明がないからだと考え、今回、時系列にまとめてみることにしました。
一つ一つの処理の意味を考えながらシーケンス図にしたのでかなり大変でしたが、まとめてみてかなり明確にイメージできるようになりました。
Payment Channelの目的
ビットコインを始めブロックチェーンベースの仮想通貨は、ブロックにトランザクションが取り込まれるまで取引が確定せず、送金の確定に時間がかかるという課題がありました。また世界中の送金をブロックチェーンに記録しようとするとブロックが溢れ、送金が滞留してしまうというスケールの課題もあります。
それに対しPayment Channelでは2者間で何度も往復させるような送金は毎回ブロックチェーンに書き込むのではなく、いつでもブロックチェーンに書き込める状況を保ったまま、最初と最後の送金トランザクションだけをブロックチェーンに書き込むことで、送金手数料を節約し、さらに1回の送金にかかる時間を大幅に短縮しようというものです。ウォレットや取引所間でPayment Channelを作れば送金手数料を大幅に下げることが可能になります。
Payment Channelにより実現できるようになったことは
* 一定の入金額の範囲内でなら何度往復させても送金手数料がタダ
* 取引が覆るリスクが(実質的に)瞬時になくなる
の2つです。回りくどいやりかたで送金トランザクションを組み立てていくのですが、各処理の合間合間に「今相手のシステムがダウンしたら資産は消えたりしないか」、「今相手が横取りを試みたらどうすればいいか」ということを意識すれば、なぜこのようになっているのかが分かってきます。
なお、トランザクション手数料は省略しています。
Channelのオープン
図1はChannelのOpen直前に組み立てられているトランザクションの状態を表しています。
AliceとBobの両方の署名があれば使用可能になる(2-of-2 multi-sig)トランザクションにAliceとBob両方が5BTCずつ送金しています。
さらにそのアウトプットを使い、特殊なアウトプットを持つトランザクションを2つ作ります。
何もない状態から始めて、ここまでの過程を順に追っていきます。
図1. Channelのオープン直前の状態
step 1. Openingトランザクションの「箱」を作る
最初にAlice, Bobはビットコインのアドレスを1組ずつ作ります。
Openingトランザクションのinputに使うため、BobはAliceにアドレスとデポジットトランザクションのtxidを教えます。
Aliceの手元にはBobのアドレス、Bobの5BTCの入金トランザクションのtxid、そしてAlice自身のアドレスと5BTCの入金トランザクションのtxidがあります。
Openingトランザクションのwtxidを決める情報が揃うので、トランザクションを組み立てます。ただしここではまだ署名しません。
従来のトランザクションでは署名しないとtxidが確定しませんでしたが、Segwit styleなトランザクションはwtxidというidが使え、署名情報を含めないので、署名なしでそのoutputを使って将来有効なトランザクションを作ることが可能です。
この時点では何もトランザクションを作っていないので途中でどちらかが裏切っても損失はありません。
Step 2. 最初のCommitmentトランザクションを作る
Aliceはsecret 1とそのハッシュを作り、ハッシュだけをBobに渡します。このsecretは適当なハッシュを使います(SHA256の2回とか)。
BobはOpeningトランザクションをinputにもつCommitment トランザクションを組み立てます。
このトランザクションは2つのoutputを持ち、一つはBobの署名があれば使用可能な5BTC,もう一つは「1000ブロック経過後にAliceの署名で使用可能」または「Bobの署名とAliceが作ったsecret1があれば使用可能」というものです。
Bobはinputに自分の署名を付加してAliceに返します。
同時にBobもsecretとハッシュを作りAliceに渡し、ちょうど左右対称になるようにC2トランザクションを作ります。
この時点でもブロードキャスト可能なトランザクションは無いのでどちらかが裏切っても損失はありません。
Step 3. 入金トランザクションとOpeningトランザクションに署名しブロードキャスト
AliceはC1をBobはC2を受け取っているので、署名をチェックします。自分の署名を付加すればトランザクションとして有効になりますが今は署名する必要はありません。
問題なければAliceはOpeningトランザクションに署名しBobに渡し、Bobもこれに署名し、Aliceに返します(BobがこのままブロードキャストしてもOKです)。
Openingトランザクションがブロックに取り込まれればPayment Channelの開始が完了です。
この時点でAliceはC1 TxをBobはC2 Txをブロードキャストできる状態にありますが、ブロードキャストしたところで5BTCは相手に渡るのでなんの得もありません。
唯一AliceがC1 Txをブロードキャストするケースは相手がシステムダウンで1000ブロック応答がない場合です。5BTCは取り戻せます。
Step 4. チャンネルのアップデート
AliceからBobに1BTC送ってみます。目指すのは図2のような状態です。
C1, C2はAlice, Bobがそれぞれ持っていますが、現時点でブロードキャストしても得はありません。
それとは別にC3, C4のトランザクションを新たに作ります。
図2 チャンネルアップデート後
C1 Tx, C2 Txを金額とsecretだけ変えて作り直し、同じ処理を行います。
最後にC1 TxでAliceが作ったsecret 1, C2 TxでBobが作ったsecret 2をお互いに明かします。
secretとハッシュの関係が確認できればBobはAliceに1 BTC相当の商品を渡しても問題ありません。
もしこの状況でAliceがC1トランザクションをブロードキャストしたらどうなるか。
Bobはまず5BTC手に入れます。さらに1000ブロック以内ならAliceが明かしたC1のsecretを使って残りの5 BTCも手に入ります。
そのためAliceはsecret1を明かした以上C1をブロードキャストする動機はありません(C1がブロードキャストされて意味があるのはBobがシステムダウンした場合です)。
その後はチャンネルのアップデートを繰り返し、Alice, Bobは5BTCの範囲内なら何度でも送り合うことができます。
毎回前回の鍵を明かすので、ブロックを常に監視しておけば相手が裏切り行為にでても自分の取り分は必ず取り返せます。そのため相手が応答を続けている限り過去のトランザクションをブロードキャストする意味はありません。
Payment Channelで損をするのは自分がシステムダウンに見舞われた場合のみです。
ここまでの処理を全て繋げるとこのようになっています。
まとめ
Payment Channelの開始の流れを組み立てて追ってみました。回りくどいやりかたですが、相手の信頼に依存せずに「トラストレス」なままビットコインの特性を活かしたまま送金を行うことができることが分かりました。
ちなみにPayment Channelの実装はLightning Networkの一部として実装されており公開されています。
https://github.com/mit-dci/lit
https://github.com/ElementsProject/lightning
また以前実際に動かしてみたブログはこちら
lightning networkでビットコインを送金してみた
続き→Payment Channelで使われるスクリプトを理解する
わたしたちと一緒に働きませんか?
コインチェックでは様々な職種の人材を積極的に募集しております!コインチェックのビジョンに共感し、その実現を本気で一緒に目指せる方、自身の力を思う存分に発揮されたい方のご応募をお待ちしております!