皆さんはビットコインを使ったサービスを事業として運営していくことを考えたことがありますか?その際に特に頭を悩ませる問題が「どこのタイミングで、どうやって売上を立てるか」です。

ここ20年を特徴づけたウェブサービスの主役であるマーケットプレイス型サービスの主な収益源は決済の仲介です。例えばメルカリ、ヤフオクのようなフリーマーケット系で7~10%、アプリストアで30%のように、仲介している金額に対して少なくない金額を手数料として売り上げています。(そのうち2~5%ほどは決済手数料としてそのまま決済会社へと支払われますが。)

ところが、ビットコインは第三者の仲介なしに取引できることが特徴であり、マーケットプレイスが決済に費用を課したところでそれを迂回するのも難しくありません。そこでライトニングを使って「買い手から売り手への送金を、必ずプラットフォームを経由させる」ことでノンカストディアルに決済の仲介をできるのではないか?という場合に使えるテクニックの1つにWrapped Invoiceがあります。

・Wrapped Invoiceの仕組み

・Lnproxyというプロジェクトで利用可能

・欠点はUXと手数料だけなのか

Wrapped Invoiceの仕組み

ライトニングでは送金経路上のノードからみて直前と直後の送金経路しかわからず、最終目的地や送金者のノードがどれかはわからない仕組みになっていました。このような条件下で「必ず自分が送金を中継している」と知る方法は1つだけです:前半・後半の2つの送金に分割することです。

もう1つ、ライトニング送金は宛先側から決済時に伝達される「プリイメージ」という秘密情報でロックされています。言い換えると、宛先側がプリイメージを送金者側へと伝達しない限り、そのライトニング送金は決済できません。また、ある送金についてのプリイメージはインボイス生成段階でそのハッシュ値によってコミットされており、変更することはできません。

これらの特徴を組み合わせて、Wrapped Invoiceは以下の形を取ります:

仲介者→売り手(最終目的地)の送金:送金②

まず、最終目的地である売り手が仲介者に対して要求する金額のインボイスを送り付けます。例えば金額10,000 sats、プリイメージハッシュH(A)とします。(この段階でプリイメージAは売り手のみが知る情報)

買い手→仲介者の送金:送金①

仲介者は売り手からもらったプリイメージハッシュH(A)を使って新しいインボイスを生成します。例えば自社の決済手数料3%を加えた10,300 sats、プリイメージハッシュH(A)というインボイスです。これを買い手に送り付けます。(この段階でもプリイメージAは売り手のみが知っており、仲介者は知りません。)

買い手はその内容を確かめて、仲介者に送金します。送金経路を辿ったsatsが仲介者に辿り着きますが、この時点で仲介者はまだプリイメージAを知らないので決済することができません。とりあえず一旦未決済の状態で保持します。(Hodl invoiceと呼ばれる状態。)

仲介者→売り手(最終目的地)の送金:送金②

買い手からの送金を受け付けて保留している仲介者は、最終目的地である売り手のインボイスに対して支払います。売り手にsatsが辿り着くと、それを決済するためにプリイメージAが伝達され仲介者まで伝えられます。

買い手→仲介者の送金:送金①

ここで仲介者はプリイメージAを使って買い手からの送金を決済することができます。これで買い手は10,300 sats+送金①の手数料を支払い、売り手は10,000 sats受け取り、仲介者は300 sats-送金②の手数料を受け取ります。

買い手に売り手のインボイスを伝えないことで、仲介者は上手く送金を仲介する立場を得ることができました。また、プリイメージハッシュH(A)を用いる限り、仲介者から売り手への送金が決済されなければ買い手から仲介者への送金も決済されないというアトミックでノンカストディアルな仕組みになっています。

実は元々Wrapped Invoiceは「仲介者に送金を通知するため」ではなく「最終目的地を秘匿するため」に生まれたアイデアですが、その仕組み上このような応用も可能というわけです。

Lnproxyというプロジェクトで利用可能

GitHub上にLnxproxyというリポジトリと、これを使ったウェブサイトがあります。これが何かというと、まさにさっきの例でいうところの「売り主(送金②)のインボイス」から「仲介者(送金①)のインボイス」であるWrapped Invoiceを生成してくれるサービスです。

lnproxy.org
A simple lightning network privacy tool.

ソースコードが公開されていることで、同じような機能を自社サービスに追加したい場合にわざわざ1から開発する必要はありません。(ただし送金を伴うサービスなので、ライトニングについて深い理解のあるエンジニアと相談するのが吉です。送金経路の制限などから高すぎる手数料を支払ってしまわないなど、考えうる攻撃方法に対してチェック体制が存在するかなど確かめましょう。)

例えばWallet Of Satoshiを使っていることがバレたくない場合や、自分のノードを相手に知ってほしくない場合などにLnproxyを使うことで最終目的地である自分のノード(売り手のノード)を秘匿することができます。知っているのはLnproxyの運営者だけです。

欠点は手数料だけなのか

さて、このように同じプリイメージの使いまわしというハッキーな手法で実現されているWrapped Invoiceですが、送金が2回発生することによって手数料がかさみやすい以外に実用上の問題はあるのでしょうか?

まず、ハッキーな手法がUX面に与える影響ですが、これは主に2箇所について分析できます。

Hodl Invoiceの利用がUX面で難しい

