Canais de Pagamento (a fundo)
Financiamento, transações de compromisso, revogação e fechamento
⚡ Lightning · Técnico
Na versão para iniciantes, um canal aparece como uma "comanda": duas pessoas abrem uma relação, atualizam saldos fora da blockchain e acertam a conta no final. Agora vamos olhar por baixo: um canal Lightning é um contrato ancorado em uma transação Bitcoin, atualizado por mensagens entre pares e protegido por transações de punição caso alguém tente publicar um estado antigo.
As fontes primárias desta página são a BOLT 2 (gerenciamento do canal entre pares), a BOLT 3 (transações e scripts) e a BOLT 5 (comportamento on-chain quando um canal fecha ou dá problema).
Conteúdo
O canal é um contrato ancorado no Bitcoin
Um canal Lightning tem uma parte on-chain e uma parte off-chain.
- On-chain: existe uma saída Bitcoin real, chamada funding output, que prende a capacidade do canal em um script controlado pelos dois participantes.
- Off-chain: os participantes trocam mensagens e assinaturas para atualizar quem tem direito a quanto desse valor, sem publicar cada atualização na blockchain.
Essa divisão é a essência da Lightning: a blockchain não registra cada pagamento, mas continua sendo o tribunal final. Se os dois cooperam, o canal fecha com uma transação simples. Se alguém some, o outro pode publicar uma transação de compromisso. Se alguém tenta usar um estado antigo, o mecanismo de revogação permite punição.
Por isso, esta página depende de alguns conceitos do Bitcoin: saídas, UTXOs, Script, witness, taxas, sequence e locktime.
Abrindo o canal
A abertura começa com uma negociação entre dois nós. Na versão clássica do protocolo, a BOLT 2 descreve uma sequência como esta:
| Mensagem | Função |
|---|---|
open_channel | O iniciador propõe abrir o canal e informa parâmetros como capacidade, limites, chaves-base e atraso de segurança. |
accept_channel | O outro nó aceita a proposta e informa seus próprios parâmetros. |
funding_created | O financiador informa a transação de funding e envia a assinatura para a commitment transaction da contraparte, antes de publicar a funding transaction. |
funding_signed | O outro nó devolve a assinatura que permite ao financiador publicar a funding transaction. |
channel_ready | Depois que a funding transaction atinge profundidade suficiente, os nós anunciam que o canal está pronto. |
Antes da funding transaction existir, os nós usam um temporary_channel_id. Depois, no modelo clássico, o channel_id é calculado a partir do outpoint de funding: conceitualmente, ele usa o funding_txid e aplica um XOR no índice da saída de funding. Já o channel point, usado com frequência em APIs e interfaces, é escrito como funding_txid:vout.
Não confunda: o channel point aponta para a saída on-chain que financia o canal. O channel_id é o identificador usado nas mensagens do protocolo. No canal v1, ele deriva do funding_txid e do índice da saída. Na abertura v2, a BOLT 2 define outro cálculo, baseado nos revocation basepoints dos participantes, para remover a dependência direta do txid da funding transaction.
Parâmetros negociados
A abertura do canal não negocia só "quanto dinheiro entra". Ela também define parâmetros que afetam segurança, custo e limites do canal:
| Parâmetro | Por que importa |
|---|---|
funding_satoshis | Capacidade do canal, isto é, o valor preso na funding output. |
dust_limit_satoshis | Limite abaixo do qual uma saída pode ser pequena demais para aparecer na commitment transaction. |
channel_reserve_satoshis | Reserva mínima que impede um lado de drenar completamente seu saldo e mantém margem econômica no canal. |
to_self_delay | Número de blocos que o publicador da commitment precisa esperar para gastar seu próprio to_local. |
max_accepted_htlcs | Quantidade máxima de HTLCs simultâneos que um lado aceita. |
feerate_per_kw | Taxa usada para estimar o custo das commitment transactions no modelo negociado. |
Esses valores não são detalhes decorativos. Eles determinam quais saídas aparecem, quanto custa fechar o canal, quanto tempo existe para reagir a uma tentativa de trapaça e qual é o espaço disponível para pagamentos em voo.
A funding transaction
Abrir o canal significa criar uma funding transaction na blockchain. Essa transação cria uma funding output: uma saída que prende os bitcoins do canal.
No modelo clássico, essa saída é uma P2WSH com um script multisig 2-de-2:
OP_2 <pubkey_alice> <pubkey_bob> OP_2 OP_CHECKMULTISIG Isso quer dizer: para gastar essa saída, são necessárias as assinaturas dos dois lados. Nenhum dos dois consegue simplesmente pegar o dinheiro sozinho a partir da funding output. O que cada um consegue fazer é publicar uma commitment transaction já assinada, que gasta essa funding output conforme o estado mais recente conhecido.
No canal single-funded, um lado financia o canal. No dual funding, os dois lados podem contribuir entradas para a funding transaction. O importante é que, depois de confirmada, a funding output vira o ponto on-chain que ancora o canal.
A funding transaction é uma transação Bitcoin normal. Ela tem entradas, saídas, txid, vout e paga taxa. O que a torna especial é a saída 2-de-2 que será gasta pelas commitment transactions.
Confirmações e canal pronto
A funding transaction precisa ser transmitida e confirmada. Só depois de uma profundidade suficiente os nós consideram o canal utilizável e trocam channel_ready. Antes disso, o canal ainda está em abertura: ele existe como negociação e como transação pendente, mas não deve ser tratado como canal ativo para encaminhar pagamentos.
Essa espera protege contra reorganizações e contra a possibilidade de a funding transaction nunca entrar de fato na cadeia ativa.
A commitment transaction
A funding output prende o dinheiro. A commitment transaction diz como esse dinheiro seria dividido se o canal fosse fechado naquele estado.
O detalhe mais importante é que cada lado mantém uma commitment transaction própria. Elas gastam a mesma funding output e representam o mesmo estado econômico, mas não são idênticas. Elas são assimétricas.
Duas versões assimétricas
Imagine um canal fictício de 1.000.000 sats. A Alice financiou o canal. Depois de um pagamento, o estado atual ficou assim:
| Participante | Saldo | Observação |
|---|---|---|
| Alice | 850.000 sats | Saldo local da Alice após pagar 150.000 sats. |
| Bob | 150.000 sats | Saldo remoto visto pela Alice. |
A commitment transaction da Alice, se publicada por ela, costuma ter:
to_local: paga a Alice, mas com atraso e com caminho de revogação.to_remote: paga o Bob de forma direta, normalmente sem atraso.- HTLC outputs: saídas condicionais para pagamentos em voo, quando existirem.
Na commitment transaction do Bob, os papéis se invertem. O to_local dele é que fica atrasado e revogável. A regra prática é: quem publica a sua própria commitment precisa esperar para gastar o próprio saldo. Essa espera dá tempo para a contraparte reagir se o estado publicado for antigo.
Outputs principais
| Saída | Função |
|---|---|
to_local | Saldo de quem publica aquela versão da commitment; fica atrasado por to_self_delay e pode ser gasto pela contraparte via revogação se o estado for antigo. |
to_remote | Saldo da contraparte; normalmente é um pagamento direto para ela. |
| HTLC oferecido | Pagamento em voo oferecido pela perspectiva de quem publica esta commitment; pode ser resolvido por timeout ou pelo recebedor com a preimage. |
| HTLC recebido | Pagamento em voo recebido pela perspectiva de quem publica esta commitment; pode ser resolvido com a preimage ou expirar. |
| anchor | Saída opcional pequena usada para facilitar aumento de taxa via CPFP em modelos com anchors. |
Os HTLCs entram aqui apenas como ponte. Eles são os pagamentos em trânsito dentro de um estado de canal. A página seguinte, Operação de Canais e Encaminhamento, abre os scripts e o fluxo dos HTLCs com mais detalhe.
Dust, fees e anchors
Uma commitment transaction não precisa conter uma saída para cada valor conceitual do canal. Se uma saída seria pequena demais em relação ao dust_limit_satoshis, ela pode ser trimmed: essa saída não aparece na transação publicada e seu valor entra na diferença entre input e outputs, afetando taxas e resultado econômico conforme as regras da BOLT 3.
Taxas também importam. No modelo clássico de canal v1, o iniciador/financiador assume o custo da commitment transaction. Em modelos com anchor outputs, a transação pode incluir saídas pequenas que permitem aumentar a taxa depois por child-pays-for-parent. Isso é importante porque um fechamento unilateral pode precisar ser confirmado em um ambiente de taxas bem diferente daquele em que o canal foi aberto.
Não trate valores de dust, taxas ou delays como constantes universais. Eles dependem dos parâmetros negociados, das opções do canal e do estado da rede Bitcoin.
Brinque com um estado fictício de canal e veja como as saídas mudam em cada versão da commitment transaction:
Transação de Compromisso
Esta ferramenta é didática. Ela usa saldos fictícios, não deve receber backup real de canal ou dados reais de carteira, e não representa todos os detalhes de BOLT 3, como ordenação de outputs, anchors reais, dust trimming e scripts completos.
Atualizando o estado
Um canal só é útil porque o estado pode mudar muitas vezes sem publicar transações. Cada mudança cria um novo par de commitment transactions e torna o estado anterior perigoso de publicar.
Um exemplo simples:
- Estado 0: Alice tem 1.000.000 sats e Bob tem 0 sats.
- Pagamento: Alice paga 150.000 sats para Bob dentro do canal.
- Estado 1: Alice passa a ter 850.000 sats e Bob passa a ter 150.000 sats.
- Revogação: os dois trocam dados que tornam o estado 0 punível se alguém tentar publicá-lo.
No protocolo, essa troca envolve mensagens como commitment_signed e revoke_and_ack. A primeira assina uma nova commitment transaction da contraparte. A segunda reconhece a transição e entrega o segredo que revoga o estado anterior.
| Passo | O que acontece |
|---|---|
commitment_signed | Um lado envia assinaturas para que o outro tenha uma nova commitment transaction válida. |
revoke_and_ack | O lado que recebeu a nova assinatura revoga seu estado anterior e confirma a atualização. |
update_fee | Quando aplicável, atualiza a feerate usada nas commitments. |
Na prática, isso é uma máquina de estados. Atualizações podem ser acumuladas antes de uma assinatura, cada lado mantém sua própria commitment transaction, e o estado só fica totalmente sincronizado quando as trocas de assinatura e revogação necessárias foram concluídas pelos dois lados.
A nuance importante é que uma transação assinada não desaparece. O protocolo não apaga magicamente o estado 0. O que ele faz é revelar informações suficientes para que publicar o estado 0 se torne uma péssima ideia.
Revogação e penalidade
A segurança dos canais Lightning depende de um truque econômico: estados antigos continuam sendo transações Bitcoin possíveis, mas viram armadilhas para quem tentar usá-los.
A saída to_local de uma commitment transaction tem dois caminhos principais:
- Caminho normal: o dono da saída gasta depois de esperar o
to_self_delay. - Caminho de revogação: a contraparte gasta imediatamente se tiver a chave de revogação daquele estado.
A cada novo estado, o estado anterior recebe um segredo revelado: o per_commitment_secret. Com ele, a contraparte consegue derivar a chave de revogação daquele estado antigo. É por isso que publicar uma commitment antiga é arriscado: a outra parte pode varrer o to_local antes que o atraso termine.
Em linguagem simples, dizemos que "quem trapaceia perde tudo". Como intuição, isso é útil. Tecnicamente, a BOLT 5 tem nuances: HTLCs podem exigir transações específicas, saídas pequenas podem ter sido removidas por dust, e há janelas de confirmação e reação. Mas a ideia central é essa: a punição torna economicamente perigoso publicar um estado revogado.
Como as chaves de revogação são derivadas
A frase "a contraparte deriva a chave de revogação" esconde um dos mecanismos mais elegantes da BOLT 3. Vale abrir, porque é ele que faz a punição funcionar sem exigir novas chaves a cada pagamento.
Na abertura, cada lado fixa um conjunto de basepoints — chaves públicas que valem para toda a vida do canal:
| Basepoint | Do que deriva a chave por estado |
|---|---|
payment_basepoint | Chave do saldo direto (to_remote na visão do outro lado). |
delayed_payment_basepoint | Chave do to_local, o saldo próprio atrasado por to_self_delay. |
htlc_basepoint | Chaves usadas nos scripts dos HTLCs. |
revocation_basepoint | Metade da chave de revogação; a outra metade vem do outro lado. |
Para cada novo estado do canal, existe um per_commitment_point (com seu segredo correspondente, o per_commitment_secret, tal que per_commitment_point = per_commitment_secret · G). A maioria das chaves de um estado é o basepoint "temperado" por esse ponto:
pubkey = basepoint + SHA256(per_commitment_point || basepoint) · G
privkey = basepoint_secret + SHA256(per_commitment_point || basepoint) Isso dá duas propriedades úteis: cada estado usa chaves diferentes (dificulta ligar saídas on-chain de estados distintos ao mesmo canal) e, conhecendo apenas o per_commitment_point do outro lado, cada nó consegue calcular as chaves públicas daquele estado.
A chave de revogação é a exceção: ela mistura o revocation_basepoint de um lado com o per_commitment_point do outro.
revocationpubkey = revocation_basepoint · SHA256(revocation_basepoint || per_commitment_point)
+ per_commitment_point · SHA256(per_commitment_point || revocation_basepoint)
A chave privada correspondente exige os dois segredos ao mesmo tempo: o revocation_basepoint_secret (de quem vai punir) e o per_commitment_secret daquele estado (de quem publicou). Enquanto um estado é o atual, cada lado só revela o per_commitment_point, nunca o segredo — então ninguém consegue montar a chave privada de revogação. Quando o estado é substituído, o dono revela o per_commitment_secret dele; só a partir daí a contraparte, que já tinha o seu revocation_basepoint_secret, consegue a revocationprivkey e varrer o to_local daquele estado revogado.
É essa construção de duas partes que permite delegar a um watchtower sem entregar o controle do canal: você repassa os segredos por estado à medida que revoga, e o watchtower só consegue derivar chaves de estados que já foram revogados — nunca do estado atual.
Guardar milhões de segredos: a shachain
Um canal movimentado pode passar por um número enorme de estados, e a contraparte precisa guardar o per_commitment_secret de cada estado revogado para poder punir. Guardar um segredo por estado não escala. A BOLT 3 resolve isso de forma determinística:
- Cada lado escolhe uma seed de 256 bits imprevisível por canal.
- Os segredos são gerados a partir dela por uma função em árvore (
generate_from_seed), começando no índice2⁴⁸−1e contando para baixo a cada novo estado. - Por causa dessa ordem, o receptor consegue armazenar todos os segredos já recebidos em uma estrutura compacta de 49 entradas (a "shachain"), derivando os intermediários sob demanda em vez de guardar um por estado.
Ou seja: revogar um estado antigo é literalmente entregar o per_commitment_secret daquele índice, e a contraparte encaixa esse segredo na shachain sem explodir o armazenamento.
Por que você precisa observar a blockchain
O to_self_delay só ajuda se a contraparte perceber a publicação do estado antigo a tempo. Por isso, um nó Lightning precisa observar a blockchain. Watchtowers podem monitorar e reagir quando o usuário está offline; backups ajudam recuperação operacional, mas não substituem a vigilância necessária contra estados revogados.
Esse é um dos motivos pelos quais a Lightning é mais exigente operacionalmente do que apenas guardar uma chave on-chain. A segurança do canal não é só criptográfica; ela também depende de reação dentro de uma janela de tempo.
Fechando o canal
Um canal termina quando o valor preso na funding output volta a ser distribuído em saídas Bitcoin comuns. A BOLT 2 trata a negociação entre pares; a BOLT 5 trata o que fazer quando algo aparece on-chain.
Fechamento cooperativo
No fechamento cooperativo, os dois lados concordam em encerrar o canal. Eles usam mensagens de fechamento, como shutdown e mensagens de negociação de assinatura e taxa conforme a variante da BOLT 2, para montar uma closing transaction. Essa closing transaction não é simplesmente "a commitment atual": ela é uma transação de fechamento assinada pelos dois, pagando os saldos finais para os scripts informados na negociação.
É o caminho feliz: menos conflito, menos espera e geralmente menos custo. Ainda assim, a taxa precisa ser negociada e a transação precisa ser minerada.
Fechamento unilateral
Se o outro nó sumiu, recusou cooperar ou a conexão falhou, um lado pode publicar sua própria commitment transaction mais recente. Isso é o fechamento unilateral, também chamado de force close.
Funciona porque a commitment transaction já estava assinada. Mas há custos:
- quem publica precisa esperar o
to_self_delaypara gastar o próprioto_local; - HTLCs em aberto podem exigir transações adicionais, como HTLC-timeout ou HTLC-success;
- a taxa pode precisar de bump por CPFP quando o canal usa anchors;
- o fechamento fica visível na blockchain.
Fechamento com estado revogado
Se alguém publica uma commitment antiga, isso é um breach: uma quebra do contrato off-chain. A contraparte usa os dados de revogação já recebidos para gastar outputs do estado antigo antes que o publicador consiga resgatá-los normalmente.
Esse mecanismo é agressivo de propósito. Sem punição, um participante teria incentivo para publicar um estado antigo que o favorecesse. Com punição, o ganho esperado vira risco de perda.
Evoluções do protocolo
O modelo acima descreve a base dos canais modernos, mas a Lightning evolui. Algumas extensões mudam detalhes importantes sem mudar a ideia central.
Anchor outputs
Anchor outputs são saídas pequenas adicionadas às commitment transactions para permitir fee bumping depois da publicação. Elas ajudam em cenários de fechamento unilateral, quando a feerate combinada antes pode não ser suficiente para confirmar a transação rapidamente.
Elas não tornam taxas irrelevantes. Elas dão uma ferramenta para reagir melhor quando a mempool muda.
Dual funding, splicing e Taproot
O protocolo também vem incorporando formas mais flexíveis de construir canais:
- Dual funding: os dois lados podem contribuir entradas para a funding transaction.
- Splicing: permite alterar a capacidade do canal com uma transação on-chain sem necessariamente encerrar toda a relação de canal.
- Canais Taproot: são uma evolução em adoção/proposta que usa Taproot e assinaturas agregadas para melhorar privacidade e eficiência on-chain fora do modelo base tratado nesta página.
Esses recursos devem ser tratados como evolução e adoção progressiva, não como pressuposto universal. Implementações e carteiras podem suportar subconjuntos diferentes.
Resumo operacional
- Um canal Lightning começa com uma funding transaction on-chain.
- A funding output prende a capacidade do canal em um controle cooperativo 2-de-2 no modelo clássico.
- O saldo atual é representado por commitment transactions assinadas, mas normalmente não publicadas.
- Cada lado tem sua própria commitment transaction, com
to_localatrasado e revogável. - Atualizar o canal significa assinar um novo estado e revogar o anterior.
- Publicar estado antigo é punível porque a contraparte recebeu dados de revogação.
- O fechamento cooperativo é o caminho mais limpo; o fechamento unilateral é o caminho de segurança; o breach é o caminho de punição.
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 2 — Peer Protocol for Channel Management
- BOLT 3 — Bitcoin Transaction and Script Formats
- BOLT 5 — Recommendations for On-chain Transaction Handling
A seguir: como o dinheiro realmente se move por um canal e através de vários canais — os HTLCs e o encaminhamento de pagamentos.