Develop with pleasure!

福岡でCloudとかBlockchainとか。

LN Offer

LN Offerは、ノードがLNを介してインボイスを要求、受信できるようにするプロトコル拡張機能の1つで、BOLTにもBOLT 12として提案されている↓

https://github.com/rustyrussell/lightning-rfc/blob/guilt/offers/12-offer-encoding.md

http://bolt12.org/

LNの支払いは、受信者がBOLT 11で定義されているインボイスを発行し、それをQRコードコードなどで読み取って送信者がLN支払いをするというのが一般的で、実際に送信者と受信者がインタラクティブに通信することはない。

LN Offerの機能

LN Offerはインボイスの前段階の処理フェーズで、Offerに基づいてインボイスの要求や発行をするための情報を提供する。

Offerを利用したフロー

Offerを利用した支払いのフローは以下のようになる:

ユーザー→サービス提供者へ支払いをする場合
  1. サービス提供者がWebサイトやQRコードでOfferを公開する。
  2. ユーザーは、LNを介して一意のインボイスを要求する。
  3. サービス提供者は2に対してインボイスを返信する。
  4. ユーザーは送られたインボイスに従って支払いをする。
ユーザーがサービス提供者から支払いを受ける場合

ATMや払い戻しなどでサービス提供者がユーザーへ支払いするフローは:

  1. サービス提供者がユーザー固有のOfferを、WebサイトやQRコードで金額と一緒に提供する。
  2. ユーザーはOfferの金額のインボイスを送信する。
  3. サービス提供者は、2のインボイスに従って支払いをする。

インボイスは1回しか使えないけど*1、Offerの場合同じものを何度でも利用可能。寄付なんかを受け付ける場合も、サイトにOfferのQRコードだけ貼っておけば、寄付したいユーザーがOfferを読んで、インボイスを要求し、発行されたインボイスに対して支払いをする。

メッセージの通信

LN Offerに対してインボイスの要求や発行する際のメッセージの送信には、既存のオニオンルーティングを使ったLNのメッセージ送信の仕組みがそのまま使われる。アプローチは、実際に支払いをしない偽の支払いを送信するLNを使ったチャットアプリとかと似てる。

bootstrap.bolt12.orgで公開されているサンプルを見ると、一番シンプルなOfferのデータは↓

{
  description: "Offer by rusty's node",
  node_id: "4b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605",
  offer_id: "28522b52ac39fa518ce3a5b3e4a9a96372487e78ba5eb1540ec4d9f02ca82718",
  signature: "f4c5b54263766d8aa86dcb28b9973449cf995ef58ce8a96430bbb5b516460f465e9794b6842f1260b400966a3eb7e1557998f858aeb5bce1459ebc984fa3cabb",
  type: "bolt12 offer",
  valid: true
}

Offerを受けつるnode_idが記載されているので、ここにインボイスの要求/発行をするメッセージをLNのネットワークを介して送信することになるっぽい。

bech32でエンコードしたデータも記載されてる↓けど、どうもQRコード自体がチェックサム機能を持っているから、bech32のチェックサムは省略されてるっぽい(bech32使う必要ないよね。。)。

lno1pg257enxv4ezqcneype82um50ynhxgrwdajx283qfwdpl28qqmc78ymlvhmxcsywdk5wrjnj36jryg488qwlrnzyjczlqs85ck65ycmkdk92smwt9zuewdzfe7v4aavvaz5kgv9mkk63v3s0ge0f099kssh3yc95qztx504hu92hnx8ctzhtt08pgk0texz0509tk
ブラインドパス

↑のOfferにはnode_idが記載されているけど、Offerとインボイス両方についてノードIDを明らかにすることなく、つまりメッセージの送信先を知ることなく、Offerへのリクエスト/レスポンスを返すことも可能。

支払いの証明

通常のLN支払いの支払いの証明は、インボイスに含まれているpayment_hashのプリイメージを示すこと。ただ、この場合、プリイメージさえ知っていれば誰でも支払いをしたと主張できてしまう。

この問題に対処するため、Offerに対してインボイスを要求する場合、送信者は公開鍵payer_keyを、リクエストのTLVフィールドに含める。そして、発行されるインボイスのTLVデータにもこのデータが含まれ、これによりインボイスの所有を証明する。※ 払い戻しの時などに、実際の支払者であることを証明するのに使われる。

また、BOLT 11インボイスの場合、署名がインボイス全体適用されるため、インボイスの全データを公開しないとインボイスを証明することはできなかった。BOLT 12では、各TLVフィールドのデータでマークルツリーを構成し、そのルートハッシュに対して署名が計算される(Taprootと同様の署名スキームを実装している)。このため、支払いに関する情報をすべて公開することなく支払いの証明が可能になる。

※ また署名アルゴリズムはSchnorr署名を採用しており、BIP340と同様、公開鍵はx座標のみをエンコードした32バイトの公開鍵が採用されている。

デプロイ状況

現在BOLT 12はまだドラフトで、c-lightningが実験的にサポートしている状況。

また↑のオニオンメッセージについても、現在まだドラフトで、現状のc-lightningは、オニオンメッセージを送信する際は、直接接続をしてるっぽいので、Torなどを使ってないとプライバシー上のリスクがある状態。

Offerが利用可能になると、OfferのQRコードを公開しておけばよく(WebサイトでもTwitterでも)、後はLNノードにインボイス要求が来たら反応するということが可能になるので、インボイス生成用にWebサーバーとかを別途用意するみたいなことしなくてもよくなる。

ただ、インボイスの要求や配信はオニオンメッセージを介して送信されるので、対象ノードまでの経路がなければ送れないだろうし、これらのメッセージを中継するノードの帯域幅やリソースは消費されることになるんじゃないかな。

*1:使用済みのインボイスは、ネットワーク上でペイメントシークレットが既知のものになっているので、同じシークレットを使用した支払いは安全ではない