高級
Invoice Encoding 發票編碼
深入了解 BOLT 11 發票的編碼格式,包括 Bech32 編碼、欄位結構和簽名驗證。
12 分鐘
BOLT 11 發票結構
BOLT 11 定義了閃電網路發票的標準編碼格式。發票使用 Bech32 編碼, 包含支付所需的所有資訊:金額、目的地、支付哈希、過期時間等。
人類可讀: BOLT 11 發票以 "ln" 開頭,後接網路標識符(bc=主網、tb=測試網), 使其易於識別為閃電發票。
發票格式解析
BOLT 11 Invoice Structure Example Invoice: lnbc10u1pj9...omitted...cqzzsxqyz5vq Breakdown: • ln : prefix (Lightning Network) • bc : network (bc=mainnet, tb=testnet, bcrt=regtest) • 10u : amount (10 micro-bitcoin = 1000 sats) • 1 : separator • pj9... : timestamp + data fields (Bech32 encoded) • cqzzsxqyz5vq : signature + recovery flag Amount Units: ┌────────┬─────────────┬─────────────────────────────┐ │ Letter │ Multiplier │ Conversion │ ├────────┼─────────────┼─────────────────────────────┤ │ m │ 0.001 │ milli-bitcoin (100,000 sats)│ │ u │ 0.000001 │ micro-bitcoin (100 sats) │ │ n │ 0.000000001 │ nano-bitcoin (0.1 sats) │ │ p │ 1e-12 │ pico-bitcoin (0.0001 sats) │ └────────┴─────────────┴─────────────────────────────┘ Examples: • lnbc1m = 0.001 BTC = 100,000 sats • lnbc100u = 0.0001 BTC = 10,000 sats • lnbc1000n = 0.000001 BTC = 100 sats • lnbc (no amount) = amount decided by payer
資料欄位(Tagged Fields)
BOLT 11 Tagged Fields
Field Structure:
┌──────────────────────────────────────────────────────────────┐
│ [type: 5 bits] [data_length: 10 bits] [data: variable] │
└──────────────────────────────────────────────────────────────┘
Required Field:
• p (1) : payment_hash - 256-bit SHA256 hash, used for HTLC
Common Fields:
• d (13) : description - short text (UTF-8)
• h (23) : description_hash - SHA256 of long description
(mutually exclusive with d)
• x (6) : expiry - expiration time in seconds (default 3600)
• n (19) : payee_pubkey - receiver public key (33 bytes)
can be recovered from signature
• c (24) : min_final_cltv_expiry_delta - minimum CLTV delta
(default 18)
Routing Hints:
• r (3) : routing_info - hints for private channels
Per hop (51 bytes):
- pubkey: 33 bytes
- short_channel_id: 8 bytes
- fee_base_msat: 4 bytes
- fee_proportional_millionths: 4 bytes
- cltv_expiry_delta: 2 bytes
Feature Bits:
• 9 (5) : feature_bits - supported features
e.g., payment_secret, basic_mpp
Payment Secret:
• s (16) : payment_secret - 256-bit random value
Prevents probing and forward-hijacking
Required for MPP Bech32 編碼
Bech32 Encoding Details Character Set (32 characters): qpzry9x8gf2tvdw0s3jn54khce6mua7l • Excludes confusing chars: 1, b, i, o • All lowercase to reduce errors Encoding Process: 1. Raw data (8-bit bytes) ↓ 2. Convert to 5-bit groups ↓ 3. Map to Bech32 characters ↓ 4. Add checksum (6 characters) Checksum Properties: • Uses BCH code (Bose-Chaudhuri-Hocquenghem) • Detects up to 4 character errors • Guarantees detection of 2 substitution errors within 89 chars • Provides error position hints Example Conversion: Timestamp 1496314658 = 0x5932DC22 (32-bit) = Split into 7 x 5-bit groups = [0b01011, 0b00100, ...] = Bech32 characters
簽名與驗證
Invoice Signature Signed Message: SHA256(SHA256( hrp (as UTF-8 bytes) || data (as 5-bit values, excluding signature) )) hrp = "lnbc" or "lntb" etc. Signature Format (65 bytes): ┌──────────────────────────────────────────────────────────────┐ │ r: 32 bytes - ECDSA signature r value │ │ s: 32 bytes - ECDSA signature s value │ │ recovery: 1 byte - public key recovery flag (0-3) │ └──────────────────────────────────────────────────────────────┘ Public Key Recovery: If invoice has no n (payee_pubkey) field: 1. Compute hash of signed message 2. Use recovery ID to recover pubkey from signature 3. Recovered pubkey is the receiver's node ID • Benefit: saves 33 bytes Verification Flow: 1. Decode Bech32 2. Verify checksum 3. Parse fields 4. Verify signature (or recover pubkey) 5. Check expiration time 6. Validate amount format
解碼範例
Invoice Decoding Example Raw Invoice: lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rq wzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahr sqsrzjqwryaup9lh50kkranzgcdnn2fgvx390wgj5jd07rwr3vxeje0glclldc wwnqqqqqqqqqqqqqqqsqfq2zs8t3c Decoded Result: • Network: mainnet (bc) • Amount: 20 mBTC = 2,000,000 sats • Timestamp: 1496314658 (2017-06-01 12:57:38 UTC) • payment_hash: 0001020304050607080900010203040506070809000102030405060708 • description_hash: 3925b6f67e2c340036ed12093dd44e0368df1b6ea26c53dbe4811f58fd5db8c1 • Expiry: 3600 seconds (default) • Signature: valid • Payee pubkey: (recovered from signature) CLI Decoding: # LND lncli decodepayreq <invoice> # Core Lightning lightning-cli decode <invoice> # Online Tool https://lightningdecoder.com/
程式碼範例
JavaScript 解碼範例:
// 使用 bolt11 庫
import * as bolt11 from 'bolt11';
const invoice = 'lnbc10u1p...';
// 解碼
const decoded = bolt11.decode(invoice);
console.log({
network: decoded.network, // 'bc' | 'tb'
satoshis: decoded.satoshis, // 金額
timestamp: decoded.timestamp, // Unix 時間戳
timeExpireDate: decoded.timeExpireDate,
paymentHash: decoded.tags.find(t => t.tagName === 'payment_hash')?.data,
description: decoded.tags.find(t => t.tagName === 'description')?.data,
payeeNodeKey: decoded.payeeNodeKey, // 收款人公鑰
});
// 創建發票(需要私鑰)
const encoded = bolt11.encode({
satoshis: 1000,
description: 'Test payment',
timestamp: Math.floor(Date.now() / 1000),
tags: [
{ tagName: 'payment_hash', data: paymentHash },
{ tagName: 'expire_time', data: 3600 },
],
});
const signedInvoice = bolt11.sign(encoded, privateKey); 發票大小限制
沒有硬性限制,但 QR 碼有實際限制。 建議保持在約 1023 字元以下以確保 QR 可讀。
大小寫
Bech32 使用小寫,但解碼器應接受大寫或小寫。 混合大小寫是無效的。
BOLT 12 演進: BOLT 12 Offers 使用 TLV 編碼取代 Bech32, 支援可重複使用的支付請求和更好的隱私。
相關資源
- • BOLT 11 規範
- • 發票格式概覽
- • BOLT12 Offers
下一步: 了解 LNURL 如何簡化支付流程。
已複製連結