ライトニングネットワークを用いて送受金を行うとき、皆さんは次の様な文字列を見たことはありませんか。

lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzq9qrsgqdfjcdk6w3ak5pca9hwfwfh63zrrz06wwfya0ydlzpgzxkn5xagsqz7x9j4jwe7yj7vaf2k9lqsdk45kts2fd0fkr28am0u4w95tt2nsq76cqw0

これは「ライトニングインボイス(Lightning Invoice)」といい送金に関する情報が記載された請求書です。

基本的には送金を受け取る側がウォレットの「請求(Receive)」ボタンを押すことで発行されます。

本稿ではインボイスについての基礎的な話からインボイスに含まれる情報の内訳、またあまり知られていないニッチな雑学まで解説を行います。

Decode Lightning Network Requests - BOLT11, LNURL, and Lightning Address
Lightning Decoder is a tool for decoding Lightning Network request codes - BOLT11s, LNURL codes, and Lightning Addresses are supported.

上記の「Lightning Decoder」はインボイスをデコードしてくれるサイトです。本稿で解説した内容と比較を行うと学習しやすいと思うので合わせてご利用ください。

それでは本題に入ります。

インボイス(Invoice)とは

インボイスはBOLT #11にて定義されたライトニングネットワーク上での支払いを要求するための請求書です。

作成時には、受取人が秘密のデータである「プリイメージ(preimage)」を生成し、そのハッシュ値(payment_hash)をインボイスに含めます。プリイメージは送金が完了する瞬間まで誰にも明かしてはいけない秘密情報で、これを鍵にすることで送金のアトミック性を担保しています。

💡
「アトミック性」とは全て成功するか、全て失敗するかの2択を表す言葉です。つまり送金が中継される過程で資金が中抜きされて中途半端に失敗することがないという意味で使われます。

プリイメージがどう送金に関わっているのか詳しく知りたい方はこちらの記事をご参照ください。

HodlインボイスがLNを舞台裏で支える | カストディを防ぐライトニング随一の「裏ワザ」とは
ライトニングネットワークにおけるHodlインボイスの仕組みと活用例、短時間の使用がライトニングのノンカストディアルな利用にとってポジティブな理由を解説。逆に、長時間のHodlインボイスが推奨されない理由となるデメリットも分かりやすく紹介します。

ライトニングインボイスの基本的な構成

インボイスは人間が読める「可読部分」と「データ部分」で構成され、Bech32でエンコードされます。基本的には全て小文字ですがQRコードにする場合はスペース効率の向上のため大文字で表現される場合が多いです。

インボイスの主な構成は以下の通りです。

可読部分

  • 接頭辞(プレフィックス)
  • 金額(amount)

データ部分

  • タイムスタンプ(Timestamp)
  • タグ付きフィールド(0個以上)
  • 署名(Signature)

なお可読部分とデータ部分の間には数字の「1」が存在します。これはBech32で定義される仕切りとして機能しています。

インボイスの構造

接頭辞(プレフィックス)

インボイスは「Lightning Network(ライトニングネットワーク)」を表すlnという文字から始まり、その後BIP173の定義を参考にメインネットなのか、テストネットかなどの環境を判別する独自の識別子が続きます。

lnbc:Bitcoin Mainnet

lntb:Testnet Bitcoin

lntbs:Bitcoin Signet

lnbcrt:Bitcoin regtest

つまりライトニングネットワークのメインネットで送金を受け取る場合はインボイスの先頭は必ずlnbcとなっているので確認することをおすすめします。

金額(amount)

接頭辞の後は金額を表す部分が続きます。

通常インボイスを発行する際は受取人が金額の指定を行いますが金額なしのインボイスを発行することも可能です。つまりスキップすることも可能。

💡
金額なしのインボイスを発行した場合は、支払者が金額を設定して送ることができます。これは寄付などを行う際に使われますがインボイスは一度きりしか使えないため圧倒的にライトニングアドレスの方が使い勝手が良いです。そのためか金額を指定しないインボイスを発行できないウォレットが最近は多い印象です。

金額の表記単位はsatoshi(sat)ではなくBTCを用います。スペース削減のため乗数で表現しており、例えば1satは10n、100satは1u、1msatは10pと表します。

単位 乗数 sat表記
m (ミリ) 0.001 100,000
u (マイクロ) 0.000001 100
n (ナノ) 0.000000001 0.1
p (ピコ) 0.000000000001 0.0001
💡
送金に関する雑学としてインボイスに記載されている額の2倍までなら私たちは送金をすることが可能です(ウォレットの実装に依る)。BOLT #11によると支払者が少額のばらつきを加えることで支払いを追跡されにくくするための目的があります。 一方で、指定された金額を変更して送金を行うことができるウォレットは少ないのでぜひ探してみてください。

