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.

  1. O recebedor sorteia uma payment_preimage e calcula payment_hash = SHA256(payment_preimage).
  2. O recebedor cria uma invoice com payment_hash, payment_secret, descrição, valor opcional, expiração, CLTV final, features e dicas de rota opcionais.
  3. O recebedor assina a invoice com a chave privada do seu node id.
  4. O pagador valida a invoice, decide se aceita valor, expiração, fees e timeout, calcula uma rota e cria o onion packet.
  5. O hop final recebe no payload onion o payment_secret e, se existir, o payment_metadata da invoice.
  6. 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:

Estrutura de uma invoice BOLT 11 dividida em HRP, separador, data part, campos com tag e assinatura.
A BOLT 11 reaproveita Bech32, mas permite invoices maiores que o limite usual de 90 caracteres.
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:

Prefixos de rede em invoices BOLT 11
Prefixo Rede Exemplo
lnbcBitcoin mainnetlnbc...
lntbBitcoin testnetlntb...
lntbsBitcoin signetlntbs...
lnbcrtBitcoin regtestlnbcrt...

O valor é opcional. Quando existe, a unidade base é bitcoin, não satoshi. A letra final é um multiplicador decimal:

Multiplicadores de valor
Sufixo Multiplicador em BTC Exemplo
m0,001lnbc20m = 0,02000000 BTC
u0,000001lnbc2500u = 0,00250000 BTC
n0,000000001lnbc100n = 10 sats
p0,000000000001lnbc1000p = 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.

Campos BOLT 11 mais importantes
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:

Versões do campo f para Bitcoin
Version Significado Dado
17P2PKHhash160 da chave pública
18P2SHhash160 do script
0 a 16Witness (SegWit)witness program da versão indicada — 0 para P2WPKH/P2WSH, 1 para P2TR
19 a 31Reservadoo 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.

Assinatura compacta ECDSA com R, S e recovery id permitindo recuperar o node id que assinou a invoice.
Se a invoice não traz campo 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

Decodificador de Invoice BOLT 11

Cole uma invoice lnbc... publica, ficticia ou de teste para ver rede, valor, campos e no assinante. Nao cole dados privados.

Aceita o texto da invoice, opcionalmente com prefixo lightning:.

Resultado da invoice

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

Resumo

Mapa de dependências conceituais

Antes de ler esta página, ajuda conhecer:

Depois desta página, siga para:

Referências técnicas usadas

A seguir, voltamos ao nível do envelope de mensagens entre peers: o Protocolo Wire.