From e537667287abf1d1618df1a8a0ccf13b79e77626 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Mon, 9 Aug 2021 11:30:39 -0300 Subject: [PATCH 1/9] Chapter19 translation concluded --- 19_0_Using_Lightning.md | 27 +++ pt/19_0_Using_Lightning.md | 25 +++ pt/19_1_Generate_a_Payment_Request.md | 184 ++++++++++++++++++ pt/19_2_Paying_a_Invoice.md | 206 ++++++++++++++++++++ pt/19_3_Closing_a_Channel.md | 259 ++++++++++++++++++++++++++ pt/19_4_Lightning_Network_Review.md | 60 ++++++ 6 files changed, 761 insertions(+) create mode 100644 pt/19_0_Using_Lightning.md create mode 100644 pt/19_1_Generate_a_Payment_Request.md create mode 100644 pt/19_2_Paying_a_Invoice.md create mode 100644 pt/19_3_Closing_a_Channel.md create mode 100644 pt/19_4_Lightning_Network_Review.md diff --git a/19_0_Using_Lightning.md b/19_0_Using_Lightning.md index 04ef4c3..008cb7c 100644 --- a/19_0_Using_Lightning.md +++ b/19_0_Using_Lightning.md @@ -23,3 +23,30 @@ Supporting objectives include the ability to: * [Section Two: Paying an Invoice](19_2_Paying_a_Invoice.md) * [Section Three: Closing a Lightning Channel](19_3_Closing_a_Channel.md) * [Section Four: Expanding the Lightning Network](19_4_Lightning_Network_Review.md) + + +# Capítulo dezenove: usando um raio + +>: Informação_Source: ** Nota: ** Este é um rascunho em andamento, para que eu possa obter algum feedback dos iniciantes. Ainda não está pronto para aprender. + +Neste capítulo, você continuará trabalhando com a interface de linha de comando "Lightning-Cli` Você criará faturas, executará pagamentos e canais fechados - todas as principais atividades para usar o Lightning. + +## Objetivos para este capítulo + +Depois de trabalhar através deste capítulo, um desenvolvedor será capaz de: + + * Execute pagamentos na rede relâmpago. + * Aplique o fechamento para um canal de relâmpago. + +Objetivos de apoio incluem a capacidade de: + + * Compreender o formato das faturas. + * Entenda o ciclo de vida dos pagamentos de rede de raios. + * Saber como expandir a rede relâmpago. + +## Índice + +* [Seção One: Gerando uma solicitação de pagamento] (19_1_Generate_A_Payment_Request.md) +* [Seção dois: pagando uma fatura] (19_2_Paying_a_invoice.md) +* [Seção três: fechando um canal de raio] (19_3_closing_a_channel.md) +* [Seção Quatro: Expandindo a rede Lightning] (19_4_lightning_network_review.md) \ No newline at end of file diff --git a/pt/19_0_Using_Lightning.md b/pt/19_0_Using_Lightning.md new file mode 100644 index 0000000..d783afe --- /dev/null +++ b/pt/19_0_Using_Lightning.md @@ -0,0 +1,25 @@ +# Capítulo 19: Usando a Lightning + +> :information_source: **NOTA:** Este é um rascunho que está em andamento, para que possa obter alguns comentários dos revisores iniciais. Ainda não está pronto. + +Neste capítulo, continuaremos trabalhando com a interface de linha de comando `lightning-cli`. Criaremos invoices, realizaremos pagamentos e fecharemos canais, todas as principais atividades para se usar a Lightning. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Efetuar pagamentos na Lightning Network; + * Aplicar o fechamento a um canal Lightning. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Compreender o formato dos invoices; + * Entender o ciclo de vida dos pagamentos da Lightning Network; + * Saber como expandir a Lightning Network. + +## Tabela de Conteúdo + +* [Seção 1: Gerando um Invoice](19_1_Generate_a_Payment_Request.md) +* [Seção 2: Pagando um Invoice](19_2_Paying_a_Invoice.md) +* [Seção 3: Fechando um canal na Lightning](19_3_Closing_a_Channel.md) +* [Seção 4: Expandindo a Lightning Network](19_4_Lightning_Network_Review.md) diff --git a/pt/19_1_Generate_a_Payment_Request.md b/pt/19_1_Generate_a_Payment_Request.md new file mode 100644 index 0000000..e56860c --- /dev/null +++ b/pt/19_1_Generate_a_Payment_Request.md @@ -0,0 +1,184 @@ +# 19.1: Gerando um Invoice + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esta seção descreve como os pagamentos funcionam na Lightning Network, como criar uma solicitação de pagamento (ou _invoice_) e, finalmente, como entendê-la. A emissão de invoices depende de termos um segundo node Lightning, conforme descrito na seção [Acessando um segundo node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md). Esses exemplos usarão um node LND como nosso node secundário, para demonstrar ainda mais as possibilidades da Lightning Network. Para diferenciar entre os nodes nestes exemplos, os prompts serão mostrados como `c $` para o node c-lightning e `lnd $` para o node LND. Se quisermos reproduzir essas etapas, devemos [instalar nosso próprio node LND secundário](18_2__Interlude_Accessing_a_Second_Lightning_Node.md#Creating-a-new-lnd-node). + +> :book: ***O que é um invoice?*** Quase todos os pagamentos feitos na Lightning Network exigem um invoice, que nada mais é do que um **pedido de pagamento** feito pelo destinatário do dinheiro e enviado por qualquer meio para o usuário que irá pagar. Todos os invoices são de uso único. Os invoices da Lightning usam a codificação bech32, que já é usada pela Segregated Witness para Bitcoin. + +## Criando um invoice + +Para criar um novo invoice na c-lightning, usaríamos o comando `lightning-cli --testnet invoice`. + +Vamos ver como funcionaria com o c-lightning, usando argumentos de um valor (em milisats), um rótulo e uma descrição. +``` +c$ lightning-cli --testnet invoice 100000 joe-payment "The money you owe me for dinner" +{ + "payment_hash": "07a1c4bd7a38b4dea35f301c173cd8f9aac253b66bd8404d7ad829f226342490", + "expires_at": 1603305795, + "bolt11": "lntb1u1p0cw3krpp5q7suf0t68z6dag6lxqwpw0xclx4vy5akd0vyqnt6mq5lyf35yjgqdpj235x2grddahx27fq09hh2gr0wajjqmt9ypnx7u3qv35kumn9wgxqyjw5qcqp2sp5r3puay46tffdyzldjv39fw6tzdgu2hnlszamqhnmgjsuxqxavpgs9qy9qsqatawvx44x5qa22m7td84jau5450v7j6sl5224tlv9k5v7wdygq9qr4drz795lfnl52gklvyvnha5e5lx72lzzmgzcfnp942va5thmhsp5sx7c2", + "warning_capacity": "No channels", + "warning_mpp_capacity": "The total incoming capacity is still insufficient even if the payer had MPP capability." +} +``` +No entanto, para este exemplo, vamos gerar um invoice em um node LND e, em seguida, pagá-la no node c-lightning. Isso requer o comando `addinvoice` ligeiramente diferente na LND. Podemos usar o argumento `--amt` para indicar a quantia a ser paga (em milisats) e adicionar uma descrição usando o argumento `--memo`. + +``` +lnd$ lncli -n testnet addinvoice --amt 10000 --memo "First LN Payment - Learning Bitcoin and Lightning from the Command line." +{ + "r_hash": "6cacdedc95b89eec15e5244bd0957b88c0ab58b153eee549735b995344bc16bb", + "payment_request": "lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd", + "add_index": "1" +} +``` +Observe que esses invoices não fazem referência direta ao canal que criamos: isso é necessário para o pagamento, mas não para solicitar o pagamento. + +## Compreendendo um invoice + +O `bolt11 payment_request` que criamos é composto de duas partes: uma é legível por humanos e a outra são apenas dados. + +> :book: **O que é um BOLT?** Os BOLTs são as [especificações individuais da Lightning Network](https://github.com/lightningnetwork/lightning-rfc). + +### Lendo a parte legível do invoice + +A parte legível dos invoices começa com um `ln`. É `lnbc` para Bitcoin mainnet, `lntb` para Bitcoin testnet ou `lnbcrt` para Bitcoin regtest. +Em seguida, listamos os fundos solicitados no invoice. + +Por exemplo, vamos olhar para a nossa fatura do node LND: +``` +lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd +``` +A parte legível por humanos é `ln` +`tb` + `100u`. + +O `lntb` diz que esta é um invoice da Lightning Network para bitcoins Testnet. + +O `100u` diz que é para 100 bitcoins vezes o multiplicador microsatoshi. Existem quatro multiplicadores de fundos (opcionais): + +* `m` (mili): multiplique por 0,001 +* `u` (micro): multiplique por 0,000001 +* `n` (nano): multiplique por 0,000000001 +* `p` (pico): multiplique por 0,000000000001 + +100 BTC * 0,000001 = 0,0001 BTC, que é o mesmo que 10.000 satoshis. + +### Lendo a parte do invoice referente aos dados + +O resto do invoice ( `1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd`) contém um marcador de tempo, dados especificamente marcados, e uma assinatura. Obviamente, não pode ler sem decodificá-lo, mas podemos pedir ao `lightning-cli` para fazer isso com o comando `decodepay`: +``` +c$ lightning-cli --testnet decodepay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd +{ + "currency": "tb", + "created_at": 1602702347, + "expiry": 3600, + "payee": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "msatoshi": 10000000, + "amount_msat": "10000000msat", + "description": "First LN Payment - Learning Bitcoin and Lightning from the Command line.", + "min_final_cltv_expiry": 40, + "payment_secret": "e946403bcb54764994306c743ed3bf1303af8ae6e7687d3cabcc3ee06dbf904d", + "features": "028200", + "payment_hash": "6cacdedc95b89eec15e5244bd0957b88c0ab58b153eee549735b995344bc16bb", + "signature": "304402202e73ebd1ef974594eb117e8301be781f2ba289041ab6abc558d432351d8365e902202a8151c3fd13419b9390c2b976503d2d064f2a6748b14cb0db64424cf4e572f4" +} + +``` +Aqui temos o que os elementos mais relevantes significam: + +1. `currency`: A moeda a ser paga; +2. `created_at`: Momento em que a fatura foi criada. O valor é dado em tempo UNIX, que é segundos desde 1970. +3. `expiry`: O momento em que nosso node marca a fatura como inválida. O padrão é 1 hora ou 3600 segundos. +4. `payee`: A chave pública da pessoa (node) que recebe o pagamento da Lightning Network; +5. `msatoshi` e `amount_msat`: O valor de satoshis a ser pago; +6. `description`: A descrição informada pelo usuário; +7. `payment_hash`: O hash da pré-imagem que é usado para bloquear o pagamento. Só podemos resgatar um pagamento bloqueado com a pré-imagem correspondente ao hash de pagamento. Isso permite o roteamento na Lightning Network sem confiar em terceiros, criando um **Pagamento Condicional** a ser preenchido; +8. `signature`: A assinatura codificada por DER. + +> :book: ***O que são pagamentos condicionais?*** Embora os canais Lightning sejam criados entre dois participantes, vários canais podem ser conectados juntos, formando uma rede de pagamento que permite envio de valores entre todos os participantes da rede, mesmo aqueles sem um canal direto entre eles. Isso é feito usando um contrato inteligente denominado **Hashed Time Locked Contract**. + +> :book: ***O que é um Hashed Time Locked Contract (HTLC)?*** Um HTLC é um pagamento condicional que usa hashlocks e timelocks para garantir a segurança do pagamento. O destinatário deve apresentar uma pré-imagem do pagamento ou gerar um comprovante criptográfico de pagamento antes de um determinado prazo, caso contrário o pagador pode cancelar o contrato gastando-o. Esses contratos são criados como saídas da **Transação de compromisso**. + +> :book: ***O que é uma transação de compromisso?*** Uma transação de compromisso é uma transação que gasta a transação de financiamento original. Cada par possui a assinatura do outro par, o que significa que qualquer um pode gastar sua transação do compromisso como quiser. Depois que cada nova transação de confirmação é criada, a antiga é revogada. A transação de confirmação é uma maneira pela qual a transação de financiamento pode ser desbloqueada na blockchain, conforme discutiremos na seção [§19.3](19_3_Closing_a_Channel.md). + +### Verificando nosso invoice + +Existem dois elementos cruciais para verificar o invoice. O primeiro, obviamente, é o valor do pagamento, que já examinamos na parte legível. O segundo é o dado do `payee`, que é o pubkey do destinatário (node): +``` + "payee": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", +``` +Precisamos verificar se ele é o destinatário esperado. + +Olhando nas seções anteriores, mais precisamente na seção [§18.3](18_3_Setting_Up_a_Channel.md#opening-a-channel), podemos observar que é de fato o ID do par que usamos quando criamos nosso canal. Também podemos verificá-lo no outro node com o comando `getinfo`. +``` +lnd$ lncli -n testnet getinfo +{ + "version": "0.11.0-beta.rc4 commit=v0.11.0-beta.rc4", + "commit_hash": "fc12656a1a62e5d69430bba6e4feb8cfbaf21542", + "identity_pubkey": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "alias": "StandUp", + "color": "#3399ff", + "num_pending_channels": 0, + "num_active_channels": 1, + "num_inactive_channels": 0, + "num_peers": 3, + "block_height": 1862983, + "block_hash": "00000000000000c8c2f58f6da2ae2a3884d6e84f55d0e1f585a366f9dfcaa860", + "best_header_timestamp": "1602702331", + "synced_to_chain": true, + "synced_to_graph": true, + "testnet": true, + "chains": [ + { + "chain": "bitcoin", + "network": "testnet" + } + ], + "uris": [ + ], + "features": { + "0": { + "name": "data-loss-protect", + "is_required": true, + "is_known": true + }, + "5": { + "name": "upfront-shutdown-script", + "is_required": false, + "is_known": true + }, + "7": { + "name": "gossip-queries", + "is_required": false, + "is_known": true + }, + "9": { + "name": "tlv-onion", + "is_required": false, + "is_known": true + }, + "13": { + "name": "static-remote-key", + "is_required": false, + "is_known": true + }, + "15": { + "name": "payment-addr", + "is_required": false, + "is_known": true + }, + "17": { + "name": "multi-path-payments", + "is_required": false, + "is_known": true + } + } +} +``` +No entanto, o `payee` também pode ser alguém novo, caso em que provavelmente precisaremos verificar com a pessoa que emitiu o invoice para garantir que está tudo correto. + +## Resumo: Gerando um Invoice + +Na maioria dos casos, precisamos receber um invoice para usar os pagamentos da Lightning Network. Neste exemplo, criamos um manualmente, mas se estivermos em um ambiente de produção, provavelmente teria sistemas fazendo isso automaticamente sempre que alguém adquirir produtos ou serviços. Claro, depois de receber um invoice, precisamos saber como lê-lo! + +## O Que Vem Depois? + +Vamos continuar "Usando a Lightning" na seção [§19.2: Pagando um Invoice](06_3_Sending_an_Automated_Multisig.md). \ No newline at end of file diff --git a/pt/19_2_Paying_a_Invoice.md b/pt/19_2_Paying_a_Invoice.md new file mode 100644 index 0000000..d464dfa --- /dev/null +++ b/pt/19_2_Paying_a_Invoice.md @@ -0,0 +1,206 @@ +# 19.2: Pagando um Invoice + +> :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 pagar um invoice usando o comando `lightning-cli pay`. Presume-se que já sabemos como analisar um invoice, de acordo com a seção [§19.1](19_1_Generate_a_Payment_Request.md) e sabemos que ele é válido. + +## Verificando o saldo + +Obviamente, a primeira coisa que precisamos fazer é nos certificarmos de que possuímos fundos suficientes para pagar o invoice. Neste caso, o canal configurado anteriormente com `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543` contém 100.000 satoshis. Este será o canal de pagamento do inoice. + +``` +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": 100000, + "our_amount_msat": "100000000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} +``` +Se não tivermos fundos suficientes, precisamos criar um novo canal. + +## Pagando nosso invoice + +Vamos usar o comando `lightning-cli pay` para pagar o invoice. Ele tentará encontrar uma rota para o destino fornecido, para posteriormente enviar os fundos solicitados. Isso é muito simples porque há um canal direto entre o pagador e o destinatário: +``` +c$ lightning-cli --testnet pay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd +{ + "destination": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "payment_hash": "6cacdedc95b89eec15e5244bd0957b88c0ab58b153eee549735b995344bc16bb", + "created_at": 1602704828.948, + "parts": 1, + "msatoshi": 10000000, + "amount_msat": "10000000msat", + "msatoshi_sent": 10000000, + "amount_sent_msat": "10000000msat", + "payment_preimage": "1af4a9bb830e49b6bc8f0bef980630e189e3794ad1705f06ad1b9c71571dce0c", + "status": "complete" +} +``` +Vamos observar todos os valores que estão em `msats`, não em `sats`! + +### Pagando o invoice pela Lightning + +No entanto, _não_ precisamos ter um canal com um node para pagá-lo. Só precisamos ter uma rota razoável pela Lightning Network. + +Imagine que recebemos esta minúscula solicitação de pagamento de 11.111 msat: +``` +c$ lightning-cli --testnet decodepay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7h058g9u4mthcaf9rl2f7g8zxsdp2t9hh2gr0wajjqmt9ypnx7u3qv35kumn9wgs8gmm0yyxqyjw5qcqp2sp5kj4xhrthmfgcgyl84zaqpl9vvdjwm5x368kr09fu5nym74setw4s9qy9qsq8hxjr73ee77vat0ay603e4w9aa8ag9sa2n55xznk5lsfrjffxxdj2k0wznvcfa98l4a57s80j7dhg0cc03vwqdwehkujlzxgm0xyynqqslwhvl +{ + "currency": "tb", + "created_at": 1602704929, + "expiry": 604800, + "payee": "02f3d74746934494fa378235e5bc44cfdbb5b8779d839263fb7f9218be032f6f61", + "msatoshi": 11111, + "amount_msat": "11111msat", + "description": "You owe me for dinner too!", + "min_final_cltv_expiry": 10, + "payment_secret": "b4aa6b8d77da518413e7a8ba00fcac6364edd0d1d1ec37953ca4c9bf56195bab", + "features": "028200", + "payment_hash": "e3e689117f7688ece226f1eb2eff35337d77d0e82f2bb5df1d4947f527c8388d", + "signature": "304402203dcd21fa39cfbcceadfd269f1cd5c5ef4fd4161d54e9430a76a7e091c929319b02202559ee14d984f4a7fd7b4f40ef979b743f187c58e035d9bdb92f88c8dbcc424c" +} +``` +Se tentássemos pagar e não tivéssemos uma rota para o destinatário por meio da Lightning Network, poderíamos esperar um erro como este: +``` +c$ lightning-cli --testnet pay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7h058g9u4mthcaf9rl2f7g8zxsdp2t9hh2gr0wajjqmt9ypnx7u3qv35kumn9wgs8gmm0yyxqyjw5qcqp2sp5kj4xhrthmfgcgyl84zaqpl9vvdjwm5x368kr09fu5nym74setw4s9qy9qsq8hxjr73ee77vat0ay603e4w9aa8ag9sa2n55xznk5lsfrjffxxdj2k0wznvcfa98l4a57s80j7dhg0cc03vwqdwehkujlzxgm0xyynqqslwhvl +{ + "code": 210, + "message": "Ran out of routes to try after 11 attempts: see `paystatus`", + "attempts": [ + { + "status": "failed", + "failreason": "Error computing a route to 02f3d74746934494fa378235e5bc44cfdbb5b8779d839263fb7f9218be032f6f61: \"Could not find a route\" (205)", + "partid": 1, + "amount": "11111msat" + }, +... +``` +Mas e se um host com o qual tínhamos um canal aberto é o destinatário pretendido? + +Nesse caso, quando formos pagar a fatura, ele _automaticamente funcionará_! +``` +c$ lightning-cli --testnet pay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7h058g9u4mthcaf9rl2f7g8zxsdp2t9hh2gr0wajjqmt9ypnx7u3qv35kumn9wgs8gmm0yyxqyjw5qcqp2sp5kj4xhrthmfgcgyl84zaqpl9vvdjwm5x368kr09fu5nym74setw4s9qy9qsq8hxjr73ee77vat0ay603e4w9aa8ag9sa2n55xznk5lsfrjffxxdj2k0wznvcfa98l4a57s80j7dhg0cc03vwqdwehkujlzxgm0xyynqqslwhvl +{ + "destination": "02f3d74746934494fa378235e5bc44cfdbb5b8779d839263fb7f9218be032f6f61", + "payment_hash": "e3e689117f7688ece226f1eb2eff35337d77d0e82f2bb5df1d4947f527c8388d", + "created_at": 1602709081.324, + "parts": 1, + "msatoshi": 11111, + "amount_msat": "11111msat", + "msatoshi_sent": 12111, + "amount_sent_msat": "12111msat", + "payment_preimage": "ec7d1b28a7b877cd92b83be396899e8bfc3ecb0b4f944f65afb4be7d0ee72617", + "status": "complete" +} +``` +Essa é a verdadeira beleza da Lightning Network: Sem nenhum esforço dos participantes ponto a ponto, nossos canais individuais se tornam uma rede! + +> :book: ***Como funcionam os pagamentos na rede?*** Digamos que o node A tem um canal aberto com o node B, o node B tem um canal aberto com o node C e o node A recebe uma fatura do node C de 11.111 msat. O node A paga ao node B 11.111 msat, mais uma pequena taxa, e então o node B paga 11.111 msat ao node C. Muito fácil. Mas lembre-se de que todos os canais são, na verdade, apenas registros de quem é o proprietário e de quanto é a Transação de Financiamento. Então o que realmente acontece é 11.111 msat da Transação de Financiamento no canal AB muda de A para B e, em seguida, 11.111 msat da Transação de Financiamento no canal BC muda de B para C. Isso significa que duas coisas são necessárias para que este pagamento funcione: Primeiro, cada canal deve ter capacidade suficiente para o pagamento e; Segundo, o pagador em cada canal deve possuir o suficiente da capacidade para fazer o pagamento. + +Observe que, neste exemplo, 12.111 msat foram enviados para pagar uma fatura de 11.111 msat: o extra sendo uma taxa fixa muito pequena (não uma porcentagem) que foi paga ao intermediário. + +## Verificando nosso saldo + +Após efetuar um pagamento com sucesso, veremos que nossos fundos foram alterados corretamente. + +Aqui está a aparência dos fundos para o node pagador após o pagamento inicial de 10.000 satoshis: +``` +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": 90000, + "our_amount_msat": "90000000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} +``` +Observe que a capacidade do canal permanece em 100.000 satoshis (isso nunca irá mudar!), Mas que o `our_amount` agora é de apenas 90.000 satoshis (ou 90.000.000 msat). + +Depois de pagar a segunda fatura, de 11.111 msat, os fundos mudam novamente: +``` +$ 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 + } + ] +} +``` +O `our_amount` agora é de apenas 89.987 satoshis, tendo pago 11.111 msat mais uma taxa de 1.000 msat. + +## Resumo: Pagando um Invoice + +Depois de recebermos um invoice, é fácil pagar com um único comando na Lightning. Mesmo se não tivermos um canal para o destinatário, o pagamento é simples, desde que haja uma rota entre nós e o node de destino. + +## O Que Vem Depois? + +Vamos continuar "Usando a Lightning" na seção [§19.3: Fechando um Canal na Lightning](19_3_Closing_a_Channel.md). \ No newline at end of file diff --git a/pt/19_3_Closing_a_Channel.md b/pt/19_3_Closing_a_Channel.md new file mode 100644 index 0000000..bfb8881 --- /dev/null +++ b/pt/19_3_Closing_a_Channel.md @@ -0,0 +1,259 @@ +# 19.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 os 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 os 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 do `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 cadeia é [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 [§18.3](18_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 [§19.4: Expandindo a rede Lightning](19_3_Closing_a_Channel.md). \ No newline at end of file diff --git a/pt/19_4_Lightning_Network_Review.md b/pt/19_4_Lightning_Network_Review.md new file mode 100644 index 0000000..acee240 --- /dev/null +++ b/pt/19_4_Lightning_Network_Review.md @@ -0,0 +1,60 @@ +# 19.4: Expandindo a Lightning Network + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esses dois capítulos cobriram apenas algumas das atividades mais importantes da Lightning. Há muito mais que pode ser feito e muitas variedades possíveis. A seguir, daremos algumas dicas importantes. + +## Usando plugins c-lightning + +O c-lightning é uma implementação leve, altamente personalizável e compatível com o padrão do protocolo Lightning Network. Ele estende a funcionalidade usando plugins. Principalmente, esses são subprocessos que são iniciados pelo daemon `lightningd` e podem interagir com o `lightningd` de várias maneiras: + +* As opções de linha de comando permitem que os plugins registrem os próprios argumentos usando a linha de comando, que são então expostos por meio do `lightningd`; +* A passagem de comando JSON-RPC permite que os plugins adicionem os próprios comandos à interface JSON-RPC; +* As assinaturas de fluxo de eventos fornecem plug-ins com um mecanismo de notificação baseados em push para o `lightnind`; +* Hooks são uma opção primitiva que permite que os plugins sejam notificados sobre eventos no daemon `lightningd` e modifiquem o comportamento ou transmitam comportamentos personalizados. + +Um plugin pode ser escrito em qualquer linguagem e pode se comunicar com o `lightningd` através do stdin e stdout do plugin. O JSON-RPCv2 é usado como protocolo no topo dos dois fluxos, com o plugin atuando como servidor e `lightningd` atuando como cliente. + +O repositório `lightningd` GitHub mantém uma lista atualizada de [plugins](https://github.com/lightningd/plugins) disponíveis. + +## Usando Mobile Wallets + +Atualmente, sabemos de duas carteiras de dispositivos móveis da Lightning que suportam a implementação do c-lightning. + +Para dispositivos iOS, o FullyNoded é uma carteira de Bitcoin iOS open source que se conecta através do serviço autenticado Tor V3 ao nosso próprio full node. A funcionalidade FullyNoded está atualmente em desenvolvimento ativo e na fase beta inicial de testes. + +* [FullyNoded](https://github.com/Fonta1n3/FullyNoded/blob/master/Docs/Lightning.md) + +O SparkWallet é uma carteira GUI minimalista para a c-lightning, acessível pela web ou por meio de aplicativos móveis e de desktop para Android. + +* [SparkWallet](https://github.com/shesek/spark-wallet) + +## Usando diferentes implementações da Lightning + +O c-lightning não é a nossa única opção. Hoje, existem três implementações amplamente utilizadas para a Lightning Network. Todos seguem as [Documentações Base para a Tecnologia Lightning (BOLT)](https://github.com/lightningnetwork/lightning-rfc), que descrevem um protocolo de segunda camada para transferências de bitcoins offchain. As especificações são atualmente um trabalho em andamento que ainda está sendo elaborado. + +| Nome | Descrição | BitcoinStandup | Linguagem | Repositório | +| ------------- | ------------- | :---: | ------------- | ------------- | +| C-lighting | Blockstream | X | C | [Download](https://github.com/ElementsProject/lightning) | +| LND | Lightning Labs | X | Go | [Download](https://github.com/lightningnetwork/lnd) | +| Eclair | ACINQ | - | Scala | [Download](https://github.com/ACINQ/eclair) | + +## Fazendo backups + +Nosso node Lightning precisa estar online o tempo todo, caso contrário, nossa contraparte pode enviar um status de canal anterior e roubar nossos fundos. No entanto, há outro cenário em que os fundos podem ser perdidos, que é quando ocorre uma falha no hardware que impede o node de estabelecer um fechamento cooperativo com a contraparte. Isso provavelmente significará que, se não tivermos uma cópia exata do estado do canal antes da falha, teremos um estado inválido que pode fazer com que o outro node o considere como uma tentativa de fraude e use a transação penalizada. Nesse caso, todos os fundos serão perdidos. Para evitar esta situação indesejável, uma solução baseada na alta disponibilidade do banco de dados postgresQL [existe](https://github.com/gabridome/docs/blob/master/c-lightning_with_postgresql_reliability.md). + +PS: Não testamos esta solução. + +## Resumo: Expandindo a Lightning Network + +Podemos usar diferentes implementações, plugins, carteiras para celular e backups para expandir nossa experiência com a Lightning. + +## O Que Vem Depois? + +Concluímos todo o livro Aprendendo sobre o Bitcoin usando a Linha de Comando, embora não precise visitar os [Apêndices](A0_Apêndices.md) que possuem configurações alternativas, podemos fazer isso agora. + +Caso contrário, nós o encorajamos a ingressar nas comunidades de desenvolvedores e programadores e também, colocar nosso novo conhecimento para funcionar. + +Também podemos nos ajudar aqui em Blockchain Commons com issues ou PRs para aprender sobre o Bitcoin ou para qualquer um de nossos outros repositórios, ou podemos até mesmo nos tornar um [patrocinador](https://github.com/sponsors/BlockchainCommons). Também podemos ajudar divulgando o trabalho, contando às pessoas nas redes sociais sobre o curso e o que aprendemos com ele! + +Agora vá lá e faça da comunidade do Bitcoin um lugar melhor! \ No newline at end of file From f726c60359ca2a6ece916b970c4bc094b4e238b7 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Mon, 9 Aug 2021 11:32:40 -0300 Subject: [PATCH 2/9] Fixing changes --- 19_0_Using_Lightning.md | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/19_0_Using_Lightning.md b/19_0_Using_Lightning.md index 008cb7c..04ef4c3 100644 --- a/19_0_Using_Lightning.md +++ b/19_0_Using_Lightning.md @@ -23,30 +23,3 @@ Supporting objectives include the ability to: * [Section Two: Paying an Invoice](19_2_Paying_a_Invoice.md) * [Section Three: Closing a Lightning Channel](19_3_Closing_a_Channel.md) * [Section Four: Expanding the Lightning Network](19_4_Lightning_Network_Review.md) - - -# Capítulo dezenove: usando um raio - ->: Informação_Source: ** Nota: ** Este é um rascunho em andamento, para que eu possa obter algum feedback dos iniciantes. Ainda não está pronto para aprender. - -Neste capítulo, você continuará trabalhando com a interface de linha de comando "Lightning-Cli` Você criará faturas, executará pagamentos e canais fechados - todas as principais atividades para usar o Lightning. - -## Objetivos para este capítulo - -Depois de trabalhar através deste capítulo, um desenvolvedor será capaz de: - - * Execute pagamentos na rede relâmpago. - * Aplique o fechamento para um canal de relâmpago. - -Objetivos de apoio incluem a capacidade de: - - * Compreender o formato das faturas. - * Entenda o ciclo de vida dos pagamentos de rede de raios. - * Saber como expandir a rede relâmpago. - -## Índice - -* [Seção One: Gerando uma solicitação de pagamento] (19_1_Generate_A_Payment_Request.md) -* [Seção dois: pagando uma fatura] (19_2_Paying_a_invoice.md) -* [Seção três: fechando um canal de raio] (19_3_closing_a_channel.md) -* [Seção Quatro: Expandindo a rede Lightning] (19_4_lightning_network_review.md) \ No newline at end of file From 8a3ebcb6bf17176dc62a0234c412eb919432beca Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 11:09:59 -0300 Subject: [PATCH 3/9] Delete old chapter 15 files --- pt/15_0_Talking_to_Bitcoind.md | 27 -- pt/15_1_Accessing_Bitcoind_with_C.md | 294 --------------- pt/15_2_Programming_Bitcoind_with_C.md | 354 ------------------ ...Receiving_Bitcoind_Notifications_with_C.md | 155 -------- 4 files changed, 830 deletions(-) delete mode 100644 pt/15_0_Talking_to_Bitcoind.md delete mode 100644 pt/15_1_Accessing_Bitcoind_with_C.md delete mode 100644 pt/15_2_Programming_Bitcoind_with_C.md delete mode 100644 pt/15_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/pt/15_0_Talking_to_Bitcoind.md b/pt/15_0_Talking_to_Bitcoind.md deleted file mode 100644 index 88bde29..0000000 --- a/pt/15_0_Talking_to_Bitcoind.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Capítulo 15: Conversando com Bitcoind usando C - -Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. - -Esta seção se concentra em três diferentes bibliotecas que podem ser usadas como base de programação C sofisticada: Uma biblioteca RPC e uma biblioteca JSON que juntas permitem recriar muito do que fazemos nos scripts de shell, porém, usando C; enquanto uma biblioteca ZMQ nos conecta a notificações, algo que não conseguiríamos acessar até agora. (O próximo capítulo cobrirá uma biblioteca ainda mais sofisticada chamada Libwally, para finalizar esta introdução à programação do Bitcoin com C). - -## Objetivos deste capítulo - -Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - - * Criar programas C que usam RPC para conversar com o Bitcoind; - * Criar programas C que usam ZMQ para conversar com o Bitcoind. - -Os objetivos secundários do capítulo incluem a capacidade de: - - * Entender como usar uma biblioteca RPC; - * Entender como usar uma biblioteca JSON; - * Compreender as capacidades do ZMQ; - * Entender como usar uma biblioteca ZMQ. - -## Tabela de conteúdo - - * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) - * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) - * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) - \ No newline at end of file diff --git a/pt/15_1_Accessing_Bitcoind_with_C.md b/pt/15_1_Accessing_Bitcoind_with_C.md deleted file mode 100644 index 2e97e1c..0000000 --- a/pt/15_1_Accessing_Bitcoind_with_C.md +++ /dev/null @@ -1,294 +0,0 @@ - -# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -Você já viu uma maneira alternativa de acessar as portas RPC do Bitcoind: Usando o ``curl``, que cobrimos no [Capítulo 4 Prefácio](04_4__interlude_using_curl.md). Interagir com o ``Bitcoind`` através de uma biblioteca de RPC usando C não é diferente do que já vimos, só precisamos de boas bibliotecas para nos auxiliar. Esta seção introduz um pacote chamado ``libbitcoinrpc``, que permite acessar a porta JSON-RPC do ``bitcoind``. Ele usa uma biblioteca ``curl`` para acessar os dados e usa a biblioteca ``jansson`` para codificar e decodificar o JSON. - -## Configurando o libbitcoinrpc - -Para usar o ``libbitcoinrpc``, precisaremos instalar uma configuração básica C e os pacotes dependentes, que são ``libcurl``, ``libjansson``, e ``libuuid``. Depois faremos isso no seu servidor Standup Bitcoin (ou em qualquer outro servidor Ubuntu). - -``` -$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev -Suggested packages: - libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev -The following NEW packages will be installed: - libcurl4-openssl-dev libjansson-dev uuid-dev -0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. -Need to get 358 kB of archives. -After this operation, 1.696 kB of additional disk space will be used. -Do you want to continue? [Y/n] y -``` -Agora, podemos baixar o [libbitcoinrpc no github](https://github.com/gitmarek/libbitcoinrpc/blob/master/readme.md). Vamos clonar ou pegar um arquivo zip, do jeito que preferir. - -``` -$ sudo apt-get install git -$ git clone https://github.com/gitmarek/libbitcoinrpc -``` - -> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. - -### Compilando o libbitcoinrpc. - -Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: -``` -$ PATH="/sbin:$PATH" -``` - -Para o Ubuntu, também precisaremos ajustar o ``install_libpath`` no ``makefile`` do ``libbitcoinrpc`` para instalar no ``/usr/lib`` ao invés do ``/usr/local/lib``: - -``` -$ emacs ~/libbitcoinrpc/Makefile -... -INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib -``` - -(Se preferir não usar o ``/usr/lib``, precisará alterar o ``etc/ld.so.conf`` ou os arquivos dependentes de maneira apropriada... Porém, para uma configuração de teste em uma máquina de teste, acredito que isso não seja um problema). - -Da mesma forma, vamos precisar ajustar o ``install_headerpath`` no ``Makefile`` do ``libbitcoinrpc`` para instalar no caminho ``/usr/include`` ao invés do ``/usr/local/inclusve``: - -``` -... -INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include -``` - -Agora, podemos compilar: -``` -$ cd libbitcoinrpc -~/libbitcoinrpc$ make - -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ -src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ --o .lib/libbitcoinrpc.so.0.2 \ --Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl -ldconfig -v -n .lib -.lib: - libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) -ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so -``` -Se tudo correr bem, podemos instalar o pacote: -``` -$ sudo make install -Installing to -install .lib/libbitcoinrpc.so.0.2 /usr/local/lib -ldconfig -n /usr/local/lib -ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so -install -m 644 src/bitcoinrpc.h /usr/local/include -Installing docs to /usr/share/doc/bitcoinrpc -mkdir -p /usr/share/doc/bitcoinrpc -install -m 644 doc/*.md /usr/share/doc/bitcoinrpc -install -m 644 CREDITS /usr/share/doc/bitcoinrpc -install -m 644 LICENSE /usr/share/doc/bitcoinrpc -install -m 644 Changelog.md /usr/share/doc/bitcoinrpc -Installing man pages -install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 -``` - -## Preparando o código - -``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. - -Para usar o ``libbitcoinrpc``, é importante certificar de que nossos arquivos do código incluam os cabeçalhos apropriados: -``` c -#include -#include -``` - -Precisaremos também vincular as bibliotecas apropriadas sempre que possamos compilar: - -``` -$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode -``` - -## Construindo a conexão - -Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. - -Primeiro, inicialize a biblioteca: -``` -bitcoinrpc_global_init(); -``` -Em seguida, vamos conectar ao ``Bitcoind`` com ``bitcoinrpc_cl_init_params``. Os quatro argumentos necessários para o ``bitcoinrpc_cl_init_params`` são o nome de usuário, a senha, o endereço IP e a porta. A esta altura, você deve saber todas essas informações, já que foram necessárias para realizar o trabalho com o [curl](04_4__interlude_using_curl.md). Apenas para recordar, o endereço de IP é 127.0.0.1 e a porta 18332 devem estar corretos para a configuração padrão da testenet descrita neste documento, enquanto podemos encontrar o usuário e a senha no arquivo ``~/.bitcoin/bitcoin.conf``. -``` -$ cat bitcoin.conf -server=1 -dbcache=1536 -par=1 -maxuploadtarget=137 -maxconnections=16 -rpcuser=StandUp -rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba -rpcallowip=127.0.0.1 -debug=tor -prune=550 -testnet=1 -[test] -rpcbind=127.0.0.1 -rpcport=18332 -[main] -rpcbind=127.0.0.1 -rpcport=8332 -[regtest] -rpcbind=127.0.0.1 -rpcport=18443 -``` -Com essas informações, vamos colocá-las no ``bitcoinrpc_cl_init_params``: -``` c -bitcoinrpc_cl_t *rpc_client; -rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); -``` - -> **MAINNET VS TESTNET:** A porta seria a 8332 caso estivéssemos usando a configuração da rede principal. - -Se o ``rpc_client`` for inicializado com sucesso, poderemos enviar os comandos do RPC. - -Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fechar da seguinte maneira: -``` c -bitcoinrpc_global_cleanup(); -``` - -### Testando o código de teste - -O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). - -Podemos compilar e executar o código da seguinte maneira: -``` -$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin -$ ./testbitcoin -Successfully connected to server! -``` - -> :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. - -## Fazendo uma chamada ao RPC - -Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). -``` c -bitcoinrpc_method_t *getmininginfo = NULL; -getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); -``` -Normalmente definiríamos os parâmetros em seguida, mas o ``GetMiningInfo`` não requer parâmetros, por isso podemos pular essa parte. - -Também devemos criar outros dois objetos, um "objeto de resposta" e um "objeto de erro". Eles podem ser inicializados da seguinte forma: -``` c -bitcoinrpc_resp_t *btcresponse = NULL; -btcresponse = bitcoinrpc_resp_init(); - -bitcoinrpc_err_t btcerror; -``` -Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos adicionar nosso método ``getmininginfo`` e os outros dois objetos: -``` c -bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); -``` - -### Mostrando o retorno da chamada - -Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: -``` c -json_t *jsonresponse = NULL; -jsonresponse = bitcoinrpc_resp_get(btcresponse); -``` -Se quisermos gerar os resultados completos da chamada RPC no JSON, podemos fazer com uma simples invocação do ``json_dumps``, da biblioteca ``jansson``: -``` c -printf("%s\n", json_dumps(j, JSON_INDENT(2))); -``` -No entanto, como agora estamos escrevendo programas completos, provavelmente iremos querer fazer um trabalho mais sutil, como retirar valores individuais do JSON para algum uso específico. A [Referência do Jansson](https6//jansson.readthedocs.Io/en/2.10/apiref.html) traz detalhes de como fazer. - -Assim como estávamos usando o [curl](04_4__interlude_using_curl.md), descobrimos que o RPC retorna um objeto JSON contendo um ``ID``, um ``error`` e, mais importante, um objeto JSON do tipo ``result``. - -A função ``json_object_get`` permite recuperar um valor (como o ``result``) de um objeto JSON usando chaves: -``` c -json_t *jsonresult = NULL; -jsonresult = json_object_get(jsonresponse,"result"); -printf("%s\n", json_dumps(jsonresult, JSON_INDENT(2))); -``` - -No entanto, provavelmente iremos querer analisar informações ainda mais profundas, para obter uma variável específica. Depois de recuperar o valor apropriado, precisaremos convertê-lo em um objeto C padrão usando a função ``JSON_*_value``. Por exemplo, para acessar um integer usamos o ``json_integer_value``: -``` c -json_t *jsonblocks = NULL; -jsonblocks = json_object_get(jsonresult,"blocks"); - -int blocks; -blocks = json_integer_value(jsonblocks); -printf("Block Count: %d\n",blocks); -``` - -> :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. - -### Testando o código de informação - -Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). -``` -$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo -$ ./getmininginfo -Full Response: { - "result": { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" - }, - "error": null, - "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" -} - -Just the Result: { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" -} - -Block Count: 1804406 -``` - -## Fazendo uma chamada RPC usando argumentos - -Mas e se a sua chamada RPC tiver argumentos? - -### Criando uma matriz JSON - -Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. - -Vamos criar a matriz JSON usando a função ``json_array do`` do ``jansson``: -``` c -json_t *params = NULL; -params = json_array(); -``` -Vamos fazer o processo inverso que fizemos para acessar valores do JSON: Vamos converter objetos no C para objetos no JSON usando as funções ``JSON_*``. Depois, vamos anexar tudo à matriz: -``` c -json_array_append_new(params,json_string(tx_rawhex)); -``` - -Observe que existem duas variantes para o comando de anexação: ``json_array_apend_new``, que acrescenta uma variável recém-criada, e ``json_array_apend``, que anexa uma variável existente. - -Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. - -### Atribuindo os parâmetros - -Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: -``` c -bitcoinrpc_method_set_params(rpc_method, params) -``` -Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. - -## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC - -Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. - -* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. - -## O Que Vem Depois? - -Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). diff --git a/pt/15_2_Programming_Bitcoind_with_C.md b/pt/15_2_Programming_Bitcoind_with_C.md deleted file mode 100644 index c1fdc38..0000000 --- a/pt/15_2_Programming_Bitcoind_with_C.md +++ /dev/null @@ -1,354 +0,0 @@ - -# 15.2: Programando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. - -## Planejando o código - -Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: - - 1. Solicitar um endereço e uma quantia; - 2. Definir uma taxa arbitrária; - 3. Preparar nosso RPC; - 4. Encontrar um UTXO que seja grande o suficiente para pagar o valor + a taxa; - 5. Criar uma mudança de endereço; - 6. Criar uma transação bruta que envie o UTXO para o endereço e altere o endereço; - 7. Assinar a transação; - 8. Enviar a transação. - -### Planejando para o futuro - -Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: - - 1. Testar e/ou higienizar as entradas; - 2. Calcular uma taxa automaticamente; - 3. Pensar logicamente sobre qual UTXO seria válido utilizar; - 4. Combinar vários UTXOs, caso seja necessário; - 5. Ficar atento a mais erros nos comandos ``libbitcoinrpc`` ou no ``jansson``; - 6. Observar se há erros nas respostas RPC. - -Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. - -## Escrevendo o sistema de transação - -Agora estamos prontos para realizar o passo a passo do nosso plano - -### Etapa 1: Solicitando um endereço e uma quantia - -Inserir as informações é bem simples se usarmos os argumentos na linha de comando: -``` c -if(argc != 3) { - - printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); - exit(-1); - -} - -char *tx_recipient = argv[1]; -float tx_amount = atof(argv[2]); - -printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); -``` - -> :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. - -### Etapa 2: Definindo uma taxa arbitrária - -Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: - -``` c -float tx_fee = 0.0005; -float tx_total = tx_amount + tx_fee; -``` - -> :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. - -### Etapa 3: Preparando nosso RPC - -Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: -``` c -bitcoinrpc_global_init(); -rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); -btcresponse = bitcoinrpc_resp_init(); -``` - -### Etapa 4: Encontrando um UTXO - -Para encontrar um UTXO, precisaremos chamar a função RPC ``listunspent``: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -``` - -No entanto, o verdadeiro trabalho consiste em decodificar a resposta. Na seção anterior vimos que a biblioteca ``jansson`` era "um tanto quanto desajeitada" e esta é a razão: Precisamos criar (e limpar) um conjunto muito grande de objetos ``json_t`` para descobrir o que queremos. - -Primeiro, precisamos nos recuperar o campo ``result`` do JSON: -``` c -json_t *lu_response = NULL; -json_t *lu_result = NULL; - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -``` - -> :warning: **ATENÇÃO:** Só obteremos um resultado se não houver nenhum erro. Aqui temos um momento para melhorar nossa verificação de erros no código que iremos colocar em produção. - -Em seguida, vamos fazer um laço, examinando cada transação que não foi gasta, que aparece como um elemento em sua matriz do resultado JSON: -``` c -int i; - -const char *tx_id = 0; -int tx_vout = 0; -double tx_value = 0.0; - -for(i = 0 ; i < json_array_size(lu_result) ; i++) { - - json_t *lu_data = NULL; - lu_data = json_array_get(lu_result, i); - - json_t *lu_value = NULL; - lu_value = json_object_get(lu_data,"amount"); - tx_value = json_real_value(lu_value); -``` - -O UTXO é grande o suficiente para pagar sua transação? Se sim, pegue-o! - -> :warning: **ATENÇÃO:** Um programa em produção pensaria com mais cuidado sobre qual UTXO utilizar, com base no tamanho e em outros fatores. Provavelmente não pegaria apenas o primeiro mais simples e pronto. - -``` c - if(tx_value > tx_total) { - - json_t *lu_txid = NULL; - lu_txid = json_object_get(lu_data,"txid"); - tx_id = strdup(json_string_value(lu_txid)); - - json_t *lu_vout = NULL; - lu_vout = json_object_get(lu_data,"vout"); - tx_vout = json_integer_value(lu_vout); - - json_decref(lu_value); - json_decref(lu_txid); - json_decref(lu_vout); - json_decref(lu_data); - break; - - } -``` -Você também deve limpar os principais elementos do JSON: -``` c -} - -json_decref(lu_result); -json_decref(lu_response); -``` - -> :warning: **ATENÇÃO:** Um programa em produção também se certificaria de que os UTXOs são passíveis de serem `gastos`. - -Se não encontramos nenhum UTXOs grande o suficiente, teremos que relatar este infortúnio ao usuário... E talvez, sugerir que ele deva usar um programa melhor, que irá mesclar os UTXOs de maneira correta. -``` c -if(!tx_id) { - - printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); - exit(-1); -} -``` - -> **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. - -### Etapa 5: Criando um endereço de troco - -Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); - -if(!rpc_method) { - - printf("ERROR: Unable to initialize listunspent method!\n"); - exit(-1); - -} - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -if(btcerror.code != BITCOINRPCE_OK) { - -printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); - - exit(-1); - -} - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -char *changeaddress = strdup(json_string_value(lu_result)); -``` -A única diferença é quais informações específicas são extraídas do objeto JSON. - -> :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. - -### Etapa 6: Criando uma transação bruta - -Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. - -Para criarmos esses parâmetros corretamente, precisaremos revisar o que o RPC ``createrawtransaction`` espera que passemos como argumento. Felizmente, isso é fácil de determinar usando a funcionalidade ``bitcoin-cli help``: -``` -$ bitcoin-cli help createrawtransaction -createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) -``` - -Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. - -#### Etapa 6.1: Criando os parâmetros de entrada - -Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): -``` c -json_t *inputtxid = NULL; -inputtxid = json_object(); - -json_object_set_new(inputtxid,"txid",json_string(tx_id)); -json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); -``` - -Pode-se notar que teremos que traduzir novamente cada tipo de variável C em um tipo de variável JSON usando a função apropriada, como ``json_string`` ou ``json_integer``. - -Para criar o array de entrada para todos os UTXOs, vamos usar o ``json_array`` e, em seguida, preenchê-lo com os objetos usando o ``json_array_append``: -``` c -json_t *inputparams = NULL; -inputparams = json_array(); -json_array_append(inputparams,inputtxid); -``` - -#### Etapa 6.2: Criando os parâmetros de saída - -Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: -``` c -json_t *outputparams = NULL; -outputparams = json_object(); - -char tx_amount_string[32]; -sprintf(tx_amount_string,"%.8f",tx_amount); -char tx_change_string[32]; -sprintf(tx_change_string,"%.8f",tx_value - tx_total); - -json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); -json_object_set(outputparams, changeaddress, json_string(tx_change_string)); -``` - -> :warning: **ATENÇÃO:** É possível pensar que teremos que inserir os valores do Bitcoin como sendo números, usando a função ``json_real``. Infelizmente, isso expõe um dos maiores problemas com a integração da biblioteca ``jansson`` e o Bitcoin. O Bitcoin só é válido até oito dígitos depois da casa decimal. Devemos nos lembrar que 0,00000001 BTC é um satoshi, e essa é a menor divisão possível de um Bitcoin. O tipo ``double`` no C oferecem mais dígitos do que precisamos, embora sejam frequentemente imprecisos depois das oito casas decimais. Se tentarmos convertê-los diretamente do nosso valor ``double`` no C (ou de um tipo ``float``, neste caso) para um valor Bitcoin, a imprecisão frequentemente criará um valor Bitcoin com mais de oito dígitos. Antes da versão Bitcoin Core 0.12, isso não era problema, e podíamos usar a função ``json_real``. Mas à partir dessa versão, se tentarmos usar a função ``createrawtransaction`` com mais do que oito dígitos, obteremos um erro e a transação não será criada. Como resultado, se o valor do Bitcoin _sempre_ se tornar um ``double`` ou ``float``, devemos deixar com apenas oito casas decimais antes de transformá-lo em uma ``string``. Obviamente, isso é um erro, portanto, certifique-se disso para que o código continue funcionando nas versões mais novas do Bitcoin Core. - -#### Etapa 6.3: Criando a Matriz de Parâmetros - -Para terminarmos de criar os parâmetros, só precisaremos agrupá-los em uma matriz JSON: -``` c -json_t *params = NULL; -params = json_array(); -json_array_append(params,inputparams); -json_array_append(params,outputparams); -``` - -#### Etapa 6.4: Fazendo a chamada ao RPC - -Vamos usar o método normal para criar uma chamada ao RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); -``` -Agora, porém, devemos adicionar os nossos parâmetros. Isso pode ser feito facilmente com a função ``bitcoinrpc_method_set_params``: -``` c -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for createrawtransaction"); - -} -``` -Depois, é só executar o RPC e obter os resultados: -``` c -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_rawhex = strdup(json_string_value(lu_result)); -``` -### Etapa 7. Assinando a transação - -É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_rawhex)); -``` -Por fim, vamos assinar a transação seguindo o rigamarole típico para criar uma chamada RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for signrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -``` -Novamente, usar a função ``jansson`` para acessar a saída pode ser complicado. Devemos lembrar que ``hex`` é parte de um objeto JSON, não um resultado independente, como era quando criamos a transação bruta. Claro, sempre podemos acessar essas informações a partir da ajuda da linha de comando: ``bitcoin-cli help signrawtransaction`` -``` c -lu_result = json_object_get(lu_response,"result"); -json_t *lu_signature = json_object_get(lu_result,"hex"); -char *tx_signrawhex = strdup(json_string_value(lu_signature)); -json_decref(lu_signature); -``` -> :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. - -### Etapa 8. Enviando a transação - -Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_signrawhex)); - -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); - -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for sendrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_newid = strdup(json_string_value(lu_result)); - -printf("Txid: %s\n",tx_newid); -``` - -O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. - -## Testando o código - -O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). - -Compile-o como de costume: -``` -$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress -``` -Agora, é possível utilizá-lo para enviar fundos para um endereço: - -``` -./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 -Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 -``` -Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). - -## Resumo do Programando o Bitcoind usando C com bibliotecas RPC - -Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. - -## O Que Vem Depois? - -Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md deleted file mode 100644 index fe166ac..0000000 --- a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md +++ /dev/null @@ -1,155 +0,0 @@ - -# 15.3 Recebendo notificações usando C com a biblioteca ZMQ - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. - -> :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). - -## Configurando o ZMQ - -Antes de podemos ouvir a blockchain, precisaremos configurar o ``bitcoind`` para permitir as notificações ZMQ. Por isso, precisamos instalar a biblioteca ZMQ para tirar proveito dessas notificações. - -### Configurando o ``bitcoind`` para usar o ZMQ - -O Bitcoin Core está pronto para ZMQ, mas devemos especificar os endpoints do ZMQ. O ZeroMQ publish-sockets prefixa cada item de dados com um prefixo de tópico arbitrário que permite aos clientes assinantes solicitarem apenas os itens com um prefixo correspondente. Existem atualmente quatro tópicos suportados pelo ``bitcoind``: -``` -$ bitcoind --help | grep zmq | grep address - -zmqpubhashblock=
- -zmqpubhashtx=
- -zmqpubrawblock=
- -zmqpubrawtx=
-``` - -Podemos executar o ``bitcoind`` com argumentos de linha de comando para endpoints ZMQ, como mostrado acima, mas também podemos criar um endpoint acessível adicionando linhas apropriadas ao nosso arquivo ``~/.bitcoin/bitcoin.conf`` e reiniciando o sistema. - -``` -zmqpubrawblock=tcp://127.0.0.1:28332 -zmqpubrawtx=tcp://127.0.0.1:28333 -``` -Podemos então testar se os nossos endpoints estão funcionando usando o RPC ``getzmqnotifications``: - -``` -$ bitcoin-cli getzmqnotifications -[ - { - "type": "pubrawblock", - "address": "tcp://127.0.0.1:28332", - "hwm": 1000 - }, - { - "type": "pubrawtx", - "address": "tcp://127.0.0.1:28333", - "hwm": 1000 - } -] -``` -Nosso ``bitcoind`` agora irá emitir as notificações ZMQ - -### Instalando o ZMQ - -Para aproveitar essas notificações, precisamos de uma biblioteca ZMQ para usar com o C, portanto, estaremos usando uma nova biblioteca ZMQ ao invés da biblioteca ``libbitcoinrpc`` nesta seção, mas no futuro, podemos combinar ambas. - -Felizmente, as bibliotecas ZMQ estão disponíveis por meio de pacotes Debian padrão: -``` -$ sudo apt-get install libzmq3-dev -$ sudo apt-get install libczmq-dev -``` -Agora estamos pronto para escrever o código! - -## Escrevendo o programa de notificação - -O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. - -O programa requer dois parâmetros: O primeiro é o "servidor", que é o ponto de conexão TCP exposto pelo ``bitcoind``. O segundo é o "tópico", que atualmente é o ``zmqpubhashblock``,``zmqpubhashtx``, ``zmqpubrawblock`` ou ``zmqpubrawtx``. O tópico precisa ter suporte do ``bitcoin.conf`` e o endereço IP e a porta do servidor devem corresponder ao que está definido no arquivo de configuração. - -``` c -#include -int main(int argc, char ** argv) { - - char *zmqserver; - char *topic; - - if(argc < 3) { - printf("\nUSAGE:\nchainlistener \n\n"); - return 0; - } else { - zmqserver = argv[1]; - topic = argv[2]; - } -``` -Abriremos um soquete ZMQ para o servidor e para o tópico definido: -``` c - zsock_t *socket = zsock_new_sub(zmqserver, topic); - assert(socket); -``` -Depois, vamos esperar: -``` c - while(1) { - zmsg_t *msg; - int rc = zsock_recv(socket, "m", &msg); - assert(rc == 0); - - char *header = zmsg_popstr(msg); - zframe_t *zdata = zmsg_pop(msg); - unsigned int *no = (unsigned int*)zmsg_popstr(msg); - - char *data = zframe_strhex(zdata); - int len = zframe_size(zdata); - printf("Size: %d\n", len); - printf("Data: %s", data); - printf("\nNo: %d\n", *no); - - free(header); - free(data); - free(no); - free(zdata); - zmsg_destroy(&msg); - sleep(1); - } -``` -Enquanto esperamos, observamos as mensagens no soquete ZMQ. Sempre que recebermos uma mensagem, iremos retirá-la da pilha, relatando o número, comprimento e, o os dados que foram importante para nós. - -É isso! - -Claro, quando terminar o processo, precisamos limpar tudo: -``` c - zsock_destroy(&socket); - return 0; -} -``` - -### Testando o código de notificação - -O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: -``` -$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq -``` -Depois, podemos executá-lo com os tópicos e endereços que definimos no nosso ``bitcoin.conf``: -``` -$ ./chainlistener tcp://127.0.0.1:28333 rawtx -Size: 250 -Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 -No: 67 -Size: 249 -Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 -No: 68 -Size: 250 -Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 -No: 69 -Size: 250 -Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 -No: 70 -....... -``` - -### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ - -Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. - -> :fire: ***Qual é o poder das notificações?*** Com as notificações, não dependemos mais dos usuários para emitir os comandos. Ou seja, podemos criar programas que monitoram o blockchain do Bitcoin e tomar as ações apropriadas quando certas coisas ocorrem. Isso, por sua vez, pode ser utilizado juntamente com os comandos RPC que programamos nas seções anteriores. Este também é um grande passo além do que poderíamos fazer com os scripts shell: Certamente, podemos criar scripts shell que fica ouvindo infinitamente, mas existem outras linguagens de programação que possuem ferramentas melhores para isso. - -## O Que Vem Depois? - -Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file From 9b3388b2c8c3cf2d5c17fec8973f3bd0ea68e138 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 11:12:20 -0300 Subject: [PATCH 4/9] Rename files chapter 19 to 20 --- pt/{19_0_Using_Lightning.md => 20_0_Using_Lightning.md} | 0 ...te_a_Payment_Request.md => 20_1_Generate_a_Payment_Request.md} | 0 pt/{19_2_Paying_a_Invoice.md => 20_2_Paying_a_Invoice.md} | 0 pt/{19_3_Closing_a_Channel.md => 20_3_Closing_a_Channel.md} | 0 ...ghtning_Network_Review.md => 20_4_Lightning_Network_Review.md} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename pt/{19_0_Using_Lightning.md => 20_0_Using_Lightning.md} (100%) rename pt/{19_1_Generate_a_Payment_Request.md => 20_1_Generate_a_Payment_Request.md} (100%) rename pt/{19_2_Paying_a_Invoice.md => 20_2_Paying_a_Invoice.md} (100%) rename pt/{19_3_Closing_a_Channel.md => 20_3_Closing_a_Channel.md} (100%) rename pt/{19_4_Lightning_Network_Review.md => 20_4_Lightning_Network_Review.md} (100%) diff --git a/pt/19_0_Using_Lightning.md b/pt/20_0_Using_Lightning.md similarity index 100% rename from pt/19_0_Using_Lightning.md rename to pt/20_0_Using_Lightning.md diff --git a/pt/19_1_Generate_a_Payment_Request.md b/pt/20_1_Generate_a_Payment_Request.md similarity index 100% rename from pt/19_1_Generate_a_Payment_Request.md rename to pt/20_1_Generate_a_Payment_Request.md diff --git a/pt/19_2_Paying_a_Invoice.md b/pt/20_2_Paying_a_Invoice.md similarity index 100% rename from pt/19_2_Paying_a_Invoice.md rename to pt/20_2_Paying_a_Invoice.md diff --git a/pt/19_3_Closing_a_Channel.md b/pt/20_3_Closing_a_Channel.md similarity index 100% rename from pt/19_3_Closing_a_Channel.md rename to pt/20_3_Closing_a_Channel.md diff --git a/pt/19_4_Lightning_Network_Review.md b/pt/20_4_Lightning_Network_Review.md similarity index 100% rename from pt/19_4_Lightning_Network_Review.md rename to pt/20_4_Lightning_Network_Review.md From 271f867edc6801e10fb7af9e31cba2e8cb6b57f0 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 11:14:11 -0300 Subject: [PATCH 5/9] Review 20_0 --- pt/20_0_Using_Lightning.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pt/20_0_Using_Lightning.md b/pt/20_0_Using_Lightning.md index d783afe..748bcde 100644 --- a/pt/20_0_Using_Lightning.md +++ b/pt/20_0_Using_Lightning.md @@ -1,25 +1,26 @@ -# Capítulo 19: Usando a Lightning +# Capítulo 20: Usando a Lightning > :information_source: **NOTA:** Este é um rascunho que está em andamento, para que possa obter alguns comentários dos revisores iniciais. Ainda não está pronto. Neste capítulo, continuaremos trabalhando com a interface de linha de comando `lightning-cli`. Criaremos invoices, realizaremos pagamentos e fecharemos canais, todas as principais atividades para se usar a Lightning. -## Objetivos deste capítulo +## Objetivos Deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: * Efetuar pagamentos na Lightning Network; - * Aplicar o fechamento a um canal Lightning. - + * Aplicar o fechamento de um canal Lightning. + Os objetivos secundários do capítulo incluem a capacidade de: * Compreender o formato dos invoices; * Entender o ciclo de vida dos pagamentos da Lightning Network; * Saber como expandir a Lightning Network. - + ## Tabela de Conteúdo * [Seção 1: Gerando um Invoice](19_1_Generate_a_Payment_Request.md) * [Seção 2: Pagando um Invoice](19_2_Paying_a_Invoice.md) -* [Seção 3: Fechando um canal na Lightning](19_3_Closing_a_Channel.md) +* [Seção 3: Fechando um Canal na Lightning](19_3_Closing_a_Channel.md) * [Seção 4: Expandindo a Lightning Network](19_4_Lightning_Network_Review.md) + From 53f83e1d41da5a7cc99f1a3277de89de0ab2c47e Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 17:47:48 -0300 Subject: [PATCH 6/9] Review 20_1 --- pt/20_1_Generate_a_Payment_Request.md | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pt/20_1_Generate_a_Payment_Request.md b/pt/20_1_Generate_a_Payment_Request.md index e56860c..312e008 100644 --- a/pt/20_1_Generate_a_Payment_Request.md +++ b/pt/20_1_Generate_a_Payment_Request.md @@ -1,12 +1,12 @@ -# 19.1: Gerando um Invoice +# 20.1: Gerando um Invoice > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Esta seção descreve como os pagamentos funcionam na Lightning Network, como criar uma solicitação de pagamento (ou _invoice_) e, finalmente, como entendê-la. A emissão de invoices depende de termos um segundo node Lightning, conforme descrito na seção [Acessando um segundo node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md). Esses exemplos usarão um node LND como nosso node secundário, para demonstrar ainda mais as possibilidades da Lightning Network. Para diferenciar entre os nodes nestes exemplos, os prompts serão mostrados como `c $` para o node c-lightning e `lnd $` para o node LND. Se quisermos reproduzir essas etapas, devemos [instalar nosso próprio node LND secundário](18_2__Interlude_Accessing_a_Second_Lightning_Node.md#Creating-a-new-lnd-node). +Esta seção descreve como os pagamentos funcionam na Lightning Network, como criar uma solicitação de pagamento (ou _invoice_) e, finalmente, como entendê-la. A emissão de invoices depende de termos um segundo node Lightning, conforme descrito na seção [Acessando um Segundo Node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md). Esses exemplos usarão um node LND como nosso node secundário, para demonstrar ainda mais as possibilidades da Lightning Network. Para diferenciar entre os nodes nestes exemplos, os prompts serão mostrados como `c $` para o node c-lightning e `lnd $` para o node LND. Se quisermos reproduzir essas etapas, devemos [instalar nosso próprio node LND secundário](19_2__Interlude_Accessing_a_Second_Lightning_Node.md#Creating-a-new-lnd-node). > :book: ***O que é um invoice?*** Quase todos os pagamentos feitos na Lightning Network exigem um invoice, que nada mais é do que um **pedido de pagamento** feito pelo destinatário do dinheiro e enviado por qualquer meio para o usuário que irá pagar. Todos os invoices são de uso único. Os invoices da Lightning usam a codificação bech32, que já é usada pela Segregated Witness para Bitcoin. -## Criando um invoice +## Criando um Invoice Para criar um novo invoice na c-lightning, usaríamos o comando `lightning-cli --testnet invoice`. @@ -21,7 +21,7 @@ c$ lightning-cli --testnet invoice 100000 joe-payment "The money you owe me for "warning_mpp_capacity": "The total incoming capacity is still insufficient even if the payer had MPP capability." } ``` -No entanto, para este exemplo, vamos gerar um invoice em um node LND e, em seguida, pagá-la no node c-lightning. Isso requer o comando `addinvoice` ligeiramente diferente na LND. Podemos usar o argumento `--amt` para indicar a quantia a ser paga (em milisats) e adicionar uma descrição usando o argumento `--memo`. +No entanto, para este exemplo, vamos gerar um invoice em um node LND e, em seguida, pagá-lo no node c-lightning. Isso requer o comando `addinvoice` ligeiramente diferente na LND. Podemos usar o argumento `--amt` para indicar a quantia a ser paga (em milisats) e adicionar uma descrição usando o argumento `--memo`. ``` lnd$ lncli -n testnet addinvoice --amt 10000 --memo "First LN Payment - Learning Bitcoin and Lightning from the Command line." @@ -33,13 +33,13 @@ lnd$ lncli -n testnet addinvoice --amt 10000 --memo "First LN Payment - Learning ``` Observe que esses invoices não fazem referência direta ao canal que criamos: isso é necessário para o pagamento, mas não para solicitar o pagamento. -## Compreendendo um invoice +## Compreendendo um Invoice O `bolt11 payment_request` que criamos é composto de duas partes: uma é legível por humanos e a outra são apenas dados. > :book: **O que é um BOLT?** Os BOLTs são as [especificações individuais da Lightning Network](https://github.com/lightningnetwork/lightning-rfc). -### Lendo a parte legível do invoice +### Lendo a Parte Legível do Invoice A parte legível dos invoices começa com um `ln`. É `lnbc` para Bitcoin mainnet, `lntb` para Bitcoin testnet ou `lnbcrt` para Bitcoin regtest. Em seguida, listamos os fundos solicitados no invoice. @@ -61,9 +61,9 @@ O `100u` diz que é para 100 bitcoins vezes o multiplicador microsatoshi. Existe 100 BTC * 0,000001 = 0,0001 BTC, que é o mesmo que 10.000 satoshis. -### Lendo a parte do invoice referente aos dados +### Lendo a Parte do Invoice Referente aos Dados -O resto do invoice ( `1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd`) contém um marcador de tempo, dados especificamente marcados, e uma assinatura. Obviamente, não pode ler sem decodificá-lo, mas podemos pedir ao `lightning-cli` para fazer isso com o comando `decodepay`: +O resto do invoice (`1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd`) contém um marcador de tempo, dados especificamente marcados e uma assinatura. Obviamente, não pode ler sem decodificá-lo, mas podemos pedir ao `lightning-cli` para fazer isso com o comando `decodepay`: ``` c$ lightning-cli --testnet decodepay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd { @@ -85,7 +85,7 @@ c$ lightning-cli --testnet decodepay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm Aqui temos o que os elementos mais relevantes significam: 1. `currency`: A moeda a ser paga; -2. `created_at`: Momento em que a fatura foi criada. O valor é dado em tempo UNIX, que é segundos desde 1970. +2. `created_at`: O momento em que a fatura foi criada. O valor é dado em tempo UNIX, que é segundos desde 1970. 3. `expiry`: O momento em que nosso node marca a fatura como inválida. O padrão é 1 hora ou 3600 segundos. 4. `payee`: A chave pública da pessoa (node) que recebe o pagamento da Lightning Network; 5. `msatoshi` e `amount_msat`: O valor de satoshis a ser pago; @@ -95,11 +95,11 @@ Aqui temos o que os elementos mais relevantes significam: > :book: ***O que são pagamentos condicionais?*** Embora os canais Lightning sejam criados entre dois participantes, vários canais podem ser conectados juntos, formando uma rede de pagamento que permite envio de valores entre todos os participantes da rede, mesmo aqueles sem um canal direto entre eles. Isso é feito usando um contrato inteligente denominado **Hashed Time Locked Contract**. -> :book: ***O que é um Hashed Time Locked Contract (HTLC)?*** Um HTLC é um pagamento condicional que usa hashlocks e timelocks para garantir a segurança do pagamento. O destinatário deve apresentar uma pré-imagem do pagamento ou gerar um comprovante criptográfico de pagamento antes de um determinado prazo, caso contrário o pagador pode cancelar o contrato gastando-o. Esses contratos são criados como saídas da **Transação de compromisso**. +> :book: ***O que é um Hashed Time Locked Contract (HTLC)?*** Um HTLC é um pagamento condicional que usa hashlocks e timelocks para garantir a segurança do pagamento. O destinatário deve apresentar uma pré-imagem do pagamento ou gerar um comprovante criptográfico de pagamento antes de um determinado prazo, caso contrário o pagador pode cancelar o contrato gastando-o. Esses contratos são criados como saídas da **Transação de Compromisso**. -> :book: ***O que é uma transação de compromisso?*** Uma transação de compromisso é uma transação que gasta a transação de financiamento original. Cada par possui a assinatura do outro par, o que significa que qualquer um pode gastar sua transação do compromisso como quiser. Depois que cada nova transação de confirmação é criada, a antiga é revogada. A transação de confirmação é uma maneira pela qual a transação de financiamento pode ser desbloqueada na blockchain, conforme discutiremos na seção [§19.3](19_3_Closing_a_Channel.md). +> :book: ***O que é uma transação de compromisso?*** Uma transação de compromisso é uma transação que gasta a transação de financiamento original. Cada par possui a assinatura do outro par, o que significa que qualquer um pode gastar sua transação do compromisso como quiser. Depois que cada nova transação de confirmação é criada, a antiga é revogada. A transação de confirmação é uma maneira pela qual a transação de financiamento pode ser desbloqueada na blockchain, conforme discutiremos na seção [§20.3](20_3_Closing_a_Channel.md). -### Verificando nosso invoice +### Verificando Nosso Invoice Existem dois elementos cruciais para verificar o invoice. O primeiro, obviamente, é o valor do pagamento, que já examinamos na parte legível. O segundo é o dado do `payee`, que é o pubkey do destinatário (node): ``` @@ -107,7 +107,7 @@ Existem dois elementos cruciais para verificar o invoice. O primeiro, obviamente ``` Precisamos verificar se ele é o destinatário esperado. -Olhando nas seções anteriores, mais precisamente na seção [§18.3](18_3_Setting_Up_a_Channel.md#opening-a-channel), podemos observar que é de fato o ID do par que usamos quando criamos nosso canal. Também podemos verificá-lo no outro node com o comando `getinfo`. +Olhando nas seções anteriores, mais precisamente na seção [§19.3](19_3_Setting_Up_a_Channel.md#opening-a-channel), podemos observar que é de fato o ID do par que usamos quando criamos nosso canal. Também podemos verificá-lo no outro node com o comando `getinfo`. ``` lnd$ lncli -n testnet getinfo { @@ -173,12 +173,12 @@ lnd$ lncli -n testnet getinfo } } ``` -No entanto, o `payee` também pode ser alguém novo, caso em que provavelmente precisaremos verificar com a pessoa que emitiu o invoice para garantir que está tudo correto. +No entanto, o `payee` também pode ser alguém novo, caso no qual provavelmente precisaremos verificar com a pessoa que emitiu o invoice para garantir que tudo está correto. ## Resumo: Gerando um Invoice -Na maioria dos casos, precisamos receber um invoice para usar os pagamentos da Lightning Network. Neste exemplo, criamos um manualmente, mas se estivermos em um ambiente de produção, provavelmente teria sistemas fazendo isso automaticamente sempre que alguém adquirir produtos ou serviços. Claro, depois de receber um invoice, precisamos saber como lê-lo! +Na maioria dos casos, precisamos receber um invoice para usar os pagamentos da Lightning Network. Neste exemplo, criamos um manualmente, mas se estivermos em um ambiente de produção, provavelmente teriam sistemas fazendo isso automaticamente sempre que alguém adquirir produtos ou serviços. Claro, depois de receber um invoice, precisamos saber como lê-lo! ## O Que Vem Depois? -Vamos continuar "Usando a Lightning" na seção [§19.2: Pagando um Invoice](06_3_Sending_an_Automated_Multisig.md). \ No newline at end of file +Vamos continuar "Usando a Lightning" na seção [§20.2: Pagando um Invoice](20_2_Paying_a_Invoice.md). \ No newline at end of file From e18d52dd9a55bb398d2ca0206d0baa3481d89e30 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 17:53:13 -0300 Subject: [PATCH 7/9] Review 20_2 --- pt/20_2_Paying_a_Invoice.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pt/20_2_Paying_a_Invoice.md b/pt/20_2_Paying_a_Invoice.md index d464dfa..3abb6d5 100644 --- a/pt/20_2_Paying_a_Invoice.md +++ b/pt/20_2_Paying_a_Invoice.md @@ -1,12 +1,12 @@ -# 19.2: Pagando um Invoice +# 20.2: Pagando um Invoice > :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 pagar um invoice usando o comando `lightning-cli pay`. Presume-se que já sabemos como analisar um invoice, de acordo com a seção [§19.1](19_1_Generate_a_Payment_Request.md) e sabemos que ele é válido. +Neste capítulo, aprenderemos como pagar um invoice usando o comando `lightning-cli pay`. Presume-se que já sabemos como analisar um invoice, de acordo com a seção [§20.1](20_1_Generate_a_Payment_Request.md), e se ele é válido. -## Verificando o saldo +## Verificando o Saldo -Obviamente, a primeira coisa que precisamos fazer é nos certificarmos de que possuímos fundos suficientes para pagar o invoice. Neste caso, o canal configurado anteriormente com `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543` contém 100.000 satoshis. Este será o canal de pagamento do inoice. +Obviamente, a primeira coisa que precisamos fazer é nos certificarmos de que possuímos fundos suficientes para pagar o invoice. Neste caso, o canal configurado anteriormente com `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543` contém 100.000 satoshis. Este será o canal de pagamento do invoice. ``` c$ lightning-cli --testnet listfunds @@ -42,7 +42,7 @@ c$ lightning-cli --testnet listfunds ``` Se não tivermos fundos suficientes, precisamos criar um novo canal. -## Pagando nosso invoice +## Pagando Nosso Invoice Vamos usar o comando `lightning-cli pay` para pagar o invoice. Ele tentará encontrar uma rota para o destino fornecido, para posteriormente enviar os fundos solicitados. Isso é muito simples porque há um canal direto entre o pagador e o destinatário: ``` @@ -60,9 +60,9 @@ c$ lightning-cli --testnet pay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk "status": "complete" } ``` -Vamos observar todos os valores que estão em `msats`, não em `sats`! +Vamos observar que todos os valores estão em `msats`, não em `sats`! -### Pagando o invoice pela Lightning +### Pagando o Invoice pela Lightning No entanto, _não_ precisamos ter um canal com um node para pagá-lo. Só precisamos ter uma rota razoável pela Lightning Network. @@ -117,13 +117,13 @@ c$ lightning-cli --testnet pay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7 "status": "complete" } ``` -Essa é a verdadeira beleza da Lightning Network: Sem nenhum esforço dos participantes ponto a ponto, nossos canais individuais se tornam uma rede! +Essa é a verdadeira beleza da Lightning Network: sem nenhum esforço dos participantes ponto a ponto, nossos canais individuais se tornam uma rede! -> :book: ***Como funcionam os pagamentos na rede?*** Digamos que o node A tem um canal aberto com o node B, o node B tem um canal aberto com o node C e o node A recebe uma fatura do node C de 11.111 msat. O node A paga ao node B 11.111 msat, mais uma pequena taxa, e então o node B paga 11.111 msat ao node C. Muito fácil. Mas lembre-se de que todos os canais são, na verdade, apenas registros de quem é o proprietário e de quanto é a Transação de Financiamento. Então o que realmente acontece é 11.111 msat da Transação de Financiamento no canal AB muda de A para B e, em seguida, 11.111 msat da Transação de Financiamento no canal BC muda de B para C. Isso significa que duas coisas são necessárias para que este pagamento funcione: Primeiro, cada canal deve ter capacidade suficiente para o pagamento e; Segundo, o pagador em cada canal deve possuir o suficiente da capacidade para fazer o pagamento. +> :book: ***Como funcionam os pagamentos na rede?*** Digamos que o node A tem um canal aberto com o node B, o node B tem um canal aberto com o node C e o node A recebe uma fatura do node C de 11.111 msat. O node A paga ao node B 11.111 msat, mais uma pequena taxa, e então o node B paga 11.111 msat ao node C. Muito fácil. Mas lembre-se de que todos os canais são, na verdade, apenas registros de quem é o proprietário e de quanto é a Transação de Financiamento. Então o que realmente acontece é 11.111 msat da Transação de Financiamento no canal AB muda de A para B e, em seguida, 11.111 msat da Transação de Financiamento no canal BC muda de B para C. Isso significa que duas coisas são necessárias para que este pagamento funcione: primeiro, cada canal deve ter capacidade suficiente para o pagamento; e segundo, o pagador em cada canal deve possuir o suficiente da capacidade para fazer o pagamento. Observe que, neste exemplo, 12.111 msat foram enviados para pagar uma fatura de 11.111 msat: o extra sendo uma taxa fixa muito pequena (não uma porcentagem) que foi paga ao intermediário. -## Verificando nosso saldo +## Verificando Nosso Saldo Após efetuar um pagamento com sucesso, veremos que nossos fundos foram alterados corretamente. @@ -160,7 +160,7 @@ c$ lightning-cli --testnet listfunds ] } ``` -Observe que a capacidade do canal permanece em 100.000 satoshis (isso nunca irá mudar!), Mas que o `our_amount` agora é de apenas 90.000 satoshis (ou 90.000.000 msat). +Observe que a capacidade do canal permanece em 100.000 satoshis (isso nunca irá mudar!), mas que o `our_amount` agora é de apenas 90.000 satoshis (ou 90.000.000 msat). Depois de pagar a segunda fatura, de 11.111 msat, os fundos mudam novamente: ``` @@ -203,4 +203,4 @@ Depois de recebermos um invoice, é fácil pagar com um único comando na Lightn ## O Que Vem Depois? -Vamos continuar "Usando a Lightning" na seção [§19.3: Fechando um Canal na Lightning](19_3_Closing_a_Channel.md). \ No newline at end of file +Vamos continuar "Usando a Lightning" na seção [§20.3: Fechando um Canal na Lightning](20_3_Closing_a_Channel.md). \ No newline at end of file From 4122c56e166df671c270f2a4637dad259ebcc378 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 18:07:04 -0300 Subject: [PATCH 8/9] Review 20_3 --- pt/20_3_Closing_a_Channel.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pt/20_3_Closing_a_Channel.md b/pt/20_3_Closing_a_Channel.md index bfb8881..15b1683 100644 --- a/pt/20_3_Closing_a_Channel.md +++ b/pt/20_3_Closing_a_Channel.md @@ -1,4 +1,4 @@ -# 19.3: Fechando um canal +# 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. @@ -6,7 +6,7 @@ Neste capítulo, aprenderemos como fechar um canal usando a interface de linha d Para fechar um canal, primeiro precisamos saber o ID do node remoto. Podemos recuperá-lo de duas maneiras. -## Encontrando nossos canais pelos saldos +## 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. ``` @@ -59,11 +59,11 @@ 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 os canais usando o JQ +## 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 os 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 do `jq`. +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`: ``` @@ -101,9 +101,9 @@ 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 +## 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. +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 { @@ -112,7 +112,7 @@ c$ lightning-cli --testnet close $nodeidremote 0 "type": "mutual" } ``` -A transação de fechamento na cadeia é [f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f] (https://blockstream.info/testnet/tx/f68de52d80a1076e36c67795f9f9db4f13048519489593f]. +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: ``` @@ -177,7 +177,7 @@ $ bitcoin-cli --named getrawtransaction txid=f68de52d80a1076e36c677ef640539c50e3 "blocktime": 1602713519 } ``` -A entrada da transação é `66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d`, que foi a transação de financiamento feita na seção [§18.3](18_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 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: @@ -226,7 +226,7 @@ $ lightning-cli --network=testnet listfunds ``` -### Compreendendo os tipos de canais de fechamento. +### 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: @@ -238,7 +238,7 @@ No caso de um fechamento cooperativo, ambos os participantes do canal concordam #### 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). +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: ``` @@ -250,10 +250,10 @@ c$ lightning-cli --network=testnet close $newidremote 60 } ``` -## Resumo: Fechando um canal +## 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 [§19.4: Expandindo a rede Lightning](19_3_Closing_a_Channel.md). \ No newline at end of file +Vamos continuar "Usando a Lightning" na seção [§20.4: Expandindo a Rede Lightning](20_4_Lightning_Network_Review.md). \ No newline at end of file From 5633bb4cd257dca09b0ea7dafb6da5824fd5202e Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 18:15:22 -0300 Subject: [PATCH 9/9] Review 20_4 --- pt/20_4_Lightning_Network_Review.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pt/20_4_Lightning_Network_Review.md b/pt/20_4_Lightning_Network_Review.md index acee240..bed52ba 100644 --- a/pt/20_4_Lightning_Network_Review.md +++ b/pt/20_4_Lightning_Network_Review.md @@ -1,10 +1,10 @@ -# 19.4: Expandindo a Lightning Network +# 20.4: Expandindo a Lightning Network > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Esses dois capítulos cobriram apenas algumas das atividades mais importantes da Lightning. Há muito mais que pode ser feito e muitas variedades possíveis. A seguir, daremos algumas dicas importantes. -## Usando plugins c-lightning +## Usando Plugins c-lightning O c-lightning é uma implementação leve, altamente personalizável e compatível com o padrão do protocolo Lightning Network. Ele estende a funcionalidade usando plugins. Principalmente, esses são subprocessos que são iniciados pelo daemon `lightningd` e podem interagir com o `lightningd` de várias maneiras: @@ -17,7 +17,7 @@ Um plugin pode ser escrito em qualquer linguagem e pode se comunicar com o `ligh O repositório `lightningd` GitHub mantém uma lista atualizada de [plugins](https://github.com/lightningd/plugins) disponíveis. -## Usando Mobile Wallets +## Usando Carteiras Mobile Atualmente, sabemos de duas carteiras de dispositivos móveis da Lightning que suportam a implementação do c-lightning. @@ -29,9 +29,9 @@ O SparkWallet é uma carteira GUI minimalista para a c-lightning, acessível pel * [SparkWallet](https://github.com/shesek/spark-wallet) -## Usando diferentes implementações da Lightning +## Usando Diferentes Implementações da Lightning -O c-lightning não é a nossa única opção. Hoje, existem três implementações amplamente utilizadas para a Lightning Network. Todos seguem as [Documentações Base para a Tecnologia Lightning (BOLT)](https://github.com/lightningnetwork/lightning-rfc), que descrevem um protocolo de segunda camada para transferências de bitcoins offchain. As especificações são atualmente um trabalho em andamento que ainda está sendo elaborado. +O c-lightning não é a nossa única opção. Hoje, existem três implementações amplamente utilizadas para a Lightning Network. Todos seguem as [Documentações Base para a Tecnologia Lightning (BOLT)](https://github.com/lightningnetwork/lightning-rfc), que descrevem um protocolo de segunda camada para transferências de bitcoins off-chain. As especificações são atualmente um trabalho em andamento que ainda está sendo elaborado. | Nome | Descrição | BitcoinStandup | Linguagem | Repositório | | ------------- | ------------- | :---: | ------------- | ------------- | @@ -39,9 +39,9 @@ O c-lightning não é a nossa única opção. Hoje, existem três implementaçõ | LND | Lightning Labs | X | Go | [Download](https://github.com/lightningnetwork/lnd) | | Eclair | ACINQ | - | Scala | [Download](https://github.com/ACINQ/eclair) | -## Fazendo backups +## Fazendo Backups -Nosso node Lightning precisa estar online o tempo todo, caso contrário, nossa contraparte pode enviar um status de canal anterior e roubar nossos fundos. No entanto, há outro cenário em que os fundos podem ser perdidos, que é quando ocorre uma falha no hardware que impede o node de estabelecer um fechamento cooperativo com a contraparte. Isso provavelmente significará que, se não tivermos uma cópia exata do estado do canal antes da falha, teremos um estado inválido que pode fazer com que o outro node o considere como uma tentativa de fraude e use a transação penalizada. Nesse caso, todos os fundos serão perdidos. Para evitar esta situação indesejável, uma solução baseada na alta disponibilidade do banco de dados postgresQL [existe](https://github.com/gabridome/docs/blob/master/c-lightning_with_postgresql_reliability.md). +Nosso node Lightning precisa estar online o tempo todo, caso contrário, nossa contraparte pode enviar um status de canal anterior e roubar nossos fundos. No entanto, há outro cenário em que os fundos podem ser perdidos, que é quando ocorre uma falha no hardware que impede o node de estabelecer um fechamento cooperativo com a contraparte. Isso provavelmente significará que, se não tivermos uma cópia exata do estado do canal antes da falha, teremos um estado inválido que pode fazer com que o outro node o considere como uma tentativa de fraude e use a transação penalizada. Nesse caso, todos os fundos serão perdidos. Para evitar esta situação indesejável, uma solução baseada na alta disponibilidade do banco de dados postgreSQL [existe](https://github.com/gabridome/docs/blob/master/c-lightning_with_postgresql_reliability.md). PS: Não testamos esta solução. @@ -51,10 +51,10 @@ Podemos usar diferentes implementações, plugins, carteiras para celular e back ## O Que Vem Depois? -Concluímos todo o livro Aprendendo sobre o Bitcoin usando a Linha de Comando, embora não precise visitar os [Apêndices](A0_Apêndices.md) que possuem configurações alternativas, podemos fazer isso agora. +Concluímos todo o livro Aprendendo sobre o Bitcoin usando a Linha de Comando. Embora não precisemos visitar os [Apêndices](A0_Appendices.md), que possuem configurações alternativas, podemos fazer isso agora. -Caso contrário, nós o encorajamos a ingressar nas comunidades de desenvolvedores e programadores e também, colocar nosso novo conhecimento para funcionar. +Caso contrário, nós o encorajamos a ingressar nas comunidades de desenvolvedores e programadores e também, colocar seu novo conhecimento para funcionar. -Também podemos nos ajudar aqui em Blockchain Commons com issues ou PRs para aprender sobre o Bitcoin ou para qualquer um de nossos outros repositórios, ou podemos até mesmo nos tornar um [patrocinador](https://github.com/sponsors/BlockchainCommons). Também podemos ajudar divulgando o trabalho, contando às pessoas nas redes sociais sobre o curso e o que aprendemos com ele! +Você também pode nos ajudar aqui na Blockchain Commons com issues ou PRs para Aprendendo Bitcoin ou para qualquer um de nossos outros repositórios, ou pode até mesmo se tornar um [patrocinador](https://github.com/sponsors/BlockchainCommons). Também pode ajudar divulgando o trabalho, contando às pessoas nas redes sociais sobre o curso e o que aprendeu com ele! Agora vá lá e faça da comunidade do Bitcoin um lugar melhor! \ No newline at end of file