タイムスタンプ(Timestamp)

データ部分の最初は35ビットのタイムスタンプです。

タイムスタンプとは1970年1月1日UTC 0時からの経過時間のことで一般的にエポック秒(Unix time / Unix timestamp)と言われます。

Bech32は5ビットで符号化されるため、35÷5=7でちょうど7文字の英数字でタイムスタンプが表現されていることがわかります。

💡
35ビットの符号なし整数の最大値は \(2^{35}\)-1=34,359,738,367秒。これは西暦3059年頃までを表現可能という事なので約1000年間は桁があふれる心配はありません。

タグ付きフィールド

タグ付きフィールドは「TLV(Type-Length-Value)」形式のデータ単位で、送金を行う際の情報を格納することができます。

基本構造としては3つの要素がtypedata_lengthdata の順で並ぶことで構成されます。

要素 サイズ 内容
type 5ビット どんな種類の情報か(識別子)
data_length 10ビット data の長さ
data data_length × 5ビット 実際の中身

5ビット単位なのは、Bech32エンコーディングが1文字当たり5ビット(32種類の文字)で表現される方式だからです。

現在定義されているタグ付きフィールド

現在定義されているタグ付きフィールドを以下に書いておきます。インボイスを作成する上ではp(payment_hash)とs(payment_secret)は必須です。またd(short description)とh(description hash)はどちらが一方を含めることが必要になります。

type文字フィールド名内容
ppayment_hash256ビットのSHA256 payment_hash。このプリイメージは支払いプロセスの中で後から明かされ、支払いの証明として機能する。
spayment_secret256ビットの秘密情報。転送ノードが受取人を探ろうとする(プロービング)のを防ぐ。
ddescription支払い目的の簡単な説明をUTF-8で記載できる。例:「コーヒー1杯」。このフィールドを設定しない場合は、代わりに h タグを使用しなければならない。
mmetadata支払いに添付する追加のメタデータ。
nnode_id受取人ノードの33バイト公開鍵を含めることができる。
hhashd フィールドに収まらない場合、より長い説明のハッシュ値をここに含めることができる。完全な説明文をどう伝えるかについてはここでは規定しない。
xexpiry有効期限(秒)。デフォルトは3600秒。
ccltvルート内の最後のHTLCに対する min_final_cltv_expiry_delta。通常デフォルトは18。
ffallbackLightning決済が何らかの理由で失敗した場合に備えた、オンチェーンのフォールバックアドレスを含めることができる。
rroute hintsプライベートルートのための追加ルーティング情報を含む、1つ以上のエントリ。各ルーティングヒントには以下が含まれる:
pubkey(264ビット)
short_channel_id(64ビット)
fee_base_msat(32ビット、ビッグエンディアン)
fee_proportional_millionths(32ビット、ビッグエンディアン)
cltv_expiry_delta(16ビット、ビッグエンディアン)
9featuresこの支払いを受け取るためにサポートまたは要求される機能を示す、1つ以上の5ビット値。

Type-Length-Value形式にしておくと、読み取り側が知らないtypeに出会っても、data_lengthを見てビット数(データの長さ)分スキップしてもいいとわかるので、将来新しいフィールド(type)を追加しても古い実装が壊れないという利点が存在します。

署名(Signature)

インボイスの末尾には520ビットの「受取人の秘密鍵による電子署名」がついています。署名は「人間可読部分+データ部分(署名は除く)」をSHA256でハッシュ化したものに対して作られるので、インボイスの中身が1文字でも改ざんされていたら署名が合わなくなる仕組みになっています。

Bech32は1文字=5ビットなので、520 ÷ 5 = 104文字が、請求書の末尾(チェックサムの手前)にちょうど署名として現れることがわかります。

💡
チェックサム(誤り検出)は署名の後ろに6文字続きます。

まとめ

Lightningインボイスは、BOLT #11で定義された送金請求書で、Bech32形式でエンコードされます。

構成は大きく「可読部分(プレフィックス+金額)」と「データ部分(タイムスタンプ+タグ付きフィールド+署名)」の2つに分かれ、その間は 1 で区切られます。

  • プレフィックスlnbc などでネットワーク環境を示す。
  • 金額m/u/n/p の乗数でBTC建てを簡潔に表現。省略も可能。
  • タイムスタンプ:発行時刻をエポック秒(35ビット)で記録。
  • タグ付きフィールド:TLV形式で p(payment_hash)や d(説明)など可変の補足情報を格納。
  • 署名:受取人の秘密鍵による520ビットの電子署名で、内容の改ざんを検知。

これらの仕組みにより、Lightningインボイスは1つの文字列だけで「誰に・いくら・何の目的で・いつまでに」支払うかを、改ざん耐性を持ったコンパクトな形で伝えることができます。