mirror of
https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line.git
synced 2025-06-18 21:36:28 +00:00
259 lines
13 KiB
Markdown
259 lines
13 KiB
Markdown
# 20.3: Fechando um Canal
|
|
|
|
> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão.
|
|
|
|
Neste capítulo, aprenderemos como fechar um canal usando a interface de linha de comando `lightning-cli close`. Fechar um canal significa que nós e a nossa contraparte enviarão o saldo do canal acordado para a blockchain, pelo qual devemos pagar as taxas de transação e esperar que a mesma seja posta em um bloco. Um fechamento pode ser cooperativo ou não, mas funciona de qualquer maneira.
|
|
|
|
Para fechar um canal, primeiro precisamos saber o ID do node remoto. Podemos recuperá-lo de duas maneiras.
|
|
|
|
## Encontrando Nossos Canais Pelos Saldos
|
|
|
|
Podemos usar o comando `lightning-cli listfunds` para ver nossos canais. Este comando RPC exibe todos os fundos disponíveis, em `outputs` não gastos (UTXOs) na carteira interna ou bloqueados em `channels` (canais) abertos.
|
|
```
|
|
c$ lightning-cli --testnet listfunds
|
|
{
|
|
"outputs": [
|
|
{
|
|
"txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d",
|
|
"output": 1,
|
|
"value": 99847,
|
|
"amount_msat": "99847000msat",
|
|
"scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c",
|
|
"address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8",
|
|
"status": "confirmed",
|
|
"blockheight": 1862856,
|
|
"reserved": false
|
|
}
|
|
],
|
|
"channels": [
|
|
{
|
|
"peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543",
|
|
"connected": true,
|
|
"state": "CHANNELD_NORMAL",
|
|
"short_channel_id": "1862856x29x0",
|
|
"channel_sat": 89987,
|
|
"our_amount_msat": "89987000msat",
|
|
"channel_total_sat": 100000,
|
|
"amount_msat": "100000000msat",
|
|
"funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d",
|
|
"funding_output": 0
|
|
}
|
|
]
|
|
}
|
|
|
|
"message_flags": 1,
|
|
"channel_flags": 2,
|
|
"active": true,
|
|
"last_update": 1595508075,
|
|
"base_fee_millisatoshi": 1000,
|
|
"fee_per_millionth": 1,
|
|
"delay": 40,
|
|
"htlc_minimum_msat": "1000msat",
|
|
"htlc_maximum_msat": "280000000msat",
|
|
"features": ""
|
|
}
|
|
```
|
|
|
|
Poderíamos também recuperar o ID do enésimo canal em uma variável como esta:
|
|
```
|
|
c$ nodeidremote=$(lightning-cli --testnet listfunds | jq '.channels[0] | .peer_id')
|
|
```
|
|
|
|
## Encontrando Canais Usando o JQ
|
|
|
|
A outra maneira de encontrar canais para serem fechados é usando o comando `listchannels`. Ele retorna dados dos canais que são conhecidos pelo node. Como os canais podem ser bidirecionais, até dois nodes serão retornados por cada canal (um para cada direção).
|
|
|
|
No entanto, assim como no mundo real, a fofoca (gossip) da Lightning Network é muito eficaz e, em pouco tempo, iremos conhecer milhares de canais. Isso é ótimo para enviar pagamentos via Lightning Network, mas é pouco útil para descobrir os nossos próprios canais. Fazer isso requer um pouco de trabalho com `jq`.
|
|
|
|
Primeiro, precisamos saber nosso próprio ID do node, que pode ser recuperado com o `getinfo`:
|
|
```
|
|
c$ nodeid=$(lightning-cli --testnet getinfo | jq .id)
|
|
c$ echo $nodeid
|
|
"03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687"
|
|
c$
|
|
```
|
|
Podemos então usar isso para procurar nos `listchannels` quaisquer canais onde nosso node seja a origem ou o destino:
|
|
```
|
|
c$ lightning-cli --testnet listchannels | jq '.channels[] | select(.source == '$nodeid' or .destination == '$nodeid')'
|
|
{
|
|
"source": "03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687",
|
|
"destination": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543",
|
|
"short_channel_id": "1862856x29x0",
|
|
"public": true,
|
|
"satoshis": 100000,
|
|
"amount_msat": "100000000msat",
|
|
"message_flags": 1,
|
|
"channel_flags": 0,
|
|
"active": true,
|
|
"last_update": 1602639570,
|
|
"base_fee_millisatoshi": 1,
|
|
"fee_per_millionth": 10,
|
|
"delay": 6,
|
|
"htlc_minimum_msat": "1msat",
|
|
"htlc_maximum_msat": "99000000msat",
|
|
"features": ""
|
|
}
|
|
```
|
|
Aqui está nosso node favorito `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543` novamente, como sendo o destino.
|
|
|
|
Depois de saber o que temos, podemos armazená-lo em uma variável:
|
|
```
|
|
c$ nodeidremote=$(lightning-cli --testnet listchannels | jq '.channels[] | select(.source == '$nodeid' or .destination == '$nodeid') | .destination')
|
|
```
|
|
|
|
## Fechando um Canal
|
|
|
|
Agora que temos um ID do node remoto, estamos prontos para usar o comando `lightning-cli close` para fechar um canal. Por padrão, ele tentará fechar o canal cooperativamente com o par; se quisermos fechá-lo unilateralmente, precisamos definir o argumento `unilateraltimeout` com o número de segundos de espera. Se definirmos como sendo 0 e o par estiver online, um fechamento mútuo ainda irá ser tentado. Para este exemplo, tentaremos um fechamento mútuo.
|
|
```
|
|
c$ lightning-cli --testnet close $nodeidremote 0
|
|
{
|
|
"tx": "02000000011d3cf2126ae36e12be3aee893b385ed6a2e19b1da7f4e579e3ef15ca234d69660000000000ffffffff021c27000000000000160014d39feb57a663803da116402d6cb0ac050bf051d9cc5e01000000000016001451c88b44420940c52a384bd8a03888e3676c150900000000",
|
|
"txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f",
|
|
"type": "mutual"
|
|
}
|
|
```
|
|
A transação de fechamento na blockchain é [f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f] (https://blockstream.info/testnet/tx/f68de52d80a1076e36c67795f9f9db4f13048519489593f].
|
|
|
|
É essa transação de fechamento que realmente gasta os fundos que foram negociados de um lado para outro por meio de transações Lightning. Isso pode ser visto examinando a transação:
|
|
```
|
|
$ bitcoin-cli --named getrawtransaction txid=f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f verbose=1
|
|
{
|
|
"txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f",
|
|
"hash": "3a6b3994932ae781bab80e159314bad06fc55d3d33453a1d663f9f9415c9719c",
|
|
"version": 2,
|
|
"size": 334,
|
|
"vsize": 169,
|
|
"weight": 673,
|
|
"locktime": 0,
|
|
"vin": [
|
|
{
|
|
"txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d",
|
|
"vout": 0,
|
|
"scriptSig": {
|
|
"asm": "",
|
|
"hex": ""
|
|
},
|
|
"txinwitness": [
|
|
"",
|
|
"304402207f8048e29192ec86019bc83be8b4cac5d1fc682374538bed0707f58192d41c390220512ebcde122d53747feedd70c09153a40c56d09a5fec02e47642afdbb20aa2ac01",
|
|
"3045022100d686a16084b60800fa0f6b14c25dca1c13d10a55c5fb7c6a3eb1c5f4a2fb20360220555f5b6e672cf9ef82941f7d46ee03dd52e0e848b9f094a41ff299deb8207cab01",
|
|
"522102f7589fd8366252cdbb37827dff65e3304abd5d17bbab57460eff71a9e32bc00b210343b980dff4f2723e0db99ac72d0841aad934b51cbe556ce3a1b257b34059a17052ae"
|
|
],
|
|
"sequence": 4294967295
|
|
}
|
|
],
|
|
"vout": [
|
|
{
|
|
"value": 0.00010012,
|
|
"n": 0,
|
|
"scriptPubKey": {
|
|
"asm": "0 d39feb57a663803da116402d6cb0ac050bf051d9",
|
|
"hex": "0014d39feb57a663803da116402d6cb0ac050bf051d9",
|
|
"reqSigs": 1,
|
|
"type": "witness_v0_keyhash",
|
|
"addresses": [
|
|
"tb1q6w07k4axvwqrmggkgqkkev9vq59lq5we5fcrzn"
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"value": 0.00089804,
|
|
"n": 1,
|
|
"scriptPubKey": {
|
|
"asm": "0 51c88b44420940c52a384bd8a03888e3676c1509",
|
|
"hex": "001451c88b44420940c52a384bd8a03888e3676c1509",
|
|
"reqSigs": 1,
|
|
"type": "witness_v0_keyhash",
|
|
"addresses": [
|
|
"tb1q28ygk3zzp9qv223cf0v2qwygudnkc9gfp30ud4"
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"hex": "020000000001011d3cf2126ae36e12be3aee893b385ed6a2e19b1da7f4e579e3ef15ca234d69660000000000ffffffff021c27000000000000160014d39feb57a663803da116402d6cb0ac050bf051d9cc5e01000000000016001451c88b44420940c52a384bd8a03888e3676c1509040047304402207f8048e29192ec86019bc83be8b4cac5d1fc682374538bed0707f58192d41c390220512ebcde122d53747feedd70c09153a40c56d09a5fec02e47642afdbb20aa2ac01483045022100d686a16084b60800fa0f6b14c25dca1c13d10a55c5fb7c6a3eb1c5f4a2fb20360220555f5b6e672cf9ef82941f7d46ee03dd52e0e848b9f094a41ff299deb8207cab0147522102f7589fd8366252cdbb37827dff65e3304abd5d17bbab57460eff71a9e32bc00b210343b980dff4f2723e0db99ac72d0841aad934b51cbe556ce3a1b257b34059a17052ae00000000",
|
|
"blockhash": "000000000000002a214b1ffc3a67c64deda838dd24d12154c15d3a6f1137e94d",
|
|
"confirmations": 1,
|
|
"time": 1602713519,
|
|
"blocktime": 1602713519
|
|
}
|
|
```
|
|
A entrada da transação é `66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d`, que foi a transação de financiamento feita na seção [§19.3](19_3_Setting_Up_a_Channel.md). A transação tem duas saídas, uma para o node remoto e outra para a carteira local da c-lightning. A saída no índice 0 corresponde ao node remoto com um valor de 0,00010012 BTC e, a saída no índice 1 corresponde ao node local com um valor de 0,00089804 BTC.
|
|
|
|
A Lightning mostrará da mesma forma 89.804 satoshis retornados como um novo UTXO em nossa carteira:
|
|
|
|
```
|
|
$ lightning-cli --network=testnet listfunds
|
|
{
|
|
"outputs": [
|
|
{
|
|
"txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d",
|
|
"output": 1,
|
|
"value": 99847,
|
|
"amount_msat": "99847000msat",
|
|
"scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c",
|
|
"address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8",
|
|
"status": "confirmed",
|
|
"blockheight": 1862856,
|
|
"reserved": false
|
|
},
|
|
{
|
|
"txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f",
|
|
"output": 1,
|
|
"value": 89804,
|
|
"amount_msat": "89804000msat",
|
|
"scriptpubkey": "001451c88b44420940c52a384bd8a03888e3676c1509",
|
|
"address": "tb1q28ygk3zzp9qv223cf0v2qwygudnkc9gfp30ud4",
|
|
"status": "confirmed",
|
|
"blockheight": 1863006,
|
|
"reserved": false
|
|
}
|
|
],
|
|
"channels": [
|
|
{
|
|
"peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543",
|
|
"connected": false,
|
|
"state": "ONCHAIN",
|
|
"short_channel_id": "1862856x29x0",
|
|
"channel_sat": 89987,
|
|
"our_amount_msat": "89987000msat",
|
|
"channel_total_sat": 100000,
|
|
"amount_msat": "100000000msat",
|
|
"funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d",
|
|
"funding_output": 0
|
|
}
|
|
]
|
|
}
|
|
|
|
```
|
|
|
|
### Compreendendo os Tipos de Canais de Fechamento.
|
|
|
|
O comando `close` do RPC tenta fechar um canal cooperativamente com nosso par ou unilateralmente após o argumento `unilateraltimeout` expirar. Isso traz alguma discussão adicional, pois vai ao cerne do design que não precisa de nenhuma confiança da Lightning:
|
|
|
|
Cada participante de um canal pode criar tantos pagamentos Lightning para a contraparte quanto os fundos permitirem. Na maioria das vezes não haverá desentendimentos entre os participantes, portanto, haverá apenas duas transações na rede, uma abrindo e outra fechando o canal. No entanto, pode haver cenários em que um par não está online ou não concorda com o estado final do canal ou quando alguém tenta roubar fundos da outra parte. É por isso que existem fechamentos cooperativos e forçados.
|
|
|
|
#### Fechamento Cooperativo
|
|
|
|
No caso de um fechamento cooperativo, ambos os participantes do canal concordam em fechar o canal e estabelecer o estado final na blockchain. Ambos os participantes devem estar online, pois o fechamento é realizado transmitindo um gasto incondicional da transação de financiamento com uma saída para cada par.
|
|
|
|
#### Fechamento Forçado
|
|
|
|
No caso de fechamento forçado, apenas um participante está online ou os participantes discordam sobre o estado final do canal. Nessa situação, um par pode realizar um fechamento unilateral do canal sem a cooperação do outro node. É executado transmitindo uma transação de confirmação que confirma o estado do canal anterior que ambas as partes concordaram. Esta transação de compromisso contém o estado do canal dividido em duas partes: o saldo de cada participante e todos os pagamentos pendentes (HTLCs).
|
|
|
|
Para realizar este tipo de fechamento, devemos especificar um argumento `unilateraltimeout`. Se este valor não for zero, o comando de fechamento fechará unilateralmente o canal quando esse número de segundos for atingido:
|
|
```
|
|
c$ lightning-cli --network=testnet close $newidremote 60
|
|
{
|
|
"tx": "0200000001a1091f727e6041cc93fead2ea46b8402133f53e6ab89ab106b49638c11f27cba00000000006a40aa8001df85010000000000160014d22818913daf3b4f86e0bcb302a5a812d1ef6b91c6772d20",
|
|
"txid": "02cc4c647eb3e06f37fcbde39871ebae4333b7581954ea86b27b85ced6a5c4f7",
|
|
"type": "unilateral"
|
|
}
|
|
|
|
```
|
|
## Resumo: Fechando um Canal
|
|
|
|
Ao fechar um canal, realizamos uma transação na blockchain encerrando nosso relacionamento financeiro com o node remoto. Para fechar um canal, devemos levar em consideração nosso status e o tipo de fechamento que desejamos executar.
|
|
|
|
## O Que Vem Depois?
|
|
|
|
Vamos continuar "Usando a Lightning" na seção [§20.4: Expandindo a Lightning Network](20_4_Lightning_Network_Review.md). |