From c8aeb00d64f768c684551e6443bc978be782faaa Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 15 Jun 2021 10:37:02 -1000 Subject: [PATCH 1/6] Create README.md --- pt/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 pt/README.md diff --git a/pt/README.md b/pt/README.md new file mode 100644 index 0000000..ec090a7 --- /dev/null +++ b/pt/README.md @@ -0,0 +1 @@ +_directory for the Portuguese translation._ From fbe086205431b2ff6cdb43c328668e98a65a55aa Mon Sep 17 00:00:00 2001 From: lukedevj <85752004+lukedevj@users.noreply.github.com> Date: Sun, 20 Jun 2021 17:23:50 -0300 Subject: [PATCH 2/6] Contributor License Agreement Assigned --- ...j.AB4609E35FB50FA1CA970EB1CF23EC813BBF.asc | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 signed-cla/CLA.lukedevj.AB4609E35FB50FA1CA970EB1CF23EC813BBF.asc diff --git a/signed-cla/CLA.lukedevj.AB4609E35FB50FA1CA970EB1CF23EC813BBF.asc b/signed-cla/CLA.lukedevj.AB4609E35FB50FA1CA970EB1CF23EC813BBF.asc new file mode 100644 index 0000000..b977bec --- /dev/null +++ b/signed-cla/CLA.lukedevj.AB4609E35FB50FA1CA970EB1CF23EC813BBF.asc @@ -0,0 +1,72 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +# Contributor License Agreement + +Version 1.0 + +Name: Luke Pavksy + +E-Mail: lukedevj.contact@protonmail.com + +Legal Jurisdiction: Wyoming, United States of America + +Project: https://github.com/BlockchainCommons/bc-lethe-kit + +Date: `06/20/2021` + +## Purpose + +This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time. + +## License + +I hereby license Blockchain Commons, LLC to: + +1. do anything with my contributions that would otherwise infringe my copyright in them + +2. do anything with my contributions that would otherwise infringe patents that I can or become able to license + +3. sublicense these rights to others on any terms they like + +## Reliability + +I understand that Blockchain Commons will rely on this license. I may not revoke this license. + +## Awareness + +I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it. + +## Copyright Guarantee + +I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately. + +## Patent Guarantee + +I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms. + +## Open Source Guarantee + +I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms. + +## Disclaimers + +***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.*** + +- --- + +To sign this Contributor License Agreement, fill in `Luke Pavksy`, `lukedevj.contact@protonmail.com`, and `06/20/2021` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./signed-cla/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com). +-----BEGIN PGP SIGNATURE----- + +iQGzBAEBCgAdFiEEiI+rRgnjX7UPocqXDrHPI+yBO78FAmDPoSUACgkQDrHPI+yB +O78efQv+IJG+7qrfk+DdLLDoubgxTUs9TUPf9SRbt71VM3tuSZ/qdnStbvQ6PRrl +qCm23cCIh0f/2icwzn1oVnMzVQs3qkmCJm25gkCUY0ABFW+4FsXXIL/kYmr3YV6+ +EoU5IYhTjJJ7w5hP+cjfRQfqCSArVxUHKqazYqVe2dYNydL9drrDfAZrlfksobuE ++tZmXz1ZZ1RCn1BFExSWWK0c4ZNOKJxV3sfm4EblAx8GTFHk3lQYeP+d7uOqJdrw +BdAcNzp3hYmPCdEwiZB9IC3Jlbb0uBpclB29ADdk3N87OXrA3VpImTz0f4Mf5wla +U3ZJReuqVJdWd7jWPJELZldjumEZsP4Qfg0Q44tskrukUVUAIYFngkmstpllyabm +L9VUqpXMcFCzFtBs4waeaiWuWU5I4HJCTXrgiMwyoV8oA99+Sy+JdS0UbpokjzwQ +zF9b43K6JcOWY1ZEIx0hTeg2IlqVEE/iYJw6JeiaCJHHlR/rG7A15+0zuwppkuh5 +WQp4ouPE +=M9k+ +-----END PGP SIGNATURE----- From 8b3b5688505007c360cdc84ea6585c64f873da40 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 11:19:30 -0300 Subject: [PATCH 3/6] Chapter 04 translated Translation: Finished Revision: Needed --- pt/04_0_Sending_Bitcoin_Transactions.md | 30 ++ pt/04_1_Sending_Coins_The_Easy_Way.md | 102 +++++ pt/04_2_Creating_a_Raw_Transaction.md | 274 +++++++++++ pt/04_2__Interlude_Using_JQ.md | 429 ++++++++++++++++++ ..._a_Raw_Transaction_with_Named_Arguments.md | 97 ++++ ..._4_Sending_Coins_with_a_Raw_Transaction.md | 187 ++++++++ pt/04_4__Interlude_Using_Curl.md | 314 +++++++++++++ ...g_Coins_with_Automated_Raw_Transactions.md | 171 +++++++ pt/04_6_Creating_a_Segwit_Transaction.md | 288 ++++++++++++ 9 files changed, 1892 insertions(+) create mode 100644 pt/04_0_Sending_Bitcoin_Transactions.md create mode 100644 pt/04_1_Sending_Coins_The_Easy_Way.md create mode 100644 pt/04_2_Creating_a_Raw_Transaction.md create mode 100644 pt/04_2__Interlude_Using_JQ.md create mode 100644 pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md create mode 100644 pt/04_4_Sending_Coins_with_a_Raw_Transaction.md create mode 100644 pt/04_4__Interlude_Using_Curl.md create mode 100644 pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md create mode 100644 pt/04_6_Creating_a_Segwit_Transaction.md diff --git a/pt/04_0_Sending_Bitcoin_Transactions.md b/pt/04_0_Sending_Bitcoin_Transactions.md new file mode 100644 index 0000000..5c3babe --- /dev/null +++ b/pt/04_0_Sending_Bitcoin_Transactions.md @@ -0,0 +1,30 @@ + +# Capítulo 4: Enviando transações no Bitcoin + +Este capítulo descreve três métodos diferentes para enviar bitcoins para endereços P2PKH normais à partir da linha de comando, usando apenas o ```bitcoin-cli```. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Decidir como enviar dinheiro usando o Bitcoin; + * Criar uma transação bruta; + * Usar a aritmética para calcular as taxas. + +Os objetivos secundários incluem a capacidade de: + + * Compreender transações e taxas de transação; + * Entender as transações ```legacy``` e ```SegWit```; + * Usar métodos básicos para enviar dinheiro; + * Usar métodos de cálculo de taxa automática para enviar dinheiro; + * Entender os perigos de transações brutas. + +## Tabela de Conteúdo + + * [Seção 1: Enviando bitcoins no modo easy](04_1_Sending_Coins_The_Easy_Way.md) + * [Seção 2: Criando uma transação bruta](04_2_Creating_a_Raw_Transaction.md) + * [Prefácio: Usando o JQ](04_2__Interlude_Using_JQ.md) + * [Seção 3: Criando uma transação bruta com argumentos nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) + * [Seção 4: Enviando bitcoins usando transações brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md) + * [Seção 5: Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) + * [Seção 6: Criando uma transação do tipo SegWit](04_6_Creating_a_Segwit_Transaction.md) \ No newline at end of file diff --git a/pt/04_1_Sending_Coins_The_Easy_Way.md b/pt/04_1_Sending_Coins_The_Easy_Way.md new file mode 100644 index 0000000..6131040 --- /dev/null +++ b/pt/04_1_Sending_Coins_The_Easy_Way.md @@ -0,0 +1,102 @@ +# 4.1: Enviando bitcoins no modo easy + +O ```bitcoin-cli``` oferece três principais maneiras de enviar bitcoins: Utilizando um simples comando; Utilizando uma transação bruta e; Utilizando uma transação bruta com cálculos. Cada um possui seus prós e contras. Este primeiro método de envio será o mais simples. + +## Definindo sua taxa de transação + +Antes de enviar qualquer bitcoin pela rede, devemos pensar sobre as taxas de transação que iremos pagar. + +> :book: ***O que é uma taxa de transação?*** Não existe almoço grátis. Os mineradores adicionam as transações nos blocos porque são pagos para fazer isso. Eles não apenas são pagos pela rede para criar o bloco, mas também são pagos pelas pessoas que realizam as transações para incluí-las na blockchain. Se não pagarmos a taxa, nossa transação pode ficar travada... Para sempre (ou, até que seja salva por alguns dos truques que falaremos no [capítulo cinco](05_0_Controlling_Bitcoin_Transactions.md)). + +Ao usar métodos simples e automatizados para criar transações, conforme descrito aqui e na sessão [§4.5: Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), o Bitcoin calculará as taxas de transação para nós. Isso é feito usando taxas flutuantes, onde o ```bitcoind``` observa quanto tempo as transações estão demorando para confirmar e calcula automaticamente o que devemos gastar. + +Podemos ter um controle dessas informações colocando os valores racionais no nosso arquivo ```~/.bitcoin/bitcoin.conf```. Os valores de baixo custo a seguir garantiriam que houvesse uma taxa de transação mínima de 10.000 satoshis por kByte de dados em nossa transação e solicitariam que as taxas flutuantes calculassem uma boa quantia para colocar a nossa transação nos próximos seis blocos. +``` +mintxfee=0.0001 +txconfirmtarget=6 +``` +No entanto, como iremos partir do pressuposto que ninguém que esteja fazendo este tutorial queira esperar para as transações serem confirmadas, vamos adotar os seguintes valores: +``` +mintxfee=0.001 +txconfirmtarget=1 +``` +Devemos inseri-los no arquivo ```~/.bitcoin/bitcoin.conf```, na seção principal, no início do arquivo ou se quisermos ter a certeza de nunca iremos utilizá-lo em outro lugar, podemos colocar na sessão ```[test]```. + +Para trabalharmos neste tutorial, estamos dispostos a gastar 100.000 satoshis por kB em cada transação, e queremos colocar cada transação no próximo bloco! Para colocar isso em uma perspectiva para melhor entendimento, uma transação simples é executada com um tamanho de 0,25 KB a 1 KB, então estaremos pagando algo em torno de 25 mil a 100 mil satoshis, sendo que atualmente, taxas acima de 10 mil são consideradas altíssimas para transações de quantidade média. + +Depois de editar o arquivo ```bitcoin.conf```, vamos reiniciar o bitcoind usando dois comandos: +``` +$ bitcoin-cli stop +$ bitcoind -daemon +``` + +## Obtendo um endereço + +Precisamos encontrar algum endereço para enviar nossas moedas. Normalmente, alguém nos envia em um endereço e talvez nos dê uma assinatura para provar que é o proprietário desse endereço. Como alternativa, podemos nos fornecer um QR code para que possamos digitalizar, evitando assim possíveis erros de digitação na hora de colocar o endereço no local do destinatário. Em nosso caso, vamos enviar os bitcoins para `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, que é o endereço de retorno de um antigo fauce da rede Testenet. + +> :book: ***O que é um QR code?*** Um QR code é apenas um jeito diferente de passar o endereço Bitcoin. Muitas carteiras geram os QR codes para nós, enquanto alguns sites tentam convertê-los em um endereço usando o QR code. Obviamente, só podemos aceitar um QR code de um site no qual confiamos. Um pagador pode usar um leitor de código de barras para ler o código QR e, em seguida, pagá-lo. + +## Enviando os bitcoins + +Agora estamos prontos para enviar alguns bitcoins. Na verdade, isso é bastante simples por meio da linha de comando. Basta usar ```bitcoin-cli sendtoaddress [endereço] [quantidade]```. Portanto, para enviar uns satoshinhos para o endereço `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, basta fazer o seguinte: +``` +$ txid=$(bitcoin-cli sendtoaddress n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi 0.001) +$ echo $txid +93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8 +``` + +> 🙏 Para ajudar a manter os faucets da rede de testes vivos, tente usar o endereço que nos foi enviado os bitcoins no capítulo anterior, onde falamos sobre os recebimentos de transações. + +Precisamos nos certificar de que o endereço digitado é o lugar para onde desejamos enviá-lo. Por isso, certifique-se _duas vezes_. Se cometermos algum erro no Bitcoin, não há como voltar atrás. + +Iremos receber um txid de retorno quando usarmos este comando. + +> ❕ Você pode acabar com um código de erro se não tivermos bitcoins suficientes na carteira para fazer a transação. Dependendo do nosso saldo atual, que podemos acessar usando o ```bitcoin-cli getbalance```, pode ser necessário ajustar o valor que iremos enviar para que bata com o valor que está sendo enviado, não se esquecendo da taxa de transação no meio deste processo. Se o nosso saldo atual for 0,001, podemos tentar enviar 0,0001. Como alternativa, seria melhor tirar a taxa que esperamos pagar que foi enviada na mensagem de erro do nosso saldo atual. Esta é uma boa prática, pois muitas carteiras esperam que calculemos nosso próprio valor + taxas ao fazermos as transações, mesmo as carteiras mais populares usam essa premissa. + +> :warning: **ATENÇÃO:** O comando ```bitcoin-cli``` realmente gera comandos usando o JSON-RPC quando está se comunicando com o bitcoind. Eles podem ser muito exigentes. Este é um exemplo: Se listarmos a quantidade de bitcoin sem o zero à esquerda (ou seja usando ".1" em vez de "0.1"), o ```bitcoin-cli``` irá acusar um erro com uma mensagem misteriosa. + +> :warning: **ATENÇÃO:** Mesmo se formos cuidadosos com nossos dados, é possível que haja este erro: _"Fee estimation failed. Fallbackfee is disabled"_. De maneira geral, isso significa que nosso ```bitcoind``` local não tem informações suficientes para estimar as taxas. Não é para vermos isso se estivermos esperado que nossa blockchain sincronize e configure nosso sistema com o Bitcoin Standup. Mas se não estivermos totalmente sincronizados, podemos nos deparar com este erro. Também pode ser que não estejamos usando um ```bitcoin.conf``` padrão: A informação ```blocksonly = 1``` fará com que nosso ```bitcoind``` não consiga estimar as taxas. + +## Examinando nossa transação + +Podemos ver nossa transação usando o ID de transação: +``` +{ + "amount": -0.00100000, + "fee": -0.00022200, + "confirmations": 0, + "trusted": true, + "txid": "93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8", + "walletconflicts": [ + ], + "time": 1592604194, + "timereceived": 1592604194, + "bip125-replaceable": "no", + "details": [ + { + "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", + "category": "send", + "amount": -0.00100000, + "vout": 1, + "fee": -0.00022200, + "abandoned": false + } + ], + "hex": "0200000001e982921bb0189afc486e20bb05cc5825c71a0ba8868043ed04ece9ab0cb12a8e010000006a47304402200fc493a01c5c9d9574f7c321cee6880f7f1df847be71039e2d996f7f75c17b3d02203057f5baa48745ba7ab5f1d4eed11585bd8beab838b1ca03a4138516fe52b3b8012102fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9bafeffffff02e8640d0000000000160014d37b6ae4a917bcc873f6395741155f565e2dc7c4a0860100000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac780b1b00" +} +``` +Você pode ver não apenas o valor transferido (0,001 BTC), mas também uma taxa de transação (0,000222 BTC), que é cerca de um quarto da taxa mínima de 0,001 BTC/kB que foi definida, o que sugere que a transação foi de cerca de um quarto de kB de tamanho. + +Enquanto esperamos que ela seja confirmada, podemos notar que o ```bitcoin-cli getbalance``` mostra que nosso dinheiro já foi debitado. Da mesma forma, o ```bitcoin-cli listunspent``` mostrará que uma transação inteira foi perdida, mesmo que fosse mais do que o que queríamos enviar. Há uma razão para isso: Sempre que temos moedas entrando, precisamos enviar _tudo_ junto, e temos que fazer um pouco de malabarismos se quisermos realmente ficar com parte dele! Mais uma vez, o ```sendtoaddress``` cuida de tudo isso para nós, o que significa que não precisamos nos preocupar em fazer qualquer alteração até enviar uma transação bruta. Nesse caso, uma nova transação aparecerá com nossa alteração quando nosso envio for incorporado a um bloco. + +## Resumo do Enviando bitcoins no modo easy + +Para enviar moedas facilmente, precisamos nos certificar de que nossos padrões de transação sejam racionais, obtendo um endereço e enviando as nossas moedas para lá. É por isso que esse modo é o mais fácil deles! + +> :fire: ***Qual é o poder de enviar moedas no modo easy?*** +> _As vantagens._ É fácil. Não precisamos nos preocupar com coisas misteriosas como UTXOs. Não precisamos calcular as taxas de transação manualmente, então, é provável que não iremos cometer erros que custem grandes valores Se o nosso único objetivo é sentar na frente do computador e enviar alguns bitcoins, este é o caminho certo para fazer isso. +> _As desvantagens._ É alto nível. Temos muito pouco controle sobre o que está acontecendo e não podemos fazer nada demais. Se estamos planejando desenvolver um software mais complexo utilizando o Bitcoin ou se desejamos um entendimento mais profundo de como o Bitcoin funciona, então o modo easy é apenas um carrossel sem graça antes de chegarmos nas montanhas russas. + +## O Que Vem Depois? + +Vamos continuar "Enviando Transações de Bitcoin" na sessão [§4.2 Criando uma transação bruta](04_2_Creating_a_Raw_Transaction.md). \ No newline at end of file diff --git a/pt/04_2_Creating_a_Raw_Transaction.md b/pt/04_2_Creating_a_Raw_Transaction.md new file mode 100644 index 0000000..4a5f0b6 --- /dev/null +++ b/pt/04_2_Creating_a_Raw_Transaction.md @@ -0,0 +1,274 @@ +# 4.2 Criando uma transação bruta + +Agora estamos pronto para criar transações brutas no Bitcoin. Isso permite que enviemos dinheiro, mas criemos as transações com a precisão desejada. Nesta primeira seção, iremos nos concentrar em uma transação simples de uma entrada e uma saída. Este tipo de transação _não_ é realmente útil, porque raramente vamos querer enviar todo o nosso dinheiro para uma pessoa (a menos que estejamos apenas encaminhando, como se estivesse movendo coisas de uma carteira para outra). Portanto, esse _não é o melhor método_ para enviar dinheiro. É apenas um conteúdo fundamental para _realmente_ enviar dinheiro com uma transação bruta. + +## Compreendendo a transação no Bitcoin + +Antes de mergulhar na criação de transações brutas, devemos nos certificar de que entendemos como uma transação no Bitcoin funciona. Tudo gira entorno dos UTXOs. + +> :book: ***O que é um UTXO?*** Quando recebemos dinheiro em nossa carteira Bitcoin, ele aparece como uma transação individual. Cada uma dessas transações é chamada de saída de transação não gasta (Unspent Transaction Output em inglês, mais conhecida como UTXO). Não importa se vários pagamentos foram feitos para o mesmo endereço ou para vários endereços: Cada transação recebida permanece distinta na carteira como um UTXO. + +Ao criarmos uma nova transação de saída, reunimos um ou mais UTXOs, cada um representando um pouquinho do dinheiro que recebemos. Nós os usamos como entradas para uma nova transação. Juntos, o valor deles deve ser igual ao que desejamos gastar _ou mais do que o total_. Em seguida, geramos uma ou mais saídas, que dão o dinheiro representado pelas entradas a uma ou mais pessoas. Isso cria novos UTXOs para os destinatários, que podem então usá-los para financiar transações futuras. + +Aqui está o truque: _Todos os UTXOs que coletarmos são gastos na íntegra!_ Isso significa que se quisermos enviar apenas parte do dinheiro em um UTXO para outra pessoa, também precisamos gerar uma saída adicional que envia o resto para nós! Por enquanto, não vamos nos preocupar com isso, mas o uso de um endereço de mudança será vital ao passar da teoria deste capítulo para transações mais práticas. + +## Listando as transações não gastas + +Para criar uma nova transação bruta, devemos saber quais UTXOs estão disponíveis para gastar. Podemos determinar essas informações com o comando ```bitcoin-cli listunspent```: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 20, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + }, + { + "txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a", + "vout": 1, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00050000, + "confirmations": 3, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 3, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] + +``` +Esta lista mostra três UTXOs diferentes, no valor de 0,0001, 0,0005 e 0,00022 BTC. Observe que cada um tem o próprio _txid_ distinto e permanece seperado na carteira, até mesmo os dois últimos, que foram enviados para o mesmo endereço. + +Quando quisermos gastar um UTXO, não é suficiente apenas saber o id da transação. Isso porque cada transação pode ter várias saídas! Lembra daquele primeiro valor que o faucet nos enviou? Na transação, parte do dinheiro foi para nós e parte para outra pessoa. O ```txid``` se refere à transação geral, enquanto um ```vout``` diz qual das múltiplas saídas recebemos. Nesta lista, cada uma dessas transações é a primeira ```vout``` de uma transação anterior, mas _não necessariamente é sempre o caso_. + +Portanto, o txid+vout=UTXO. Essa será a base de qualquer transação bruta. + +## Escrevendo uma transação bruta com uma saída + +You're now ready to write a simple, example raw transaction that shows how to send the entirety of a UTXO to another party. As noted, this is not necessarily a very realistic real-world case. +Agora estamos prontos para escrever um exemplo simples de transação bruta que mostra como enviar um UTXO inteiro para outra parte. Conforme falamos anteriormente, este não é um caso muito realista. + +> :warning: **Atenção:** É muito fácil perder dinheiro com uma transação bruta. Considere que todas as instruções sobre como enviar bitcoins por meio de transações brutas são _muito_, _muito_ perigosas. Sempre que estiver enviando moedas na _mainnet_ para outras pessoas, devemos usar um dos outros métodos explicados neste capítulo. Criar transações brutas é extremamente útil se estivermos escrevendo programas para o bitcoin, mas _só_ neste caso. Por exemplo: Ao escrever este exemplo para uma versão anterior deste tutorial, acidentalmente gastamos a transação errada, embora tivessemos cerca de 10 vezes mais. Quase tudo isso foi enviado para os mineradores. + +### Preparando a transação bruta + +Para as melhores práticas, iremos começar cada transação registrando cuidadosamente os txids e vouts que iremos gastar. + +Nesse caso, vamos gastar um no valor de 0,00050000 BTC porque é o único com um valor decente. +``` +$ utxo_txid="61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a" +$ utxo_vout="1" +``` +Da mesma forma, devemos registrar o endereço do destinatário para ter certeza de que está correto. No nosso exemplo estamos enviando novamente o saldo de volta para o faucet: +``` +$ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" +``` +Como de prache, vamos verificar as variáveis com cuidado, para ter certeza de que são aquilo que esperamos! +``` +$ echo $utxo_txid +61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a +$ echo $utxo_vout +1 +$ echo $recipient +n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi +``` +Esse destinatário é particularmente importante, porque se bagunçarmos tudo, nosso dinheiro terá dado _tchau tchau_! E como já vimos, escolher a transação errada pode resultar em perda de dinheiro! Portanto, vamos verificar tudo, pelo menos uma vez mais do que a quantidade de costume. + +### Entendendo a taxa de transação + +Cada transação tem uma taxa associada. Ela fica _implícita_ quando enviamos uma transação bruta: O valor que vamos pagar como taxa é sempre igual ao valor de entrada menos o valor de saída. Portanto, temos que diminuir um pouco o valor enviado para ter certeza de que nossa transação será realizada. + +> :warning: **Atenção:** Esta é a parte muito perigosa das transações brutas! Como gastamos automaticamente toda a quantidade de UTXOs que tivermos, é extremamente importante certificar-se de que sabemos: (1) Precisamente quais UTXOs estamos utilizando; (2) Exatamente quanto dinheiro ele possui; (3) Exatamente quanto dinheiro estamos enviando; e (4) qual é a diferença que ficará para os mineradores. Se errarmos e, por exemplo, usarmos o UTXO errado (um que tenha mais dinheiro do que pensávamos) ou se enviarmos muito pouco dinheiro, o excesso será perdido. _Para sempre_! Não podemos cometer esse erro! Por isso, é importante sabermos as entradas e saídas com _precisão_. Ou melhor, não utilizarmos as transações brutas, exceto como parte de um programa cuidadosamente considerado e verificado três vezes. + +> :book: ***Quanto devemos gastar com taxas de transação?*** [Bitcoin Fees](https://bitcoinfees.21.co/) tem uma ótima avaliação ao vivo. O site diz que "fastest and cheapest transaction fee is currently XXX satoshis/byte" onde o XXX será a quantidade de satoshis por byte que precisaremos pagar e também, "For the median transaction size of YYY bytes, this results in a fee of ZZ,ZZZ satoshis", onde YYY é o tamanho de uma transação média e ZZ,ZZZ é o resultado da multiplicação entre YYY e XXX. No caso, precisamos apenas observar o valor ZZ,ZZZ descrito no site. + +No momento em que este tutorial está sendo escrito, o _Bitcoin Fees_ sugere uma taxa de transação de cerca de 10.000 satoshis, que é o mesmo que 0,0001 BTC. Obviamente, isso é para a mainnet, não para a testnet, mas queremos testar as coisas de forma realista, então iremos utilizar esta quantidade. + +Nesse caso, isso vamos pegar 0,0005 BTC no UTXO que selecionamos, reduzindo a quantidade de 0,0001 BTC para a taxa de transação e enviar os 0,0004 BTC restantes. E este é um exemplo do porque os micropagamentos não funcionam na rede principal do Bitcoin, porque uma taxa de transação que consome 20% do valor enviado é muito cara, agora imagina se os valores forem menores do que a taxa de transação. Por isso que temos a Lightning. + +> :warning: **Atenção:** Quanto menor for a taxa de transação, mais tempo irá demorar para que nossa transação entre na blockchain. O site _Bitcoin Fees_ lista os tempos que precisaremos esperar em relação a quantidade de satoshi por byte. Como os blocos são construídos em média a cada 10 minutos, a mudança de taxa pode significar uma mudança de espera de minutos para algumas horas ou dias! Portanto, escolha uma taxa de transação apropriada para o que estamos enviando. É importante observar que nunca devemos colocar taxas abaixo da quantidade mínima para transação, que é 0,0001 BTC. + +### Escrevendo a transação bruta + +Agora estamos prontos para criar a transação bruta. Usaremos o comando ```createrawtransaction```, que pode parecer um pouco intimidante. Isso porque o comando ```createrawtransaction``` não o protege inteiramente do JSON RPC que o ```bitcoin-cli``` utiliza. Ao invés disso, vamos inserir uma matriz JSON para listar os UTXOs que está gastando e um objeto JSON para listar as saídas. + +Este é o formato padrão: +``` +$ bitcoin-cli createrawtransaction +'''[ + { + "txid": "'$your_txid'", + "vout": '$your_vout' + } +]''' +'''{ + "'$your_recipient'": bitcoin_amount + }''' +``` + + Não, não é um erro de digitação. Existem todos os tipos de citações malucas, mas confie que elas farão a coisa certa. Vamos usar `'''` para marcar o início e o fim do array e no objeto JSON. Protegendo as palavras normais como ```"this"```, mas não precisamos proteger os números: ```0```. Se forem variáveis, vamos inserir as aspas simples, como ```"'$this_word'"``` e ```'$this_num'```. (Ufa! Não se preocupe, você pega o jeito). + + Aqui está um comando que cria uma transação bruta para enviar $utxo para o $recipient. +``` +$ rawtxhex=$(bitcoin-cli createrawtransaction '''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' '''{ "'$recipient'": 0.0004 }''') +$ echo $rawtxhex +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f3610100000000ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +``` + +### Verificando a transação bruta + +Depois disso, devemos verificar a transação bruta com o comando ```decoderawtransaction``` para ter certeza de que faremos a coisa certa. +``` +$ bitcoin-cli decoderawtransaction $rawtxhex +{ + "txid": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298", + "hash": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298", + "version": 2, + "size": 85, + "vsize": 85, + "weight": 340, + "locktime": 0, + "vin": [ + { + "txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00040000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + ] + } + } + ] +} +``` + +É importante verificarmos o ```vin```. Estamos gastando a transação certa? Ela contém a quantia de dinheiro esperada? (Vamos verificar com o comando ```bitcoin-cli gettransaction``` e nos certificar de olhar o ```vout``` se está correto). Além disso, vamos verificar o nosso ```vout```. Estamos enviando a quantidade correta? Está indo para o endereço certo? Finalmente, vamos fazer as contas para ter certeza de que o dinheiro que irá para as taxas está correto. O valor do UTXO menos a quantia que está sendo gasta é igual à taxa da transação esperada? + +> :information_source: **NOTA:** Podemos notar que cada entrada tem um número de sequência, definido aqui como 4294967295, que é 0xFFFFFFFF. Esta é a última fronteira das transações Bitcoin, porque é um campo padrão em transações que foram originalmente planejadas para um propósito específico, mas nunca foram totalmente implementadas. Portanto, agora existe esse inteiro parado em transações que podem ser reaproveitadas para outros usos. E, de fato, tem sido. No momento em que este livro foi escrito, havia três usos diferentes para a variável chamada ```nSequence``` no código Bitcoin Core: Ela habilita a possibilidade de RBF, ```nLockTime``` e timelocks relativos. Se não houver nada de estranho acontecendo, o ```nSequence``` será definido como 4294967295. Ajustar para um valor mais baixo sinaliza que coisas especiais estão acontecendo. + +### Assinando a transação bruta + +Até o momento, nossa transação bruta é apenas uma teoria: _Podemos_ enviá-la, mas nada irá acontecer. Precisamos fazer algumas coisas para colocá-la na rede. + +Primeiro, precisamos assinar nossa transação bruta: +``` + +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex +{ + "hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", + "complete": true +} +$ signedtx="02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000" +``` +Observe que capturamos o hexadecimal assinado manualmente, ao invés de tentar analisá-lo a partir do objeto JSON. Um pacote de software chamado "JQ" poderia ter um desempenho melhor, como explicaremos no próximo prefácio. + +### Enviando a transação bruta + +Agora temos uma transação bruta pronta para ser usada, mas nada acontece com ela se não a colocarmos na rede, o que iremos fazer com o comando ```sendrawtransaction```. O retorno dele será uma txid: +``` +$ bitcoin-cli sendrawtransaction $signedtx +a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a +``` +Iremos observar imediatamente que o UTXO e o as nossas moedas foram removidas da nossa carteira: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 23, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 6, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] + +$ bitcoin-cli getbalance +0.00032000 +``` +Logo o ```listtransactions``` deve mostrar uma transação confirmada da categoria 'send'. +``` + { + "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", + "category": "send", + "amount": -0.00040000, + "vout": 0, + "fee": -0.00010000, + "confirmations": 1, + "trusted": true, + "txid": "a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a", + "walletconflicts": [ + ], + "time": 1592608574, + "timereceived": 1592608574, + "bip125-replaceable": "no", + "abandoned": false + } +``` +Podemos observar que ele corresponde aos endereços ```txid``` e ```recipient``` (recebedor). Não só mostra o ```amount``` (montante) enviado, mas também mostra a ```fee``` (taxa) da transação. E, a transação já recebeu uma confirmação, porque oferecemos uma taxa que seria colocado no próximo bloco. + +Parabéns! Estamos um pouco mais pobres agora! + +## Resumo do Criando uma transação bruta + +Quando satoshinhos entram na nossa carteira Bitcoin, eles permanecem em quantidades distintas, chamadas de UTXOs. Ao criar uma transação bruta para enviar as moedas, usamos um ou mais UTXOs para financiá-la. Podemos então, criar uma transação bruta, assiná-la e enviá-la pela rede Bitcoin. No entanto, esta é apenas uma base do que realmente acontece: Geralmente precisaremos criar uma transação bruta com várias saídas para realmente enviar algo na rede Bitcoin! + +## O que vem depois? + +Vamos fazer uma pausa do "Enviando transações de Bitcoin" para lermos o [Interlúdio: Usando JQ](04_2__Interlude_Using_JQ.md). \ No newline at end of file diff --git a/pt/04_2__Interlude_Using_JQ.md b/pt/04_2__Interlude_Using_JQ.md new file mode 100644 index 0000000..00b46cf --- /dev/null +++ b/pt/04_2__Interlude_Using_JQ.md @@ -0,0 +1,429 @@ +# Prefácio: Usando o JQ + +A criação de uma transação bruta revelou como resultados mais complexos do ```bitcoin-cli``` que não podem ser salvos facilmente em variáveis de linha de comando. A resposta para isso e usar o JQ, que permite filtrar elementos individuais de dados JSON mais complexos. + +## Instalando o JQ + +O JQ está disponível em um [repositório no Github](https://stedolan.github.io/jq/). Basta fazermos o download para Linux, OS X ou Windows, de acordo com o seu sistema operacional. + +Depois de baixar o binário, podemos instalá-lo em nosso sistema. Se estivermos trabalhando em um VPS Debian, fazendo o passo a passo desse curso, nossa instalação será parecida com esta: +``` +$ mv jq-linux64 jq +$ sudo /usr/bin/install -m 0755 -o root -g root -t /usr/local/bin jq +``` +> :book: ***O que é o JQ?*** O repositório explica melhor, dizendo "O jq é como o sed para dados o JSON - você pode usá-lo para dividir, filtrar, mapear e transformar dados estruturados com a mesma facilidade que o sed, awk, grep e permitem que você brinque com o texto". + +## Usando o JQ para acessar um valor do objeto JSON pelo índice + +**Caso de uso:** _Capturando o hex de uma transação bruta assinada._ + +Na seção anterior, o uso de ```signrawtransaction``` não pareceu ser um bom método devido ao fato de não ser capaz de capturar os dados facilmente em variáveis devido a seu retorno no formato JSON: +``` +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex +{ + "hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", + "complete": true +} +``` +Felizmente, o JQ pode facilmente capturar os dados desse tipo! + +Para usar o JQ, vamos executar ```jq``` no backend de um pipe e sempre usar a invocação padrão que é ```jq -r '.'```. O ```-r``` diz ao JQ para diminuir a saída bruta, que funcionará para variáveis de linha de comando, enquanto o ```.``` diz ao JQ para mostrar na tela Protegemos esse argumento com ```''``` porque precisaremos dessa proteção mais tarde conforme nossas invocações ```JQ``` se tornarem mais complexas. + +Para capturar um valor específico de um objeto JSON, basta listar o índice após o ```.```: +``` +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex' +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +``` +Com essa ferramenta em mãos, podemos capturar as informações dos objetos JSON para variáveis na linha de comando: +``` +$ signedtx=$(bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex') +$ echo $signedtx +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +``` +Podemos usar então essas variáveis facilmente e sem erros: +``` +$ bitcoin-cli sendrawtransaction $signedtx +3f9ccb6e16663e66dc119de1866610cc4f7a83079bfec2abf0598ed3adf10a78 +``` +## Usando o JQ para acessar valores únicos do objeto JSON em um array usando o índice + +**Caso de uso:** _Capturando o txid e o vout para um UTXO selecionado._ + +Extrair dados de um objeto JSON é fácil, mas e se esse objeto JSON estiver em uma matriz JSON? O comando ```listunspent``` oferece um ótimo exemplo, porque geralmente contém várias transações diferentes. E se quisermos capturar as informações específicas de _um_ deles? + +Ao trabalhar com um array JSON, a primeira coisa que precisamos fazer é informar ao JQ qual índice acessar. Por exemplo, podemos estar olhando nossas transações no ```listunspent``` e decidimos que queremos trabalhar com a segunda. Podemos usar o ```'. [1]'``` para acessar o primeiro elemento. O ```[]``` diz que estamos referenciando um array JSON e o ```0``` diz que queremos o índice 0. +``` +$ bitcoin-cli listunspent | jq -r '.[1]' +{ + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022, + "confirmations": 9, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true +} +``` +Podemos então capturar um valor individual dessa matriz (1) selecionada usando um pipe _dentro_ dos argumentos JQ; e então o (2) solicitando o valor específico posteriormente, como no exemplo anterior. Isso iria capturar o ```txid``` do primeiro objeto JSON na matriz JSON produzida pelo comando ```listunspent```: +``` +$ bitcoin-cli listunspent | jq -r '.[1] | .txid' +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c +``` +Observe cuidadosamente como os ```''``` circundam toda a expressão JQ _incluindo_ o pipe. + +Este método pode ser usado para preencher variáveis para um UTXO que desejamos utilizar: +``` +$ newtxid=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') +$ newvout=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') +$ echo $newtxid +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c +$ echo $newvout +0 +``` +Pronto! Agora podemos criar uma nova transação bruta usando nosso primeiro UTXO como entrada, sem ter que digitar qualquer uma das informações do UTXO manualmente! + +## Usando o JQ para acessar valores dos objetos JSON correspondentes em um array usando os índices + +**Caso de uso:** _Listar o valor de todos os UTXOs._ + +Ao invés de acessar um único valor específico em um objeto JSON específico, podemos acessar todos os valores específicos em todos os objetos JSON. Isso é feito com ```. []```, Onde nenhum índice é especificado. Por exemplo, podemos listar todos os saldos não gastos: +``` +$ bitcoin-cli listunspent | jq -r '.[] | .amount' +0.0001 +0.00022 +``` + +## Usando o JQ para cálculos simples usando índices + +**Caso de uso:** _Adicionando o valor de todos os UTXOs não gastos._ + +Neste ponto, podemos começar a usar o retorno do JQ para fazermos uma matemática simples. Por exemplo, somar os valores dessas transações não gastas com um script ```awk``` simples nos daria o equivalente ao ```getbalance```: +``` +$ bitcoin-cli listunspent | jq -r '.[] | .amount' | awk '{s+=$1} END {print s}' +0.00032 +$ bitcoin-cli getbalance +0.00032000 +``` + +## Usando o JQ para exibir vários valores de um objeto JSON em um array usando vários índice + +**Caso de uso:** _Listar as informações de uso para todos os UTXOs._ + +O JQ pode capturar facilmente elementos individuais de objetos JSON e arrays e colocar os elementos em variáveis. Esse será o principal uso que iremos fazer nas seções futuras. No entanto, ele também pode ser usado para reduzir grandes quantidades de informações geradas pelo ```bitcoin-cli``` em quantidades razoáveis de informações. + +Por exemplo, podemos querer ver uma lista de todos os nossos UTXOs (```. []```) E obter uma lista de todas as informações mais importantes (```.txid, .vout, .amount```): +``` +$ bitcoin-cli listunspent | jq -r '.[] | .txid, .vout, .amount' +ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36 +0 +0.0001 +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c +0 +0.00022 +``` +Isso torna mais fácil decidir quais UTXOs gastar em uma transação bruta, mas não é muito bonito. + +Felizmente, o JQ também permite que sejamos mais sofisticados. Podemos usar as ```{}``` para criar novos objetos JSON (para análise adicional ou para um retorno mais bonito). Também podemos definir o nome da nova chave para cada um dos valores. A saída resultante deve ser muito mais intuitiva e menos sujeita a erros (embora, menos útil para jogar as informações diretamente nas variáveis). + +O exemplo a seguir mostra exatamente a mesma análise do ```listunspent```, mas com cada objeto JSON antigo reconstruído como um novo objeto JSON abreviado, com todos os novos valores nomeados com os índices antigos: +``` +$ bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }' +{ + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "amount": 0.0001 +} +{ + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "amount": 0.00022 +} +``` +Podemos, é claro, renomear nossos novos índices conforme acharmos necessário. Não há nada de mágico nos nomes originais: +``` +$ bitcoin-cli listunspent | jq -r '.[] | { tx: .txid, output: .vout, bitcoins: .amount }' +{ + "tx": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "output": 0, + "bitcoins": 0.0001 +} +{ + "tx": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "output": 0, + "bitcoins": 0.00022 +} +``` +## Usando o JQ para acessar os objetos JSON usando um valor pesquisado + +**Caso de uso:** _Pesquisando automaticamente os UTXOs que estão sendo usados em uma transação._ + +As pesquisas JQ até agora são bastante simples: Usamos um índice para pesquisar um ou mais valores em um objeto JSON ou no array. Mas e se quisermos pesquisar um valor em um objeto JSON... usando outro valor? Esse tipo de pesquisa indireta tem aplicabilidade real quando estamos trabalhando com transações criadas usando as UTXOs existentes. Por exemplo, podemos calcular o valor da soma dos UTXOs sendo usados em uma transação, algo de vital importância. + +Este exemplo usa a seguinte transação bruta. Podemos observar que esta é uma transação bruta mais complexa com duas entradas e duas saídas. Aprenderemos como fazer isso nas próximas sessões, mas por enquanto, é necessário sermos capazes de oferecer exemplos robustos. Observe que, ao contrário dos nossos exemplos anteriores, neste, temos dois objetos em nosso array ```vin``` e dois em nosso array ```vout```. +``` +$ bitcoin-cli decoderawtransaction $rawtxhex +{ + "txid": "6f83a0b78c598de01915554688592da1d7a3047eacacc8a9be39f5396bf0a07e", + "hash": "6f83a0b78c598de01915554688592da1d7a3047eacacc8a9be39f5396bf0a07e", + "size": 160, + "vsize": 160, + "version": 2, + "locktime": 0, + "vin": [ + { + "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.00000000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 cfc39be7ea3337c450a0c77a839ad0e160739058 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914cfc39be7ea3337c450a0c77a839ad0e16073905888ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mzTWVv2QSgBNqXx7RC56zEhaQPve8C8VS9" + ] + } + }, + { + "value": 0.04500000, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 166692bda9f25ced145267bb44286e8ee3963d26 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914166692bda9f25ced145267bb44286e8ee3963d2688ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mhZQ3Bih6wi7jP1tpFZrCcyr4NsfCapiZP" + ] + } + } + ] +} +``` + +### Recuperando o(s) valor(es) + +Suponha que saibamos exatamente como essa transação é construída: Sabemos que ela usa dois UTXOs como entrada. Para recuperar o txid para os dois UTXOs, poderíamos usar ```jq``` para consultar o valor .vin da transação e, em seguida, fazer referência ao primeiro índice do .vin e, em seguida, ao valor .txid desse array. Posteriormente, poderíamos fazer o mesmo com o primeiro array e, em seguida, o mesmo com os dois valores .vout de .vin. Simples: +``` +$ usedtxid1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .txid') +$ echo $usedtxid1 +d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c +$ usedtxid2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .txid') +$ echo $usedtxid2 +c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b + +$ usedvout1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .vout') +$ echo $usedvout1 +1 +$ usedvout2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .vout') +$ echo $usedvout2 +1 +``` +No entanto, seria melhor ter um caso geral que salvasse _automaticamente_ todos os txids de nossos UTXOs. + +Já sabemos que podemos acessar todos os ```.txid``` usando um valor do array ```. [] ```. Podemos usar isso para criar uma pesquisa geral no .txid: +``` +$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) +$ echo ${usedtxid[0]} +d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c +$ echo ${usedtxid[1]} +c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b + +$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) +$ echo ${usedvout[0]} +1 +$ echo ${usedvout[1]} +1 +``` +O único truque real aqui é como salvamos as informações usando o shell bash. Ao invés de salvar em uma variável com ```$ (command)```, nós salvamos em um array com ```($ (command))```. Fomos então capazes de acessar os elementos individuais do array bash com uma construção ```$ {variable [n]}```. Ao invés disso, poderíamos acessar todo o array usando a ```$ {variable [@]}```. (E antes que diga algo, ninguém nunca disse que o bash ficaria bonito). + +> :warning: **ATENÇÃO:** Lembre-se sempre de que um UTXO é uma transação _mais_ um vout. Perdemos o vout na primeira vez que escrevemos este exemplo JQ, e ele parou de funcionar quando acabamos com uma situação em que dois ```vouts``` foram enviados da mesma transação. + +### Recuperando o(s) objeto(s) relacionado(s) + +Agora podemos usar as informações salvas no ```txid``` e no ```vout``` para referenciar os UTXOs no ```listunspent```. Para encontrar as informações sobre os UTXOs usados pela transação bruta, precisamos examinar todo o array JSON (```[]```) com as transações não gastas. Podemos então escolher (```select```) objetos JSON individuais que incluem (```contains```) os txids. _Então_ selecionamos (```select```) as transações entre aquelas que _também_ contém (```contêm```) o valor correto. + +O uso de outro nível do pipe é a metodologia padrão do JQ: Pegamos um conjunto de dados, depois a reduzimos para todas as transações relevantes e, em seguida, reduzimos para os valores que foram realmente usados nessas transações. No entanto, os argumentos ```select``` e ```contains``` são algo novo. Eles mostram um pouco da complexidade do JSON que vai além do escopo deste tutorial. Por enquanto, saiba apenas que esta invocação em particular funcionará para capturar objetos correspondentes. + +Para começar de forma simples, vamos selecionar os dois UTXOs, um de cada vez: +``` +$ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[0]}'")) | select(.vout | contains('${usedvout[0]}'))' +{ + "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", + "vout": 1, + "address": "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH", + "scriptPubKey": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac", + "amount": 0.9, + "confirmations": 6, + "spendable": true, + "solvable": true +} +$ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[1]}'")) | select(.vout | contains('${usedvout[1]}'))' +{ + "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", + "vout": 1, + "address": "mzizSuAy8aL1ytFijds7pm4MuDPx5aYH5Q", + "scriptPubKey": "76a914d2b12da30320e81f2dfa416c5d9499d08f778f9888ac", + "amount": 0.4, + "confirmations": 5, + "spendable": true, + "solvable": true +} +``` +Ao invés disso, um simples bash usando um loop em ```for``` poderia nos dar _todos_ os nossos UTXOs: +``` +$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout'))'; done; +{ + "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", + "vout": 1, + "address": "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH", + "scriptPubKey": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac", + "amount": 0.9, + "confirmations": 7, + "spendable": true, + "solvable": true +} +{ + "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", + "vout": 1, + "address": "mzizSuAy8aL1ytFijds7pm4MuDPx5aYH5Q", + "scriptPubKey": "76a914d2b12da30320e81f2dfa416c5d9499d08f778f9888ac", + "amount": 0.4, + "confirmations": 6, + "spendable": true, + "solvable": true +} + +``` +Observe que estamos deixando um pouquinho mais feio nosso array ```$ {# usedtxid [*]}``` para determinar o tamanho dele, em seguida, acessamos cada valor no array ```usedtxid``` e cada valor no array ```usedvout``` paralelo, os colocando em variáveis mais simples para termos um acesso menos feio. + +## Usando o JSON para cálculos simples usando os valores + +**Caso de uso:** _Calcular automaticamente o valor dos UTXOs usados em uma transação._ + +Agora podemos ir um passo adiante e solicitar o .amount (ou qualquer outro valor do índice do JSON) dos UTXOs que estamos recuperando. + +Este exemplo repete o uso dos arrays ```$usedtxid``` e ```$usedvout``` definidos da seguinte forma: + +``` +$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) +$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) +``` + +O mesmo script ```for``` pode ser usado para percorrer os arrays, mas com um pipe adicionado no JQ que produz o valor ```amount``` para cada um dos UTXOs selecionados. + +``` +$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done; +0.9 +0.4 +``` + +Neste ponto, podemos somar os .amounts com um script ```awk```, para realmente ver quantas moedas estão nos UTXOs gastos na transação: + +``` +$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done | awk '{s+=$1} END {print s}' +1.3 +``` + +Perfeito! + +## Usando o JQ para cálculos complexos + +**Caso de uso:** _Calcular a taxa de uma transação._ + +Descobrir a taxa de transação completa neste ponto requer apenas mais um pouco de matemática: Bastando determinar quanto dinheiro está passando pelo .vout. Este é um uso simples de JQ onde apenas usamos o ```awk``` para somar o ```valor``` de todas as informações do ```vout```: + +``` +$ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}' +1.045 +``` + +Para completar o cálculo da taxa de transação, vamos subtrair o .vout .amount (1.045) do .vin .amount (1.3). +Para fazer isso, precisaremos instalar o ```bc```: + +``` +$ sudo apt-get intall bc +``` + +Se juntarmos tudo, iremos criar uma calculadora completa com apenas um script de cinco linhas: + +``` +$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) +$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) +$ btcin=$(for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done | awk '{s+=$1} END {print s}') +$ btcout=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}') +$ echo "$btcin-$btcout"| /usr/bin/bc +.255 +``` + +E esse também é um bom exemplo de por que precisamos verificar nossas suas taxas: Pretendíamos enviar uma taxa de transação com 5.000 satoshis, mas invés disso enviamos pagando 255.000 satoshis de taxa. Ops! + +> :warning: **Atenção:** A primeira vez que escrevemos esta lição, realmente calculamos mal a nossa taxa e não a vimos até que executamos nossa calculadora de taxas. É *tão* fácil, que nosso dinheiro acabou. (O exemplo acima é, na verdade, de nossa segunda iteração da calculadora, e dessa vez cometemos o erro de propósito). + +Para mais magia usando o JSON (e se alguma coisa não estiver clara), leia o [Manual JSON](https://stedolan.github.io/jq/manual/) e o [Livro de Receitas do JSON](https://github.com/stedolan/jq/wiki/Cookbook). Estaremos usando o JQ regularmente nos exemplos futuros. + +## Fazendo alguns aliases novos + +O código JQ pode ser um pouco pesado, então devemos considerar adicionar algumas invocações mais longas e interessantes ao nosso ```~/.bash_profile```. + +Sempre que estivermos procurando por uma grande massa de informações em uma saída de objeto JSON por um comando ```bitcoin-cli```, precisamos considerar escrever um alias para reduzi-lo exatamente ao que desejamos observar. + +``` +alias btcunspent="bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }'" +``` + +## Executando o script de taxa de transação + +O [script de cálculo de taxa](src/04_2_i_txfee-calc.sh) está disponível no diretório src/. Você pode baixá-lo e salvá-lo como ```txfee-calc.sh```. + +> :warning: **Atenção:** Este script não foi verificado extensivamente. Se for usá-lo para verificar as taxas de transação reais, só deve fazê-lo depois de fazer uma verificação pessoal dos valores. + +Certifique-se de que as permissões no script estejam corretas: + +``` +$ chmod 755 txfee-calc.sh +``` + +Podemos então, executar o script da seguinte maneira: + +``` +$ ./txfee-calc.sh $rawtxhex +.255 +``` + +Também podemos criar um alias: + +``` +alias btctxfee="~/txfee-calc.sh" +``` + +## Resumo do Usando o JQ + +O JQ facilita a extração de informações de arrays e objetos JSON. Ele também pode ser usado em scripts shell para cálculos bastante complexos que tornarão nossa vida mais fácil. + +## O que vem depois? + +Continue "Enviando Transações de Bitcoin" na sessão [§4.3 Criando uma transação bruta com argumentos nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md). \ No newline at end of file diff --git a/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md b/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md new file mode 100644 index 0000000..2ff9957 --- /dev/null +++ b/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md @@ -0,0 +1,97 @@ +# 4.3 Criando uma transação bruta com argumentos nomeados + +Às vezes, pode ser assustador descobrir a ordem correta dos argumentos para um comando ```bitcoin-cli```. Felizmente, podemos usar _ argumentos nomeados_ como alternativa. + +> :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.14.0. Se usarmos os scripts de configuração do tutorial, o que é importante fazer, precisamos verificar novamente a versão se tiver algum problema. Há também um bug no uso do comando ```createrawtransaction``` usando argumentos nomeados que presumivelmente serão corrigidos na versão 0.14.1. + +## Criando um alias do argumento nomeado + +Para usar um argumento nomeado, devemos executar o ```bitcoin-cli``` com o argumento ```-named```. Se planejamos fazer isso regularmente, provavelmente precisaremos criar um alias: +``` +alias bitcoin-cli="bitcoin-cli -named" +``` +Como de costume, isso é apenas para facilitar o uso, mas continuaremos usando todos os comandos para manter a clareza. + +## Testando um argumento nomeado + +Para saber quais são os nomes dos argumentos de um comando, precisamos consultar o ```bitcoin-cli help```. Ele listará os argumentos com a ordem adequada, mas agora também fornecerá nomes para cada um deles. + +Por exemplo, `bitcoin-cli help getbalance` lista estes argumentos: + + 1. dummy [costumava ser account] + 2. minconf + 3. include_watchonly + 4. avoid_reuse + +O exemplo seguinte mostra um uso tradicional e não intuitivo do ```getbalance``` usando o argumento de confirmação mínimo: +``` +$ bitcoin-cli getbalance "*" 1 +``` +Com argumentos nomeados, podemos esclarecer o que estamos fazendo, o que também minimiza os erros: +``` +$ bitcoin-cli -named getbalance minconf=1 +``` + +## Testando uma transação bruta + +Veja como seriam os comandos para enviar uma transação bruta com argumentos nomeados: +``` +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00001 }''') +$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex +{ + "txid": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5", + "hash": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5", + "version": 2, + "size": 85, + "vsize": 85, + "weight": 340, + "locktime": 0, + "vin": [ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00001000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + ] + } + } + ] +} + +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +e70dd2aa13422d12c222481c17ca21a57071f92ff86bdcffd7eaca71772ba172 +``` +Pronto! Enviamos outra transação bruta, mas desta vez usando argumentos nomeados para ter maior clareza e redução de erros. + +> :warning: **AVISO DE VERSÃO:** É aqui que o bug no Bitcoin Core 0.14 aparece: O argumento ```inputs``` no ```createrawtransaction``` tem o nome ```transactions``` incorreto. Portanto, se estivermos no Bitcoin Core 0.14.0, substitua o argumento nomeado ```inputs``` por ```transactions``` para este e também para os exemplos futuros. No entanto, a partir do Bitcoin Core 0.14.1, esse código deve funcionar normalmente. + +## Resumo do Criando uma transação bruta com argumentos nomeados + +Executando o ```bitcoin-cli``` com o argumento ```-named```, podemos usar argumentos nomeados ao invés de depender de argumentos ordenados. O comando ```bitcoin-cli help``` sempre mostrará o nome correto para cada argumento. Isso pode resultar em um código mais robusto, mais fácil de ler e menos sujeito a erros. + +_À partir de agora, usaremos argumentos nomeados para todos os exemplos futuros, para maior clareza e para estabelecer as melhores práticas. No entanto, também mostraremos todos os argumentos na ordem correta. Portanto, se preferir não usar os argumentos nomeados, apenas retire o argumento ```-named``` e todos os ```name =``` que os exemplos devem continuar funcionando corretamente._ + +## O que vem depois? + +Continue "Enviando Transações de Bitcoin" na sessão [§4.4: Enviando bitcoins usando transações brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md). \ No newline at end of file diff --git a/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md b/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md new file mode 100644 index 0000000..5a3b40e --- /dev/null +++ b/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -0,0 +1,187 @@ +# 4.4: Enviando bitcoins usando transações brutas + +Conforme observado no início deste capítulo, a interface ```bitcoin-cli``` oferece três maneiras principais de enviar moedas. A sessão [§4.1](04_1_Sending_Coins_The_Easy_Way.md) falou sobre como enviá-la pela primeira vez, usando o comando ```sendtoaddress```. Desde então, estamos construindo coisas mais detalhadas sobre como enviar moedas de uma segunda maneira, com transações brutas. A sessão [§4.2](04_2_Creating_a_Raw_Transaction.md) nos ensinou como criar uma transação bruta, um [Prefácio](04_2__Interlude_Using_JQ.md) explicou sobre o JQ e a sessão [§4.3](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) demonstrou os argumentos nomeados. + +Agora podemos colocá-los juntos e realmente enviar fundos usando uma transação bruta. + +## Criando uma endereço de troco + +Nosso exemplo de transação bruta na seção §4.2 era simples demais: Enviamos um UTXO inteiro para um novo endereço. Com mais frequência, iremos desejar enviar a alguém uma quantia em dinheiro que não corresponde a um UTXO. Mas, devemos nos lembrar que o excesso de dinheiro de um UTXO que não é enviado ao destinatário se torna apenas a taxa de transação. Então, como enviar para alguém apenas uma parte de um UTXO, enquanto guardamos o resto pra gente? + +A solução é _enviar_ o restante dos fundos para um segundo endereço, um endereço de troco que criamos em nossa carteira especificamente para recebê-los: +``` +$ changeaddress=$(bitcoin-cli getrawchangeaddress legacy) +$ echo $changeaddress +mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h +``` +Observe que isso usa uma nova função: ```getrawchangeaddress```. É basicamente é a mesma coisa que o ```getnewaddress```, mas é otimizado para uso como um endereço de truco em uma transação bruta, portanto, não faz coisas como criar entradas em nossa lista de endereços. Selecionamos novamente o endereço ```legacy```, ao invés de usar o padrão ```bech32```, simplesmente para consistência. Esta é uma situação em que teria sido seguro gerar um endereço Bech32 padrão, apenas usando ```bitcoin-cli getrawchangeaddress```, porque ele seria enviado e recebido por nós em nosso node Bitcoin Core, que tem suporte integral a isso. Mas, estamos adiantando as coisas. Vamos mudar sobre como mudar o endereço para Bech32 na sessão [§4.6](04_6_Creating_a_Segwit_Transaction.md). + +Agora temos um endereço adicional em nossa carteira, para que possamos receber o troco de um UTXO! Para usá-lo, precisaremos criar uma transação bruta com duas saídas. + +## Escolhendo os UTXOs suficientes + +Nosso exemplo de transação bruta era simples também de outra maneira: Assumia que havia dinheiro suficiente em um único UTXO para cobrir toda a transação. Frequentemente, esse será o caso, mas às vezes desejaremos criar transações que gastem mais dinheiro do que temos em um único UTXO. Para fazer isso, devemos criar uma transação bruta com duas (ou mais) entradas. + +## Escrevendo uma transação bruta real + +Para resumir: A criação de uma transação bruta real para enviar moedas, às vezes, requer múltiplas entradas e, quase sempre, múltiplas saídas, uma das quais é um endereço de troco. Estaremos criando esse tipo de transação mais realista, um exemplo que mostra um caso de uso da vida real, enviando fundos por meio da segunda metodologia do Bitcoin, as transações brutas. + +Vamos usar nossos UTXOs 0 e 2: +``` +$ bitcoin-cli listunspent +[ +[ + { + "txid": "0619fecf6b2668fab1308fbd7b291ac210932602a6ac6b8cc11c7ae22c43701e", + "vout": 1, + "address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + "label": "", + "scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac", + "amount": 0.00899999, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 15, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + }, + { + "txid": "0df23a9dba49e822bbc558f15516f33021a64a5c2e48962cec541e0bcc79854d", + "vout": 0, + "address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + "label": "", + "scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac", + "amount": 0.00100000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp", + "safe": true + } +] + +``` +Em nosso exemplo, enviaremos 0,009 BTC, que é (um pouco) maior do que qualquer um de nossos UTXOs. Para isso, será necessário que os combinemos e, em seguida, vamos usar nosso endereço de troco para recuperar os fundos não gastos. + +### Configurando as variáveis + +Já temos as variáveis ​​```$changeaddress``` e ```$recipient``` dos exemplos anteriores: +``` +$ echo $changeaddress +mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h +$ echo $recipient +n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi +``` +Também precisamos registrar o txid e vout para cada um de nossos dois UTXOs. Tendo identificado os UTXOs que queremos gastar, podemos usar as técnicas do JQ para garantir que o acesso a eles esteja livre de erros: +``` +$ utxo_txid_1=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout_1=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') +$ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') +``` + +### Escrevendo a transação + +Escrever a transação bruta real é surpreendentemente simples. Tudo o que precisamos fazer é incluir um objeto JSON adicional separado por vírgula na matriz JSON de entradas e um par de valores-chave adicional separado por vírgula em um objeto JSON de saídas. + +Aqui temos um exemplo. Observe as múltiplas entradas após o argumento ```inputs``` e as múltiplas saídas após o argumento ```outputs```. +``` +$ rawtxhex2=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.009, "'$changeaddress'": 0.0009 }''') +``` +Fomos _muito_ cuidadosos em calcular a quantidade. Esses dois UTXOs contêm 0,00999999 BTC. Depois de enviar 0,009 BTC, teremos 0,00099999 BTC restantes. Escolhemos 0,00009999 BTC como a nossa taxa de transação. Para acomodar essa taxa, definimos o troco como sendo 0,0009 BTC. Se não tivermos prestado atenção nisso, e definido nosso troco para 0,00009 BTC, essa quantidade de BTC adicional seria enviado para os mineradores! Se tivéssemos esquecido de fazer o troco, todo o excesso teria desaparecido. Portanto, novamente, _ tenha cuidado_. + +Felizmente, podemos verificar três vezes com o alias ```btctxfee``` do Prefácio do JQ: +``` +$ ./txfee-calc.sh $rawtxhex2 +.00009999 +``` + +### Concluindo + +Agora podemos assinar, selar e entregar nossa transação, e ela é sua (e do faucet): +``` +$ signedtx2=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex2 | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx2 +e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d +``` + +### Esperando + +Como de costume, nossas moedas estarão no fluxo por um tempo: O troco ficará indisponível até que a transação seja realmente confirmada e um novo UTXO seja nos dado. + +Mas, em 10 minutos ou menos (provavelmente), teremos o dinheiro restante de volta e totalmente utilizável novamente. Por enquanto, ainda precisamos esperar: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 15, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] +``` +E o troco eventualmente voltará para nós: +``` +[ + { + "txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d", + "vout": 1, + "address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + "scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac", + "amount": 0.00090000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 16, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] +``` +Este também pode ser um bom momento para revisitar um explorador de blockchain, para que possamos ver mais intuitivamente como as entradas, saídas e as taxas estão dispostas na transação: [e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d](https://mempool.space/pt/testnet/tx/e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d). + +## Resumo do Enviando bitcoins usando transações brutas + +Para enviar moedas usando transações brutas, precisamos criar uma transação bruta com uma ou mais entradas (para ter fundos suficientes) e uma ou mais saídas (para recuperar usando o troco). Então, podemos seguir nosso procedimento normal de usar o ```createrawtransaction``` com argumentos nomeados junto com o JQ, conforme descrito nas seções anteriores. + +> :fire: ***Qual é o ponto positivo de enviar moedas com transações brutas?*** +> _As vantagens._ Oferece maior controle. Se o nosso objetivo é escrever um programa ou script Bitcoin mais complexo, provavelmente usaremos as transações brutas para saber exatamente o que está acontecendo. Essa também é a situação mais _segura_ para usar transações brutas, porque podemos garantir que não cometeremos nenhum erro na parte da programação. +> _As desvantagens._ É muito fácil perder dinheiro. Não há avisos, bloqueios e barreiras na programação, a não ser que as criemos. Também é tudo muito misterioso. A formatação é desagradável, mesmo usando a interface ```bitcoin-cli``` que é fácil de usar, e temos que fazer muitas pesquisas e cálculos manualmente. + +## O que vem depois? + +Veja uma forma alternativa de inserir comandos no [Prefácio: Usando o JQ] (04_4__Interlude_Using_Curl.md). + +Ou, se preferir pular, o que é francamente uma digressão, podemos aprender mais com "Enviando Transações de Bitcoin" na sessão [§4.5 Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file diff --git a/pt/04_4__Interlude_Using_Curl.md b/pt/04_4__Interlude_Using_Curl.md new file mode 100644 index 0000000..2fa3fe6 --- /dev/null +++ b/pt/04_4__Interlude_Using_Curl.md @@ -0,0 +1,314 @@ +# Prefácio: Acessando o Bitcoind com Curl + +O ```bitcoin-cli``` é, em última análise, apenas um invólucro. É uma forma de interagir com ```bitcoind``` a partir da linha de comando, fornecendo acesso simplificado aos seus diversos comandos RPC. Mas o RPC pode, é claro, ser acessado diretamente. É disso que iremos falar nessa sessão: Como nos conectarmos diretamente ao RPC com o comando ```curl```. + +It won't be used much in the future chapters, but it's an important building block that you can see as an alternative access to `bitcoind` is you so prefer. +Não será muito usado nos próximos capítulos, mas essas informações serão importantes caso queiramos uma alternativa para acessar o ```bitcoind```. + +## Conhecendo o Curl + +O ```curl```, abreviação de "ver URL", é uma ferramenta de linha de comando que permite acessar URLs diretamente usando a linha de comando. É uma maneira fácil de interagir com servidores como o ```bitcoind```, que ficam ouvindo as portas da internet e conversam utilizando uma variedade de protocolos. O Curl também está disponível como uma biblioteca para muitas linguagens de programação, como C, Java, PHP e Python. Então, depois de saber como trabalhar com o Curl, teremos uma base sólida para usar várias APIs diferentes. + +Para usar o ```curl``` com o ```bitcoind```, devemos saber três coisas: O formato padrão, o nome de usuário e senha e a porta correta. + +### Conhecendo o formato + +Os comandos ```bitcoin-cli``` estão todos vinculados aos comandos RPC no ```bitcoind```. Isso torna a transição do uso de ```bitcoin-cli``` para o uso do ```curl``` muito simples. Na verdade, se olharmos qualquer uma das páginas de ajuda do ```bitcoin-cli```, veremos que eles listam não apenas os comandos ```bitcoin-cli```, mas também os comandos ```curl``` paralelos. Por exemplo, aqui temos o resultado do comando ```bitcoin-cli help getmininginfo```: +``` +$ bitcoin-cli help getmininginfo +getmininginfo + +Returns a json object containing mining-related information. +Result: +{ (json object) + "blocks" : n, (numeric) The current block + "currentblockweight" : n, (numeric, optional) The block weight of the last assembled block (only present if a block was ever assembled) + "currentblocktx" : n, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled) + "difficulty" : n, (numeric) The current difficulty + "networkhashps" : n, (numeric) The network hashes per second + "pooledtx" : n, (numeric) The size of the mempool + "chain" : "str", (string) current network name (main, test, regtest) + "warnings" : "str" (string) any network and blockchain warnings +} + +Examples: +> bitcoin-cli getmininginfo +> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ +``` +E tem o comando ```curl```, no final da tela de ajuda! Este comando um tanto longo tem quatro partes principais: (1) Uma lista do nome de usuário; (2) Um sinalizador ```--data-binary```; (3) Um objeto JSON que diz ao ```bitcoind``` o que fazer, incluindo um array JSON com os parâmetros e; (4) Um cabeçalho HTTP que inclui a URL do ```bitcoind```. + +Quando estamos trabalhando com o ```curl```, muitos desses argumentos do ```curl``` permanecerão os mesmos de um comando para outro, apenas as entradas ```method``` e ```params``` no array JSON normalmente mudam. No entanto, precisaremos saber como preencher o nome do usuário e endereço da URL para que funcione, antes de mais nada! + +_Sempre que não tivermos certeza sobre como usar o curl no RPC, basta usarmos a ajuda do bitcoin-cli e continuar._ + +### Descobrindo o nome de usuário + +Para falar com a porta do ```bitcoind```, precisamos de um nome de usuário e senha. Eles foram criados como parte da configuração inicial do Bitcoin e podem ser encontrados no arquivo `~/.bitcoin/bitcoin.conf`. + +Por exemplo, aqui está nossa configuração atual: +``` +$ cat ~/.bitcoin/bitcoin.conf +server=1 +dbcache=1536 +par=1 +maxuploadtarget=137 +maxconnections=16 +rpcuser=StandUp +rpcpassword=8eaf562eaf45c33c3328bc66008f2dd1 +rpcallowip=127.0.0.1 +debug=tor +prune=550 +testnet=1 +mintxfee=0.001 +txconfirmtarget=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 +``` +Nosso nome de usuário é ```StandUp``` e nossa senha é ```8eaf562eaf45c33c3328bc66008f2dd1```. + +> **Atenção:** Obviamente, não é muito seguro ter essas informações em um arquivo de texto simples. A partir do Bitcoin Core 0.12, podemos omitir o ```rpcpassword``` do arquivo ```bitcoin.conf``` e fazer com que o ```bitcoind``` gere um novo cookie sempre que iniciarmos o serviço. A desvantagem disso é que torna o uso de comandos RPC por outros aplicativos, como os detalhados neste capítulo, mais difícil. Então, vamos ficar com as informações simples do ```rpcuser``` e ```rpcpassword``` por enquanto, mas para softwares em produção, é importante considerarmos essa alteração para cookies. + +A maneira segura de usar o RPC com ```bitcoind``` é a seguinte: +``` +$ curl --user StandUp --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ +Enter host password for user 'bitcoinrpc': +``` +Conforme observado, nossa senha será solicitada. + +> :link: **TESTNET vs MAINNET:** A Testnet usa uma URL com a porta 18332 e a mainnet usa uma URL com a porta 8332. Se tivermos alguma dúvida, basta olharmos nosso ```bitcoin.conf```. As configurações estão todas lá. + +A maneira insegura e errada de fazer isso é a seguinte: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ +``` +> **Atenção:** Digitar a senha na linha de comando pode colocá-la na tabela de processos e/ou salvá-la em um histórico qualquer. Isso é ainda menos recomendado do que colocá-la em um arquivo, exceto para testes utilizando a testnet. Se quisermos fazer em qualquer outro lugar, precisamos nos certificar de saber o que estamos fazendo! + +### Conhecendo os comandos e os parâmetros + +Com tudo isso em mãos, estamos prontos para enviar os comandos RPC padrão com o ```curl```, mas ainda precisamos saber como incorporar os dois elementos que tendem a mudar no comando ```curl```. + +O primeiro é o ```method```, que é o método RPC que está sendo utilizado. Isso geralmente deve corresponder aos nomes de comando que alimentamos no ```bitcoin-cli``` por muito tempo. + +O segundo é o ```params```, que é uma matriz JSON de parâmetros. Eles são iguais aos argumentos (ou argumentos nomeados) que estamos usando. Eles também são a parte mais confusa do ```curl```, em grande parte porque são um array estruturado ao invés de uma simples lista. + +Esta é a aparência de algumas matrizes de parâmetros: + + * `[]` — Um array vazio; + * `["000b4430a7a2ba60891b01b718747eaf9665cb93fbc0c619c99419b5b5cf3ad2"]` — Um array com dados; + * `["'$signedhex'"]` — Um array com uma variável; + * `[6, 9999999]` — Uma array com dois parâmetros; + * `{}` - Um objeto vazio; + * `[''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.298, "'$changeaddress'": 1.0}'']` — Um array com um array contendo um objeto e um objeto vazio. + +## Obtendo a informação + +Agora podemos enviar nosso primeiro comando ```curl``` acessando o RPC ```getmininginfo```: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ +{"result":{"blocks":1772428,"difficulty":10178811.40698772,"networkhashps":91963587385939.06,"pooledtx":61,"chain":"test","warnings":"Warning: unknown new rules activated (versionbit 28)"},"error":null,"id":"curltest"}``` +Note that we provided the method, `getmininginfo`, and the parameter, `[]`, but that everything else was the standard `curl` command line. +``` +> **Atenção:** Se obtivermos como resultado o seguinte erro: "Failed to connect to 127.0.0.1 port 8332: Connection refused", precisamos nos certificar de que uma linha como ```rpcallowip = 127.0.0.1``` esteja configurada no ```~/.bitcoin/bitcoin.conf```. Se ainda não funcionar, precisaremos permitir o acesso à porta 18332 (ou 8332) do nosso host local. Nossa configuração padrão do [Capítulo 2: Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) deve fazer tudo isso. + +The result is another JSON array, which is unfortunately ugly to read if you're using `curl` by hand. Fortunately, you can clean it up simply by piping it through `jq`: +O resultado é outro array JSON, que infelizmente é ruim de se ler se estivermos usando o ```curl``` manualmente. Felizmente, podemos limpá-lo simplesmente usando o ```jq```: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed +100 295 100 218 100 77 72666 25666 --:--:-- --:--:-- --:--:-- 98333 +{ + "result": { + "blocks": 1772429, + "difficulty": 10178811.40698772, + "networkhashps": 90580030969896.44, + "pooledtx": 4, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" + }, + "error": null, + "id": "curltest" +} +``` +Você verá um pouco de relatório de conectividade à medida que os dados são baixados, então, quando os dados chegarem a ```jq```, tudo será corretamente identado. Estaremos omitindo as informações do download nos próximos exemplos. + +## Manipulando nossa carteira + +Embora já estejamos acessando o ```bitcoind``` diretamente, ainda teremos acesso à funcionalidade de carteira, porque ela está amplamente armazenada no próprio ```bitcoind```. + +### Pesquisando endereços + +Usando o RPC ```getaddressesbylabel``` para listar todos os nossos endereços atuais: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getaddressesbylabel", "params": [""] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": { + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE": { + "purpose": "receive" + }, + "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff": { + "purpose": "receive" + }, + "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B": { + "purpose": "receive" + }, + "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d": { + "purpose": "receive" + }, + "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6": { + "purpose": "receive" + }, + "tb1qmtucvjtga68kgrvkl7q05x4t9lylxhku7kqdpr": { + "purpose": "receive" + } + }, + "error": null, + "id": "curltest" +} +``` +Este é o nosso primeiro exemplo de um parâmetro real, ```" "```. Este é o parâmetro ```label``` obrigatório para o ```getaddressesbylabel```, mas todos os nossos endereços estão sob o rótulo padrão, então nada de especial foi necessário neste momento. + +O resultado é uma lista de todos os endereços que foram usados na nossa carteira. Alguns dos quais presumivelmente possuem saldo. + +### Pesquisando pelos saldos + +Use o RPC ```listunspent``` para listar os saldos que temos disponíveis: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": [ + { + "txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d", + "vout": 1, + "address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + "scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac", + "amount": 0.0009, + "confirmations": 4, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022, + "confirmations": 19, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } + ], + "error": null, + "id": "curltest" +} +``` +Esta é quase exatamente a mesma saída que recebemos quando digitamos ```bitcoin-cli listunspent```, mostrando como as duas interfaces estão intimamente ligadas. Se nenhuma limpeza ou ajuda extra for necessária, então o ```bitcoin-cli``` apenas produzirá o RPC. Simples assim! + +### Criando um endereço + +Depois de saber onde estão os saldos, a próxima etapa na elaboração de uma transação é obter um endereço de alteração. Agora provavelmente já pegamos o jeito e sabemos que para os comandos RPC simples, tudo que precisamos fazer é ajustar o ```method``` no comando ```curl```: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": "mrSqN37TPs89GcidSZTvXmMzjxoJZ6RKoz", + "error": null, + "id": "curltest" +} + +``` +Neste ponto, podemos até mesmo voltar à nossa prática padrão de salvar os resultados em variáveis com a ajuda adicional do `jq`: +``` +$ changeaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') +$ echo $changeaddress +mqdfnjgWr2r3sCCeuTDfe8fJ1CnycF2e6R +``` +Não precisamos nos preocupar com as informações do download. Ele irá para o ```STDERR``` e será exibido em nossa tela, enquanto os resultados irão para o ```STDOUT``` e serão salvos em nossa variável. + +## Criando uma transação + +Agora estamos prontos para criar uma transação com o ```curl```. + +### Preparando as variáveis + +Assim como no ```bitcoin-cli```, para criar uma transação usando o Curl com o RPC, devemos primeiro salvar nossas variáveis. A única mudança aqui é que o ```curl``` cria um objeto JSON que inclui um valor-chave ```result```, então sempre precisaremos usar o pipe (```|```) através da tag ```.result``` antes de fazer qualquer outra coisa. + +Este exemplo configura nossas variáveis para usar o BTC de 1.2985 em fundos listados na primeira transação não gasta acima: +``` +$ utxo_txid=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .txid') +$ utxo_vout=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .vout') +$ recipient=mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf +$ changeaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') + +$ echo $utxo_txid +e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d +$ echo $utxo_vout +1 +$ echo $recipient +mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf +$ echo $changeaddress +n2jf3MzeFpFGa7wq8rXKVnVuv5FoNSJZ1N +``` + +### Criando a transação + +A transação criada com o ```curl``` é muito semelhante à transação criada com o ```bitcoin-cli```, mas com algumas diferenças sutis: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": "02000000010d6acd0356db222ca3a7ee7fa1e3044316223ceec1f64b58aeb2e0de921007e70100000000ffffffff0230750000000000001976a914ac19d3fd17710e6b9a331022fe92c693fdf6659588ac50c30000000000001976a9147021efec134057043386decfaa6a6aa4ee5f19eb88ac00000000", + "error": null, + "id": "curltest" +} +``` +O coração da transação é, obviamente, o array JSON ```params```, que estamos colocando em uso total pela primeira vez. + +Podemos observar que todos os ```params``` estão alojados nos ```[]``` para marcar o array de parâmetros. + +Nós também variamos as citações de como as coisas funcionavam no ```bitcoin-cli```, para iniciar e terminar cada array e objeto dentro do array ```params``` com ```''``` ao invés do tradicional ```'' '```. Isso porque todo o conjunto de argumentos JSON já tem um ```'``` em torno dele. Como de costume, basta dar uma olhada na bizarra citação do shell e se acostumar com isso. + +No entanto, há uma última coisa a ser observada neste exemplo, e pode ser _enlouquecedor_ se não tivermos percebido. Quando executamos um comando ```createrawtransaction``` com ```bitcoin-cli```, o array JSON de entradas e o objeto JSON de saídas eram parâmetros distintos, portanto, foram separados por um espaço. Agora, porque eles são parte do array JSON ```params```, eles são separados por uma vírgula (```,```). Se não tivermos percebido isso obteremos um ```parse error``` sem muitas informações. + +> **Atenção:** Todo mundo já teve problemas para depurar o ```curl```, não é mesmo? Para resolver isso basta adicionar o argumento ```--trace-ascii/tmp/foo```. Informações completas sobre o que está sendo enviado ao servidor serão salvas em ```/tmp/foo``` (ou qualquer nome de arquivo que quisermos informar). + +Depois de verificarmos se as coisas estão funcionando, provavelmente iremos desejar salvar o código hexadecimal em uma variável: +``` +$ hexcode=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') +``` + +### Assinando e enviando + +Assinar e enviar a nossa transação usando ```curl``` é bem simples, basta usar os seguintes comandos do RPC ```signrawtransactionwithwallet``` e ```sendrawtransaction```: + +``` +$ signedhex=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "signrawtransactionwithwallet", "params": ["'$hexcode'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .hex') + +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "sendrawtransaction", "params": ["'$signedhex'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d", + "error": null, + "id": "curltest" +} +``` +## Resumo do Acessando o Bitcoind com Curl + +Terminando esta seção, podemos sentir que acessar o ```bitcoind``` através de ```curl``` é muito parecido com acessá-lo através de ```bitcoin-cli```, porém, é mais complicado. E estamos certos. O ```bitcoin-cli``` tem funcionalidade RPC bem completa, então qualquer coisa que fizermos através do ```curl``` provavelmente poderemos fazer através do ```bitcoin-cli```. É por isso que vamos continuar nos concentrando no ```bitcoin-cli``` após esta digressão. + +Mas ainda há razões para usar ```curl``` ao invés do ```bitcoin-cli```: + +_Qual é o poder do curl?_ Obviamente, o ```curl``` elimina um nível intermediário. Ao invés de trabalhar com o ```bitcoin-cli```, que envia comandos RPC para o ```bitcoind```, estamos enviando esses comandos RPC diretamente para ele. Isso permite uma programação mais robusta, porque não precisamos nos preocupar com as coisas inesperadas que o ```bitcoin-cli``` pode fazer ou como isso pode mudar com o tempo. No entanto, também estamos dando os primeiros passos para usar uma linguagem de programação mais abrangente do que as opções pobres oferecidas por um script de shell. Como veremos nos últimos capítulos deste livro, podemos realmente ver que as bibliotecas curl são outras funções que acessam os comandos RPC em uma variedade de linguagens de programação: Mas isso ainda está muito longe, ainda. + +## O que vem depois? + +Aprenda mais uma maneira de "Enviando Transações de Bitcoin" com [§4.5 Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). diff --git a/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md b/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md new file mode 100644 index 0000000..42a8716 --- /dev/null +++ b/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md @@ -0,0 +1,171 @@ +# 4.5: Enviando bitcoins usando transações brutas automatizadas + +Este capítulo apresenta três maneiras de enviar fundos por meio da interface cli do Bitcoin. A sessão [§4.1](04_1_Sending_Coins_The_Easy_Way.md) descreveu como fazer isso com um comando simples, a sessão [§4.4](04_4_Sending_Coins_with_a_Raw_Transaction.md) detalhou como usar uma transação bruta mais perigosa. Esta seção fica no meio termo de ambas, mostrando como tornar as transações brutas mais simples e seguras. + +## Deixando o Bitcoin fazer os cálculos para nós + +A metodologia para transações brutas automatizadas é simples: Criamos uma transação bruta, mas usamos o comando ```fundrawtransaction``` para pedir ao bitcoind para executar os cálculos para nós. + +Para usar este comando, precisaremos garantir que nosso arquivo ```~/.bitcoin/bitcoin.conf``` contenha as variáveis ​​racionais para calcular as taxas de transação. Podemos consultar a sessão [§4.1: Enviando bitcoins no modo easy](04_1_Sending_Coins_The_Easy_Way.md) para obter mais informações sobre isso. + +Vamos usar números conservadores, por isso sugerimos adicionar o seguinte ao `bitcoin.conf`: +``` +mintxfee=0.0001 +txconfirmtarget=6 +``` +Para manter o tutorial em constante movimento (em outras palavras, para movimentarmos nosso dinheiro rápido sem ficar esperando muito), sugerimos o seguinte: +``` +mintxfee=0.001 +txconfirmtarget=1 +``` + +## Criando uma transação bruta + +Para usar o ```fundrawtransaction``` primeiro precisamos criar uma transação bruta básica que liste _nenhuma_ entrada e _nenhuma_ mudança de endereço. Apenas listaremos o nosso destinatário e quanto desejamos enviar, neste caso ```$recipient``` e ```0,0002``` BTC. +``` +$ recipient=n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi +$ unfinishedtx=$(bitcoin-cli -named createrawtransaction inputs='''[]''' outputs='''{ "'$recipient'": 0.0002 }''') +``` + +## Financiando nossa transação bruta + +Dizemos ao ```bitcoin-cli``` para financiar essa transação básica: +``` +$ bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx +{ + "hex": "02000000012db87641c6a21e5a68b20c226428544978e6ac44964d5d8060d7388000c584eb0100000000feffffff02204e0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac781e0000000000001600140cc9cdcf45d4ea17f5227a7ead52367aad10a88400000000", + "fee": 0.00022200, + "changepos": 1 +} +``` +Isso fornece muitas informações úteis, mas uma vez que tenhamos certeza de como funciona, vamos querer usar o JQ para salvar nosso hex em uma variável, como de costume: +``` +$ rawtxhex3=$(bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx | jq -r '.hex') +``` +## Verificando nossa transação financiada + +Parece mágica, então nas primeiras vezes que usarmos o ```fundrawtransaction```, provavelmente vamos querer verificá-la. + +Vamos executar o comando ```decoderawtransaction``` para mostrar que a transação bruta agora está disposta corretamente, usando um ou mais dos nossos UTXOs e enviando fundos excedentes de volta para um endereço de alteração: +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 +{ + "txid": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99", + "hash": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99", + "version": 2, + "size": 116, + "vsize": 116, + "weight": 464, + "locktime": 0, + "vin": [ + { + "txid": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.00020000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + ] + } + }, + { + "value": 0.00007800, + "n": 1, + "scriptPubKey": { + "asm": "0 a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "hex": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r" + ] + } + } + ] +} +``` +Uma coisa de interesse aqui é o endereço de troco, que é o segundo ```vout```. Observe que é um endereço ```tb1```, o que significa que é do tipo Bech32. Quando demos ao Bitcoin Core a capacidade total de gerenciar as alterações, ele o fez usando o tipo de endereço padrão, Bech32, e funcionou bem. É por isso que nossa mudança para endereços SegWit na sessão [§4.6](04_6_Creating_a_Segwit_Transaction.md) realmente não é um grande negócio, mas existem algumas dicas para uso mais amplo, sobre as quais falaremos lá. + +Embora tenhamos visto a taxa na saída no ```fundrawtransaction```, ela não pode ser visível aqui. No entanto, podemos verificar isso com o script JQ ```txfee-calc.sh``` criado na sessão [Prefácio: Usando o JQ](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master /04_2__Interlude_Using_JQ.md): +``` +$ ~/txfee-calc.sh $rawtxhex3 +.000222 +``` +Finalmente, podemos usar o ```getaddressinfo``` para ver se o endereço de alteração gerado realmente nos pertence: +``` +$ bitcoin-cli -named getaddressinfo address=tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r +{ + "address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + "scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "ismine": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar", + "iswatchonly": false, + "isscript": false, + "iswitness": true, + "witness_version": 0, + "witness_program": "a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "pubkey": "038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5", + "ischange": true, + "timestamp": 1592335137, + "hdkeypath": "m/0'/1'/10'", + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", + "hdmasterfingerprint": "d6043800", + "labels": [ + ] +} +``` +Observe os conteúdo do `ismine`. + +## Enviando a transação financiada + +Neste ponto, podemos assinar e enviar a transação normalmente. +``` +$ signedtx3=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex3 | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx3 +8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa +``` +Em alguns minutos, teremos o nosso troco de volta: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa", + "vout": 1, + "address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + "scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "amount": 0.00007800, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar", + "safe": true + } +] +``` + +## Resumo do Enviando bitcoins usando transações brutas automatizadas + +Se formos enviar fundos usando transações brutas, então o ```fundrawtransaction``` oferece uma boa alternativa onde taxas, entradas e saídas são calculadas para nós, para que não percamos acidentalmente muito dinheiro. + +> :fire: ***Qual é o poder de enviar moedas com transações brutas automatizadas?*** +> _As vantagens._ Proporciona um bom meio de campo. Se estamos enviando fundos manualmente e o ```sendtoaddress``` não oferece controle suficiente por qualquer motivo, podemos obter algumas das vantagens das transações brutas sem os perigos dela. Essa metodologia deve ser usada sempre que possível se estivermos enviando transações brutas manualmente. +> _As desvantagens._ É uma meio termo. Embora existam algumas opções adicionais no ```fundrawtransaction``` que não foram mencionadas aqui, nosso controle ainda é limitado. Provavelmente, nunca desejaríamos usar esse método se formos escrever um programa cujo objetivo é saber exatamente o que está acontecendo. + +## O que vem depois? + +Vamos concluir o capítulo "Enviando transações no Bitcoin" com a sessão [§4.6: Criando uma transação do tipo SegWit](04_6_Creating_a_Segwit_Transaction.md). \ No newline at end of file diff --git a/pt/04_6_Creating_a_Segwit_Transaction.md b/pt/04_6_Creating_a_Segwit_Transaction.md new file mode 100644 index 0000000..9b7c1bf --- /dev/null +++ b/pt/04_6_Creating_a_Segwit_Transaction.md @@ -0,0 +1,288 @@ +# 4.6: Criando uma transação do tipo SegWit + +> :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. + +Era uma vez, nos céus do Bitcoin, uma guerra entre os tamanhos de blocos eclodiu. As taxas disparavam e os usuários estavam preocupados se o Bitcoin podia realmente escalar. Os desenvolvedores do Bitcoin Core relutaram em simplesmente aumentar o tamanho do bloco, mas chegaram a um acordo: Fizeram o SegWit, que significa Segregated Witness. A Segregated Witness é uma maneira elegante de dizer "Assinatura Separada". Ele cria novos tipos de transações que removem assinaturas no final da transação. Ao combinar isso com o aumento dos tamanhos de bloco que são visíveis apenas para nós atualizados, o SegWit resolveu os problemas de dimensionamento do Bitcoin na época e também resolveu um bug de maleabilidade desagradável, tornando o dimensionamento ainda melhor para protocolos de segunda camada, como a Lightning Network. + +A sacada? O SegWit usa endereços diferentes, alguns dos quais são compatíveis com nodes mais antigos e outros não. + +> :warning: **AVISO DE VERSÃO:** O SegWit foi introduzido no BitCoin 0.16.0, que foi descrito na época como tendo "suporte total". Dito isso, havia algumas falhas na integração com o ```bitcoin-cli``` na época, que impediam a assinatura de funcionar corretamente em novos endereços P2SH-SegWit. O endereço Bech32, não compatível com versões anteriores, também foi introduzido no Bitcoin 0.16.0 e se tornou o tipo de endereço padrão no Bitcoin 0.19.0. Toda essa funcionalidade deve estar totalmente funcional em relação às funções ```bitcoin-cli``` (e, portanto, devem funcionar completamente neste tutorial). + +> O problema está em interagir com o mundo. Todos devem ser capazes de enviar para um endereço P2SH-SegWit porque foi construído propositadamente para suportar compatibilidade com as versões anteriores, envolvendo a funcionalidade SegWit em um Script Bitcoin. O mesmo não é verdade para endereços Bech32: Se alguém nos disser que não pode enviar para o nosso endereço Bech32 precisaremos gerar um endereço ```legado``` ou P2SH-SegWit para fazer a transação. (Muitos sites, principalmente as exchanges, também não podem gerar ou receber em endereços SegWit, particularmente endereços Bech32, mas isso é um problema totalmente diferente e não afeta o uso delas). + +## Compreendendo uma transação SegWit + +Em transações clássicas, as informações de assinatura (witness) eram armazenadas no meio da transação, enquanto nas transações SegWit, elas ficavam na parte inferior. Isso anda de mãos dadas com os aumentos de tamanho do bloco que foram introduzidos na atualização do SegWit. O tamanho do bloco foi aumentado de 1 mega para um valor variável com base em quantas transações SegWit estão em um bloco, começando em 1 mega (sem transações SegWit) e podendo chegar a 4 megas (caso todas as transações sejam SegWit). Este tamanho variável foi criado para acomodar os nodes legados, de forma que tudo permaneça compatível com as versões anteriores. Se um node clássico vê uma transação SegWit, ele joga fora as informações da witness (resultando em um bloco de tamanho menor, abaixo do antigo limite de 1 mega), enquanto se um novo node vê uma transação SegWit, ele mantém as informações da witness (resultando em um maior tamanho de bloco, até o novo limite de 4 megas). + +Portanto, acabamos de responder o quê são e como funcionam as transações SegWit. Não que precisemos saber disso para usá-las. A maioria das transações na rede Bitcoin são SegWit. Elas são aquilo que iremos utilizar nativamente para as transações e recebimentos de bitcoins. Os detalhes não são mais relevantes à partir deste ponto, tanto quanto não são mais relevantes como o Bitcoin funciona. + +## Criando um endereço SegWit + +Criamos um endereço SegWit da mesma maneira que qualquer outro endereço, com os comandos ```getnewaddress``` e ```getrawchangeaddress```. + +Se precisarmos criar um endereço para alguém que não pode enviar para os endereços Bech32 mais recentes, podemos usar um endereço ```p2sh-segwit```: +``` +$ bitcoin-cli -named getnewaddress address_type=p2sh-segwit +2N5h2r4karVqN7uFtpcn8xnA3t5cbpszgyN +``` +Se conseguirmos ver um endereço com o prefixo "2" significa que fizemos tudo certo. + +> :link: **TESTNET vs MAINNET:** "3" no caso da mainnet. + +No entanto, se a pessoa com quem estamos interagindo tem um node com uma versão mais nova, ela poderá enviar para um endereço Bech32, que criamos usando os comandos da maneira padrão: +``` +$ bitcoin-cli getnewaddress +tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 +``` +Como já vimos, os endereços de troco gerados a partir do ```bitcoin-cli``` interagem bem com os endereços Bech32, então não há motivo nenhum usar o sinalizador ```legacy``` lá também: +``` +$ bitcoin-cli getrawchangeaddress +tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff +``` + +Aqui, podemos observar que o prefixo "tb1" exclusivo denota que o endereço é um Bech32. + +> :link: ** TESTNET vs MAINNET: ** "bc1" no caso da mainnet. + +O Bitcoin-cli não se importa com o tipo de endereço que estamos utilizando. Podemos executar um comando como ```listaddressgroupings``` que ele irá misturar os endereços livremente não importando os tipos: +``` +$ bitcoin-cli listaddressgroupings +[ + [ + [ + "mfsiRhxbQxcD7HLS4PiAim99oeGyb9QY7m", + 0.01000000, + "" + ] + ], + [ + [ + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + 0.00000000, + "" + ], + [ + "tb1q6dak4e9fz77vsulk89t5z92l2e0zm37yvre4gt", + 0.00000000 + ] + ], + [ + [ + "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + 0.00022000, + "" + ] + ], + [ + [ + "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + 0.00000000 + ], + [ + "mqjrdY5raxKzXQf5t2VvVvzhvFAgersu9B", + 0.00000000 + ], + [ + "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + 0.00000000, + "" + ], + [ + "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + 0.00007800 + ] + ], + [ + [ + "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q", + 0.01000000, + "" + ] + ], + [ + [ + "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6", + 0.01000000, + "" + ] + ] +] +``` + +## Enviando uma transação SegWit no modo easy + +Então, como enviamos uma transação Segwit? Exatamente como qualquer outra transação. Não importa se o UTXO é SegWit, o endereço é SegWit ou alguma combinação dos dois. Podemos ter a certeza que o ```bitcoin-cli``` irá fazer a coisa certa. Embora possamos perceber algumas diferenças nos endereços, eles não importam para interagir com as coisas no nível do ```bitcoin-cli``` ou do RPC. (E esta é uma das vantagens de usar a linha de comando e a interface do RPC, conforme sugerido neste tutorial: Os especialistas já fizeram o trabalho duro para nós, incluindo coisas como enviar para endereços legados e Bech32. Acabamos usando essa funcionalidade para nosso próprio benefício). + +Aqui está um exemplo de um envio para um endereço SegWit, no modo easy: +``` +$ bitcoin-cli sendtoaddress tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005 +854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42 +``` +Se olhar para a nossa transação, podemos ver o uso do endereço Bech32: +``` +$ bitcoin-cli gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42" verbose=true +{ + "amount": -0.00500000, + "fee": -0.00036600, + "confirmations": 0, + "trusted": true, + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "walletconflicts": [ + ], + "time": 1592948795, + "timereceived": 1592948795, + "bip125-replaceable": "no", + "details": [ + { + "address": "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", + "category": "send", + "amount": -0.00500000, + "vout": 1, + "fee": -0.00036600, + "abandoned": false + } + ], + "hex": "0200000002114d5a4c3b847bc796b2dc166ca7120607b874aa6904d4a43dd5f9e0ea79d4ba010000006a47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042dfeffffffa71321e81ef039af490251379143f7247ad91613c26c8f3e3404184218361733000000006a47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7efeffffff026854160000000000160014d591091b8074a2375ed9985a9c4b18efecfd416520a1070000000000160014751e76e8199196d454941c45d1b3a323f1433bd6c60e1b00", + "decoded": { + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "hash": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "version": 2, + "size": 366, + "vsize": 366, + "weight": 1464, + "locktime": 1773254, + "vin": [ + { + "txid": "bad479eae0f9d53da4d40469aa74b8070612a76c16dcb296c77b843b4c5a4d11", + "vout": 1, + "scriptSig": { + "asm": "304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7[ALL] 03ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d", + "hex": "47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d" + }, + "sequence": 4294967294 + }, + { + "txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7", + "vout": 0, + "scriptSig": { + "asm": "304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a316[ALL] 0339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e", + "hex": "47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01463400, + "n": 0, + "scriptPubKey": { + "asm": "0 d591091b8074a2375ed9985a9c4b18efecfd4165", + "hex": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh" + ] + } + }, + { + "value": 0.00500000, + "n": 1, + "scriptPubKey": { + "asm": "0 751e76e8199196d454941c45d1b3a323f1433bd6", + "hex": "0014751e76e8199196d454941c45d1b3a323f1433bd6", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx" + ] + } + } + ] + } +} +``` +Na verdade, ambos os ```vouts``` usam endereços Bech32: O nosso destinatário e o endereço de troco gerado automaticamente. + +Mas quando retrocedemos nosso ```vin```, descobrimos que veio de um endereço legado. Isso porque não importa: +``` +$ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7" +{ + "amount": 0.01000000, + "confirmations": 43, + "blockhash": "00000000000000e2365d2f814d1774b063d9a04356f482010cdfdd537b1a24bb", + "blockheight": 1773212, + "blockindex": 103, + "blocktime": 1592937103, + "txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7", + "walletconflicts": [ + ], + "time": 1592936845, + "timereceived": 1592936845, + "bip125-replaceable": "no", + "details": [ + { + "address": "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 0 + } + ], + "hex": "020000000001016a66efa334f06e2c54963e48d049a35d7a1bda44633b7464621cae302f35174a0100000017160014f17b16c6404e85165af6f123173e0705ba31ec25feffffff0240420f00000000001976a914626ab1ca41d98f597d18d1ff8151e31a40d4967288acd2125d000000000017a914d5e76abfe5362704ff6bbb000db9cdfa43cd2881870247304402203b3ba83f51c1895b5f639e9bfc40124715e2495ef2c79d4e49c0f8f70fbf2feb02203d50710abe3cf37df4d2a73680dadf3cecbe4f2b5d0b276dbe7711d0c2fa971a012102e64f83ee1c6548bcf44cb965ffdb803f30224459bd2e57a5df97cb41ba476b119b0e1b00" +} +``` + +## Enviando uma transação SegWit o modo hard + +Da mesma forma, podemos financiar uma transação com um endereço Bech32, sem nenhuma diferença em relação às técnicas que aprendemos até agora. Aqui está uma maneira exata de fazer isso com uma transação bruta completa: +``` +$ changeaddress=$(bitcoin-cli getrawchangeaddress) +$ echo $changeaddress +tb1q4xje3mx9xn7f8khv7p69ekfn0q72kfs8x3ay4j +$ bitcoin-cli listunspent +[ +... + { + "txid": "003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452", + "vout": 0, + "address": "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6", + "label": "", + "scriptPubKey": "0014a226e1dfd08537b02de04f667a49bd46f9b9f578", + "amount": 0.01000000, + "confirmations": 5, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/0'/5']0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640)#hd66hknp", + "safe": true + } +] +$ recipient=tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') +$ echo $utxo_txid $utxo_vout +003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452 0 +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.002, "'$changeaddress'": 0.007 }''') +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +e02568b706b21bcb56fcf9c4bb7ba63fdbdec1cf2866168c4f50bc0ad693f26c +``` +Tudo funciona exatamente da mesma forma que outros tipos de transações! + +### Reconhecendo o novo descritor + +Se olharmos o campo ```desc```, notaremos que o endereço SegWit tem um descritor de estilo diferente daqueles encontrados na sessão [§3.5: Entendendo o descritor](03_5_Understanding_the_Descriptor.md). Um descritor legado descrito nessa sessão se parecia com algo assim: `pkh ([d6043800 / 0 '/ 0' / 18 '] 03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388) # 4ahsl9pk`. Nosso novo descritor SegWit se parece mais com isso: `wpkh ([d6043800 / 0 '/ 0' / 5 '] 0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640) # hd66hknp" `. + +A grande diferença que precisamos notar é que a função mudou. Anteriormente, era ```pkh```, que é um endereço padrão de chave pública com hash P2PKH. Ao invés disso, o endereço SegWit é ```wpkh```, o que significa que é um endereço SegWit P2WPKH nativo. Isso dá destaque ao :fire: ***poder dos descritores***. Eles descrevem como criar um endereço a partir de uma chave ou outra informação, com as funções definindo de forma inequívoca como fazer o endereço com base no tipo de cada endereço. + +## Resumo do Criando uma transação do tipo SegWit + +Realmente não há complexidade para criar transações SegWit. Internamente, elas são estruturadas de forma diferente das transações legadas, mas na linha de comando não existe diferença: Apesar usamos um endereço com um prefixo diferente. A única coisa a ser observada é que algumas pessoas podem não conseguir enviar para um endereço Bech32 se estiverem usando um software obsoleto. + +> :fire: ***Qual é o poder de criar transações usando o SegWit?*** +> _As vantagens._ As transações do SegWit são menores e, portanto, serão mais baratas de serem enviadas do que as transações legadas devido às taxas mais baixas. O Bech32 diminui essa vantagem e também cria endereços que são mais difíceis de errar durante a transcrição, e isso é muito importante, visto que o erro do usuário é uma das maneiras mais prováveis ​​de terem seus bitcoins perdidos. +> _As desvantagens._ Os endereços SegWit não tem suporte em nodes do Bitcoin obsoleto. Em particular, as pessoas podem não conseguir enviar para o nosso endereço Bech32. + +## O que vem depois? + +Vamos avançar mais um pouco no "bitcoin-cli" com o [Capítulo 5: Controlando as transações do Bitcoin](05_0_Controlling_Bitcoin_Transactions.md). \ No newline at end of file From 9712478a77e9915bf73fad4ad92341d1df767f50 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 11:19:43 -0300 Subject: [PATCH 4/6] Revert "Chapter 04 translated" This reverts commit 8b3b5688505007c360cdc84ea6585c64f873da40. --- pt/04_0_Sending_Bitcoin_Transactions.md | 30 -- pt/04_1_Sending_Coins_The_Easy_Way.md | 102 ----- pt/04_2_Creating_a_Raw_Transaction.md | 274 ----------- pt/04_2__Interlude_Using_JQ.md | 429 ------------------ ..._a_Raw_Transaction_with_Named_Arguments.md | 97 ---- ..._4_Sending_Coins_with_a_Raw_Transaction.md | 187 -------- pt/04_4__Interlude_Using_Curl.md | 314 ------------- ...g_Coins_with_Automated_Raw_Transactions.md | 171 ------- pt/04_6_Creating_a_Segwit_Transaction.md | 288 ------------ 9 files changed, 1892 deletions(-) delete mode 100644 pt/04_0_Sending_Bitcoin_Transactions.md delete mode 100644 pt/04_1_Sending_Coins_The_Easy_Way.md delete mode 100644 pt/04_2_Creating_a_Raw_Transaction.md delete mode 100644 pt/04_2__Interlude_Using_JQ.md delete mode 100644 pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md delete mode 100644 pt/04_4_Sending_Coins_with_a_Raw_Transaction.md delete mode 100644 pt/04_4__Interlude_Using_Curl.md delete mode 100644 pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md delete mode 100644 pt/04_6_Creating_a_Segwit_Transaction.md diff --git a/pt/04_0_Sending_Bitcoin_Transactions.md b/pt/04_0_Sending_Bitcoin_Transactions.md deleted file mode 100644 index 5c3babe..0000000 --- a/pt/04_0_Sending_Bitcoin_Transactions.md +++ /dev/null @@ -1,30 +0,0 @@ - -# Capítulo 4: Enviando transações no Bitcoin - -Este capítulo descreve três métodos diferentes para enviar bitcoins para endereços P2PKH normais à partir da linha de comando, usando apenas o ```bitcoin-cli```. - -## Objetivos deste capítulo - -Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - - * Decidir como enviar dinheiro usando o Bitcoin; - * Criar uma transação bruta; - * Usar a aritmética para calcular as taxas. - -Os objetivos secundários incluem a capacidade de: - - * Compreender transações e taxas de transação; - * Entender as transações ```legacy``` e ```SegWit```; - * Usar métodos básicos para enviar dinheiro; - * Usar métodos de cálculo de taxa automática para enviar dinheiro; - * Entender os perigos de transações brutas. - -## Tabela de Conteúdo - - * [Seção 1: Enviando bitcoins no modo easy](04_1_Sending_Coins_The_Easy_Way.md) - * [Seção 2: Criando uma transação bruta](04_2_Creating_a_Raw_Transaction.md) - * [Prefácio: Usando o JQ](04_2__Interlude_Using_JQ.md) - * [Seção 3: Criando uma transação bruta com argumentos nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) - * [Seção 4: Enviando bitcoins usando transações brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md) - * [Seção 5: Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) - * [Seção 6: Criando uma transação do tipo SegWit](04_6_Creating_a_Segwit_Transaction.md) \ No newline at end of file diff --git a/pt/04_1_Sending_Coins_The_Easy_Way.md b/pt/04_1_Sending_Coins_The_Easy_Way.md deleted file mode 100644 index 6131040..0000000 --- a/pt/04_1_Sending_Coins_The_Easy_Way.md +++ /dev/null @@ -1,102 +0,0 @@ -# 4.1: Enviando bitcoins no modo easy - -O ```bitcoin-cli``` oferece três principais maneiras de enviar bitcoins: Utilizando um simples comando; Utilizando uma transação bruta e; Utilizando uma transação bruta com cálculos. Cada um possui seus prós e contras. Este primeiro método de envio será o mais simples. - -## Definindo sua taxa de transação - -Antes de enviar qualquer bitcoin pela rede, devemos pensar sobre as taxas de transação que iremos pagar. - -> :book: ***O que é uma taxa de transação?*** Não existe almoço grátis. Os mineradores adicionam as transações nos blocos porque são pagos para fazer isso. Eles não apenas são pagos pela rede para criar o bloco, mas também são pagos pelas pessoas que realizam as transações para incluí-las na blockchain. Se não pagarmos a taxa, nossa transação pode ficar travada... Para sempre (ou, até que seja salva por alguns dos truques que falaremos no [capítulo cinco](05_0_Controlling_Bitcoin_Transactions.md)). - -Ao usar métodos simples e automatizados para criar transações, conforme descrito aqui e na sessão [§4.5: Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), o Bitcoin calculará as taxas de transação para nós. Isso é feito usando taxas flutuantes, onde o ```bitcoind``` observa quanto tempo as transações estão demorando para confirmar e calcula automaticamente o que devemos gastar. - -Podemos ter um controle dessas informações colocando os valores racionais no nosso arquivo ```~/.bitcoin/bitcoin.conf```. Os valores de baixo custo a seguir garantiriam que houvesse uma taxa de transação mínima de 10.000 satoshis por kByte de dados em nossa transação e solicitariam que as taxas flutuantes calculassem uma boa quantia para colocar a nossa transação nos próximos seis blocos. -``` -mintxfee=0.0001 -txconfirmtarget=6 -``` -No entanto, como iremos partir do pressuposto que ninguém que esteja fazendo este tutorial queira esperar para as transações serem confirmadas, vamos adotar os seguintes valores: -``` -mintxfee=0.001 -txconfirmtarget=1 -``` -Devemos inseri-los no arquivo ```~/.bitcoin/bitcoin.conf```, na seção principal, no início do arquivo ou se quisermos ter a certeza de nunca iremos utilizá-lo em outro lugar, podemos colocar na sessão ```[test]```. - -Para trabalharmos neste tutorial, estamos dispostos a gastar 100.000 satoshis por kB em cada transação, e queremos colocar cada transação no próximo bloco! Para colocar isso em uma perspectiva para melhor entendimento, uma transação simples é executada com um tamanho de 0,25 KB a 1 KB, então estaremos pagando algo em torno de 25 mil a 100 mil satoshis, sendo que atualmente, taxas acima de 10 mil são consideradas altíssimas para transações de quantidade média. - -Depois de editar o arquivo ```bitcoin.conf```, vamos reiniciar o bitcoind usando dois comandos: -``` -$ bitcoin-cli stop -$ bitcoind -daemon -``` - -## Obtendo um endereço - -Precisamos encontrar algum endereço para enviar nossas moedas. Normalmente, alguém nos envia em um endereço e talvez nos dê uma assinatura para provar que é o proprietário desse endereço. Como alternativa, podemos nos fornecer um QR code para que possamos digitalizar, evitando assim possíveis erros de digitação na hora de colocar o endereço no local do destinatário. Em nosso caso, vamos enviar os bitcoins para `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, que é o endereço de retorno de um antigo fauce da rede Testenet. - -> :book: ***O que é um QR code?*** Um QR code é apenas um jeito diferente de passar o endereço Bitcoin. Muitas carteiras geram os QR codes para nós, enquanto alguns sites tentam convertê-los em um endereço usando o QR code. Obviamente, só podemos aceitar um QR code de um site no qual confiamos. Um pagador pode usar um leitor de código de barras para ler o código QR e, em seguida, pagá-lo. - -## Enviando os bitcoins - -Agora estamos prontos para enviar alguns bitcoins. Na verdade, isso é bastante simples por meio da linha de comando. Basta usar ```bitcoin-cli sendtoaddress [endereço] [quantidade]```. Portanto, para enviar uns satoshinhos para o endereço `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, basta fazer o seguinte: -``` -$ txid=$(bitcoin-cli sendtoaddress n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi 0.001) -$ echo $txid -93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8 -``` - -> 🙏 Para ajudar a manter os faucets da rede de testes vivos, tente usar o endereço que nos foi enviado os bitcoins no capítulo anterior, onde falamos sobre os recebimentos de transações. - -Precisamos nos certificar de que o endereço digitado é o lugar para onde desejamos enviá-lo. Por isso, certifique-se _duas vezes_. Se cometermos algum erro no Bitcoin, não há como voltar atrás. - -Iremos receber um txid de retorno quando usarmos este comando. - -> ❕ Você pode acabar com um código de erro se não tivermos bitcoins suficientes na carteira para fazer a transação. Dependendo do nosso saldo atual, que podemos acessar usando o ```bitcoin-cli getbalance```, pode ser necessário ajustar o valor que iremos enviar para que bata com o valor que está sendo enviado, não se esquecendo da taxa de transação no meio deste processo. Se o nosso saldo atual for 0,001, podemos tentar enviar 0,0001. Como alternativa, seria melhor tirar a taxa que esperamos pagar que foi enviada na mensagem de erro do nosso saldo atual. Esta é uma boa prática, pois muitas carteiras esperam que calculemos nosso próprio valor + taxas ao fazermos as transações, mesmo as carteiras mais populares usam essa premissa. - -> :warning: **ATENÇÃO:** O comando ```bitcoin-cli``` realmente gera comandos usando o JSON-RPC quando está se comunicando com o bitcoind. Eles podem ser muito exigentes. Este é um exemplo: Se listarmos a quantidade de bitcoin sem o zero à esquerda (ou seja usando ".1" em vez de "0.1"), o ```bitcoin-cli``` irá acusar um erro com uma mensagem misteriosa. - -> :warning: **ATENÇÃO:** Mesmo se formos cuidadosos com nossos dados, é possível que haja este erro: _"Fee estimation failed. Fallbackfee is disabled"_. De maneira geral, isso significa que nosso ```bitcoind``` local não tem informações suficientes para estimar as taxas. Não é para vermos isso se estivermos esperado que nossa blockchain sincronize e configure nosso sistema com o Bitcoin Standup. Mas se não estivermos totalmente sincronizados, podemos nos deparar com este erro. Também pode ser que não estejamos usando um ```bitcoin.conf``` padrão: A informação ```blocksonly = 1``` fará com que nosso ```bitcoind``` não consiga estimar as taxas. - -## Examinando nossa transação - -Podemos ver nossa transação usando o ID de transação: -``` -{ - "amount": -0.00100000, - "fee": -0.00022200, - "confirmations": 0, - "trusted": true, - "txid": "93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8", - "walletconflicts": [ - ], - "time": 1592604194, - "timereceived": 1592604194, - "bip125-replaceable": "no", - "details": [ - { - "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", - "category": "send", - "amount": -0.00100000, - "vout": 1, - "fee": -0.00022200, - "abandoned": false - } - ], - "hex": "0200000001e982921bb0189afc486e20bb05cc5825c71a0ba8868043ed04ece9ab0cb12a8e010000006a47304402200fc493a01c5c9d9574f7c321cee6880f7f1df847be71039e2d996f7f75c17b3d02203057f5baa48745ba7ab5f1d4eed11585bd8beab838b1ca03a4138516fe52b3b8012102fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9bafeffffff02e8640d0000000000160014d37b6ae4a917bcc873f6395741155f565e2dc7c4a0860100000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac780b1b00" -} -``` -Você pode ver não apenas o valor transferido (0,001 BTC), mas também uma taxa de transação (0,000222 BTC), que é cerca de um quarto da taxa mínima de 0,001 BTC/kB que foi definida, o que sugere que a transação foi de cerca de um quarto de kB de tamanho. - -Enquanto esperamos que ela seja confirmada, podemos notar que o ```bitcoin-cli getbalance``` mostra que nosso dinheiro já foi debitado. Da mesma forma, o ```bitcoin-cli listunspent``` mostrará que uma transação inteira foi perdida, mesmo que fosse mais do que o que queríamos enviar. Há uma razão para isso: Sempre que temos moedas entrando, precisamos enviar _tudo_ junto, e temos que fazer um pouco de malabarismos se quisermos realmente ficar com parte dele! Mais uma vez, o ```sendtoaddress``` cuida de tudo isso para nós, o que significa que não precisamos nos preocupar em fazer qualquer alteração até enviar uma transação bruta. Nesse caso, uma nova transação aparecerá com nossa alteração quando nosso envio for incorporado a um bloco. - -## Resumo do Enviando bitcoins no modo easy - -Para enviar moedas facilmente, precisamos nos certificar de que nossos padrões de transação sejam racionais, obtendo um endereço e enviando as nossas moedas para lá. É por isso que esse modo é o mais fácil deles! - -> :fire: ***Qual é o poder de enviar moedas no modo easy?*** -> _As vantagens._ É fácil. Não precisamos nos preocupar com coisas misteriosas como UTXOs. Não precisamos calcular as taxas de transação manualmente, então, é provável que não iremos cometer erros que custem grandes valores Se o nosso único objetivo é sentar na frente do computador e enviar alguns bitcoins, este é o caminho certo para fazer isso. -> _As desvantagens._ É alto nível. Temos muito pouco controle sobre o que está acontecendo e não podemos fazer nada demais. Se estamos planejando desenvolver um software mais complexo utilizando o Bitcoin ou se desejamos um entendimento mais profundo de como o Bitcoin funciona, então o modo easy é apenas um carrossel sem graça antes de chegarmos nas montanhas russas. - -## O Que Vem Depois? - -Vamos continuar "Enviando Transações de Bitcoin" na sessão [§4.2 Criando uma transação bruta](04_2_Creating_a_Raw_Transaction.md). \ No newline at end of file diff --git a/pt/04_2_Creating_a_Raw_Transaction.md b/pt/04_2_Creating_a_Raw_Transaction.md deleted file mode 100644 index 4a5f0b6..0000000 --- a/pt/04_2_Creating_a_Raw_Transaction.md +++ /dev/null @@ -1,274 +0,0 @@ -# 4.2 Criando uma transação bruta - -Agora estamos pronto para criar transações brutas no Bitcoin. Isso permite que enviemos dinheiro, mas criemos as transações com a precisão desejada. Nesta primeira seção, iremos nos concentrar em uma transação simples de uma entrada e uma saída. Este tipo de transação _não_ é realmente útil, porque raramente vamos querer enviar todo o nosso dinheiro para uma pessoa (a menos que estejamos apenas encaminhando, como se estivesse movendo coisas de uma carteira para outra). Portanto, esse _não é o melhor método_ para enviar dinheiro. É apenas um conteúdo fundamental para _realmente_ enviar dinheiro com uma transação bruta. - -## Compreendendo a transação no Bitcoin - -Antes de mergulhar na criação de transações brutas, devemos nos certificar de que entendemos como uma transação no Bitcoin funciona. Tudo gira entorno dos UTXOs. - -> :book: ***O que é um UTXO?*** Quando recebemos dinheiro em nossa carteira Bitcoin, ele aparece como uma transação individual. Cada uma dessas transações é chamada de saída de transação não gasta (Unspent Transaction Output em inglês, mais conhecida como UTXO). Não importa se vários pagamentos foram feitos para o mesmo endereço ou para vários endereços: Cada transação recebida permanece distinta na carteira como um UTXO. - -Ao criarmos uma nova transação de saída, reunimos um ou mais UTXOs, cada um representando um pouquinho do dinheiro que recebemos. Nós os usamos como entradas para uma nova transação. Juntos, o valor deles deve ser igual ao que desejamos gastar _ou mais do que o total_. Em seguida, geramos uma ou mais saídas, que dão o dinheiro representado pelas entradas a uma ou mais pessoas. Isso cria novos UTXOs para os destinatários, que podem então usá-los para financiar transações futuras. - -Aqui está o truque: _Todos os UTXOs que coletarmos são gastos na íntegra!_ Isso significa que se quisermos enviar apenas parte do dinheiro em um UTXO para outra pessoa, também precisamos gerar uma saída adicional que envia o resto para nós! Por enquanto, não vamos nos preocupar com isso, mas o uso de um endereço de mudança será vital ao passar da teoria deste capítulo para transações mais práticas. - -## Listando as transações não gastas - -Para criar uma nova transação bruta, devemos saber quais UTXOs estão disponíveis para gastar. Podemos determinar essas informações com o comando ```bitcoin-cli listunspent```: -``` -$ bitcoin-cli listunspent -[ - { - "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", - "vout": 0, - "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", - "label": "", - "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", - "amount": 0.00010000, - "confirmations": 20, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", - "safe": true - }, - { - "txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a", - "vout": 1, - "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", - "label": "", - "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", - "amount": 0.00050000, - "confirmations": 3, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", - "safe": true - }, - { - "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", - "vout": 0, - "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", - "label": "", - "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", - "amount": 0.00022000, - "confirmations": 3, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", - "safe": true - } -] - -``` -Esta lista mostra três UTXOs diferentes, no valor de 0,0001, 0,0005 e 0,00022 BTC. Observe que cada um tem o próprio _txid_ distinto e permanece seperado na carteira, até mesmo os dois últimos, que foram enviados para o mesmo endereço. - -Quando quisermos gastar um UTXO, não é suficiente apenas saber o id da transação. Isso porque cada transação pode ter várias saídas! Lembra daquele primeiro valor que o faucet nos enviou? Na transação, parte do dinheiro foi para nós e parte para outra pessoa. O ```txid``` se refere à transação geral, enquanto um ```vout``` diz qual das múltiplas saídas recebemos. Nesta lista, cada uma dessas transações é a primeira ```vout``` de uma transação anterior, mas _não necessariamente é sempre o caso_. - -Portanto, o txid+vout=UTXO. Essa será a base de qualquer transação bruta. - -## Escrevendo uma transação bruta com uma saída - -You're now ready to write a simple, example raw transaction that shows how to send the entirety of a UTXO to another party. As noted, this is not necessarily a very realistic real-world case. -Agora estamos prontos para escrever um exemplo simples de transação bruta que mostra como enviar um UTXO inteiro para outra parte. Conforme falamos anteriormente, este não é um caso muito realista. - -> :warning: **Atenção:** É muito fácil perder dinheiro com uma transação bruta. Considere que todas as instruções sobre como enviar bitcoins por meio de transações brutas são _muito_, _muito_ perigosas. Sempre que estiver enviando moedas na _mainnet_ para outras pessoas, devemos usar um dos outros métodos explicados neste capítulo. Criar transações brutas é extremamente útil se estivermos escrevendo programas para o bitcoin, mas _só_ neste caso. Por exemplo: Ao escrever este exemplo para uma versão anterior deste tutorial, acidentalmente gastamos a transação errada, embora tivessemos cerca de 10 vezes mais. Quase tudo isso foi enviado para os mineradores. - -### Preparando a transação bruta - -Para as melhores práticas, iremos começar cada transação registrando cuidadosamente os txids e vouts que iremos gastar. - -Nesse caso, vamos gastar um no valor de 0,00050000 BTC porque é o único com um valor decente. -``` -$ utxo_txid="61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a" -$ utxo_vout="1" -``` -Da mesma forma, devemos registrar o endereço do destinatário para ter certeza de que está correto. No nosso exemplo estamos enviando novamente o saldo de volta para o faucet: -``` -$ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" -``` -Como de prache, vamos verificar as variáveis com cuidado, para ter certeza de que são aquilo que esperamos! -``` -$ echo $utxo_txid -61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a -$ echo $utxo_vout -1 -$ echo $recipient -n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi -``` -Esse destinatário é particularmente importante, porque se bagunçarmos tudo, nosso dinheiro terá dado _tchau tchau_! E como já vimos, escolher a transação errada pode resultar em perda de dinheiro! Portanto, vamos verificar tudo, pelo menos uma vez mais do que a quantidade de costume. - -### Entendendo a taxa de transação - -Cada transação tem uma taxa associada. Ela fica _implícita_ quando enviamos uma transação bruta: O valor que vamos pagar como taxa é sempre igual ao valor de entrada menos o valor de saída. Portanto, temos que diminuir um pouco o valor enviado para ter certeza de que nossa transação será realizada. - -> :warning: **Atenção:** Esta é a parte muito perigosa das transações brutas! Como gastamos automaticamente toda a quantidade de UTXOs que tivermos, é extremamente importante certificar-se de que sabemos: (1) Precisamente quais UTXOs estamos utilizando; (2) Exatamente quanto dinheiro ele possui; (3) Exatamente quanto dinheiro estamos enviando; e (4) qual é a diferença que ficará para os mineradores. Se errarmos e, por exemplo, usarmos o UTXO errado (um que tenha mais dinheiro do que pensávamos) ou se enviarmos muito pouco dinheiro, o excesso será perdido. _Para sempre_! Não podemos cometer esse erro! Por isso, é importante sabermos as entradas e saídas com _precisão_. Ou melhor, não utilizarmos as transações brutas, exceto como parte de um programa cuidadosamente considerado e verificado três vezes. - -> :book: ***Quanto devemos gastar com taxas de transação?*** [Bitcoin Fees](https://bitcoinfees.21.co/) tem uma ótima avaliação ao vivo. O site diz que "fastest and cheapest transaction fee is currently XXX satoshis/byte" onde o XXX será a quantidade de satoshis por byte que precisaremos pagar e também, "For the median transaction size of YYY bytes, this results in a fee of ZZ,ZZZ satoshis", onde YYY é o tamanho de uma transação média e ZZ,ZZZ é o resultado da multiplicação entre YYY e XXX. No caso, precisamos apenas observar o valor ZZ,ZZZ descrito no site. - -No momento em que este tutorial está sendo escrito, o _Bitcoin Fees_ sugere uma taxa de transação de cerca de 10.000 satoshis, que é o mesmo que 0,0001 BTC. Obviamente, isso é para a mainnet, não para a testnet, mas queremos testar as coisas de forma realista, então iremos utilizar esta quantidade. - -Nesse caso, isso vamos pegar 0,0005 BTC no UTXO que selecionamos, reduzindo a quantidade de 0,0001 BTC para a taxa de transação e enviar os 0,0004 BTC restantes. E este é um exemplo do porque os micropagamentos não funcionam na rede principal do Bitcoin, porque uma taxa de transação que consome 20% do valor enviado é muito cara, agora imagina se os valores forem menores do que a taxa de transação. Por isso que temos a Lightning. - -> :warning: **Atenção:** Quanto menor for a taxa de transação, mais tempo irá demorar para que nossa transação entre na blockchain. O site _Bitcoin Fees_ lista os tempos que precisaremos esperar em relação a quantidade de satoshi por byte. Como os blocos são construídos em média a cada 10 minutos, a mudança de taxa pode significar uma mudança de espera de minutos para algumas horas ou dias! Portanto, escolha uma taxa de transação apropriada para o que estamos enviando. É importante observar que nunca devemos colocar taxas abaixo da quantidade mínima para transação, que é 0,0001 BTC. - -### Escrevendo a transação bruta - -Agora estamos prontos para criar a transação bruta. Usaremos o comando ```createrawtransaction```, que pode parecer um pouco intimidante. Isso porque o comando ```createrawtransaction``` não o protege inteiramente do JSON RPC que o ```bitcoin-cli``` utiliza. Ao invés disso, vamos inserir uma matriz JSON para listar os UTXOs que está gastando e um objeto JSON para listar as saídas. - -Este é o formato padrão: -``` -$ bitcoin-cli createrawtransaction -'''[ - { - "txid": "'$your_txid'", - "vout": '$your_vout' - } -]''' -'''{ - "'$your_recipient'": bitcoin_amount - }''' -``` - - Não, não é um erro de digitação. Existem todos os tipos de citações malucas, mas confie que elas farão a coisa certa. Vamos usar `'''` para marcar o início e o fim do array e no objeto JSON. Protegendo as palavras normais como ```"this"```, mas não precisamos proteger os números: ```0```. Se forem variáveis, vamos inserir as aspas simples, como ```"'$this_word'"``` e ```'$this_num'```. (Ufa! Não se preocupe, você pega o jeito). - - Aqui está um comando que cria uma transação bruta para enviar $utxo para o $recipient. -``` -$ rawtxhex=$(bitcoin-cli createrawtransaction '''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' '''{ "'$recipient'": 0.0004 }''') -$ echo $rawtxhex -02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f3610100000000ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 -``` - -### Verificando a transação bruta - -Depois disso, devemos verificar a transação bruta com o comando ```decoderawtransaction``` para ter certeza de que faremos a coisa certa. -``` -$ bitcoin-cli decoderawtransaction $rawtxhex -{ - "txid": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298", - "hash": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298", - "version": 2, - "size": 85, - "vsize": 85, - "weight": 340, - "locktime": 0, - "vin": [ - { - "txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a", - "vout": 1, - "scriptSig": { - "asm": "", - "hex": "" - }, - "sequence": 4294967295 - } - ], - "vout": [ - { - "value": 0.00040000, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" - ] - } - } - ] -} -``` - -É importante verificarmos o ```vin```. Estamos gastando a transação certa? Ela contém a quantia de dinheiro esperada? (Vamos verificar com o comando ```bitcoin-cli gettransaction``` e nos certificar de olhar o ```vout``` se está correto). Além disso, vamos verificar o nosso ```vout```. Estamos enviando a quantidade correta? Está indo para o endereço certo? Finalmente, vamos fazer as contas para ter certeza de que o dinheiro que irá para as taxas está correto. O valor do UTXO menos a quantia que está sendo gasta é igual à taxa da transação esperada? - -> :information_source: **NOTA:** Podemos notar que cada entrada tem um número de sequência, definido aqui como 4294967295, que é 0xFFFFFFFF. Esta é a última fronteira das transações Bitcoin, porque é um campo padrão em transações que foram originalmente planejadas para um propósito específico, mas nunca foram totalmente implementadas. Portanto, agora existe esse inteiro parado em transações que podem ser reaproveitadas para outros usos. E, de fato, tem sido. No momento em que este livro foi escrito, havia três usos diferentes para a variável chamada ```nSequence``` no código Bitcoin Core: Ela habilita a possibilidade de RBF, ```nLockTime``` e timelocks relativos. Se não houver nada de estranho acontecendo, o ```nSequence``` será definido como 4294967295. Ajustar para um valor mais baixo sinaliza que coisas especiais estão acontecendo. - -### Assinando a transação bruta - -Até o momento, nossa transação bruta é apenas uma teoria: _Podemos_ enviá-la, mas nada irá acontecer. Precisamos fazer algumas coisas para colocá-la na rede. - -Primeiro, precisamos assinar nossa transação bruta: -``` - -$ bitcoin-cli signrawtransactionwithwallet $rawtxhex -{ - "hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", - "complete": true -} -$ signedtx="02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000" -``` -Observe que capturamos o hexadecimal assinado manualmente, ao invés de tentar analisá-lo a partir do objeto JSON. Um pacote de software chamado "JQ" poderia ter um desempenho melhor, como explicaremos no próximo prefácio. - -### Enviando a transação bruta - -Agora temos uma transação bruta pronta para ser usada, mas nada acontece com ela se não a colocarmos na rede, o que iremos fazer com o comando ```sendrawtransaction```. O retorno dele será uma txid: -``` -$ bitcoin-cli sendrawtransaction $signedtx -a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a -``` -Iremos observar imediatamente que o UTXO e o as nossas moedas foram removidas da nossa carteira: -``` -$ bitcoin-cli listunspent -[ - { - "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", - "vout": 0, - "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", - "label": "", - "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", - "amount": 0.00010000, - "confirmations": 23, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", - "safe": true - }, - { - "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", - "vout": 0, - "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", - "label": "", - "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", - "amount": 0.00022000, - "confirmations": 6, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", - "safe": true - } -] - -$ bitcoin-cli getbalance -0.00032000 -``` -Logo o ```listtransactions``` deve mostrar uma transação confirmada da categoria 'send'. -``` - { - "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", - "category": "send", - "amount": -0.00040000, - "vout": 0, - "fee": -0.00010000, - "confirmations": 1, - "trusted": true, - "txid": "a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a", - "walletconflicts": [ - ], - "time": 1592608574, - "timereceived": 1592608574, - "bip125-replaceable": "no", - "abandoned": false - } -``` -Podemos observar que ele corresponde aos endereços ```txid``` e ```recipient``` (recebedor). Não só mostra o ```amount``` (montante) enviado, mas também mostra a ```fee``` (taxa) da transação. E, a transação já recebeu uma confirmação, porque oferecemos uma taxa que seria colocado no próximo bloco. - -Parabéns! Estamos um pouco mais pobres agora! - -## Resumo do Criando uma transação bruta - -Quando satoshinhos entram na nossa carteira Bitcoin, eles permanecem em quantidades distintas, chamadas de UTXOs. Ao criar uma transação bruta para enviar as moedas, usamos um ou mais UTXOs para financiá-la. Podemos então, criar uma transação bruta, assiná-la e enviá-la pela rede Bitcoin. No entanto, esta é apenas uma base do que realmente acontece: Geralmente precisaremos criar uma transação bruta com várias saídas para realmente enviar algo na rede Bitcoin! - -## O que vem depois? - -Vamos fazer uma pausa do "Enviando transações de Bitcoin" para lermos o [Interlúdio: Usando JQ](04_2__Interlude_Using_JQ.md). \ No newline at end of file diff --git a/pt/04_2__Interlude_Using_JQ.md b/pt/04_2__Interlude_Using_JQ.md deleted file mode 100644 index 00b46cf..0000000 --- a/pt/04_2__Interlude_Using_JQ.md +++ /dev/null @@ -1,429 +0,0 @@ -# Prefácio: Usando o JQ - -A criação de uma transação bruta revelou como resultados mais complexos do ```bitcoin-cli``` que não podem ser salvos facilmente em variáveis de linha de comando. A resposta para isso e usar o JQ, que permite filtrar elementos individuais de dados JSON mais complexos. - -## Instalando o JQ - -O JQ está disponível em um [repositório no Github](https://stedolan.github.io/jq/). Basta fazermos o download para Linux, OS X ou Windows, de acordo com o seu sistema operacional. - -Depois de baixar o binário, podemos instalá-lo em nosso sistema. Se estivermos trabalhando em um VPS Debian, fazendo o passo a passo desse curso, nossa instalação será parecida com esta: -``` -$ mv jq-linux64 jq -$ sudo /usr/bin/install -m 0755 -o root -g root -t /usr/local/bin jq -``` -> :book: ***O que é o JQ?*** O repositório explica melhor, dizendo "O jq é como o sed para dados o JSON - você pode usá-lo para dividir, filtrar, mapear e transformar dados estruturados com a mesma facilidade que o sed, awk, grep e permitem que você brinque com o texto". - -## Usando o JQ para acessar um valor do objeto JSON pelo índice - -**Caso de uso:** _Capturando o hex de uma transação bruta assinada._ - -Na seção anterior, o uso de ```signrawtransaction``` não pareceu ser um bom método devido ao fato de não ser capaz de capturar os dados facilmente em variáveis devido a seu retorno no formato JSON: -``` -$ bitcoin-cli signrawtransactionwithwallet $rawtxhex -{ - "hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", - "complete": true -} -``` -Felizmente, o JQ pode facilmente capturar os dados desse tipo! - -Para usar o JQ, vamos executar ```jq``` no backend de um pipe e sempre usar a invocação padrão que é ```jq -r '.'```. O ```-r``` diz ao JQ para diminuir a saída bruta, que funcionará para variáveis de linha de comando, enquanto o ```.``` diz ao JQ para mostrar na tela Protegemos esse argumento com ```''``` porque precisaremos dessa proteção mais tarde conforme nossas invocações ```JQ``` se tornarem mais complexas. - -Para capturar um valor específico de um objeto JSON, basta listar o índice após o ```.```: -``` -$ bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex' -02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 -``` -Com essa ferramenta em mãos, podemos capturar as informações dos objetos JSON para variáveis na linha de comando: -``` -$ signedtx=$(bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex') -$ echo $signedtx -02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 -``` -Podemos usar então essas variáveis facilmente e sem erros: -``` -$ bitcoin-cli sendrawtransaction $signedtx -3f9ccb6e16663e66dc119de1866610cc4f7a83079bfec2abf0598ed3adf10a78 -``` -## Usando o JQ para acessar valores únicos do objeto JSON em um array usando o índice - -**Caso de uso:** _Capturando o txid e o vout para um UTXO selecionado._ - -Extrair dados de um objeto JSON é fácil, mas e se esse objeto JSON estiver em uma matriz JSON? O comando ```listunspent``` oferece um ótimo exemplo, porque geralmente contém várias transações diferentes. E se quisermos capturar as informações específicas de _um_ deles? - -Ao trabalhar com um array JSON, a primeira coisa que precisamos fazer é informar ao JQ qual índice acessar. Por exemplo, podemos estar olhando nossas transações no ```listunspent``` e decidimos que queremos trabalhar com a segunda. Podemos usar o ```'. [1]'``` para acessar o primeiro elemento. O ```[]``` diz que estamos referenciando um array JSON e o ```0``` diz que queremos o índice 0. -``` -$ bitcoin-cli listunspent | jq -r '.[1]' -{ - "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", - "vout": 0, - "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", - "label": "", - "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", - "amount": 0.00022, - "confirmations": 9, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", - "safe": true -} -``` -Podemos então capturar um valor individual dessa matriz (1) selecionada usando um pipe _dentro_ dos argumentos JQ; e então o (2) solicitando o valor específico posteriormente, como no exemplo anterior. Isso iria capturar o ```txid``` do primeiro objeto JSON na matriz JSON produzida pelo comando ```listunspent```: -``` -$ bitcoin-cli listunspent | jq -r '.[1] | .txid' -91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c -``` -Observe cuidadosamente como os ```''``` circundam toda a expressão JQ _incluindo_ o pipe. - -Este método pode ser usado para preencher variáveis para um UTXO que desejamos utilizar: -``` -$ newtxid=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') -$ newvout=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') -$ echo $newtxid -91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c -$ echo $newvout -0 -``` -Pronto! Agora podemos criar uma nova transação bruta usando nosso primeiro UTXO como entrada, sem ter que digitar qualquer uma das informações do UTXO manualmente! - -## Usando o JQ para acessar valores dos objetos JSON correspondentes em um array usando os índices - -**Caso de uso:** _Listar o valor de todos os UTXOs._ - -Ao invés de acessar um único valor específico em um objeto JSON específico, podemos acessar todos os valores específicos em todos os objetos JSON. Isso é feito com ```. []```, Onde nenhum índice é especificado. Por exemplo, podemos listar todos os saldos não gastos: -``` -$ bitcoin-cli listunspent | jq -r '.[] | .amount' -0.0001 -0.00022 -``` - -## Usando o JQ para cálculos simples usando índices - -**Caso de uso:** _Adicionando o valor de todos os UTXOs não gastos._ - -Neste ponto, podemos começar a usar o retorno do JQ para fazermos uma matemática simples. Por exemplo, somar os valores dessas transações não gastas com um script ```awk``` simples nos daria o equivalente ao ```getbalance```: -``` -$ bitcoin-cli listunspent | jq -r '.[] | .amount' | awk '{s+=$1} END {print s}' -0.00032 -$ bitcoin-cli getbalance -0.00032000 -``` - -## Usando o JQ para exibir vários valores de um objeto JSON em um array usando vários índice - -**Caso de uso:** _Listar as informações de uso para todos os UTXOs._ - -O JQ pode capturar facilmente elementos individuais de objetos JSON e arrays e colocar os elementos em variáveis. Esse será o principal uso que iremos fazer nas seções futuras. No entanto, ele também pode ser usado para reduzir grandes quantidades de informações geradas pelo ```bitcoin-cli``` em quantidades razoáveis de informações. - -Por exemplo, podemos querer ver uma lista de todos os nossos UTXOs (```. []```) E obter uma lista de todas as informações mais importantes (```.txid, .vout, .amount```): -``` -$ bitcoin-cli listunspent | jq -r '.[] | .txid, .vout, .amount' -ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36 -0 -0.0001 -91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c -0 -0.00022 -``` -Isso torna mais fácil decidir quais UTXOs gastar em uma transação bruta, mas não é muito bonito. - -Felizmente, o JQ também permite que sejamos mais sofisticados. Podemos usar as ```{}``` para criar novos objetos JSON (para análise adicional ou para um retorno mais bonito). Também podemos definir o nome da nova chave para cada um dos valores. A saída resultante deve ser muito mais intuitiva e menos sujeita a erros (embora, menos útil para jogar as informações diretamente nas variáveis). - -O exemplo a seguir mostra exatamente a mesma análise do ```listunspent```, mas com cada objeto JSON antigo reconstruído como um novo objeto JSON abreviado, com todos os novos valores nomeados com os índices antigos: -``` -$ bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }' -{ - "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", - "vout": 0, - "amount": 0.0001 -} -{ - "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", - "vout": 0, - "amount": 0.00022 -} -``` -Podemos, é claro, renomear nossos novos índices conforme acharmos necessário. Não há nada de mágico nos nomes originais: -``` -$ bitcoin-cli listunspent | jq -r '.[] | { tx: .txid, output: .vout, bitcoins: .amount }' -{ - "tx": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", - "output": 0, - "bitcoins": 0.0001 -} -{ - "tx": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", - "output": 0, - "bitcoins": 0.00022 -} -``` -## Usando o JQ para acessar os objetos JSON usando um valor pesquisado - -**Caso de uso:** _Pesquisando automaticamente os UTXOs que estão sendo usados em uma transação._ - -As pesquisas JQ até agora são bastante simples: Usamos um índice para pesquisar um ou mais valores em um objeto JSON ou no array. Mas e se quisermos pesquisar um valor em um objeto JSON... usando outro valor? Esse tipo de pesquisa indireta tem aplicabilidade real quando estamos trabalhando com transações criadas usando as UTXOs existentes. Por exemplo, podemos calcular o valor da soma dos UTXOs sendo usados em uma transação, algo de vital importância. - -Este exemplo usa a seguinte transação bruta. Podemos observar que esta é uma transação bruta mais complexa com duas entradas e duas saídas. Aprenderemos como fazer isso nas próximas sessões, mas por enquanto, é necessário sermos capazes de oferecer exemplos robustos. Observe que, ao contrário dos nossos exemplos anteriores, neste, temos dois objetos em nosso array ```vin``` e dois em nosso array ```vout```. -``` -$ bitcoin-cli decoderawtransaction $rawtxhex -{ - "txid": "6f83a0b78c598de01915554688592da1d7a3047eacacc8a9be39f5396bf0a07e", - "hash": "6f83a0b78c598de01915554688592da1d7a3047eacacc8a9be39f5396bf0a07e", - "size": 160, - "vsize": 160, - "version": 2, - "locktime": 0, - "vin": [ - { - "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", - "vout": 1, - "scriptSig": { - "asm": "", - "hex": "" - }, - "sequence": 4294967295 - }, - { - "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", - "vout": 1, - "scriptSig": { - "asm": "", - "hex": "" - }, - "sequence": 4294967295 - } - ], - "vout": [ - { - "value": 1.00000000, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 cfc39be7ea3337c450a0c77a839ad0e160739058 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914cfc39be7ea3337c450a0c77a839ad0e16073905888ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "mzTWVv2QSgBNqXx7RC56zEhaQPve8C8VS9" - ] - } - }, - { - "value": 0.04500000, - "n": 1, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 166692bda9f25ced145267bb44286e8ee3963d26 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914166692bda9f25ced145267bb44286e8ee3963d2688ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "mhZQ3Bih6wi7jP1tpFZrCcyr4NsfCapiZP" - ] - } - } - ] -} -``` - -### Recuperando o(s) valor(es) - -Suponha que saibamos exatamente como essa transação é construída: Sabemos que ela usa dois UTXOs como entrada. Para recuperar o txid para os dois UTXOs, poderíamos usar ```jq``` para consultar o valor .vin da transação e, em seguida, fazer referência ao primeiro índice do .vin e, em seguida, ao valor .txid desse array. Posteriormente, poderíamos fazer o mesmo com o primeiro array e, em seguida, o mesmo com os dois valores .vout de .vin. Simples: -``` -$ usedtxid1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .txid') -$ echo $usedtxid1 -d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c -$ usedtxid2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .txid') -$ echo $usedtxid2 -c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b - -$ usedvout1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .vout') -$ echo $usedvout1 -1 -$ usedvout2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .vout') -$ echo $usedvout2 -1 -``` -No entanto, seria melhor ter um caso geral que salvasse _automaticamente_ todos os txids de nossos UTXOs. - -Já sabemos que podemos acessar todos os ```.txid``` usando um valor do array ```. [] ```. Podemos usar isso para criar uma pesquisa geral no .txid: -``` -$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) -$ echo ${usedtxid[0]} -d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c -$ echo ${usedtxid[1]} -c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b - -$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) -$ echo ${usedvout[0]} -1 -$ echo ${usedvout[1]} -1 -``` -O único truque real aqui é como salvamos as informações usando o shell bash. Ao invés de salvar em uma variável com ```$ (command)```, nós salvamos em um array com ```($ (command))```. Fomos então capazes de acessar os elementos individuais do array bash com uma construção ```$ {variable [n]}```. Ao invés disso, poderíamos acessar todo o array usando a ```$ {variable [@]}```. (E antes que diga algo, ninguém nunca disse que o bash ficaria bonito). - -> :warning: **ATENÇÃO:** Lembre-se sempre de que um UTXO é uma transação _mais_ um vout. Perdemos o vout na primeira vez que escrevemos este exemplo JQ, e ele parou de funcionar quando acabamos com uma situação em que dois ```vouts``` foram enviados da mesma transação. - -### Recuperando o(s) objeto(s) relacionado(s) - -Agora podemos usar as informações salvas no ```txid``` e no ```vout``` para referenciar os UTXOs no ```listunspent```. Para encontrar as informações sobre os UTXOs usados pela transação bruta, precisamos examinar todo o array JSON (```[]```) com as transações não gastas. Podemos então escolher (```select```) objetos JSON individuais que incluem (```contains```) os txids. _Então_ selecionamos (```select```) as transações entre aquelas que _também_ contém (```contêm```) o valor correto. - -O uso de outro nível do pipe é a metodologia padrão do JQ: Pegamos um conjunto de dados, depois a reduzimos para todas as transações relevantes e, em seguida, reduzimos para os valores que foram realmente usados nessas transações. No entanto, os argumentos ```select``` e ```contains``` são algo novo. Eles mostram um pouco da complexidade do JSON que vai além do escopo deste tutorial. Por enquanto, saiba apenas que esta invocação em particular funcionará para capturar objetos correspondentes. - -Para começar de forma simples, vamos selecionar os dois UTXOs, um de cada vez: -``` -$ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[0]}'")) | select(.vout | contains('${usedvout[0]}'))' -{ - "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", - "vout": 1, - "address": "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH", - "scriptPubKey": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac", - "amount": 0.9, - "confirmations": 6, - "spendable": true, - "solvable": true -} -$ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[1]}'")) | select(.vout | contains('${usedvout[1]}'))' -{ - "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", - "vout": 1, - "address": "mzizSuAy8aL1ytFijds7pm4MuDPx5aYH5Q", - "scriptPubKey": "76a914d2b12da30320e81f2dfa416c5d9499d08f778f9888ac", - "amount": 0.4, - "confirmations": 5, - "spendable": true, - "solvable": true -} -``` -Ao invés disso, um simples bash usando um loop em ```for``` poderia nos dar _todos_ os nossos UTXOs: -``` -$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout'))'; done; -{ - "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", - "vout": 1, - "address": "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH", - "scriptPubKey": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac", - "amount": 0.9, - "confirmations": 7, - "spendable": true, - "solvable": true -} -{ - "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", - "vout": 1, - "address": "mzizSuAy8aL1ytFijds7pm4MuDPx5aYH5Q", - "scriptPubKey": "76a914d2b12da30320e81f2dfa416c5d9499d08f778f9888ac", - "amount": 0.4, - "confirmations": 6, - "spendable": true, - "solvable": true -} - -``` -Observe que estamos deixando um pouquinho mais feio nosso array ```$ {# usedtxid [*]}``` para determinar o tamanho dele, em seguida, acessamos cada valor no array ```usedtxid``` e cada valor no array ```usedvout``` paralelo, os colocando em variáveis mais simples para termos um acesso menos feio. - -## Usando o JSON para cálculos simples usando os valores - -**Caso de uso:** _Calcular automaticamente o valor dos UTXOs usados em uma transação._ - -Agora podemos ir um passo adiante e solicitar o .amount (ou qualquer outro valor do índice do JSON) dos UTXOs que estamos recuperando. - -Este exemplo repete o uso dos arrays ```$usedtxid``` e ```$usedvout``` definidos da seguinte forma: - -``` -$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) -$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) -``` - -O mesmo script ```for``` pode ser usado para percorrer os arrays, mas com um pipe adicionado no JQ que produz o valor ```amount``` para cada um dos UTXOs selecionados. - -``` -$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done; -0.9 -0.4 -``` - -Neste ponto, podemos somar os .amounts com um script ```awk```, para realmente ver quantas moedas estão nos UTXOs gastos na transação: - -``` -$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done | awk '{s+=$1} END {print s}' -1.3 -``` - -Perfeito! - -## Usando o JQ para cálculos complexos - -**Caso de uso:** _Calcular a taxa de uma transação._ - -Descobrir a taxa de transação completa neste ponto requer apenas mais um pouco de matemática: Bastando determinar quanto dinheiro está passando pelo .vout. Este é um uso simples de JQ onde apenas usamos o ```awk``` para somar o ```valor``` de todas as informações do ```vout```: - -``` -$ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}' -1.045 -``` - -Para completar o cálculo da taxa de transação, vamos subtrair o .vout .amount (1.045) do .vin .amount (1.3). -Para fazer isso, precisaremos instalar o ```bc```: - -``` -$ sudo apt-get intall bc -``` - -Se juntarmos tudo, iremos criar uma calculadora completa com apenas um script de cinco linhas: - -``` -$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) -$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) -$ btcin=$(for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done | awk '{s+=$1} END {print s}') -$ btcout=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}') -$ echo "$btcin-$btcout"| /usr/bin/bc -.255 -``` - -E esse também é um bom exemplo de por que precisamos verificar nossas suas taxas: Pretendíamos enviar uma taxa de transação com 5.000 satoshis, mas invés disso enviamos pagando 255.000 satoshis de taxa. Ops! - -> :warning: **Atenção:** A primeira vez que escrevemos esta lição, realmente calculamos mal a nossa taxa e não a vimos até que executamos nossa calculadora de taxas. É *tão* fácil, que nosso dinheiro acabou. (O exemplo acima é, na verdade, de nossa segunda iteração da calculadora, e dessa vez cometemos o erro de propósito). - -Para mais magia usando o JSON (e se alguma coisa não estiver clara), leia o [Manual JSON](https://stedolan.github.io/jq/manual/) e o [Livro de Receitas do JSON](https://github.com/stedolan/jq/wiki/Cookbook). Estaremos usando o JQ regularmente nos exemplos futuros. - -## Fazendo alguns aliases novos - -O código JQ pode ser um pouco pesado, então devemos considerar adicionar algumas invocações mais longas e interessantes ao nosso ```~/.bash_profile```. - -Sempre que estivermos procurando por uma grande massa de informações em uma saída de objeto JSON por um comando ```bitcoin-cli```, precisamos considerar escrever um alias para reduzi-lo exatamente ao que desejamos observar. - -``` -alias btcunspent="bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }'" -``` - -## Executando o script de taxa de transação - -O [script de cálculo de taxa](src/04_2_i_txfee-calc.sh) está disponível no diretório src/. Você pode baixá-lo e salvá-lo como ```txfee-calc.sh```. - -> :warning: **Atenção:** Este script não foi verificado extensivamente. Se for usá-lo para verificar as taxas de transação reais, só deve fazê-lo depois de fazer uma verificação pessoal dos valores. - -Certifique-se de que as permissões no script estejam corretas: - -``` -$ chmod 755 txfee-calc.sh -``` - -Podemos então, executar o script da seguinte maneira: - -``` -$ ./txfee-calc.sh $rawtxhex -.255 -``` - -Também podemos criar um alias: - -``` -alias btctxfee="~/txfee-calc.sh" -``` - -## Resumo do Usando o JQ - -O JQ facilita a extração de informações de arrays e objetos JSON. Ele também pode ser usado em scripts shell para cálculos bastante complexos que tornarão nossa vida mais fácil. - -## O que vem depois? - -Continue "Enviando Transações de Bitcoin" na sessão [§4.3 Criando uma transação bruta com argumentos nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md). \ No newline at end of file diff --git a/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md b/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md deleted file mode 100644 index 2ff9957..0000000 --- a/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md +++ /dev/null @@ -1,97 +0,0 @@ -# 4.3 Criando uma transação bruta com argumentos nomeados - -Às vezes, pode ser assustador descobrir a ordem correta dos argumentos para um comando ```bitcoin-cli```. Felizmente, podemos usar _ argumentos nomeados_ como alternativa. - -> :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.14.0. Se usarmos os scripts de configuração do tutorial, o que é importante fazer, precisamos verificar novamente a versão se tiver algum problema. Há também um bug no uso do comando ```createrawtransaction``` usando argumentos nomeados que presumivelmente serão corrigidos na versão 0.14.1. - -## Criando um alias do argumento nomeado - -Para usar um argumento nomeado, devemos executar o ```bitcoin-cli``` com o argumento ```-named```. Se planejamos fazer isso regularmente, provavelmente precisaremos criar um alias: -``` -alias bitcoin-cli="bitcoin-cli -named" -``` -Como de costume, isso é apenas para facilitar o uso, mas continuaremos usando todos os comandos para manter a clareza. - -## Testando um argumento nomeado - -Para saber quais são os nomes dos argumentos de um comando, precisamos consultar o ```bitcoin-cli help```. Ele listará os argumentos com a ordem adequada, mas agora também fornecerá nomes para cada um deles. - -Por exemplo, `bitcoin-cli help getbalance` lista estes argumentos: - - 1. dummy [costumava ser account] - 2. minconf - 3. include_watchonly - 4. avoid_reuse - -O exemplo seguinte mostra um uso tradicional e não intuitivo do ```getbalance``` usando o argumento de confirmação mínimo: -``` -$ bitcoin-cli getbalance "*" 1 -``` -Com argumentos nomeados, podemos esclarecer o que estamos fazendo, o que também minimiza os erros: -``` -$ bitcoin-cli -named getbalance minconf=1 -``` - -## Testando uma transação bruta - -Veja como seriam os comandos para enviar uma transação bruta com argumentos nomeados: -``` -$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') -$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') -$ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" - -$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00001 }''') -$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex -{ - "txid": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5", - "hash": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5", - "version": 2, - "size": 85, - "vsize": 85, - "weight": 340, - "locktime": 0, - "vin": [ - { - "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", - "vout": 0, - "scriptSig": { - "asm": "", - "hex": "" - }, - "sequence": 4294967295 - } - ], - "vout": [ - { - "value": 0.00001000, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" - ] - } - } - ] -} - -$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') -$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx -e70dd2aa13422d12c222481c17ca21a57071f92ff86bdcffd7eaca71772ba172 -``` -Pronto! Enviamos outra transação bruta, mas desta vez usando argumentos nomeados para ter maior clareza e redução de erros. - -> :warning: **AVISO DE VERSÃO:** É aqui que o bug no Bitcoin Core 0.14 aparece: O argumento ```inputs``` no ```createrawtransaction``` tem o nome ```transactions``` incorreto. Portanto, se estivermos no Bitcoin Core 0.14.0, substitua o argumento nomeado ```inputs``` por ```transactions``` para este e também para os exemplos futuros. No entanto, a partir do Bitcoin Core 0.14.1, esse código deve funcionar normalmente. - -## Resumo do Criando uma transação bruta com argumentos nomeados - -Executando o ```bitcoin-cli``` com o argumento ```-named```, podemos usar argumentos nomeados ao invés de depender de argumentos ordenados. O comando ```bitcoin-cli help``` sempre mostrará o nome correto para cada argumento. Isso pode resultar em um código mais robusto, mais fácil de ler e menos sujeito a erros. - -_À partir de agora, usaremos argumentos nomeados para todos os exemplos futuros, para maior clareza e para estabelecer as melhores práticas. No entanto, também mostraremos todos os argumentos na ordem correta. Portanto, se preferir não usar os argumentos nomeados, apenas retire o argumento ```-named``` e todos os ```name =``` que os exemplos devem continuar funcionando corretamente._ - -## O que vem depois? - -Continue "Enviando Transações de Bitcoin" na sessão [§4.4: Enviando bitcoins usando transações brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md). \ No newline at end of file diff --git a/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md b/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md deleted file mode 100644 index 5a3b40e..0000000 --- a/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md +++ /dev/null @@ -1,187 +0,0 @@ -# 4.4: Enviando bitcoins usando transações brutas - -Conforme observado no início deste capítulo, a interface ```bitcoin-cli``` oferece três maneiras principais de enviar moedas. A sessão [§4.1](04_1_Sending_Coins_The_Easy_Way.md) falou sobre como enviá-la pela primeira vez, usando o comando ```sendtoaddress```. Desde então, estamos construindo coisas mais detalhadas sobre como enviar moedas de uma segunda maneira, com transações brutas. A sessão [§4.2](04_2_Creating_a_Raw_Transaction.md) nos ensinou como criar uma transação bruta, um [Prefácio](04_2__Interlude_Using_JQ.md) explicou sobre o JQ e a sessão [§4.3](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) demonstrou os argumentos nomeados. - -Agora podemos colocá-los juntos e realmente enviar fundos usando uma transação bruta. - -## Criando uma endereço de troco - -Nosso exemplo de transação bruta na seção §4.2 era simples demais: Enviamos um UTXO inteiro para um novo endereço. Com mais frequência, iremos desejar enviar a alguém uma quantia em dinheiro que não corresponde a um UTXO. Mas, devemos nos lembrar que o excesso de dinheiro de um UTXO que não é enviado ao destinatário se torna apenas a taxa de transação. Então, como enviar para alguém apenas uma parte de um UTXO, enquanto guardamos o resto pra gente? - -A solução é _enviar_ o restante dos fundos para um segundo endereço, um endereço de troco que criamos em nossa carteira especificamente para recebê-los: -``` -$ changeaddress=$(bitcoin-cli getrawchangeaddress legacy) -$ echo $changeaddress -mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h -``` -Observe que isso usa uma nova função: ```getrawchangeaddress```. É basicamente é a mesma coisa que o ```getnewaddress```, mas é otimizado para uso como um endereço de truco em uma transação bruta, portanto, não faz coisas como criar entradas em nossa lista de endereços. Selecionamos novamente o endereço ```legacy```, ao invés de usar o padrão ```bech32```, simplesmente para consistência. Esta é uma situação em que teria sido seguro gerar um endereço Bech32 padrão, apenas usando ```bitcoin-cli getrawchangeaddress```, porque ele seria enviado e recebido por nós em nosso node Bitcoin Core, que tem suporte integral a isso. Mas, estamos adiantando as coisas. Vamos mudar sobre como mudar o endereço para Bech32 na sessão [§4.6](04_6_Creating_a_Segwit_Transaction.md). - -Agora temos um endereço adicional em nossa carteira, para que possamos receber o troco de um UTXO! Para usá-lo, precisaremos criar uma transação bruta com duas saídas. - -## Escolhendo os UTXOs suficientes - -Nosso exemplo de transação bruta era simples também de outra maneira: Assumia que havia dinheiro suficiente em um único UTXO para cobrir toda a transação. Frequentemente, esse será o caso, mas às vezes desejaremos criar transações que gastem mais dinheiro do que temos em um único UTXO. Para fazer isso, devemos criar uma transação bruta com duas (ou mais) entradas. - -## Escrevendo uma transação bruta real - -Para resumir: A criação de uma transação bruta real para enviar moedas, às vezes, requer múltiplas entradas e, quase sempre, múltiplas saídas, uma das quais é um endereço de troco. Estaremos criando esse tipo de transação mais realista, um exemplo que mostra um caso de uso da vida real, enviando fundos por meio da segunda metodologia do Bitcoin, as transações brutas. - -Vamos usar nossos UTXOs 0 e 2: -``` -$ bitcoin-cli listunspent -[ -[ - { - "txid": "0619fecf6b2668fab1308fbd7b291ac210932602a6ac6b8cc11c7ae22c43701e", - "vout": 1, - "address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", - "label": "", - "scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac", - "amount": 0.00899999, - "confirmations": 1, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp", - "safe": true - }, - { - "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", - "vout": 0, - "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", - "label": "", - "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", - "amount": 0.00022000, - "confirmations": 15, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", - "safe": true - }, - { - "txid": "0df23a9dba49e822bbc558f15516f33021a64a5c2e48962cec541e0bcc79854d", - "vout": 0, - "address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", - "label": "", - "scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac", - "amount": 0.00100000, - "confirmations": 1, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp", - "safe": true - } -] - -``` -Em nosso exemplo, enviaremos 0,009 BTC, que é (um pouco) maior do que qualquer um de nossos UTXOs. Para isso, será necessário que os combinemos e, em seguida, vamos usar nosso endereço de troco para recuperar os fundos não gastos. - -### Configurando as variáveis - -Já temos as variáveis ​​```$changeaddress``` e ```$recipient``` dos exemplos anteriores: -``` -$ echo $changeaddress -mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h -$ echo $recipient -n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi -``` -Também precisamos registrar o txid e vout para cada um de nossos dois UTXOs. Tendo identificado os UTXOs que queremos gastar, podemos usar as técnicas do JQ para garantir que o acesso a eles esteja livre de erros: -``` -$ utxo_txid_1=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') -$ utxo_vout_1=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') -$ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') -$ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') -``` - -### Escrevendo a transação - -Escrever a transação bruta real é surpreendentemente simples. Tudo o que precisamos fazer é incluir um objeto JSON adicional separado por vírgula na matriz JSON de entradas e um par de valores-chave adicional separado por vírgula em um objeto JSON de saídas. - -Aqui temos um exemplo. Observe as múltiplas entradas após o argumento ```inputs``` e as múltiplas saídas após o argumento ```outputs```. -``` -$ rawtxhex2=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.009, "'$changeaddress'": 0.0009 }''') -``` -Fomos _muito_ cuidadosos em calcular a quantidade. Esses dois UTXOs contêm 0,00999999 BTC. Depois de enviar 0,009 BTC, teremos 0,00099999 BTC restantes. Escolhemos 0,00009999 BTC como a nossa taxa de transação. Para acomodar essa taxa, definimos o troco como sendo 0,0009 BTC. Se não tivermos prestado atenção nisso, e definido nosso troco para 0,00009 BTC, essa quantidade de BTC adicional seria enviado para os mineradores! Se tivéssemos esquecido de fazer o troco, todo o excesso teria desaparecido. Portanto, novamente, _ tenha cuidado_. - -Felizmente, podemos verificar três vezes com o alias ```btctxfee``` do Prefácio do JQ: -``` -$ ./txfee-calc.sh $rawtxhex2 -.00009999 -``` - -### Concluindo - -Agora podemos assinar, selar e entregar nossa transação, e ela é sua (e do faucet): -``` -$ signedtx2=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex2 | jq -r '.hex') -$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx2 -e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d -``` - -### Esperando - -Como de costume, nossas moedas estarão no fluxo por um tempo: O troco ficará indisponível até que a transação seja realmente confirmada e um novo UTXO seja nos dado. - -Mas, em 10 minutos ou menos (provavelmente), teremos o dinheiro restante de volta e totalmente utilizável novamente. Por enquanto, ainda precisamos esperar: -``` -$ bitcoin-cli listunspent -[ - { - "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", - "vout": 0, - "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", - "label": "", - "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", - "amount": 0.00022000, - "confirmations": 15, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", - "safe": true - } -] -``` -E o troco eventualmente voltará para nós: -``` -[ - { - "txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d", - "vout": 1, - "address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", - "scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac", - "amount": 0.00090000, - "confirmations": 1, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk", - "safe": true - }, - { - "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", - "vout": 0, - "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", - "label": "", - "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", - "amount": 0.00022000, - "confirmations": 16, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", - "safe": true - } -] -``` -Este também pode ser um bom momento para revisitar um explorador de blockchain, para que possamos ver mais intuitivamente como as entradas, saídas e as taxas estão dispostas na transação: [e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d](https://mempool.space/pt/testnet/tx/e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d). - -## Resumo do Enviando bitcoins usando transações brutas - -Para enviar moedas usando transações brutas, precisamos criar uma transação bruta com uma ou mais entradas (para ter fundos suficientes) e uma ou mais saídas (para recuperar usando o troco). Então, podemos seguir nosso procedimento normal de usar o ```createrawtransaction``` com argumentos nomeados junto com o JQ, conforme descrito nas seções anteriores. - -> :fire: ***Qual é o ponto positivo de enviar moedas com transações brutas?*** -> _As vantagens._ Oferece maior controle. Se o nosso objetivo é escrever um programa ou script Bitcoin mais complexo, provavelmente usaremos as transações brutas para saber exatamente o que está acontecendo. Essa também é a situação mais _segura_ para usar transações brutas, porque podemos garantir que não cometeremos nenhum erro na parte da programação. -> _As desvantagens._ É muito fácil perder dinheiro. Não há avisos, bloqueios e barreiras na programação, a não ser que as criemos. Também é tudo muito misterioso. A formatação é desagradável, mesmo usando a interface ```bitcoin-cli``` que é fácil de usar, e temos que fazer muitas pesquisas e cálculos manualmente. - -## O que vem depois? - -Veja uma forma alternativa de inserir comandos no [Prefácio: Usando o JQ] (04_4__Interlude_Using_Curl.md). - -Ou, se preferir pular, o que é francamente uma digressão, podemos aprender mais com "Enviando Transações de Bitcoin" na sessão [§4.5 Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file diff --git a/pt/04_4__Interlude_Using_Curl.md b/pt/04_4__Interlude_Using_Curl.md deleted file mode 100644 index 2fa3fe6..0000000 --- a/pt/04_4__Interlude_Using_Curl.md +++ /dev/null @@ -1,314 +0,0 @@ -# Prefácio: Acessando o Bitcoind com Curl - -O ```bitcoin-cli``` é, em última análise, apenas um invólucro. É uma forma de interagir com ```bitcoind``` a partir da linha de comando, fornecendo acesso simplificado aos seus diversos comandos RPC. Mas o RPC pode, é claro, ser acessado diretamente. É disso que iremos falar nessa sessão: Como nos conectarmos diretamente ao RPC com o comando ```curl```. - -It won't be used much in the future chapters, but it's an important building block that you can see as an alternative access to `bitcoind` is you so prefer. -Não será muito usado nos próximos capítulos, mas essas informações serão importantes caso queiramos uma alternativa para acessar o ```bitcoind```. - -## Conhecendo o Curl - -O ```curl```, abreviação de "ver URL", é uma ferramenta de linha de comando que permite acessar URLs diretamente usando a linha de comando. É uma maneira fácil de interagir com servidores como o ```bitcoind```, que ficam ouvindo as portas da internet e conversam utilizando uma variedade de protocolos. O Curl também está disponível como uma biblioteca para muitas linguagens de programação, como C, Java, PHP e Python. Então, depois de saber como trabalhar com o Curl, teremos uma base sólida para usar várias APIs diferentes. - -Para usar o ```curl``` com o ```bitcoind```, devemos saber três coisas: O formato padrão, o nome de usuário e senha e a porta correta. - -### Conhecendo o formato - -Os comandos ```bitcoin-cli``` estão todos vinculados aos comandos RPC no ```bitcoind```. Isso torna a transição do uso de ```bitcoin-cli``` para o uso do ```curl``` muito simples. Na verdade, se olharmos qualquer uma das páginas de ajuda do ```bitcoin-cli```, veremos que eles listam não apenas os comandos ```bitcoin-cli```, mas também os comandos ```curl``` paralelos. Por exemplo, aqui temos o resultado do comando ```bitcoin-cli help getmininginfo```: -``` -$ bitcoin-cli help getmininginfo -getmininginfo - -Returns a json object containing mining-related information. -Result: -{ (json object) - "blocks" : n, (numeric) The current block - "currentblockweight" : n, (numeric, optional) The block weight of the last assembled block (only present if a block was ever assembled) - "currentblocktx" : n, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled) - "difficulty" : n, (numeric) The current difficulty - "networkhashps" : n, (numeric) The network hashes per second - "pooledtx" : n, (numeric) The size of the mempool - "chain" : "str", (string) current network name (main, test, regtest) - "warnings" : "str" (string) any network and blockchain warnings -} - -Examples: -> bitcoin-cli getmininginfo -> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ -``` -E tem o comando ```curl```, no final da tela de ajuda! Este comando um tanto longo tem quatro partes principais: (1) Uma lista do nome de usuário; (2) Um sinalizador ```--data-binary```; (3) Um objeto JSON que diz ao ```bitcoind``` o que fazer, incluindo um array JSON com os parâmetros e; (4) Um cabeçalho HTTP que inclui a URL do ```bitcoind```. - -Quando estamos trabalhando com o ```curl```, muitos desses argumentos do ```curl``` permanecerão os mesmos de um comando para outro, apenas as entradas ```method``` e ```params``` no array JSON normalmente mudam. No entanto, precisaremos saber como preencher o nome do usuário e endereço da URL para que funcione, antes de mais nada! - -_Sempre que não tivermos certeza sobre como usar o curl no RPC, basta usarmos a ajuda do bitcoin-cli e continuar._ - -### Descobrindo o nome de usuário - -Para falar com a porta do ```bitcoind```, precisamos de um nome de usuário e senha. Eles foram criados como parte da configuração inicial do Bitcoin e podem ser encontrados no arquivo `~/.bitcoin/bitcoin.conf`. - -Por exemplo, aqui está nossa configuração atual: -``` -$ cat ~/.bitcoin/bitcoin.conf -server=1 -dbcache=1536 -par=1 -maxuploadtarget=137 -maxconnections=16 -rpcuser=StandUp -rpcpassword=8eaf562eaf45c33c3328bc66008f2dd1 -rpcallowip=127.0.0.1 -debug=tor -prune=550 -testnet=1 -mintxfee=0.001 -txconfirmtarget=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 -``` -Nosso nome de usuário é ```StandUp``` e nossa senha é ```8eaf562eaf45c33c3328bc66008f2dd1```. - -> **Atenção:** Obviamente, não é muito seguro ter essas informações em um arquivo de texto simples. A partir do Bitcoin Core 0.12, podemos omitir o ```rpcpassword``` do arquivo ```bitcoin.conf``` e fazer com que o ```bitcoind``` gere um novo cookie sempre que iniciarmos o serviço. A desvantagem disso é que torna o uso de comandos RPC por outros aplicativos, como os detalhados neste capítulo, mais difícil. Então, vamos ficar com as informações simples do ```rpcuser``` e ```rpcpassword``` por enquanto, mas para softwares em produção, é importante considerarmos essa alteração para cookies. - -A maneira segura de usar o RPC com ```bitcoind``` é a seguinte: -``` -$ curl --user StandUp --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ -Enter host password for user 'bitcoinrpc': -``` -Conforme observado, nossa senha será solicitada. - -> :link: **TESTNET vs MAINNET:** A Testnet usa uma URL com a porta 18332 e a mainnet usa uma URL com a porta 8332. Se tivermos alguma dúvida, basta olharmos nosso ```bitcoin.conf```. As configurações estão todas lá. - -A maneira insegura e errada de fazer isso é a seguinte: -``` -$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ -``` -> **Atenção:** Digitar a senha na linha de comando pode colocá-la na tabela de processos e/ou salvá-la em um histórico qualquer. Isso é ainda menos recomendado do que colocá-la em um arquivo, exceto para testes utilizando a testnet. Se quisermos fazer em qualquer outro lugar, precisamos nos certificar de saber o que estamos fazendo! - -### Conhecendo os comandos e os parâmetros - -Com tudo isso em mãos, estamos prontos para enviar os comandos RPC padrão com o ```curl```, mas ainda precisamos saber como incorporar os dois elementos que tendem a mudar no comando ```curl```. - -O primeiro é o ```method```, que é o método RPC que está sendo utilizado. Isso geralmente deve corresponder aos nomes de comando que alimentamos no ```bitcoin-cli``` por muito tempo. - -O segundo é o ```params```, que é uma matriz JSON de parâmetros. Eles são iguais aos argumentos (ou argumentos nomeados) que estamos usando. Eles também são a parte mais confusa do ```curl```, em grande parte porque são um array estruturado ao invés de uma simples lista. - -Esta é a aparência de algumas matrizes de parâmetros: - - * `[]` — Um array vazio; - * `["000b4430a7a2ba60891b01b718747eaf9665cb93fbc0c619c99419b5b5cf3ad2"]` — Um array com dados; - * `["'$signedhex'"]` — Um array com uma variável; - * `[6, 9999999]` — Uma array com dois parâmetros; - * `{}` - Um objeto vazio; - * `[''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.298, "'$changeaddress'": 1.0}'']` — Um array com um array contendo um objeto e um objeto vazio. - -## Obtendo a informação - -Agora podemos enviar nosso primeiro comando ```curl``` acessando o RPC ```getmininginfo```: -``` -$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ -{"result":{"blocks":1772428,"difficulty":10178811.40698772,"networkhashps":91963587385939.06,"pooledtx":61,"chain":"test","warnings":"Warning: unknown new rules activated (versionbit 28)"},"error":null,"id":"curltest"}``` -Note that we provided the method, `getmininginfo`, and the parameter, `[]`, but that everything else was the standard `curl` command line. -``` -> **Atenção:** Se obtivermos como resultado o seguinte erro: "Failed to connect to 127.0.0.1 port 8332: Connection refused", precisamos nos certificar de que uma linha como ```rpcallowip = 127.0.0.1``` esteja configurada no ```~/.bitcoin/bitcoin.conf```. Se ainda não funcionar, precisaremos permitir o acesso à porta 18332 (ou 8332) do nosso host local. Nossa configuração padrão do [Capítulo 2: Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) deve fazer tudo isso. - -The result is another JSON array, which is unfortunately ugly to read if you're using `curl` by hand. Fortunately, you can clean it up simply by piping it through `jq`: -O resultado é outro array JSON, que infelizmente é ruim de se ler se estivermos usando o ```curl``` manualmente. Felizmente, podemos limpá-lo simplesmente usando o ```jq```: -``` -$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' - % Total % Received % Xferd Average Speed Time Time Time Current - Dload Upload Total Spent Left Speed -100 295 100 218 100 77 72666 25666 --:--:-- --:--:-- --:--:-- 98333 -{ - "result": { - "blocks": 1772429, - "difficulty": 10178811.40698772, - "networkhashps": 90580030969896.44, - "pooledtx": 4, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" - }, - "error": null, - "id": "curltest" -} -``` -Você verá um pouco de relatório de conectividade à medida que os dados são baixados, então, quando os dados chegarem a ```jq```, tudo será corretamente identado. Estaremos omitindo as informações do download nos próximos exemplos. - -## Manipulando nossa carteira - -Embora já estejamos acessando o ```bitcoind``` diretamente, ainda teremos acesso à funcionalidade de carteira, porque ela está amplamente armazenada no próprio ```bitcoind```. - -### Pesquisando endereços - -Usando o RPC ```getaddressesbylabel``` para listar todos os nossos endereços atuais: -``` -$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getaddressesbylabel", "params": [""] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' -{ - "result": { - "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE": { - "purpose": "receive" - }, - "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff": { - "purpose": "receive" - }, - "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B": { - "purpose": "receive" - }, - "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d": { - "purpose": "receive" - }, - "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6": { - "purpose": "receive" - }, - "tb1qmtucvjtga68kgrvkl7q05x4t9lylxhku7kqdpr": { - "purpose": "receive" - } - }, - "error": null, - "id": "curltest" -} -``` -Este é o nosso primeiro exemplo de um parâmetro real, ```" "```. Este é o parâmetro ```label``` obrigatório para o ```getaddressesbylabel```, mas todos os nossos endereços estão sob o rótulo padrão, então nada de especial foi necessário neste momento. - -O resultado é uma lista de todos os endereços que foram usados na nossa carteira. Alguns dos quais presumivelmente possuem saldo. - -### Pesquisando pelos saldos - -Use o RPC ```listunspent``` para listar os saldos que temos disponíveis: -``` -$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' -{ - "result": [ - { - "txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d", - "vout": 1, - "address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", - "scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac", - "amount": 0.0009, - "confirmations": 4, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk", - "safe": true - }, - { - "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", - "vout": 0, - "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", - "label": "", - "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", - "amount": 0.00022, - "confirmations": 19, - "spendable": true, - "solvable": true, - "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", - "safe": true - } - ], - "error": null, - "id": "curltest" -} -``` -Esta é quase exatamente a mesma saída que recebemos quando digitamos ```bitcoin-cli listunspent```, mostrando como as duas interfaces estão intimamente ligadas. Se nenhuma limpeza ou ajuda extra for necessária, então o ```bitcoin-cli``` apenas produzirá o RPC. Simples assim! - -### Criando um endereço - -Depois de saber onde estão os saldos, a próxima etapa na elaboração de uma transação é obter um endereço de alteração. Agora provavelmente já pegamos o jeito e sabemos que para os comandos RPC simples, tudo que precisamos fazer é ajustar o ```method``` no comando ```curl```: -``` -$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' -{ - "result": "mrSqN37TPs89GcidSZTvXmMzjxoJZ6RKoz", - "error": null, - "id": "curltest" -} - -``` -Neste ponto, podemos até mesmo voltar à nossa prática padrão de salvar os resultados em variáveis com a ajuda adicional do `jq`: -``` -$ changeaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') -$ echo $changeaddress -mqdfnjgWr2r3sCCeuTDfe8fJ1CnycF2e6R -``` -Não precisamos nos preocupar com as informações do download. Ele irá para o ```STDERR``` e será exibido em nossa tela, enquanto os resultados irão para o ```STDOUT``` e serão salvos em nossa variável. - -## Criando uma transação - -Agora estamos prontos para criar uma transação com o ```curl```. - -### Preparando as variáveis - -Assim como no ```bitcoin-cli```, para criar uma transação usando o Curl com o RPC, devemos primeiro salvar nossas variáveis. A única mudança aqui é que o ```curl``` cria um objeto JSON que inclui um valor-chave ```result```, então sempre precisaremos usar o pipe (```|```) através da tag ```.result``` antes de fazer qualquer outra coisa. - -Este exemplo configura nossas variáveis para usar o BTC de 1.2985 em fundos listados na primeira transação não gasta acima: -``` -$ utxo_txid=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .txid') -$ utxo_vout=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .vout') -$ recipient=mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf -$ changeaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') - -$ echo $utxo_txid -e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d -$ echo $utxo_vout -1 -$ echo $recipient -mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf -$ echo $changeaddress -n2jf3MzeFpFGa7wq8rXKVnVuv5FoNSJZ1N -``` - -### Criando a transação - -A transação criada com o ```curl``` é muito semelhante à transação criada com o ```bitcoin-cli```, mas com algumas diferenças sutis: -``` -$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' -{ - "result": "02000000010d6acd0356db222ca3a7ee7fa1e3044316223ceec1f64b58aeb2e0de921007e70100000000ffffffff0230750000000000001976a914ac19d3fd17710e6b9a331022fe92c693fdf6659588ac50c30000000000001976a9147021efec134057043386decfaa6a6aa4ee5f19eb88ac00000000", - "error": null, - "id": "curltest" -} -``` -O coração da transação é, obviamente, o array JSON ```params```, que estamos colocando em uso total pela primeira vez. - -Podemos observar que todos os ```params``` estão alojados nos ```[]``` para marcar o array de parâmetros. - -Nós também variamos as citações de como as coisas funcionavam no ```bitcoin-cli```, para iniciar e terminar cada array e objeto dentro do array ```params``` com ```''``` ao invés do tradicional ```'' '```. Isso porque todo o conjunto de argumentos JSON já tem um ```'``` em torno dele. Como de costume, basta dar uma olhada na bizarra citação do shell e se acostumar com isso. - -No entanto, há uma última coisa a ser observada neste exemplo, e pode ser _enlouquecedor_ se não tivermos percebido. Quando executamos um comando ```createrawtransaction``` com ```bitcoin-cli```, o array JSON de entradas e o objeto JSON de saídas eram parâmetros distintos, portanto, foram separados por um espaço. Agora, porque eles são parte do array JSON ```params```, eles são separados por uma vírgula (```,```). Se não tivermos percebido isso obteremos um ```parse error``` sem muitas informações. - -> **Atenção:** Todo mundo já teve problemas para depurar o ```curl```, não é mesmo? Para resolver isso basta adicionar o argumento ```--trace-ascii/tmp/foo```. Informações completas sobre o que está sendo enviado ao servidor serão salvas em ```/tmp/foo``` (ou qualquer nome de arquivo que quisermos informar). - -Depois de verificarmos se as coisas estão funcionando, provavelmente iremos desejar salvar o código hexadecimal em uma variável: -``` -$ hexcode=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') -``` - -### Assinando e enviando - -Assinar e enviar a nossa transação usando ```curl``` é bem simples, basta usar os seguintes comandos do RPC ```signrawtransactionwithwallet``` e ```sendrawtransaction```: - -``` -$ signedhex=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "signrawtransactionwithwallet", "params": ["'$hexcode'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .hex') - -$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "sendrawtransaction", "params": ["'$signedhex'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' -{ - "result": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d", - "error": null, - "id": "curltest" -} -``` -## Resumo do Acessando o Bitcoind com Curl - -Terminando esta seção, podemos sentir que acessar o ```bitcoind``` através de ```curl``` é muito parecido com acessá-lo através de ```bitcoin-cli```, porém, é mais complicado. E estamos certos. O ```bitcoin-cli``` tem funcionalidade RPC bem completa, então qualquer coisa que fizermos através do ```curl``` provavelmente poderemos fazer através do ```bitcoin-cli```. É por isso que vamos continuar nos concentrando no ```bitcoin-cli``` após esta digressão. - -Mas ainda há razões para usar ```curl``` ao invés do ```bitcoin-cli```: - -_Qual é o poder do curl?_ Obviamente, o ```curl``` elimina um nível intermediário. Ao invés de trabalhar com o ```bitcoin-cli```, que envia comandos RPC para o ```bitcoind```, estamos enviando esses comandos RPC diretamente para ele. Isso permite uma programação mais robusta, porque não precisamos nos preocupar com as coisas inesperadas que o ```bitcoin-cli``` pode fazer ou como isso pode mudar com o tempo. No entanto, também estamos dando os primeiros passos para usar uma linguagem de programação mais abrangente do que as opções pobres oferecidas por um script de shell. Como veremos nos últimos capítulos deste livro, podemos realmente ver que as bibliotecas curl são outras funções que acessam os comandos RPC em uma variedade de linguagens de programação: Mas isso ainda está muito longe, ainda. - -## O que vem depois? - -Aprenda mais uma maneira de "Enviando Transações de Bitcoin" com [§4.5 Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). diff --git a/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md b/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md deleted file mode 100644 index 42a8716..0000000 --- a/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md +++ /dev/null @@ -1,171 +0,0 @@ -# 4.5: Enviando bitcoins usando transações brutas automatizadas - -Este capítulo apresenta três maneiras de enviar fundos por meio da interface cli do Bitcoin. A sessão [§4.1](04_1_Sending_Coins_The_Easy_Way.md) descreveu como fazer isso com um comando simples, a sessão [§4.4](04_4_Sending_Coins_with_a_Raw_Transaction.md) detalhou como usar uma transação bruta mais perigosa. Esta seção fica no meio termo de ambas, mostrando como tornar as transações brutas mais simples e seguras. - -## Deixando o Bitcoin fazer os cálculos para nós - -A metodologia para transações brutas automatizadas é simples: Criamos uma transação bruta, mas usamos o comando ```fundrawtransaction``` para pedir ao bitcoind para executar os cálculos para nós. - -Para usar este comando, precisaremos garantir que nosso arquivo ```~/.bitcoin/bitcoin.conf``` contenha as variáveis ​​racionais para calcular as taxas de transação. Podemos consultar a sessão [§4.1: Enviando bitcoins no modo easy](04_1_Sending_Coins_The_Easy_Way.md) para obter mais informações sobre isso. - -Vamos usar números conservadores, por isso sugerimos adicionar o seguinte ao `bitcoin.conf`: -``` -mintxfee=0.0001 -txconfirmtarget=6 -``` -Para manter o tutorial em constante movimento (em outras palavras, para movimentarmos nosso dinheiro rápido sem ficar esperando muito), sugerimos o seguinte: -``` -mintxfee=0.001 -txconfirmtarget=1 -``` - -## Criando uma transação bruta - -Para usar o ```fundrawtransaction``` primeiro precisamos criar uma transação bruta básica que liste _nenhuma_ entrada e _nenhuma_ mudança de endereço. Apenas listaremos o nosso destinatário e quanto desejamos enviar, neste caso ```$recipient``` e ```0,0002``` BTC. -``` -$ recipient=n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi -$ unfinishedtx=$(bitcoin-cli -named createrawtransaction inputs='''[]''' outputs='''{ "'$recipient'": 0.0002 }''') -``` - -## Financiando nossa transação bruta - -Dizemos ao ```bitcoin-cli``` para financiar essa transação básica: -``` -$ bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx -{ - "hex": "02000000012db87641c6a21e5a68b20c226428544978e6ac44964d5d8060d7388000c584eb0100000000feffffff02204e0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac781e0000000000001600140cc9cdcf45d4ea17f5227a7ead52367aad10a88400000000", - "fee": 0.00022200, - "changepos": 1 -} -``` -Isso fornece muitas informações úteis, mas uma vez que tenhamos certeza de como funciona, vamos querer usar o JQ para salvar nosso hex em uma variável, como de costume: -``` -$ rawtxhex3=$(bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx | jq -r '.hex') -``` -## Verificando nossa transação financiada - -Parece mágica, então nas primeiras vezes que usarmos o ```fundrawtransaction```, provavelmente vamos querer verificá-la. - -Vamos executar o comando ```decoderawtransaction``` para mostrar que a transação bruta agora está disposta corretamente, usando um ou mais dos nossos UTXOs e enviando fundos excedentes de volta para um endereço de alteração: -``` -$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 -{ - "txid": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99", - "hash": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99", - "version": 2, - "size": 116, - "vsize": 116, - "weight": 464, - "locktime": 0, - "vin": [ - { - "txid": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d", - "vout": 1, - "scriptSig": { - "asm": "", - "hex": "" - }, - "sequence": 4294967294 - } - ], - "vout": [ - { - "value": 0.00020000, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" - ] - } - }, - { - "value": 0.00007800, - "n": 1, - "scriptPubKey": { - "asm": "0 a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", - "hex": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", - "reqSigs": 1, - "type": "witness_v0_keyhash", - "addresses": [ - "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r" - ] - } - } - ] -} -``` -Uma coisa de interesse aqui é o endereço de troco, que é o segundo ```vout```. Observe que é um endereço ```tb1```, o que significa que é do tipo Bech32. Quando demos ao Bitcoin Core a capacidade total de gerenciar as alterações, ele o fez usando o tipo de endereço padrão, Bech32, e funcionou bem. É por isso que nossa mudança para endereços SegWit na sessão [§4.6](04_6_Creating_a_Segwit_Transaction.md) realmente não é um grande negócio, mas existem algumas dicas para uso mais amplo, sobre as quais falaremos lá. - -Embora tenhamos visto a taxa na saída no ```fundrawtransaction```, ela não pode ser visível aqui. No entanto, podemos verificar isso com o script JQ ```txfee-calc.sh``` criado na sessão [Prefácio: Usando o JQ](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master /04_2__Interlude_Using_JQ.md): -``` -$ ~/txfee-calc.sh $rawtxhex3 -.000222 -``` -Finalmente, podemos usar o ```getaddressinfo``` para ver se o endereço de alteração gerado realmente nos pertence: -``` -$ bitcoin-cli -named getaddressinfo address=tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r -{ - "address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", - "scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", - "ismine": true, - "solvable": true, - "desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar", - "iswatchonly": false, - "isscript": false, - "iswitness": true, - "witness_version": 0, - "witness_program": "a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", - "pubkey": "038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5", - "ischange": true, - "timestamp": 1592335137, - "hdkeypath": "m/0'/1'/10'", - "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", - "hdmasterfingerprint": "d6043800", - "labels": [ - ] -} -``` -Observe os conteúdo do `ismine`. - -## Enviando a transação financiada - -Neste ponto, podemos assinar e enviar a transação normalmente. -``` -$ signedtx3=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex3 | jq -r '.hex') -$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx3 -8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa -``` -Em alguns minutos, teremos o nosso troco de volta: -``` -$ bitcoin-cli listunspent -[ - { - "txid": "8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa", - "vout": 1, - "address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", - "scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", - "amount": 0.00007800, - "confirmations": 1, - "spendable": true, - "solvable": true, - "desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar", - "safe": true - } -] -``` - -## Resumo do Enviando bitcoins usando transações brutas automatizadas - -Se formos enviar fundos usando transações brutas, então o ```fundrawtransaction``` oferece uma boa alternativa onde taxas, entradas e saídas são calculadas para nós, para que não percamos acidentalmente muito dinheiro. - -> :fire: ***Qual é o poder de enviar moedas com transações brutas automatizadas?*** -> _As vantagens._ Proporciona um bom meio de campo. Se estamos enviando fundos manualmente e o ```sendtoaddress``` não oferece controle suficiente por qualquer motivo, podemos obter algumas das vantagens das transações brutas sem os perigos dela. Essa metodologia deve ser usada sempre que possível se estivermos enviando transações brutas manualmente. -> _As desvantagens._ É uma meio termo. Embora existam algumas opções adicionais no ```fundrawtransaction``` que não foram mencionadas aqui, nosso controle ainda é limitado. Provavelmente, nunca desejaríamos usar esse método se formos escrever um programa cujo objetivo é saber exatamente o que está acontecendo. - -## O que vem depois? - -Vamos concluir o capítulo "Enviando transações no Bitcoin" com a sessão [§4.6: Criando uma transação do tipo SegWit](04_6_Creating_a_Segwit_Transaction.md). \ No newline at end of file diff --git a/pt/04_6_Creating_a_Segwit_Transaction.md b/pt/04_6_Creating_a_Segwit_Transaction.md deleted file mode 100644 index 9b7c1bf..0000000 --- a/pt/04_6_Creating_a_Segwit_Transaction.md +++ /dev/null @@ -1,288 +0,0 @@ -# 4.6: Criando uma transação do tipo SegWit - -> :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. - -Era uma vez, nos céus do Bitcoin, uma guerra entre os tamanhos de blocos eclodiu. As taxas disparavam e os usuários estavam preocupados se o Bitcoin podia realmente escalar. Os desenvolvedores do Bitcoin Core relutaram em simplesmente aumentar o tamanho do bloco, mas chegaram a um acordo: Fizeram o SegWit, que significa Segregated Witness. A Segregated Witness é uma maneira elegante de dizer "Assinatura Separada". Ele cria novos tipos de transações que removem assinaturas no final da transação. Ao combinar isso com o aumento dos tamanhos de bloco que são visíveis apenas para nós atualizados, o SegWit resolveu os problemas de dimensionamento do Bitcoin na época e também resolveu um bug de maleabilidade desagradável, tornando o dimensionamento ainda melhor para protocolos de segunda camada, como a Lightning Network. - -A sacada? O SegWit usa endereços diferentes, alguns dos quais são compatíveis com nodes mais antigos e outros não. - -> :warning: **AVISO DE VERSÃO:** O SegWit foi introduzido no BitCoin 0.16.0, que foi descrito na época como tendo "suporte total". Dito isso, havia algumas falhas na integração com o ```bitcoin-cli``` na época, que impediam a assinatura de funcionar corretamente em novos endereços P2SH-SegWit. O endereço Bech32, não compatível com versões anteriores, também foi introduzido no Bitcoin 0.16.0 e se tornou o tipo de endereço padrão no Bitcoin 0.19.0. Toda essa funcionalidade deve estar totalmente funcional em relação às funções ```bitcoin-cli``` (e, portanto, devem funcionar completamente neste tutorial). - -> O problema está em interagir com o mundo. Todos devem ser capazes de enviar para um endereço P2SH-SegWit porque foi construído propositadamente para suportar compatibilidade com as versões anteriores, envolvendo a funcionalidade SegWit em um Script Bitcoin. O mesmo não é verdade para endereços Bech32: Se alguém nos disser que não pode enviar para o nosso endereço Bech32 precisaremos gerar um endereço ```legado``` ou P2SH-SegWit para fazer a transação. (Muitos sites, principalmente as exchanges, também não podem gerar ou receber em endereços SegWit, particularmente endereços Bech32, mas isso é um problema totalmente diferente e não afeta o uso delas). - -## Compreendendo uma transação SegWit - -Em transações clássicas, as informações de assinatura (witness) eram armazenadas no meio da transação, enquanto nas transações SegWit, elas ficavam na parte inferior. Isso anda de mãos dadas com os aumentos de tamanho do bloco que foram introduzidos na atualização do SegWit. O tamanho do bloco foi aumentado de 1 mega para um valor variável com base em quantas transações SegWit estão em um bloco, começando em 1 mega (sem transações SegWit) e podendo chegar a 4 megas (caso todas as transações sejam SegWit). Este tamanho variável foi criado para acomodar os nodes legados, de forma que tudo permaneça compatível com as versões anteriores. Se um node clássico vê uma transação SegWit, ele joga fora as informações da witness (resultando em um bloco de tamanho menor, abaixo do antigo limite de 1 mega), enquanto se um novo node vê uma transação SegWit, ele mantém as informações da witness (resultando em um maior tamanho de bloco, até o novo limite de 4 megas). - -Portanto, acabamos de responder o quê são e como funcionam as transações SegWit. Não que precisemos saber disso para usá-las. A maioria das transações na rede Bitcoin são SegWit. Elas são aquilo que iremos utilizar nativamente para as transações e recebimentos de bitcoins. Os detalhes não são mais relevantes à partir deste ponto, tanto quanto não são mais relevantes como o Bitcoin funciona. - -## Criando um endereço SegWit - -Criamos um endereço SegWit da mesma maneira que qualquer outro endereço, com os comandos ```getnewaddress``` e ```getrawchangeaddress```. - -Se precisarmos criar um endereço para alguém que não pode enviar para os endereços Bech32 mais recentes, podemos usar um endereço ```p2sh-segwit```: -``` -$ bitcoin-cli -named getnewaddress address_type=p2sh-segwit -2N5h2r4karVqN7uFtpcn8xnA3t5cbpszgyN -``` -Se conseguirmos ver um endereço com o prefixo "2" significa que fizemos tudo certo. - -> :link: **TESTNET vs MAINNET:** "3" no caso da mainnet. - -No entanto, se a pessoa com quem estamos interagindo tem um node com uma versão mais nova, ela poderá enviar para um endereço Bech32, que criamos usando os comandos da maneira padrão: -``` -$ bitcoin-cli getnewaddress -tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 -``` -Como já vimos, os endereços de troco gerados a partir do ```bitcoin-cli``` interagem bem com os endereços Bech32, então não há motivo nenhum usar o sinalizador ```legacy``` lá também: -``` -$ bitcoin-cli getrawchangeaddress -tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff -``` - -Aqui, podemos observar que o prefixo "tb1" exclusivo denota que o endereço é um Bech32. - -> :link: ** TESTNET vs MAINNET: ** "bc1" no caso da mainnet. - -O Bitcoin-cli não se importa com o tipo de endereço que estamos utilizando. Podemos executar um comando como ```listaddressgroupings``` que ele irá misturar os endereços livremente não importando os tipos: -``` -$ bitcoin-cli listaddressgroupings -[ - [ - [ - "mfsiRhxbQxcD7HLS4PiAim99oeGyb9QY7m", - 0.01000000, - "" - ] - ], - [ - [ - "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", - 0.00000000, - "" - ], - [ - "tb1q6dak4e9fz77vsulk89t5z92l2e0zm37yvre4gt", - 0.00000000 - ] - ], - [ - [ - "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", - 0.00022000, - "" - ] - ], - [ - [ - "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", - 0.00000000 - ], - [ - "mqjrdY5raxKzXQf5t2VvVvzhvFAgersu9B", - 0.00000000 - ], - [ - "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", - 0.00000000, - "" - ], - [ - "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", - 0.00007800 - ] - ], - [ - [ - "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q", - 0.01000000, - "" - ] - ], - [ - [ - "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6", - 0.01000000, - "" - ] - ] -] -``` - -## Enviando uma transação SegWit no modo easy - -Então, como enviamos uma transação Segwit? Exatamente como qualquer outra transação. Não importa se o UTXO é SegWit, o endereço é SegWit ou alguma combinação dos dois. Podemos ter a certeza que o ```bitcoin-cli``` irá fazer a coisa certa. Embora possamos perceber algumas diferenças nos endereços, eles não importam para interagir com as coisas no nível do ```bitcoin-cli``` ou do RPC. (E esta é uma das vantagens de usar a linha de comando e a interface do RPC, conforme sugerido neste tutorial: Os especialistas já fizeram o trabalho duro para nós, incluindo coisas como enviar para endereços legados e Bech32. Acabamos usando essa funcionalidade para nosso próprio benefício). - -Aqui está um exemplo de um envio para um endereço SegWit, no modo easy: -``` -$ bitcoin-cli sendtoaddress tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005 -854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42 -``` -Se olhar para a nossa transação, podemos ver o uso do endereço Bech32: -``` -$ bitcoin-cli gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42" verbose=true -{ - "amount": -0.00500000, - "fee": -0.00036600, - "confirmations": 0, - "trusted": true, - "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", - "walletconflicts": [ - ], - "time": 1592948795, - "timereceived": 1592948795, - "bip125-replaceable": "no", - "details": [ - { - "address": "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", - "category": "send", - "amount": -0.00500000, - "vout": 1, - "fee": -0.00036600, - "abandoned": false - } - ], - "hex": "0200000002114d5a4c3b847bc796b2dc166ca7120607b874aa6904d4a43dd5f9e0ea79d4ba010000006a47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042dfeffffffa71321e81ef039af490251379143f7247ad91613c26c8f3e3404184218361733000000006a47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7efeffffff026854160000000000160014d591091b8074a2375ed9985a9c4b18efecfd416520a1070000000000160014751e76e8199196d454941c45d1b3a323f1433bd6c60e1b00", - "decoded": { - "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", - "hash": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", - "version": 2, - "size": 366, - "vsize": 366, - "weight": 1464, - "locktime": 1773254, - "vin": [ - { - "txid": "bad479eae0f9d53da4d40469aa74b8070612a76c16dcb296c77b843b4c5a4d11", - "vout": 1, - "scriptSig": { - "asm": "304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7[ALL] 03ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d", - "hex": "47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d" - }, - "sequence": 4294967294 - }, - { - "txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7", - "vout": 0, - "scriptSig": { - "asm": "304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a316[ALL] 0339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e", - "hex": "47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e" - }, - "sequence": 4294967294 - } - ], - "vout": [ - { - "value": 0.01463400, - "n": 0, - "scriptPubKey": { - "asm": "0 d591091b8074a2375ed9985a9c4b18efecfd4165", - "hex": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", - "reqSigs": 1, - "type": "witness_v0_keyhash", - "addresses": [ - "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh" - ] - } - }, - { - "value": 0.00500000, - "n": 1, - "scriptPubKey": { - "asm": "0 751e76e8199196d454941c45d1b3a323f1433bd6", - "hex": "0014751e76e8199196d454941c45d1b3a323f1433bd6", - "reqSigs": 1, - "type": "witness_v0_keyhash", - "addresses": [ - "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx" - ] - } - } - ] - } -} -``` -Na verdade, ambos os ```vouts``` usam endereços Bech32: O nosso destinatário e o endereço de troco gerado automaticamente. - -Mas quando retrocedemos nosso ```vin```, descobrimos que veio de um endereço legado. Isso porque não importa: -``` -$ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7" -{ - "amount": 0.01000000, - "confirmations": 43, - "blockhash": "00000000000000e2365d2f814d1774b063d9a04356f482010cdfdd537b1a24bb", - "blockheight": 1773212, - "blockindex": 103, - "blocktime": 1592937103, - "txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7", - "walletconflicts": [ - ], - "time": 1592936845, - "timereceived": 1592936845, - "bip125-replaceable": "no", - "details": [ - { - "address": "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q", - "category": "receive", - "amount": 0.01000000, - "label": "", - "vout": 0 - } - ], - "hex": "020000000001016a66efa334f06e2c54963e48d049a35d7a1bda44633b7464621cae302f35174a0100000017160014f17b16c6404e85165af6f123173e0705ba31ec25feffffff0240420f00000000001976a914626ab1ca41d98f597d18d1ff8151e31a40d4967288acd2125d000000000017a914d5e76abfe5362704ff6bbb000db9cdfa43cd2881870247304402203b3ba83f51c1895b5f639e9bfc40124715e2495ef2c79d4e49c0f8f70fbf2feb02203d50710abe3cf37df4d2a73680dadf3cecbe4f2b5d0b276dbe7711d0c2fa971a012102e64f83ee1c6548bcf44cb965ffdb803f30224459bd2e57a5df97cb41ba476b119b0e1b00" -} -``` - -## Enviando uma transação SegWit o modo hard - -Da mesma forma, podemos financiar uma transação com um endereço Bech32, sem nenhuma diferença em relação às técnicas que aprendemos até agora. Aqui está uma maneira exata de fazer isso com uma transação bruta completa: -``` -$ changeaddress=$(bitcoin-cli getrawchangeaddress) -$ echo $changeaddress -tb1q4xje3mx9xn7f8khv7p69ekfn0q72kfs8x3ay4j -$ bitcoin-cli listunspent -[ -... - { - "txid": "003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452", - "vout": 0, - "address": "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6", - "label": "", - "scriptPubKey": "0014a226e1dfd08537b02de04f667a49bd46f9b9f578", - "amount": 0.01000000, - "confirmations": 5, - "spendable": true, - "solvable": true, - "desc": "wpkh([d6043800/0'/0'/5']0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640)#hd66hknp", - "safe": true - } -] -$ recipient=tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx -$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') -$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') -$ echo $utxo_txid $utxo_vout -003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452 0 -$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.002, "'$changeaddress'": 0.007 }''') -$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') -$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx -e02568b706b21bcb56fcf9c4bb7ba63fdbdec1cf2866168c4f50bc0ad693f26c -``` -Tudo funciona exatamente da mesma forma que outros tipos de transações! - -### Reconhecendo o novo descritor - -Se olharmos o campo ```desc```, notaremos que o endereço SegWit tem um descritor de estilo diferente daqueles encontrados na sessão [§3.5: Entendendo o descritor](03_5_Understanding_the_Descriptor.md). Um descritor legado descrito nessa sessão se parecia com algo assim: `pkh ([d6043800 / 0 '/ 0' / 18 '] 03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388) # 4ahsl9pk`. Nosso novo descritor SegWit se parece mais com isso: `wpkh ([d6043800 / 0 '/ 0' / 5 '] 0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640) # hd66hknp" `. - -A grande diferença que precisamos notar é que a função mudou. Anteriormente, era ```pkh```, que é um endereço padrão de chave pública com hash P2PKH. Ao invés disso, o endereço SegWit é ```wpkh```, o que significa que é um endereço SegWit P2WPKH nativo. Isso dá destaque ao :fire: ***poder dos descritores***. Eles descrevem como criar um endereço a partir de uma chave ou outra informação, com as funções definindo de forma inequívoca como fazer o endereço com base no tipo de cada endereço. - -## Resumo do Criando uma transação do tipo SegWit - -Realmente não há complexidade para criar transações SegWit. Internamente, elas são estruturadas de forma diferente das transações legadas, mas na linha de comando não existe diferença: Apesar usamos um endereço com um prefixo diferente. A única coisa a ser observada é que algumas pessoas podem não conseguir enviar para um endereço Bech32 se estiverem usando um software obsoleto. - -> :fire: ***Qual é o poder de criar transações usando o SegWit?*** -> _As vantagens._ As transações do SegWit são menores e, portanto, serão mais baratas de serem enviadas do que as transações legadas devido às taxas mais baixas. O Bech32 diminui essa vantagem e também cria endereços que são mais difíceis de errar durante a transcrição, e isso é muito importante, visto que o erro do usuário é uma das maneiras mais prováveis ​​de terem seus bitcoins perdidos. -> _As desvantagens._ Os endereços SegWit não tem suporte em nodes do Bitcoin obsoleto. Em particular, as pessoas podem não conseguir enviar para o nosso endereço Bech32. - -## O que vem depois? - -Vamos avançar mais um pouco no "bitcoin-cli" com o [Capítulo 5: Controlando as transações do Bitcoin](05_0_Controlling_Bitcoin_Transactions.md). \ No newline at end of file From 53230f69c9ff6d7c4c6ebd7366ef6c69e1cf5b0f Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 1 Jul 2021 16:06:30 -0300 Subject: [PATCH 5/6] Finished translation of Chapter 5 --- pt/05_0_Controlling_Bitcoin_Transactions.md | 23 +++ pt/05_1_Watching_for_Stuck_Transactions.md | 59 ++++++ pt/05_2_Resending_a_Transaction_with_RBF.md | 214 ++++++++++++++++++++ pt/05_3_Funding_a_Transaction_with_CPFP.md | 128 ++++++++++++ 4 files changed, 424 insertions(+) create mode 100644 pt/05_0_Controlling_Bitcoin_Transactions.md create mode 100644 pt/05_1_Watching_for_Stuck_Transactions.md create mode 100644 pt/05_2_Resending_a_Transaction_with_RBF.md create mode 100644 pt/05_3_Funding_a_Transaction_with_CPFP.md diff --git a/pt/05_0_Controlling_Bitcoin_Transactions.md b/pt/05_0_Controlling_Bitcoin_Transactions.md new file mode 100644 index 0000000..d283e81 --- /dev/null +++ b/pt/05_0_Controlling_Bitcoin_Transactions.md @@ -0,0 +1,23 @@ +# Capítulo 5: Controlando as transações de Bitcoin + +O envio de uma transação nem sempre termina com um "viveram felizes para sempre". Usando os protocolos RBF (Replace-By-Fee, ou Substituindo-A -Taxa no português) e CPFP (Child-Pays-For-Parent, ou Filho-Paga-Pelo-Pai), um desenvolvedor pode continuar a controlar a transação após ela ter sido enviada, para melhorar a eficiência ou para recuperar transações que estava presas na _mempool_. Esses métodos irão começar a mostrar o verdadeiro poder do Bitcoin. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Decidir se o RBF ou o CPFP pode ajudar uma transação; + * Criar uma transação de substituição usando o RBF; + * Criar novas transações usando o protocolo CPFP. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Entender a Mempool; + * Entender a diferença entre o RBF e o CPFP; + * Planejar a taxa do RBF. + +## Tabela de conteúdo + + * [Seção 1: Observando as transações presas na mempool](05_1_Watching_for_Stuck_Transactions.md) + * [Seção 2: Reenviando uma transação com o RBF](05_2_Resending_a_Transaction_with_RBF.md) + * [Seção 3: Financiando uma transação com o CPFP](05_3_Funding_a_Transaction_with_CPFP.md) \ No newline at end of file diff --git a/pt/05_1_Watching_for_Stuck_Transactions.md b/pt/05_1_Watching_for_Stuck_Transactions.md new file mode 100644 index 0000000..e887056 --- /dev/null +++ b/pt/05_1_Watching_for_Stuck_Transactions.md @@ -0,0 +1,59 @@ +# 5.1: Observando as transações presas na mempool + +Às vezes, uma transação de Bitcoin pode ficar presa. Isso normalmente ocorre porque não havia taxa de transação suficiente, mas também pode ser devido a uma falha da rede ou do software. + +## Observando as transações enviadas + +Nós devemos _sempre_ observar as transações para garantir que tenham sido encerradas. O ```bitcoin-cli listtransactions``` mostrará todas as nossas transações de entrada e saída, enquanto o ```bitcoin-cli gettransaction``` juntamente com um txid, irá mostrar uma transação específica. + +Abaixo temos uma transação que não foi incluída em um bloco. Podemos garantir isso porque não temos nenhuma confirmação. +``` +$ bitcoin-cli -named gettransaction txid=fa2ddf84a4a632586d435e10880a2921db6310dfbd6f0f8f583aa0feacb74c8e +{ + "amount": -0.00020000, + "fee": -0.00001000, + "confirmations": 0, + "trusted": true, + "txid": "fa2ddf84a4a632586d435e10880a2921db6310dfbd6f0f8f583aa0feacb74c8e", + "walletconflicts": [ + ], + "time": 1592953220, + "timereceived": 1592953220, + "bip125-replaceable": "no", + "details": [ + { + "address": "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", + "category": "send", + "amount": -0.00020000, + "vout": 0, + "fee": -0.00001000, + "abandoned": false + } + ], + "hex": "02000000014cda1f42a1bd39d8d0ff5958a804bc2bc548b71d7ceadbde53ea15aeaf1e2691000000006a473044022016a7a9f045a0f6a52129f48adb7da35c2f54a0741d6614e9d55b8a3bc3e1490a0220391e9085a3697bc790e94bb924d5310e16f23489d9c600864a32674e871f523c01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff02204e000000000000160014751e76e8199196d454941c45d1b3a323f1433bd6e8030000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919600000000" +``` +Uma transação pode ser considerada presa se permanecer nesse estado por um longo período de tempo. A tempos atrás, podíamos ter a certeza de que todas as transações iriam ser confirmadas _eventualmente_. Mas, isso não é mais verdade devido ao aumento exponencial do uso do Bitcoin. Agora, se uma transação ficar travada por muito tempo, ela sairá da mempool e, em seguida, estará perdida para sempre na rede Bitcoin. + +> :book: ***O que é a mempool?*** A Mempool (ou Piscina de Memória) é um local onde todas as transações não confirmadas em um node bitcoin ficam. Estas são as transações que um node recebeu da rede P2P que ainda não estão incluídas em um bloco. Cada node bitcoin pode ter um conjunto ligeiramente diferente de transações em sua mempool: Transações diferentes podem ter sido propagadas para um node específico. Isso depende de quando o node foi iniciado pela última vez e também os limites de tamanho. Quando um minerador faz um bloco, ele usa as transações da mempool. Então, quando um bloco é verificado, todos os mineradores removem essas transações da mempool. A partir do Bitcoin 0.12, as transações não confirmadas também podem expirar na mempool se forem antigas o suficiente, normalmente o tempo é de 72 horas. No caso das versões 0.14.0 o tempo foi aumentado para 2 semanas. As pools de mineração podem ter seus próprios mecanismos de gerenciamento da mempool. + +Esta lista tem de todas as [transações não confirmadas](https://blockchain.info/unconfirmed-transactions) e pode não corresponder a nenhuma mempool de um node específico, mas pode ser considerada (principalmente) um superconjunto de todas elas. + +## Decidindo o que fazer + +Se sua transação ficar paralisada por mais tempo do que esperamos, normalmente podemos fazer uma dessas quatro coisas: + +**1. Esperar até que seja confirmada.** Se enviamos a transação com uma taxa baixa ou média, ela deve ser processada cedo ou tarde. Conforme mostrado no site [Mempool Space](https://mempool.space), aqueles com taxas mais baixas _irão esperar mais_. (Vamos dar uma olhada na transação mais à esquerda e ver quanto tempo ela está esperando e quanto ela pagou de taxa). + +**2. Esperar até que seja expirada.** Se acidentalmente enviamos uma transação sem taxa, ou se colocamos uma taxa muito baixa em um momento de congestionamento da rede, então nossa transação pode nunca ser concluída. No entanto, nossos bitcoins não serão perdidos. Contanto que não tenhamos uma carteira que fique reenviando propositalmente transações não confirmadas, ela deve ser eliminada da mempool em aproximadamente duas semanas, e então podemos tentar novamente utilizando valores mais altos nas taxas. + +**3. Usar o RBF como sendo o remetente.** Se formos nós quem estamos enviando a transação e optarmos por usar o RBF (Replace-By-Fee), podemos tentar novamente com uma taxa mais alta. Podemos consultar a sessão [§5.2: Reenviando uma transação com o RBF](05_2_Resending_a_Transaction_with_RBF.md) para sabermos mais sobre isso. + +**4. Use o CPFP como sendo o destinatário.** Se nós formos os recebedores do saldo, podemos usar o CPFP (Child-Pays-For-Parent) para usar a transação não confirmada como um input para uma nova transação. Podemos consultar a sessão [§5.3: Financiando uma transação com o CPFP](05_3_Funding_a_Transaction_with_CPFP.md). + +## Resumo do Observando as transações presas na mempool + +Esta é uma introdução ao poder das transações do Bitcoin. Se sabemos que uma transação está presa, podemos decidir como liberá-la com recursos como o RBF ou o CPFP. + +## O que vem depois? + +Continuemos "Controlando as transações de Bitcoin" com a sessão [§5.2: Reenviando uma transação com o RBF](05_2_Resending_a_Transaction_with_RBF.md). diff --git a/pt/05_2_Resending_a_Transaction_with_RBF.md b/pt/05_2_Resending_a_Transaction_with_RBF.md new file mode 100644 index 0000000..29f1150 --- /dev/null +++ b/pt/05_2_Resending_a_Transaction_with_RBF.md @@ -0,0 +1,214 @@ +# 5.2: Reenviando uma transação com o RBF + +Se a nossa transação Bitcoin travar e formos a parte que está enviando o saldo, podemos reenviá-la usando o RBF (Replace-By-Fee). No entanto, isso não é tudo que o RBF pode fazer: Geralmente é um recurso poderoso que permite aos remetentes do Bitcoin recriar transações por vários motivos. + +> :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.12.0, que atingiu a maturidade total na carteira do Bitcoin Core na versão 0.14.0. Obviamente, a maioria das pessoas já deveria estar usando-a. + +## Opt-In para o RBF + +O RBF é um recurso opcional do Bitcoin. As transações só são elegíveis para usar o RBF se tiverem sido criadas com um sinalizador RBF especial. Isso é feito configurando qualquer um dos números de sequência UTXO da transação (que normalmente são configurados automaticamente), de modo que seja maior que 0 e menor que 0xffffffff-1 (4294967294). + +Isso pode ser feito simplesmente adicionando uma variável ```sequence``` às nossas entradas do UTXO: +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "sequence": 1 } ]''' outputs='''{ "'$recipient'": 0.00007658, "'$changeaddress'": 0.00000001 }''') +``` +Obviamente, devemos assinar e enviar nossa transação, como fazemos normalmente: +``` +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 +``` +Agora, quando olharmos para nossa transação, devemos ver algo novo: A linha ```bip125-replaceeable```, que sempre foi marcada como ```no``` antes, agora está marcada como ```yes```: +``` +$ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 + +{ + "amount": 0.00000000, + "fee": -0.00000141, + "confirmations": 0, + "trusted": true, + "txid": "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375", + "walletconflicts": [ + ], + "time": 1592954399, + "timereceived": 1592954399, + "bip125-replaceable": "yes", + "details": [ + ], + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b01000000000100000002ea1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077007dff4df9ce75430e3065c82321dca9f6bdcfd5812f8dc0daeb957d3dfd1602203a624d4e9720a06def613eeea67fbf13ce1fb6188d3b7e780ce6e40e859f275d0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" +} +``` +O sinalizador ```bip125-replaceeable``` permanecerá como ```yes``` até que a transação receba confirmações. Nesse ponto, ela não é mais substituível. + +> :book: ***Devo confiar nas transações que não possuem confirmações?*** Não, nunca. Isso era uma verdade antes do RBF e continua sendo depois do RBF. As transações devem receber confirmações antes de serem determinadas como confiáveis. Isto é especialmente verdadeiro se uma transação for marcada como ```bip125-replaceable```, porque ela pode muito bem ser... substituída. + +> :information_source: **NOTA - SEQUÊNCIA:** Este é o primeiro uso do valor ```nSequence``` no Bitcoin. Podemos configurá-lo entre 1 e 0xffffffff-2 (4294967293) e habilitar o RBF, mas se não tivermos cuidado, poderemos bater de frente com o uso paralelo do ```nSequence``` que serve para _timelocks_ relativos. Sugerimos sempre configurá-lo como "1", que é o que o Bitcoin Core faz, mas a outra opção é configurá-lo com um valor entre 0xf0000000 (4026531840) e 0xffffffff-2 (4294967293). Configurá-lo como sendo "1" efetivamente torna os bloqueios de tempo relativos irrelevantes e configurá-lo para 0xf0000000 ou superior os desativa. Tudo isso é explicado posteriormente na sessão [§11.3: Usando CSV nos Scripts](11_3_Using_CSV_in_Scripts.md). Por enquanto, basta escolhermos um dos valores não conflitantes para o ```nSequence```. + +### Opcional: Sempre habilite o RBF + +Se preferirmos, podemos _sempre_ optar por habilitar o RBF. Podemos fazer isso executando nosso ```bitcoind``` com o comando ``` -walletrbf```. Depois de fazermos isso (e reiniciarmos nosso ```bitcoind```), todos os UTXOs devem ter um número de sequência inferior e as transações posteriores devem ser marcadas como ```bip125-replaceable```. + +> :warning: **AVISO DE VERSÃO:** O sinalizador walletrbf requer o Bitcoin Core v.0.14.0 ou superior. + +## Entendendo o funcionamento do RBF + +A funcionalidade RBF é baseada no [BIP 125](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki), que lista as seguintes regras para usá-lo: + +> 1. As transações originais sinalizam a possibilidade de serem substituídas de maneira explicita ou por herança, conforme descrito na sessão anterior. + +Isso significa que o número de sequência deve ser definido para menos de 0xffffffff-1 (4294967294), ou o mesmo é verdadeiro para transações pai não confirmadas. + +> 2. A transação de substituição paga uma taxa absolutamente mais alta do que a soma paga pelas transações originais. +> 3. A transação de substituição não contém nenhuma nova entrada não confirmada que não apareceu anteriormente na mempool. Entradas não confirmadas são entradas e saídas de gastos de transações atualmente não confirmadas. +> 4. A transação de substituição deve pagar por seu próprio tamanho, além do valor pago pelas transações originais, ou acima da taxa definida pela configuração de taxa de retransmissão mínima do node. Por exemplo, se a taxa mínima de retransmissão for 1 satoshi/byte e a transação de substituição for de 500 bytes no total, a substituição deverá pagar uma taxa pelo menos 500 satoshis superior à soma das transações originais. +> 5. O número de transações originais a serem substituídas e as transações filhas que serão removidas do mempool não deve exceder um total de 100 transações. + +> :book: ***O que é um BIP?*** Um BIP é uma proposta de melhoria de Bitcoin (Bitcoin Improvement Proposal). É uma sugestão detalhada para uma mudança no código Bitcoin Core. Frequentemente, quando um BIP foi suficientemente discutido e atualizado, ele se tornará uma parte real do código do Bitcoin Core. Por exemplo, o BIP 125 foi implementado no Bitcoin Core 0.12.0. + +A outra coisa a ser entendida sobre o RBF é que, para usá-lo, devemos gastar o dobro, reutilizando um ou mais UTXOs. Apenas enviar outra transação com um UTXO diferente para o mesmo destinatário não resolverá o problema (e provavelmente resultará em perda do saldo). Ao invés disso, devemos criar um conflito proposital, onde o mesmo UTXO é usado em duas transações diferentes. + +Diante desse conflito, os mineradores saberão usar aquele com a taxa mais alta e serão incentivados a isso devido a taxa ser mais alta. + +> :book: ***O que é um gasto duplo?*** Um gasto duplo ocorre quando alguém envia os mesmos fundos eletrônicos para duas pessoas diferentes (ou, para a mesma pessoa duas vezes, em duas transações diferentes). Este é um problema central para qualquer sistema de dinheiro digital. É resolvido no Bitcoin devido a blockchain imutável: Uma vez que uma transação seja suficientemente confirmada, nenhum minerador irá verificar transações que reutilizam o mesmo UTXO. No entanto, é possível fazer o gasto duplo _antes_ de uma transação ser confirmada. É por isso que sempre desejamos ter uma ou mais confirmações antes de finalizar uma transação. No caso do RBF, podemos propositalmente duplicar o gasto porque uma transação inicial ficou presa, e os mineradores aceitam o nosso gasto duplo se atendermos aos critérios específicos estabelecidos pelo BIP 125. + +> :warning: **ATENÇÃO:** Algumas discussões anteriores sobre esta política sugeriram que o número ```nSequence``` também fosse aumentado. Na verdade, esse era o uso pretendido do ```nSequence``` em sua forma original. Isso _não_ faz parte da política publicada no BIP 125. Na verdade, aumentar o número da sequência pode bloquear travar nossa transação com um _timelock_ relativo, a menos que usemos números de sequência no intervalo de 0xf0000000 (4026531840) a 0xffffffff-2 (4294967293) . + +## Substituindo uma transação no modo hard: Manualmente + +Para criar uma transação RBF manual, tudo o que precisamos fazer é criar uma transação bruta que: (1) Substitua uma transação bruta anterior onde o RBF foi habilitado e que não foi confirmada; (2) Reutilizar um ou mais dos mesmos UTXOs; (3) Aumentar as taxas e; (4) Pagar a taxa mínima de ambas as transações [que já podem ser atendidas no item (3)]. + +O exemplo a seguir apenas reutiliza as variáveis ​​existentes, mas diminui o valor enviado para o endereço de troco, para aumentar a taxa de 0 BTC acidental da transação original para uma taxa de 0,01 BTC, excessivamente generosa, diga-se de passagem, nesta nova transação: +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "sequence": 1 } ]''' outputs='''{ "'$recipient'": 0.000075, "'$changeaddress'": 0.00000001 }''') +``` +É claro que devemos assiná-la novamente e reenviá-la: +``` +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b +``` +Agora podemos olhar para a nossa transação original e ver se ela tem ```walletconflicts```: +``` +$ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 +{ + "amount": 0.00000000, + "fee": -0.00000141, + "confirmations": 0, + "trusted": false, + "txid": "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375", + "walletconflicts": [ + "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b" + ], + "time": 1592954399, + "timereceived": 1592954399, + "bip125-replaceable": "yes", + "details": [ + ], + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b01000000000100000002ea1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077007dff4df9ce75430e3065c82321dca9f6bdcfd5812f8dc0daeb957d3dfd1602203a624d4e9720a06def613eeea67fbf13ce1fb6188d3b7e780ce6e40e859f275d0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" +} +``` +Isso representa o fato de que duas transações diferentes estão tentando usar o mesmo UTXO. + +Eventualmente, a transação com a taxa maior deve ser aceita: +``` +$ bitcoin-cli -named gettransaction txid=c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b +{ + "amount": 0.00000000, + "fee": -0.00000299, + "confirmations": 2, + "blockhash": "0000000000000055ac4b6578d7ffb83b0eccef383ca74500b00f59ddfaa1acab", + "blockheight": 1773266, + "blockindex": 9, + "blocktime": 1592955002, + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "walletconflicts": [ + "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375" + ], + "time": 1592954467, + "timereceived": 1592954467, + "bip125-replaceable": "no", + "details": [ + ], + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b010000000001000000024c1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077dcdd98d85f6247450185c2b918a0f434d9b2e647330d741944ecae60d6ff790220424f85628cebe0ffe9fa11029b8240d08bdbfcc0c11f799483e63b437841b1cd0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" +} +``` +Enquanto isso, a transação original com a taxa mais baixa começa a receber confirmações negativas, para mostrar a divergência com a blockchain: +``` +$ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 +{ + "amount": 0.00000000, + "fee": -0.00000141, + "confirmations": -2, + "trusted": false, + "txid": "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375", + "walletconflicts": [ + "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b" + ], + "time": 1592954399, + "timereceived": 1592954399, + "bip125-replaceable": "yes", + "details": [ + ], + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b01000000000100000002ea1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077007dff4df9ce75430e3065c82321dca9f6bdcfd5812f8dc0daeb957d3dfd1602203a624d4e9720a06def613eeea67fbf13ce1fb6188d3b7e780ce6e40e859f275d0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" +} +``` +Nossos destinatários terão nosso saldo, e a transação original que foi falha acabará saindo do mempool. + +## Substituindo uma transação no modo easy: Usando o bumpfee + +As transações brutas são muito poderosas e podemos fazer muitas coisas interessantes combinando-as com o RBF. No entanto, às vezes _tudo_ o que desejamos é apenas liberar uma transação que está presa na mempool. Podemos fazer isso com um comando simples, o ```bumpfee```. + +Por exemplo, para aumentar a taxa da transação ```4460175e8276d5a1935f6136e36868a0a3561532d44ddffb09b7cb878f76f927```, executaríamos o seguinte comando: +``` +$ bitcoin-cli -named bumpfee txid=4460175e8276d5a1935f6136e36868a0a3561532d44ddffb09b7cb878f76f927 +{ + "txid": "75208c5c8cbd83081a0085cd050fc7a4064d87c7d73176ad9a7e3aee5e70095f", + "origfee": 0.00000000, + "fee": 0.00022600, + "errors": [ + ] +} +``` +O resultado é a geração automática de uma nova transação que tem uma taxa determinada pelo arquivo ```bitcoin.conf```: +``` +$ bitcoin-cli -named gettransaction txid=75208c5c8cbd83081a0085cd050fc7a4064d87c7d73176ad9a7e3aee5e70095f +{ + "amount": -0.10000000, + "fee": -0.00022600, + "confirmations": 0, + "trusted": false, + "txid": "75208c5c8cbd83081a0085cd050fc7a4064d87c7d73176ad9a7e3aee5e70095f", + "walletconflicts": [ + "4460175e8276d5a1935f6136e36868a0a3561532d44ddffb09b7cb878f76f927" + ], + "time": 1491605676, + "timereceived": 1491605676, + "bip125-replaceable": "yes", + "replaces_txid": "4460175e8276d5a1935f6136e36868a0a3561532d44ddffb09b7cb878f76f927", + "details": [ + { + "account": "", + "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", + "category": "send", + "amount": -0.10000000, + "vout": 0, + "fee": -0.00022600, + "abandoned": false + } + ], + "hex": "02000000014e843e22cb8ee522fbf4d8a0967a733685d2ad92697e63f52ce41bec8f7c8ac0020000006b48304502210094e54afafce093008172768d205d99ee2e9681b498326c077f0b6a845d9bbef702206d90256d5a2edee3cab1017b9b1c30b302530b0dd568e4af6f2d35380bbfaa280121029f39b2a19943fadbceb6697dbc859d4a53fcd3f9a8d2c8d523df2037e7c32a71010000000280969800000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac38f25c05000000001976a914c101d8c34de7b8d83b3f8d75416ffaea871d664988ac00000000" +} +``` +> :aviso: **AVISO DE VERSÃO:** O comando ```bumpfee``` no RPC requer o Bitcoin Core v.0.14.0. + +## Resumo do Reenviando uma transação com o RBF + +Se uma transação ficar presa na mempool e não quisermos esperar que ela expire, e se habilitamos o RBF nela, podemos fazer um gasto duplo usando o RBF para criar uma transação de substituição (ou apenas usar o comando ```bumpfee```). + +> :fire: ***Qual é o poder do RBF?*** Obviamente, o RBF é muito útil se criarmos uma transação com uma taxa muito baixa e precisamos acelerá-la. No entanto, a capacidade de substituir transações não confirmadas por transações atualizadas tem mais poder do que apenas isso (e é por isso que podemos querer continuar usando o RBF com transações brutas, mesmo após sabermos que existe o ```bumpfee```). + +> Por exemplo, podemos enviar uma transação e, antes de ser confirmada, combiná-la com uma segunda transação. Isso permite que possamos comprimir várias transações em uma única, diminuindo as taxas totais. Também podemos oferecer benefícios à privacidade. Existem outras razões para usarmos o RBF, como por exemplo contratos inteligentes ou transferência de transações, conforme descrito na parte referente a [Perguntas frequentes sobre RBF de opt-in](https://bitcoincore.org/en/faq/optin_rbf/). + +## O que vem depois? + +Vamos continuar "Controlando as transações de Bitcoin" na sessão [§5.3: Financiando uma transação com o CPFP](05_3_Funding_a_Transaction_with_CPFP.md). diff --git a/pt/05_3_Funding_a_Transaction_with_CPFP.md b/pt/05_3_Funding_a_Transaction_with_CPFP.md new file mode 100644 index 0000000..1f51150 --- /dev/null +++ b/pt/05_3_Funding_a_Transaction_with_CPFP.md @@ -0,0 +1,128 @@ +# 5.3: Financiando uma transação com o CPFP + +Se nossa transação do Bitcoin travar e formos os _recebedores_, poderemos aumentar a velocidade usando o CPFP (Child-Pays-For-Parent). Esta é uma alternativa semelhante ao que a parte que _ envia_ o saldo pode fazer usando o RBF. + +> :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.13.0, o que novamente significa que a maioria das pessoas já deve estar utilizando-a. + +## Entendendo o funcionamento do CPFP + +O RBF é possível caso você seja a parte que está enviando o saldo. O remetente errou e precisou aumentar a taxa, ou queria ser inteligente e combinar transações por diversos motivos. O RBF é um poderoso recurso voltado para o remetente. De certa forma, o CPFP é o oposto do RBF, pois dá poder ao destinatário que sabe que o dinheiro ainda não chegou e quer acelerar o processo. No entanto, também é um recurso muito mais simples, com aplicabilidade não tão ampla quanto a primeira. + +Basicamente, a ideia do CPFP é que um destinatário tenha uma transação que não foi confirmada e deseja gastar o seu saldo. Portanto, ele inclui essa transação não confirmada em uma nova transação e paga uma taxa alta o suficiente para encorajar um minerador a incluir a transação original (pai) e a nova transação (filha) em um bloco. Como resultado, as duas transações são confirmadas e eliminadas da mempool simultaneamente. + +Devemos observar que o CPFP não é um recurso novo no protocolo, assim como o RBF. É apenas um novo esquema de incentivo que pode ser usado para a seleção de transações pelos mineradores. Isso também significa que não é tão confiável quanto uma alteração feita pelo RBF: Pode haver motivos para que o filho não seja selecionado para ser colocado em um bloco e isso impedirá que o pai também seja colocado no bloco. + +## Gastando UTXOs não confirmados + +Financiar uma transação com o CPFP é um processo muito simples, usando os métodos com os quais já estamos familiarizados: + + 1. Encontre o ```txid``` e ```vout``` da transação não confirmada. Esta será a parte mais complicada, já que o ```bitcoin-cli``` geralmente tenta nos proteger de transações não confirmadas. O remetente pode enviar essas informações para nós, mesmo com apenas o ```txid```, devemos ser capazes de descobrir o ```vout``` em um explorador da blockchain; + +Temos uma outra opção: Podemos usar o ```bitcoin-cli getrawmempool```, que pode ser usado para listar o conteúdo de toda a nossa mempool, onde estarão as transações não confirmadas. Podemos vasculhar várias transações se nossa mempool estiver cheia. Podemos obter mais informações sobre uma transação específica usando o comando ```bitcoin-cli getrawtransaction``` com o sinalizador verbose definido como ```true```: +``` +$ bitcoin-cli getrawmempool +[ + "95d51e813daeb9a861b2dcdddf1da8c198d06452bbbecfd827447881ff79e061" +] + +$ bitcoin-cli getrawtransaction 95d51e813daeb9a861b2dcdddf1da8c198d06452bbbecfd827447881ff79e061 true +{ + "txid": "95d51e813daeb9a861b2dcdddf1da8c198d06452bbbecfd827447881ff79e061", + "hash": "9729e47b8aee776112a82cec46df7638d112ca51856c53e238a9b1f7af3be4ce", + "version": 2, + "size": 247, + "vsize": 166, + "weight": 661, + "locktime": 1773277, + "vin": [ + { + "txid": "7a0178472300247d423ac4a04ff9165fa5b944104f6d6f9ebc557c6d207e7524", + "vout": 0, + "scriptSig": { + "asm": "0014334f3a112df0f22e743ad97eec8195a00faa59a0", + "hex": "160014334f3a112df0f22e743ad97eec8195a00faa59a0" + }, + "txinwitness": [ + "304402207966aa87db340841d76d3c3596d8b4858e02aed1c02d87098dcedbc60721d8940220218aac9d728c9a485820b074804a8c5936fa3145ce68e24dcf477024b19e88ae01", + "03574b1328a5dc2d648498fc12523cdf708efd091c28722a422d122f8a0db8daa9" + ], + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01000000, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 f079f77f2ef0ef1187093379d128ec28d0b4bf76 OP_EQUAL", + "hex": "a914f079f77f2ef0ef1187093379d128ec28d0b4bf7687", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2NFAkGiwnp8wvCodRBx3smJwxncuG3hndn5" + ] + } + }, + { + "value": 0.02598722, + "n": 1, + "scriptPubKey": { + "asm": "OP_HASH160 8799be12fb9eae6644659d95b9602ddfbb4b2aff OP_EQUAL", + "hex": "a9148799be12fb9eae6644659d95b9602ddfbb4b2aff87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N5cDPPuCTtYq13oXw8RfpY9dHJW8sL64U2" + ] + } + } + ], + "hex": "0200000000010124757e206d7c55bc9e6f6d4f1044b9a55f16f94fa0c43a427d2400234778017a0000000017160014334f3a112df0f22e743ad97eec8195a00faa59a0feffffff0240420f000000000017a914f079f77f2ef0ef1187093379d128ec28d0b4bf768742a727000000000017a9148799be12fb9eae6644659d95b9602ddfbb4b2aff870247304402207966aa87db340841d76d3c3596d8b4858e02aed1c02d87098dcedbc60721d8940220218aac9d728c9a485820b074804a8c5936fa3145ce68e24dcf477024b19e88ae012103574b1328a5dc2d648498fc12523cdf708efd091c28722a422d122f8a0db8daa9dd0e1b00" +} +``` +Vamos observar o array ```vout```. Assim, encontramos o objeto que corresponde ao nosso endereço. No nosso exemplo ele é o único. O valor ```n``` é o nosso ```vout```. Agora temos tudo que precisamos para criar uma nova transação CPFP. +``` +$ utxo_txid=2NFAkGiwnp8wvCodRBx3smJwxncuG3hndn5 +$ utxo_vout=0 +$ recipient2=$(bitcoin-cli getrawchangeaddress) +``` + + 2. Criar uma transação bruta usando a transação não confirmada como entrada; + 3. Dobrar as taxas de transação (ou colocar mais do que isso); + +Ao seguir essas etapas, tudo deve parecer igual ao que já fizemos, apesar de estarmos trabalhando com uma transação não confirmada. Para verificar se tudo está bem, podemos até olhar os resultados de nossa assinatura antes de salvarmos as informações em uma variável: +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient2'": 0.03597 }''') + +$ bitcoin-cli -named signrawtransaction hexstring=$rawtxhex | jq -r '.hex' +02000000012b137ef780666ba214842ff6ea2c3a0b36711bcaba839c3710f763e3d9687fed000000006a473044022003ca1f6797d781ef121ba7c2d1d41d763a815e9dad52aa8bc5ea61e4d521f68e022036b992e8e6bf2c44748219ca6e0056a88e8250f6fd0794dc69f79a2e8993671601210317b163ab8c8862e09c71767112b828abd3852e315441893fa0f535de4fa39b8dffffffff01905abd07000000001976a91450b1d90a130c4f3f1e5fbfa7320fd36b7265db0488ac00000000 + +$ signedtx=$(bitcoin-cli -named signrawtransaction hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +6a184a2f07fa30189f4831d6f041d52653a103b3883d2bec2f79187331fd7f0e +``` + + 4. Cruzar os dedos não é necessário. Verificamos que nossos dados estão corretos. Deste ponto em diante, as coisas estão fora de nosso controle. + +Nossas transações podem ser processadas rapidamente, ou não. Tudo depende se os mineradores que estão gerando aleatoriamente os blocos possuem o patch CPFP ou não. Apesar disso, fizemos tudo o que pudemos. + +E isso realmente é tudo o que podemos fazer. + +### Atenção aos nuances + +Embora o CPFP seja geralmente descrito como sendo um destinatário que usa uma nova transação para pagar por uma antiga que não foi confirmada, existem alguns nuances. + +A parte que está _enviando_ poderia usar o CPFP para liberar uma transação se recebesse algum troco. Ele apenas usaria essa mudança como uma entrada, e o uso resultante do CPFP liberaria toda a transação. Lembre-se de que ele poderia fazer algo melhor se usasse o RBF, desde que estivesse habilitado, pois as taxas totais seriam menores. + +A parte que está _recebendo_ pode usar o CPFP mesmo se não estiver planejando gastar o dinheiro imediatamente, por exemplo, se estiver preocupado que os fundos possam não ser reenviados se a transação expirar. Nesse caso, ele apenas cria uma transação secundária que envia todo o dinheiro (menos a taxa de transação) para um endereço de troco. Isso é o que fizemos no nosso exemplo. + +## Resumo do Financiando uma transação com o CPFP + +Podemos aproveitar os incentivos do CPFP para liberar fundos que nos foram enviados, mas que não foram confirmados. Basta usar a transação não confirmada como sendo um UTXO e pagar uma taxa de transação acima da média. + +> :fire: ***What is the power of CPFP?*** Mostly, CPFP is just useful to get funds unstuck when you're the recipient and the sender isn't being helpful for whatever reason. It doesn't have the more powerful possibilities of RBF, but is an alternatve way to exert control over a transaction after it's been placed in the mempool, but before it's confirmed in a block. +> :fire: ***Qual é o poder do CPFP?*** O seu uso é apenas para liberar fundos quando formos os recebedores dos fundos e o remetente não quer ajudar por qualquer que seja o motivo. Ele não tem as mesmas habilidades que o RBF, mas é uma maneira alternativa de exercer controle sobre uma transação depois que ela foi colocada na mempool, mas antes de ser confirmada em um bloco. + +## O que vem depois? + +Vamos avançar para o [Capítulo 6: Expandindo as Transações de Bitcoin com Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md). \ No newline at end of file From 89288a1b588ad83943b6f923828d70efd056d18d Mon Sep 17 00:00:00 2001 From: hgrams <77242934+hgrams@users.noreply.github.com> Date: Tue, 13 Jul 2021 17:10:13 -0100 Subject: [PATCH 6/6] finish review --- pt/05_1_Watching_for_Stuck_Transactions.md | 2 +- pt/05_2_Resending_a_Transaction_with_RBF.md | 2 +- pt/05_3_Funding_a_Transaction_with_CPFP.md | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pt/05_1_Watching_for_Stuck_Transactions.md b/pt/05_1_Watching_for_Stuck_Transactions.md index e887056..9a08734 100644 --- a/pt/05_1_Watching_for_Stuck_Transactions.md +++ b/pt/05_1_Watching_for_Stuck_Transactions.md @@ -32,7 +32,7 @@ $ bitcoin-cli -named gettransaction txid=fa2ddf84a4a632586d435e10880a2921db6310d ], "hex": "02000000014cda1f42a1bd39d8d0ff5958a804bc2bc548b71d7ceadbde53ea15aeaf1e2691000000006a473044022016a7a9f045a0f6a52129f48adb7da35c2f54a0741d6614e9d55b8a3bc3e1490a0220391e9085a3697bc790e94bb924d5310e16f23489d9c600864a32674e871f523c01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff02204e000000000000160014751e76e8199196d454941c45d1b3a323f1433bd6e8030000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919600000000" ``` -Uma transação pode ser considerada presa se permanecer nesse estado por um longo período de tempo. A tempos atrás, podíamos ter a certeza de que todas as transações iriam ser confirmadas _eventualmente_. Mas, isso não é mais verdade devido ao aumento exponencial do uso do Bitcoin. Agora, se uma transação ficar travada por muito tempo, ela sairá da mempool e, em seguida, estará perdida para sempre na rede Bitcoin. +Uma transação pode ser considerada presa se permanecer nesse estado por um longo período de tempo. A tempos atrás, podíamos ter a certeza de que todas as transações iriam ser confirmadas _eventualmente_. Mas, isso não é mais verdade devido ao aumento exponencial do uso do Bitcoin. Agora, se uma transação ficar travada por muito tempo, ela sairá da mempool e, em seguida, será esquecida para sempre da rede Bitcoin. > :book: ***O que é a mempool?*** A Mempool (ou Piscina de Memória) é um local onde todas as transações não confirmadas em um node bitcoin ficam. Estas são as transações que um node recebeu da rede P2P que ainda não estão incluídas em um bloco. Cada node bitcoin pode ter um conjunto ligeiramente diferente de transações em sua mempool: Transações diferentes podem ter sido propagadas para um node específico. Isso depende de quando o node foi iniciado pela última vez e também os limites de tamanho. Quando um minerador faz um bloco, ele usa as transações da mempool. Então, quando um bloco é verificado, todos os mineradores removem essas transações da mempool. A partir do Bitcoin 0.12, as transações não confirmadas também podem expirar na mempool se forem antigas o suficiente, normalmente o tempo é de 72 horas. No caso das versões 0.14.0 o tempo foi aumentado para 2 semanas. As pools de mineração podem ter seus próprios mecanismos de gerenciamento da mempool. diff --git a/pt/05_2_Resending_a_Transaction_with_RBF.md b/pt/05_2_Resending_a_Transaction_with_RBF.md index 29f1150..2b2d632 100644 --- a/pt/05_2_Resending_a_Transaction_with_RBF.md +++ b/pt/05_2_Resending_a_Transaction_with_RBF.md @@ -71,7 +71,7 @@ Diante desse conflito, os mineradores saberão usar aquele com a taxa mais alta > :book: ***O que é um gasto duplo?*** Um gasto duplo ocorre quando alguém envia os mesmos fundos eletrônicos para duas pessoas diferentes (ou, para a mesma pessoa duas vezes, em duas transações diferentes). Este é um problema central para qualquer sistema de dinheiro digital. É resolvido no Bitcoin devido a blockchain imutável: Uma vez que uma transação seja suficientemente confirmada, nenhum minerador irá verificar transações que reutilizam o mesmo UTXO. No entanto, é possível fazer o gasto duplo _antes_ de uma transação ser confirmada. É por isso que sempre desejamos ter uma ou mais confirmações antes de finalizar uma transação. No caso do RBF, podemos propositalmente duplicar o gasto porque uma transação inicial ficou presa, e os mineradores aceitam o nosso gasto duplo se atendermos aos critérios específicos estabelecidos pelo BIP 125. -> :warning: **ATENÇÃO:** Algumas discussões anteriores sobre esta política sugeriram que o número ```nSequence``` também fosse aumentado. Na verdade, esse era o uso pretendido do ```nSequence``` em sua forma original. Isso _não_ faz parte da política publicada no BIP 125. Na verdade, aumentar o número da sequência pode bloquear travar nossa transação com um _timelock_ relativo, a menos que usemos números de sequência no intervalo de 0xf0000000 (4026531840) a 0xffffffff-2 (4294967293) . +> :warning: **ATENÇÃO:** Algumas discussões anteriores sobre esta política sugeriram que o número ```nSequence``` também fosse aumentado. Na verdade, esse era o uso pretendido do ```nSequence``` em sua forma original. Isso _não_ faz parte da política publicada no BIP 125. Na verdade, aumentar o número da sequência, pode travar acidentalmente nossa transação com um _timelock_ relativo, a menos que usemos números de sequência no intervalo de 0xf0000000 (4026531840) a 0xffffffff-2 (4294967293) . ## Substituindo uma transação no modo hard: Manualmente diff --git a/pt/05_3_Funding_a_Transaction_with_CPFP.md b/pt/05_3_Funding_a_Transaction_with_CPFP.md index 1f51150..3e36c38 100644 --- a/pt/05_3_Funding_a_Transaction_with_CPFP.md +++ b/pt/05_3_Funding_a_Transaction_with_CPFP.md @@ -80,7 +80,7 @@ $ bitcoin-cli getrawtransaction 95d51e813daeb9a861b2dcdddf1da8c198d06452bbbecfd8 "hex": "0200000000010124757e206d7c55bc9e6f6d4f1044b9a55f16f94fa0c43a427d2400234778017a0000000017160014334f3a112df0f22e743ad97eec8195a00faa59a0feffffff0240420f000000000017a914f079f77f2ef0ef1187093379d128ec28d0b4bf768742a727000000000017a9148799be12fb9eae6644659d95b9602ddfbb4b2aff870247304402207966aa87db340841d76d3c3596d8b4858e02aed1c02d87098dcedbc60721d8940220218aac9d728c9a485820b074804a8c5936fa3145ce68e24dcf477024b19e88ae012103574b1328a5dc2d648498fc12523cdf708efd091c28722a422d122f8a0db8daa9dd0e1b00" } ``` -Vamos observar o array ```vout```. Assim, encontramos o objeto que corresponde ao nosso endereço. No nosso exemplo ele é o único. O valor ```n``` é o nosso ```vout```. Agora temos tudo que precisamos para criar uma nova transação CPFP. +Vamos observar o vetor ```vout```. Assim, encontramos o objeto que corresponde ao nosso endereço. No nosso exemplo ele é o único. O valor ```n``` é o nosso ```vout```. Agora temos tudo que precisamos para criar uma nova transação CPFP. ``` $ utxo_txid=2NFAkGiwnp8wvCodRBx3smJwxncuG3hndn5 $ utxo_vout=0 @@ -89,7 +89,7 @@ $ recipient2=$(bitcoin-cli getrawchangeaddress) 2. Criar uma transação bruta usando a transação não confirmada como entrada; 3. Dobrar as taxas de transação (ou colocar mais do que isso); - + Ao seguir essas etapas, tudo deve parecer igual ao que já fizemos, apesar de estarmos trabalhando com uma transação não confirmada. Para verificar se tudo está bem, podemos até olhar os resultados de nossa assinatura antes de salvarmos as informações em uma variável: ``` $ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient2'": 0.03597 }''') @@ -103,7 +103,7 @@ $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx ``` 4. Cruzar os dedos não é necessário. Verificamos que nossos dados estão corretos. Deste ponto em diante, as coisas estão fora de nosso controle. - + Nossas transações podem ser processadas rapidamente, ou não. Tudo depende se os mineradores que estão gerando aleatoriamente os blocos possuem o patch CPFP ou não. Apesar disso, fizemos tudo o que pudemos. E isso realmente é tudo o que podemos fazer. @@ -120,8 +120,7 @@ A parte que está _recebendo_ pode usar o CPFP mesmo se não estiver planejando Podemos aproveitar os incentivos do CPFP para liberar fundos que nos foram enviados, mas que não foram confirmados. Basta usar a transação não confirmada como sendo um UTXO e pagar uma taxa de transação acima da média. -> :fire: ***What is the power of CPFP?*** Mostly, CPFP is just useful to get funds unstuck when you're the recipient and the sender isn't being helpful for whatever reason. It doesn't have the more powerful possibilities of RBF, but is an alternatve way to exert control over a transaction after it's been placed in the mempool, but before it's confirmed in a block. -> :fire: ***Qual é o poder do CPFP?*** O seu uso é apenas para liberar fundos quando formos os recebedores dos fundos e o remetente não quer ajudar por qualquer que seja o motivo. Ele não tem as mesmas habilidades que o RBF, mas é uma maneira alternativa de exercer controle sobre uma transação depois que ela foi colocada na mempool, mas antes de ser confirmada em um bloco. +> :fire: ***Qual é o poder do CPFP?*** O seu uso é apenas para liberar fundos quando formos os recebedores dos fundos e o remetente não quer ajudar por qualquer que seja o motivo. Ele não tem as mesmas habilidades que o RBF, mas é uma maneira alternativa de exercer controle sobre uma transação depois que ela foi colocada na mempool, mas antes de ser confirmada em um bloco. ## O que vem depois?