Pedidos de Pagamento BOLT 11
Como uma invoice codifica valor, destino, hash, features e dicas de rota
Lightning · Técnico
Uma invoice Lightning é um pedido de pagamento assinado pelo recebedor. Ela diz ao pagador qual rede usar, qual valor pagar, qual payment_hash travará o HTLC, qual payment_secret deve chegar ao destino, quais features são exigidas e, quando necessário, como encontrar o recebedor por canais privados.
A especificação principal é a BOLT 11. Ela usa Bech32, SHA256 e assinatura ECDSA sobre a curva secp256k1. No fluxo de pagamento, os dados da invoice alimentam o buscador de caminho, o payload onion e os HTLCs enviados pelos canais.
Esta página fala de BOLT 11. BOLT 12 offers aparecem no fim como evolução, mas não são o mesmo formato: BOLT 12 usa TLV, assinaturas Schnorr/BIP340 e um fluxo interativo de offer -> invoice_request -> invoice.
Conteúdo
Modelo mental
Uma invoice BOLT 11 não move dinheiro. Ela prepara o pagamento. O dinheiro só se move quando o pagador transforma aquela invoice em uma rota, monta um pacote onion e envia um update_add_htlc pelo primeiro canal.
- O recebedor sorteia uma
payment_preimagee calculapayment_hash = SHA256(payment_preimage). - O recebedor cria uma invoice com
payment_hash,payment_secret, descrição, valor opcional, expiração, CLTV final, features e dicas de rota opcionais. - O recebedor assina a invoice com a chave privada do seu node id.
- O pagador valida a invoice, decide se aceita valor, expiração, fees e timeout, calcula uma rota e cria o onion packet.
- O hop final recebe no payload onion o
payment_secrete, se existir, opayment_metadatada invoice. - Se o recebedor aceitar o conjunto de HTLCs, ele revela a preimage. A preimage vira a prova prática de pagamento daquele
payment_hash.
Estrutura da invoice
Uma invoice como lnbc... tem duas grandes partes separadas pelo último caractere 1:
- HRP, ou human-readable part. Começa com
ln, inclui o prefixo de rede e pode incluir o valor. - Data part. Contém timestamp, campos com tag, assinatura compacta e checksum Bech32.
Descrição longa do diagrama
O diagrama mostra uma string de invoice separada em HRP, separador 1 e data part. A data part é quebrada em timestamp, campos com tag, assinatura e checksum. A imagem destaca que o HRP informa rede e valor, enquanto a data part carrega os dados técnicos usados para pagar.
lnbc2500u1...
^^^^^^^^
ln = invoice Lightning
bc = Bitcoin mainnet
2500u = 2500 micro-bitcoins = 0,00250000 BTC Rede e valor no HRP
O prefixo de rede fica dentro do HRP. Para Bitcoin, os prefixos comuns são:
| Prefixo | Rede | Exemplo |
|---|---|---|
| lnbc | Bitcoin mainnet | lnbc... |
| lntb | Bitcoin testnet | lntb... |
| lntbs | Bitcoin signet | lntbs... |
| lnbcrt | Bitcoin regtest | lnbcrt... |
O valor é opcional. Quando existe, a unidade base é bitcoin, não satoshi. A letra final é um multiplicador decimal:
| Sufixo | Multiplicador em BTC | Exemplo |
|---|---|---|
| m | 0,001 | lnbc20m = 0,02000000 BTC |
| u | 0,000001 | lnbc2500u = 0,00250000 BTC |
| n | 0,000000001 | lnbc100n = 10 sats |
| p | 0,000000000001 | lnbc1000p = 100 msat |
O sufixo p trabalha em pico-bitcoin. Como a Lightning encaminha HTLCs em millisatoshis, a BOLT 11 exige que valores com p terminem em 0, evitando valor abaixo de 1 msat.
Invoice sem valor não significa pagamento livre sem validação. Significa que o pagador escolhe o valor, mas o recebedor ainda pode recusar no momento de aceitar o HTLC.
Data part e tagged fields
A data part começa com um timestamp de 35 bits, em segundos desde 1970-01-01 UTC. Depois vem uma sequência de campos com tag. Cada campo tem:
[ type: 5 bits ][ data_length: 10 bits ][ data: data_length grupos de 5 bits ] O tamanho máximo do dado de um campo é limitado por data_length: 1023 grupos de 5 bits, isto é, até 639 bytes. Isso importa para descrições, metadata e extensões futuras.
| Tag | Nome | Obrigação | Dado | Uso |
|---|---|---|---|---|
| p (1) | payment_hash | obrigatório, exatamente um | 32 bytes | Hash SHA256 da preimage que o recebedor revelará se o pagamento for concluído. |
| s (16) | payment_secret | obrigatório, exatamente um | 32 bytes | Segredo escolhido pelo recebedor para dificultar probing e amarrar o pagamento ao payload final. |
| d (13) | description | d ou h, exatamente um dos dois | UTF-8 variável | Descrição curta do motivo do pagamento. |
| h (23) | description_hash | d ou h, exatamente um dos dois | 32 bytes | Hash SHA256 de uma descrição externa maior. |
| x (6) | expiry | opcional | inteiro em segundos | Tempo relativo de expiração. Se ausente, o default da BOLT 11 é 3600 segundos. |
| c (24) | min_final_cltv_expiry_delta | recomendado | inteiro em blocos | Delta mínimo de CLTV que o recebedor exige no HTLC final. Se ausente, o pagador usa pelo menos 18. |
| n (19) | node_id | opcional | 33 bytes | Chave pública comprimida do nó recebedor. Se ausente, o pagador recupera o node id pela assinatura. |
| 9 (5) | features | opcional | feature vector | Funcionalidades exigidas ou aceitas para este pagamento, seguindo a BOLT 9. |
| r (3) | routing_info | opcional, pode repetir | rotas de 51 bytes por hop | Dicas de rota para canais privados ou não anunciados. |
| f (9) | fallback_address | opcional, pode repetir | endereço on-chain codificado | Endereço Bitcoin de fallback caso o pagamento Lightning falhe. |
| m (27) | payment_metadata | opcional | bytes variáveis | Metadados que o pagador copia para o payload onion final. |
O parser precisa ser tolerante com campos que pode ignorar, mas rígido com estrutura inválida. Campos fixos como p, h, s e n precisam ter o tamanho correto. A invoice deve ter exatamente um p, exatamente um s e exatamente um entre d e h.
Tamanho fixo e a regra de "pular" em vez de falhar
Como data_length conta grupos de 5 bits, os campos de tamanho fixo têm um número exato de grupos, não de bytes. É por isso que p, s e h ocupam 52 grupos e n ocupa 53:
campo bits data_length (grupos de 5 bits) bytes
p 256 52 (52 × 5 = 260 bits, 4 de padding) 32
s 256 52 32
h 256 52 32
n 264 53 (53 × 5 = 265 bits, 1 de padding) 33 A BOLT 11 trata tamanho errado nesses campos de um jeito específico: em vez de rejeitar a invoice inteira, o leitor ignora um p, s, h ou n cujo data_length não seja o esperado, como se o campo não existisse. Isso mantém a compatibilidade com extensões futuras, mas tem uma consequência prática: um p com tamanho errado é descartado em silêncio, e a invoice passa a não ter nenhum payment_hash — aí sim ela falha na validação de campos obrigatórios. Ou seja, "pular o campo" não relaxa a exigência de haver exatamente um p e um s válidos; só muda onde o erro aparece.
entrada: invoice BOLT 11
1. verificar Bech32 sem limite de 90 caracteres
2. separar HRP e data part pelo separador "1"
3. validar prefixo "ln" + rede + valor opcional
4. ler timestamp de 35 bits
5. percorrer tagged fields:
- type: 5 bits
- data_length: 10 bits
- data: data_length grupos de 5 bits
6. separar os últimos 104 grupos de 5 bits como assinatura
7. validar campos obrigatórios:
- exatamente um p
- exatamente um s
- exatamente um d ou exatamente um h
8. validar a assinatura ECDSA/secp256k1
9. montar o pagamento:
- payment_hash vem do campo p
- payment_secret vem do campo s
- min_final_cltv_expiry_delta vem do campo c ou default
- routing hints vem dos campos r
- features vem do campo 9 payment_hash, payment_secret e metadata
O campo p carrega o payment_hash. Ele é o cadeado do pagamento: todos os HTLCs daquele pagamento usam o mesmo hash, e o recebedor só recebe de fato ao revelar a preimage correta.
O campo s carrega o payment_secret. Esse valor não é a preimage. Ele é um segredo diferente, escolhido pelo recebedor, que o pagador precisa colocar no payload onion do hop final. Isso ajuda o recebedor a rejeitar tentativas de probing que descobriram um payment_hash mas não possuem a invoice correta.
Quando o campo m aparece, ele vira payment_metadata no payload final. Ele permite que o recebedor seja mais stateless, porque pode embutir dados de contexto na invoice e receber esses dados de volta no pagamento. O custo é tamanho: metadata grande consome espaço dentro do pacote onion e pode reduzir o comprimento máximo prático da rota.
tlv_payload do hop final
type 2 amt_to_forward = 100000 msat
type 4 outgoing_cltv_value = 850000
type 8 payment_data:
payment_secret = 32 bytes vindos do campo s da invoice
total_msat = 100000
type 16 payment_metadata = bytes vindos do campo m, se existir Nunca trate payment_secret como chave privada, seed ou backup. Ele é sensível para aquela tentativa de pagamento, mas não controla fundos sozinho. Mesmo assim, ferramentas educativas devem usar apenas exemplos fictícios.
Routing hints e fallback
Um recebedor pode ter canais privados, isto é, canais que não aparecem no gossip público. Nesse caso, o pagador não consegue descobrir sozinho o último trecho do caminho. O campo r resolve isso fornecendo dicas de rota.
campo r: uma entrada de rota privada
pubkey 33 bytes
short_channel_id 8 bytes
fee_base_msat 4 bytes
fee_proportional_millionths 4 bytes
cltv_expiry_delta 2 bytes
total: 51 bytes por hop Uma invoice pode ter mais de um campo r. Cada um representa uma opção de caminho, em ordem de preferência. O pagador pode combinar essas dicas com o grafo público, calcular fees e CLTVs, e tentar uma rota até o recebedor.
O campo f é diferente: ele não ajuda a rotear pela Lightning. Ele fornece um endereço Bitcoin on-chain de fallback. Pela BOLT 11, se a tentativa Lightning falhar, o pagador pode tentar usar o primeiro fallback que entende. Isso não deve ser usado automaticamente sem mostrar ao usuário, porque uma transação on-chain tem outra privacidade, outra taxa, outro tempo de confirmação e não segue a mesma semântica de HTLC.
Como o campo f codifica o endereço
O f não guarda o endereço em texto (bc1... ou 1...): ele guarda a forma binária. Os primeiros 5 bits do dado são um version, e o resto é o programa correspondente. É esse byte de versão que diz ao pagador que tipo de saída construir:
| Version | Significado | Dado |
|---|---|---|
| 17 | P2PKH | hash160 da chave pública |
| 18 | P2SH | hash160 do script |
| 0 a 16 | Witness (SegWit) | witness program da versão indicada — 0 para P2WPKH/P2WSH, 1 para P2TR |
| 19 a 31 | Reservado | o leitor deve ignorar |
Repare que 17 e 18 reaproveitam números fora da faixa de versões de witness (0 a 16) justamente para caber os endereços legados P2PKH e P2SH no mesmo campo de 5 bits. É a mesma lógica de "version byte" que uma carteira usa ao montar o scriptPubKey on-chain.
Para entender o lado on-chain do fallback, veja Transação, Saída, Endereço, Bech32 e Memory Pool.
Assinatura e node id
No fim da data part vem a assinatura compacta ECDSA/secp256k1: 64 bytes de R || S mais 1 byte de recovery id. Como ela cobre o HRP e a data part sem a assinatura, qualquer alteração no valor, descrição, hash, features ou expiração quebra a validação.
n, o pagador recupera o node id a partir da assinatura.Descrição longa do diagrama
O diagrama mostra os componentes da assinatura no fim da invoice: os 32 bytes de R, os 32 bytes de S e o byte de recuperação. Uma seta indica que esses dados, junto com o hash da invoice sem a assinatura, permitem recuperar a chave pública comprimida do emissor.
Quando o campo n existe, ele declara explicitamente o node id do recebedor, e a assinatura deve validar contra essa chave. Quando n não existe, o pagador recupera a chave pública pela assinatura. Isso é útil para economizar bytes, mas implementações precisam validar assinatura e regras de canonicalidade com cuidado.
O que exatamente é assinado, e como o recovery id devolve o node id
A assinatura não cobre a string Bech32 final, e sim os dados antes da conversão para caracteres. A mensagem assinada é:
mensagem = SHA256( HRP_em_ASCII ‖ data_part_sem_assinatura )
- HRP_em_ASCII: os bytes do human-readable part, ex. "lnbc2500u"
- data_part_sem_assinatura: o timestamp + os tagged fields,
em grupos de 5 bits convertidos para bytes com zero-padding
no fim (a assinatura e o checksum ficam de fora) Como o HRP entra na mensagem, trocar a rede ou o valor no prefixo invalida a assinatura tanto quanto mexer num campo da data part. É isso que impede alguém de pegar uma invoice de lnbc e reapresentá-la como lntb, ou de inflar o valor sem refazer a assinatura.
O último byte da assinatura é o recovery id (um valor de 0 a 3). Com ele, a partir de R, S e do hash da mensagem, o secp256k1 reconstrói a chave pública que assinou — não é preciso já ter a chave. É exatamente esse passo que o decodificador da página executa: quando não há campo n, ele recupera o node id diretamente da assinatura e o usa como destino do pagamento. Quando há n, a chave recuperada tem que bater com a declarada; se não bater, a invoice é inválida.
Feature bits
O campo 9 usa feature bits no contexto de invoice. A semântica par/ímpar segue a BOLT 9: bit par representa funcionalidade obrigatória; bit ímpar representa funcionalidade opcional. Se a invoice contém um bit par desconhecido, o pagador deve falhar em vez de tentar pagar algo que não entende.
Features relevantes em invoices incluem basic_mpp, option_route_blinding, option_attribution_data e option_payment_metadata. Nem todo bit que aparece em init ou node_announcement é válido no contexto da tag 9; a coluna de contexto da BOLT 9 é a referência para isso.
Para experimentar a interpretação de bits, use também a ferramenta Feature Bits BOLT 9.
Ferramenta: decodificador de invoice
Use o decodificador com invoices públicas, de teste ou fictícias. Ele roda no navegador, valida a estrutura Bech32, mostra HRP, valor, timestamp, campos principais e tenta recuperar o node id pela assinatura. Ele não deve receber seed, mnemonic, chave privada, macaroon, senha, backup de canal ou dados reais de carteira.
Decodificador de Invoice BOLT 11
A ferramenta é didática. Ela ajuda a inspecionar campos e assinatura, mas não substitui uma implementação completa de carteira: uma carteira real também precisa validar políticas de pagamento, fees, timeout, dependências de features, rotas, expiração e resultado do pagamento.
BOLT 12 em contexto
BOLT 11 resolve bem pedidos de pagamento individuais, mas tem limitações: a invoice é de uso único, expira, mistura Bech32 com dados de pagamento, e a assinatura cobre a invoice inteira. Reutilizar a mesma invoice para várias pessoas é perigoso, porque reaproveita o mesmo payment_hash e enfraquece a semântica de recibo.
BOLT 12 muda o modelo. Um offer com prefixo lno é um convite reutilizável. O pagador envia um invoice_request por onion message, e o recebedor responde com uma invoice nova, em formato TLV, assinada com Schnorr/BIP340. O fluxo também usa blinded paths para melhorar a privacidade do recebedor.
Por isso, BOLT 12 não deve ser descrito como "uma invoice BOLT 11 melhorada". Ele é outro protocolo de negociação. Esta página fica em BOLT 11; offers merecem uma página própria quando a seção avançar.
Armadilhas comuns
- Confundir
payment_hashcompayment_secret. O primeiro trava o HTLC; o segundo autentica o pagamento esperado pelo recebedor. - Aceitar invoice sem
s. A BOLT 11 atual exige exatamente umpayment_secret. - Aceitar invoice com
dehao mesmo tempo, ou sem nenhum dos dois. - Ignorar a expiração
xe tentar pagar uma invoice vencida. - Renderizar a descrição
dcomo HTML confiável. Descrição de invoice é entrada do usuário e precisa ser escapada. - Tratar routing hint
rcomo canal público. Ele é uma dica fornecida pelo recebedor, não gossip validado globalmente. - Usar fallback on-chain automaticamente depois de falha Lightning sem consentimento explícito do usuário.
- Aplicar todas as features de BOLT 9 como se valessem no campo
9. O contexto da feature importa.
Resumo
- BOLT 11 é o formato clássico de invoice Lightning.
- O HRP indica rede e valor opcional; a data part traz timestamp, campos com tag e assinatura.
p,se exatamente um entred/hsão centrais para uma invoice válida.rajuda a chegar em canais privados;fé fallback on-chain, não rota Lightning.- O campo
9negocia features específicas do pagamento. - BOLT 12 é uma evolução com offers, invoice requests, TLV, Schnorr e blinded paths.
Mapa de dependências conceituais
Antes de ler esta página, ajuda conhecer:
Depois desta página, siga para:
Referências técnicas usadas
- BOLT 11 — Invoice Protocol for Lightning Payments
- BOLT 4 — Onion Routing Protocol
- BOLT 9 — Assigned Feature Flags
- BOLT 12 — Negotiation Protocol for Lightning Payments
- Bech32
- Assinatura
A seguir, voltamos ao nível do envelope de mensagens entre peers: o Protocolo Wire.