暗号通貨とそれらが織りなす経済圏について⑥

(※一部修正しました)

ペイメントチャネル。

前回までは、ペイメントチャネルってなあに?という概要に触れましたが、どうやって途中のトランザクションを台帳に記録せずに、AliceとBobは取引を進めることができているのか?というのが、前回からのつづきです。

これは、昨日の記事でも今日の記事でも参考文献にさせていただいたお方の、かなり詳しい記事があるので(しかも2年前に・・・!)、そちらをご参照ください、と言ってしまうと終わってしまうので、私なりの理解を書いておこうと思います。

https://techmedia-think.hatenablog.com/entry/2016/08/06/212453

まず、ストーリーとして理解した方が早いので、そうします。

AliceとBobは、どちらも一定額のBTCを受け取ろうとしています。

どこから?というと、10BTC入っている資金プールです(送金元であり、インプットと呼ばれるもの)。

ちなみにこの資金プールは、そもそもAliceとBobから5BTCずつ送金されてできたアウトプット(送金先)だとします。何だか混乱しそうですが、5BTCずつ拠出された10BTCが確定したところからのスタートです。

これがオープニングトランザクションといって、最初に開かれるチャネルです。AliceとBobのどっちでもいいのでどちらかによってブロードキャストされ、ブロックチェーンに記録されます。ただし、ブロードキャストするのは、ここから始まる1回目のトランザクションの作成と交換が終わった後です。

最初の、ブロードキャスト前の10BTCを送金元とし、Aliceに4BTC、Bobに6BTCが送られるという内容のトランザクションを、「それぞれが」作成し、自分の署名をし、交換します。「それぞれ」というのがポイントです。

ただそもそも、上記1度の取引だけなら、別にペイメントチャネルを使う必要ないのですが、どういうわけかお互いに途中で心変わりがあり、協議した結果、10BTCの出元から、Aliceに8BTC、Bobに2BTCが渡ることになりました。AliceとBobの間で何があったか知りませんが、途中でお互いが受け取るBTCの金額を変更したい、というケースなのだそうです。そんなの、最初から決めておけやと思うのですが、まぁそういう変更があったケースに対応する、ということなのですかね。しかも都度、台帳に記録することなく。

なので、2回目の取引が発生します。ここでも、それぞれが最初と同じく、出元を10BTCとし、金額をAlice宛に8BTCとBob宛に2BTCにしたトランザクションを作成し、署名し、お互いに渡します。そして2つ目のトランザクションを正とし、台帳に記録させたい、となったとしましょう。

ここで、なぜ、それぞれがトランザクションを作成して、しかも交換するなんて面倒なことをやるんだ?というところを考えます。それは、お互いが、裏切れないような仕掛けを仕込んであるからです。

トランザクションというのは必ず宛先と送金額が含まれています。

これまでの話を具体的な流れで、1つ目の、AliceとBobがそれぞれ作ったトランザクションから見ていきます。オープニング、クロージング以外の、本来は台帳に記録されないトランザクションを、コミットメントトランザクションと呼びます。

【1つ目のコミットメントトランザクション】

<1>Bobの作ったトランザクション(Bobの視点で作成)

2つ宛先が含まれている。10BTCを出元とし、Bob(自分)宛に6BTC送ってね、というものが1つ目。2つ目は、特別な条件が満たされた時に鍵が開き、4BTCが受け取れる、閉じられた箱。箱の開錠条件は以下。

ア) 一定の時間が経過後、Alice(相手)の秘密鍵で開く

イ) Alice(相手)しか知らないシークレットを持っていれば、Bob(自分)の秘密鍵で開錠可能

そして、Bobは作ったトランザクションに自分の署名をして、Aliceに渡します。あとはAliceが署名すれば、ブロードキャストできます。

<2>Aliceの作ったトランザクション(Aliceの視点で作成)

同じく宛先は2つ。1つ目がAlice(自分)宛に4BTC送ってね、というもの。2つ目が、同じく特別な条件が満たされた時に鍵が開き、6BTCが受け取れる、閉じられた箱。箱の開錠条件は以下。

ア)一定の時間が経過後、Bob(相手)の秘密鍵で開く

イ)Bob(相手)しか知らないシークレットを持っていれば、Alice(自分)の秘密鍵で開錠可能

そして、Aliceは作ったトランザクションに自分の署名をして、Bobに渡します。あとはBobが署名すれば、ブロードキャストできます。

うーん、混乱しますよね。実行される分には同じ内容なのですが、自分視点のトランザクションを作成し、それを相手に預けるわけです。

そしてシークレットという言葉が出てきましたが、お互い自分しか知らないシークレットコードを持っており、そこから生成されたシークレットハッシュというのをもとに、トランザクションを作成しています。ややこしいですが、必要なんだそうです。そしてそのハッシュからはシークレットを逆算することはできないので、お互いこの時点ではまだ相手のシークレットは知りません。ただそのシークレットは、追って入手する機会があります。

【オープニングトランザクション】