送金①に必然的にHodl Invoiceを用いることになりますが、もし短時間で送金②が決済されればすぐに送金①も決済できるため大きな問題はありません。困るのは、送金②が何らかの理由ですぐに決済されない場合––例えば売り主がオフラインだったり、いたずらで決済を先延ばしにしたり、経路上のいずれかのノードがオフラインの場合です。

一般的にウォレットからみて支払っているインボイスがHodl Invoiceかどうかを判別する方法がないため、送金が成功も失敗もしない、ぐるぐる待機状態となってしまいユーザーが混乱する可能性があります。カストディアルウォレットによってはこの状態が解消されるまで次の送金を行えないように制限されている場合もあり、UX面で問題となります。

幸い、オフラインになるようなルーティングノードは淘汰されていくと考えられますが、売り主がインボイスを生成してから買い手が支払うまで通常のEC決済と比べて大きなタイムラグが予想されるため現実的なリスクです。

プリイメージの使いまわしがセキュリティ面で課題

同じプリイメージを2回使うと、送金を中継するノードが過去の知識を使って勝手に送金を横取りしてしまうリスクがあります。したがって予測可能なプリイメージの使用も推奨されません。

しかし、Wrapped Invoiceでは同じインボイスを使った送金が2回行われます。以下のようなケースで送金関連の攻撃が起こり得ます:

1.送金者から仲介サービスへの送金経路上に宛先ノードBが存在する場合

送金経路を選ぶのは送金者なので実際にそのような経路を選んでしまうかは確率的な問題ですが、この場合売り主が送金①をBから決済してしまいつつ(+10,300 sats)、送金②をキャンセルする(+0 sats)ことでプラットフォームの決済手数料込みの金額を横取りすることができます。プラットフォーム側から見ると売り手への送金がキャンセルされ、買い手に返金した形になります。(損をしているのは買い手です)

予定と異なる形で最終目的地にはちゃんと送金されているにもかかわらず、第三者による紛争解決は難しく、プラットフォームの視点では送金①のHodl Invoiceは受け取ったが売り主への支払いが失敗したためキャンセルし返金したという状態になります。

2.送金①と送金②の経路上に同じノードが存在する場合

こちらのほうが確率的には高いかもしれません。送金②が決済されてプリイメージが回ってきた際に、プラットフォームより売り主側にいるノードがプラットフォームより買い主側にもいた場合、やはりプラットフォームをすっ飛ばしてプリイメージを伝達させることで

1,2どちらも送金経路上の2つのノードが内通していて、決済時にその中間のノードをすっ飛ばすことで彼らが得るはずであった手数料を横取りしてしまう攻撃で、このような攻撃はワームホール攻撃と言います。どちらの場合も買い手は送金②に合致するプリイメージを持っているため、攻撃があったことを推測することはできます。しかし、ワームホール攻撃をしたのが売り手自身なのか、中間ノードなのかを証明するのは困難です。

また、プラットフォームに人気が出ればワームホール攻撃を試行するインセンティブが十分に生まれてしまうかもしれません。Wrapped Invoiceを使うプラットフォームのノードに大量にチャネルさえ貼れば偶然ワームホール攻撃の機会が発生するかもしれないためです。プラットフォーム側は信頼できるノードをホワイトリスト方式で選ぶことでリスクを少し軽減できますが。

プラットフォーム視点だとすでに返金は済んでいるため、お客様対応として返金するわけにもいかないのも難しいですね。もししたらそれ目当ての自作自演ワームホール攻撃も発生するでしょうし。

送金①にはにトラストが必要

買い手の視点ではプリイメージが使いまわしか判断することができません。したがって、送金内容についてプラットフォームをトラストする必要があります。実は与えられたインボイスはプラットフォームが生成したもので、送金すると横領される可能性もあります。正直プラットフォームを利用してる時点でノンカストディアルであったとしてもある程度のトラストは発生していると思いますが一応。


このように、手数料の側面以外にもWrapped Invoiceにはいくつかセキュリティ上の課題があります。現時点では広く使われておらずワームホール攻撃の話は聞きませんが、多数のチャネルを張って資金を拘束してもペイする程度の収益が見込めるような大盛況のプラットフォームにとってはビジネス上のリスクとなります。

Wrapped Invoiceの説明に「Poor man's rendez-vous」とあるように、ランデブールーティング、トランポリンペイメントのような特定ノードを経由するよう指定しつつ最終目的地を秘匿できるインボイス方式(本命)が広く導入されるまでの実験的なつなぎだと考えておいたほうが良いでしょう。

LNの送金者・支払先を互いに秘匿する
ライトニングによる支払いはオンチェーンの支払いと大きく異るプライバシーの特性があります。一般にオンチェーンの取引と比較してプライバシーが高いと言われることの多いライトニングですが、それでもプライバシー面で独自の課題がたくさんあります。 その1つである、ライトニングで送金を受け付ける際にインボイスにノードIDやチャネルIDを含める必要がある問題に対しての、ルートブラインディングという機能提案を紹介しようと思います。 ついでに似たコンセプトであるランデブールーティング、そしてトランポリンペイメントと組み合わせた際の効果についても説明します。 ランデブールーティング 冒頭で触れた通り、通常のライトニングインボイスにはノードIDやプライベートチャネルの情報などが含まれてしまうため、インボイスが漏洩するだけでノードやチャネルの情報、ひいてはオンチェーンの資金に関する情報まで漏れてしまいかねません。また、複数のインボイスを入手した攻撃者はそれらの情報を照らし合わせることで同じ支払先のインボイスを結びつけることもできてしまいます。 そこでランデブールーティングではインボイスを発行する際に