ここで(1回目のコミットメントトランザクションが終わったタイミングで)、初めて、オープニングトランザクションをブロードキャストし、取引を開始するためのチャネルを開きます。オープニングトランザクションとは、一番最初に出てきた、AliceとBobが共同で5BTCずつ資金プールにデポジットしたトランザクションのことです。これが台帳に記録されれば、出元=インプットの資金が10BTCで確定します。

【2回目のコミットメントトランザクション】

そして、2回目の「やっぱ金額を変えよっと」のトランザクションです。

Aliceに8BTC、Bobに2BTCが渡ることになり、2人は先ほどと全く同じやり方で、金額を変えて、トランザクションのやり取りをします。

そして、このタイミングで初めて、1回目のトランザクション作成に使用したお互いのシークレットを、交換します。相手に自分のシークレットを渡すわけです。

Bobがここで急に裏切り行為に出たらどうなるでしょう。Bobは実は2BTCという金額に不満を持っていて、1回目のトランザクションでもらえるはずだった6BTCを受け取りたい!と強く思ったとします。そこで、1回目のトランザクションを正にしようと動いたとします。Bobが持っているのは、Aliceが作成したトランザクションです。それに自分の署名を入れてブロードキャストしたらどうなるでしょう。

当然、1回目のトランザクションが実行されるので、まずAliceに4BTC渡りますが、残りの6BTCは先ほどの条件にあったとおり、一定期間が経過するまでロックされてしまい、それまでBobの秘密鍵では取り出せません。一方Aliceは、すでにBobのシークレットを持っているので、6BTCゲットできるというわけです。

なので、ブロードキャストする理由はBobにはありませんよね。自分の得られるはずの6BTC、もとい2BTCすらも失ってしまうわけですから。

ここでの一定の時間、というのが、CSVロックタイムといって、時間を絶対量として、1000ブロック経過するまでは、資金をロック=受け取れないようにする仕組みです。このように、相手を欺こうとしてブロードキャストさせたとしても、そこから一定の時間が経過するまでは、受け取れず、結果すべての金額は相手に取られてしまうという仕組みなんですね。

※その後訂正(2018年8月11日)。CSVロックタイムは、絶対的なものではなくむしろ相対的なもの。ブロックに含まれてからの相対時間でした。CLTVが絶対時間ですね。失礼しました。

なので、1回目(元)のトランザクションが自分にとって好都合だったとしても、ブロードキャストすることはせず、最新のトランザクションを参照しにいきますよ、というものだそうです。

【クロージングトランザクション】

そして、最後にクロージングトランザクションとして、オープニングトランザクションのアウトプットであった10BTCから2人の宛先に2BTC,8BTCに割り当てた残高をブロードキャストして、確定し、終了します。

ただ、一つ解せないのが、オープニングトランザクションをブロードキャストするのが、なぜ1回目と2回目のコミットメントトランザクションの間のタイミングなのか?というのは、ハッキリとした理由が分からず、教えていただきたいのですが、恐らく1回目と2回目の間にやることに意味があるのでしょう。2回目のトランザクションの参照先として10BTCを指定する必要があるからですかね。ただそうすると、3回目がもし発生した時にはどうするんでしょうね。

いや、そもそも双方向ペイメントチャネルは、Segwit(セグウィット)が実装されていることが条件なので、未署名のままのオープニングトランザクションであっても、インプットとして参照できます。自分に引っ掛け問題を出している私・・・。笑 Segwitというのは署名をしていなくても、署名領域をトランザクションのインプットから外しているので、署名の有無が、インプットを参照する際に必要なトランザクションIDに影響を与えないというものです。

そうすると、3回目以降が発生しても、問題ないぜ!ということですね。ただやはりなぜ1回目と2回目の間なのか・・・1回目のトランザクションの前に、いっちばん最初にやっちゃ、何がまずいんでしょうかね?だって、未署名のトランザクションじゃないと参照できないってことはないんですよね。あとは、またそもそもですが、この流れだけ見ていると、途中でBTCの送金額を変更する前提であるがために、わざわざ面倒くさいステップを踏んでいるようにも見えますよね。どういう用途を想定してのことなんでしょうか。まだまだ勉強不足ですね。ウォレットをまた触ってみますかね。

※その後安土さんより速攻でご教示いただきました。オープニングトランザクションが最初のコミットメントトランザクションの後にブロードキャストされるのは、払い戻しを可能にするため、とのこと。オープニングトランザクションイコールマルチシグへのデポジットになりますが、オープニングトランザクションをブロードキャスト後、どちらか一方が音信不通になると全額がずっとロックされたままになるため。それを避けるため、チャネルの最初にそれぞれの残高が設定されたコミットメントトランザクションを作成し署名後、オープニングトランザクションに署名してブロードキャストするようになってます、とのこと。素晴らしいご解説でした。ありがとうございました!


認識できていない点、相違がございましたら、ご指摘くださいますと幸いです。

ただ、ロックタイムとシークレットが重要な役割を果たしていそうなことは何となく見えてきたので、次回は、もともと話したかった、アトミックスワップについて進めていきたいと思います。インターオペラビリティが降ってきてからえらいことになってしまいましたが、有意義な寄り道でした。それが終わったら、ステーブルの話に行きたいです!

今夜もありがとうございました。