From f0bedd25c16105355f07681ecc3ffd41c3a47839 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 24 Jun 2021 21:30:52 -0300 Subject: [PATCH 001/155] Contributor License Agreement Signed --- ...BD6AD8C042ED6E9C5A232F3B909765FBEA7B30.asc | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 signed-cla/CLA.KoreaComK.F2BD6AD8C042ED6E9C5A232F3B909765FBEA7B30.asc diff --git a/signed-cla/CLA.KoreaComK.F2BD6AD8C042ED6E9C5A232F3B909765FBEA7B30.asc b/signed-cla/CLA.KoreaComK.F2BD6AD8C042ED6E9C5A232F3B909765FBEA7B30.asc new file mode 100644 index 0000000..b342600 --- /dev/null +++ b/signed-cla/CLA.KoreaComK.F2BD6AD8C042ED6E9C5A232F3B909765FBEA7B30.asc @@ -0,0 +1,75 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + + +# Contributor License Agreement + +Version 1.0 + +Name: `KoreaComK` + +E-Mail: `koreacomk@protonmail.com` + +Legal Jurisdiction: Wyoming, United States of America + +Project: https://github.com/BlockchainCommons/bc-lethe-kit + +Date: `2021-06-16` + +## 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 `KoreaComK`, `koreacomk@protonmail.com`, and `2021-06-16` 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----- + +iQIzBAEBCgAdFiEE8r1q2MBC7W6cWiMvO5CXZfvqezAFAmDKToEACgkQO5CXZfvq +ezCpJg/8DuIIHflWCcNSHljnOQgQfW/Qzys6axIB0FAO5E7VqZHD5tUzwThgxuU0 +BbniGNiqascqcMkTRWfOOXyx/Nef5bTt2CUqRU6k/3sK1VlXnWGB/zSikYeDWCUT +rggzQ052cBm103yiaOMg2Hx0Y4qTtcN/vJyXg0aESUXz+drMItKEaQBsF2fkwtPr +pGv7hqyu2O/u+9pMtZg8+lvHEPBdGfOVaCynrNLFTUE4+NSRNriPG/l5CTG8oEAC +h+e7HcZDiDVK2uQvhrPJLYhXWjiUqJ0MYpI9EKA88wkotUtilNsGKC8NqU724xIu +80hG+BeN9JWAR0wGPweVBtjkj1+hWNRbrm7ESK3gw53mfQBnAbpf23Rvk+tv24kG +/is8dAiHGHpLxBlD4DfGeyeKReXGjWhzaOkzJSBqXC0UBq3nyqcRQtbLd2hn0zpF +zm8/PwmB+PRGQ8TeRUa2j1o5ZUYyRCKtTARB68CrF0D26dpmtSheCGAqwp5mQqN2 +SBIHnFnFUTFJ3CEZJ4LVVGsHwfBt9BZL5D67grVJ9h19PLZsq9t4iEZLX47p8gP0 +Cp8YorqkelFZ/u+7VP1bJiZlX5E0Q/aGdLKemtSA5vbo4ua59fSw1bNWO9x19yt+ +u6u/PT8G5OoUhLldj4L8G3BFBXllb29nphtAVjh/PWxJj0dcupA= +=o+hW +-----END PGP SIGNATURE----- From 8be593a08fb2f6aedd9b83754917084614200cc8 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 24 Jun 2021 21:34:18 -0300 Subject: [PATCH 002/155] Chapter 01 translated The both files were revised by @lukedevj in the closed PR (https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/pull/224) --- pt/01_0_Introduction.md | 64 ++++++++++++++ pt/01_1_Introducing_Bitcoin.md | 150 +++++++++++++++++++++++++++++++++ 2 files changed, 214 insertions(+) create mode 100644 pt/01_0_Introduction.md create mode 100644 pt/01_1_Introducing_Bitcoin.md diff --git a/pt/01_0_Introduction.md b/pt/01_0_Introduction.md new file mode 100644 index 0000000..116b7e4 --- /dev/null +++ b/pt/01_0_Introduction.md @@ -0,0 +1,64 @@ + +# CAPÍTULO 1: Introdução à Aprendizagem do Bitcoin Core (& Lightning Network) pela linha de comando + +## Introdução + +Os modos como fazemos pagamentos por bens e serviços têm mudado drasticamente nas últimas décadas. Antigamente todas as transações eram realizadas utilizando dinheiro ou cheques, e atualmente os diversos métodos de pagamento eletrônico são à regra. Porém, a maioria dos pagamentos eletrônicos ainda ocorre utilizando sistemas centralizados, onde empresas de cartão de crédito, bancos ou até instituições financeiras baseadas apenas na Internet, como o PayPal, mantêm listas de transações longas e correlacionadas individualmente, tendo o poder de censurar as transações que não gostarem. + +Esses riscos de centralização foram alguns dos catalisadores primordiais para a criação de criptomoedas, sendo a primeira e mais bem sucedida, o Bitcoin. O Bitcoin oferece pseudonímia; torna difícil correlacionar as transações; e torna a censura por entidades individuais, algo próximo do impossível. Essas vantagens fizeram dele uma das moedas mais rápidas do mundo. Esse crescimento, por sua vez, despertou o interesse dos empresários e desenvolvedores, ansiosos para criar novos serviços para a comunidade do Bitcoin. + +Se você é um desses empreendedores ou desenvolvedores, então este curso é para você, porque ele tem tudo o que necessita para aprender a programar no Bitcoin. É um curso introdutório que explica todas as nuances e características do Bitcoin e de tudo o que vem com ele. O curso também oferece algumas coisas mais específicas, como aulas de como utilizar _diretamente_ o Bitcoin Core com o servidor C-Lightning usando suas interfaces RPC. + +Por que não utilizar algumas das bibliotecas mais detalhadas encontradas em várias linguagens de programação? Por que não criar a sua própria do zero? Porque trabalhar com criptomoedas é perigoso. Não há redes de segurança. Se você acidentalmente pagar taxas muito altas ou perder uma chave de assinatura ou criar uma transação inválida ou fazer qualquer outros milhares de erros potenciais, você dará adeus a suas moedas para sempre. Muito dessa responsabilidade, é claro, fica com você como sendo um programador de criptomoedas, mas também pode ser minimizado, trabalhando com as interfaces de criptomoedas mais robustas e seguras que estão disponíveis, as que foram criadas pelas próprias equipes de programação dessas criptomoedas: A ``Bitcoind`` e a ``Lightningd``. + +Grande parte deste livro discute como fazer um script em bitcoin (e na Lightning Network) diretamente pela linha de comando. Alguns capítulos adiantes lidam com linguagens de programação mais sofisticadas, mas novamente continuam a interagir diretamente com o `` Bitcoind`` e a ``Lightningd``, usando o RPC ou interagindo com os arquivos que são criados por eles. Isso permite que você se mantenha no mesmo nível dos gigantes e use a tecnologia confiável para aprender como criar seus próprios sistemas confiáveis. + +## Nível de Habilidade Necessária + +Você não precisa ser particularmente uma pessoa da área técnica para boa parte deste curso. Tudo o que precisará é a confiança para executar comandos básicos pela linha de comando do UNIX. Se você está familiarizado com coisas como ``ssh``, ``cd``, e ``ls``, o curso irá te fornecer o resto. + +Uma minoria deste curso requer conhecimento de programação, e você deve pular essas seções, se necessário, conforme iremos discutir na próxima seção. + +## Resumo dos tópicos + +Este livro é dividido nas seguintes seções: + +| Parte | Descrição | Habilidades | +|-------|---------|---------| +| **Parte 1: Se preparando para o Bitcoin** | Entendendo os fundamentos do Bitcoin e configurando um servidor para uso. | Linha de Comando | +| **Parte 2: Usando o bitcoin-cli** | Usando o Bitcoin-cli para criar transações. | Linha de Comando | +| **Parte 3: Fazendo scripts com Bitcoin** | Expandindo seu trabalho no bitcoin com scripts. | Conceitos de Programação | +| **Parte 4: Usando o Tor** | Melhorando a segurança do _node_ com tor | Linha de Comando | +| **Parte 5: Programando com RPC** | Acessando o RPC com C e outras linguagens. | Programando em C | +| **Parte 6: Usando a lightning-cli** | Usando a Lightning-CLI para criar transações. | Linha de Comando | +| **Apêndices.** | Utilizando configurações incomuns no Bitcoin. | Linha de Comando | + +## Como Usar Este Curso + +Então, por onde você começa? Este livro é destinado principalmente para ser lido em sequência. Basta seguir o "O que vem depois?" que estarão no final de cada seção e/ou clicar nos links individuais de cada seção em cada página do capítulo. Você conseguirá o melhor entendimento deste curso se realmente se construir um servidor Bitcoin (no capítulo 2) e, em seguida, passar por todos os exemplos que estarão disponíveis ao longo do livro: Testar os exemplos é uma excelente metodologia de aprendizado. + +Se você tem diferentes níveis de habilidade ou se quiser aprender coisas diferentes, poderá pular para algumas partes diferentes do livro: + +* Se você já tem um ambiente pronto do Bitcoin para ser utilizado, vá para o [Capítulo 3: Entendendo sua configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). +* Se você só se importa com os Scriptos em Bitcoin, pule para o [Capítulo 9: Apresentando os Scripts no Bitcoin](09_0_Introducing_Bitcoin_Scripts.md). +* Se você quiser apenas ler sobre o uso das linguagens de programação, pule para o [Capítulo 15: Falando com o Bitcoin](15_0_Talking_to_Bitcoind.md). +* Se não quer programar nada, definitivamente ignore os capítulos 15 ao 17 enquanto estiver lendo, e talvez seja melhor pular os capítulos 9 ao 13. O resto do curso ainda deve fazer sentido sem eles. +* Se estiver interessado apenas na Lightning Network, corra para o [Capítulo 18: Entendendo sua configuração da Lightning Network](18_0_Understanding_Your_Lightning_Setup.md). +* Se quiser ler o conteúdo novo adicionado na versão 2 do curso (2020), seguido da versão 1 (2017), leia [§3.5: Entendendo o descritor](03_5_Understanding_the_Descriptor.md), [§4.6: Criando uma transação SegWit](04_6_Creating_a_Segwit_Transaction.md), [Capítulo 7: Expandindo o Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md), [§9.5: Criando um script P2WPKH](09_5_Scripting_a_P2WPKH.md), [§10.5: Criando um script SegWit](10_5_Scripting_a_Segwit_Script.md), [Capítulo 14: Usando o Tor](14_0_Using_Tor.md), [Capítulo 15: Conversando com o Bitcoin com C](15_0_Talking_to_Bitcoind.md), [Capítulo 16: Programando com Libwally](16_0_Programming_with_Libwally.md), [Capítulo 17: Conversando com o Bitcoind usando outras linguagens](17_0_Talking_to_Bitcoind_Other.md), [Capítulo 18: Entendendo sua configuração da Lightning ](18_0_Understanding_Your_Lightning_Setup.md), e [Capítulo 19: Usando a Lightning](19_0_Using_Lightning.md). + +## Por Que Utilizar Este Curso + +Obviamente, você está querendo fazer este curso porque está interessado no Bitcoin. Além de transmitir o conhecimento básico, também ajudará os leitores a participar (ou criar) projetos open source e obter empregos de cargos júnior na área de programação envolvendo o Bitcoin. Um número de estagiários na Blockchain Commons aprendeu sobre o Bitcoin através deste curso, e muitos dos membros da nossa equipe de programação também. + +## Como Ajudar Este Curso + +* Por favor, use a área de [Issues](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) para quaisquer dúvidas. A Blockchain Commons não tem uma equipe ativa de suporte, e não podemos abordar problemas ou perguntas individuais, mas olharemos iremos tratá-los com o tempo e os usaremos para melhorar nossas futuras iterações no curso. +* Por favor, use os [PRs](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/pulls) para quaisquer correções de erros de digitação ou comandos incorretos (ou que foram alterados). Para alterações técnicas ou de linha de comando, é muito útil se você usar também os comentários para explicar por que fez o que você fez, para que não precisemos gastar tempo pesquisando o motivo. +* Por favor, use nossa [Área de Discussão da Comunidade](https://github.com/BlockchainCommons/Community/discussions) para falar sobre carreiras e habilidades. A Blockchain Commons ocasionalmente oferece estágios, como falado em nosso repo da comunidade. +* Por favor, [torne-se um patrono](https://github.com/sponsors/BlockchainCommons) se achar este curso útil ou se quiser ajudar a educar a próxima geração de programadores da blockchain. + +## O Que Vem Depois? + +Se você quiser uma introdução básica ao Bitcoin, criptografia de chave pública, ECC, blockchains e Lightning Network, leia o prefácio [Introdução ao Bitcoin](01_1_Introducing_Bitcoin.md). + +Caso contrário, se já estiver pronto para mergulhar de cabeça no curso, vá para [Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md). diff --git a/pt/01_1_Introducing_Bitcoin.md b/pt/01_1_Introducing_Bitcoin.md new file mode 100644 index 0000000..5408df8 --- /dev/null +++ b/pt/01_1_Introducing_Bitcoin.md @@ -0,0 +1,150 @@ + +# Prefácio: Apresentando o Bitcoin + +Antes de começar a programar em Bitcoin (e Lightning), você deve ter uma compreensão básica do que são e como funcionam. Esta seção fornece essa visão geral. Várias outras definições irão aparecer mais à frente. O objetivo deste capítulo é apenas dar o conteúdo base. + +## Sobre o Bitcoin + +O Bitcoin é um sistema programável que permite a transferência da moeda bitcoin. Tem como base um sistema descentralizado _peer-to-peer_ (de ponta à ponta) de nodes, que inclui full nodes, carteiras e mineradores. Trabalhando juntos, eles garantem que as transações do bitcoin sejam rápidas e irreversíveis. Graças à natureza descentralizada do sistema, essas transações também são resistentes à censura e podem fornecer outras vantagens, como pseudo-anonimato, caso sejam bem utilizadas. + +Obviamente, Bitcoin é o coração deste livro, mas também é o originador de muitos outros sistemas, incluindo a blockchain e Lightning, que são detalhados neste tutorial, e muitas outras criptomoedas, como Ethereum e Litecoin, que não são. + +**_Como as moedas são transferidas?_** O Bitcoin não possui moedas físicas. Elas são uma série interminável de trocas títulos de propriedade. Quando uma pessoa envia as moedas para outra, essa transferência é armazenada como uma transação. É a transação que realmente registra a propriedade do dinheiro, isso significa que não existe nenhuma moeda que sai da carteira ou da máquina do proprietário. + +**_Para quem você pode enviar as moedas?_** A grande maioria das transações de bitcoin envolvem o envio de moedas para pessoas comuns (ou pelo menos para endereços Bitcoin de pessoas comuns). No entanto, metodologias mais complexas podem ser usadas para enviar bitcoins para um grupo de pessoas ou para scripts. Essas várias metodologias possuem nomes como P2PKH, multisig e P2SH. + +**_Como as transações são armazenadas?_** As transações são combinadas em grandes blocos de dados, que são gravados na _ledger da blockchain_. Um bloco é construído de tal forma que não pode ser substituído ou reescrito, uma vez que vários blocos tenham sido construídos depois dele. Isso é o que torna os bitcoins irreversíveis: Um livro razão (_ledger_) global descentralizado, onde tudo é registrado, é efetivamente um banco de dados permanente e imutável. + +Porém, o processo de construção desses blocos é estocástico: É um tanto aleatório, então não podemos ter certeza se uma transação será colocada em um bloco específico. Também pode haver alterações nos blocos se forem muito recentes, mas apenas se forem _muitíssimo_ recentes. Então, as coisas se tornam irreversíveis (permanentes, imutáveis) depois de um alguns minutos. + +**_Como as transações são protegidas?_** Os fundos contidos em uma transação Bitcoin são assegurados por um quebra-cabeça criptográfico. Esses quebra-cabeças são projetados para que possam ser facilmente resolvidos pela pessoa para quem os fundos foram enviados. Isso é feito usando o poder da criptografia de chave pública. Tecnicamente, uma transação é protegida por uma assinatura que prova que você é o proprietário da chave pública para a qual a transação foi enviada: Essa prova de propriedade é o quebra-cabeça que está sendo resolvido. + +Os fundos são protegidos pelo uso de hashes. As chaves públicas não são realmente armazenadas na blockchain até que os fundos sejam gastos: Apenas os hashes de chave pública são. Isso significa que, mesmo que um computador quântico seja criado, as transações do Bitcoin permaneceriam protegidas por esse segundo nível de criptografia. + +**_Como as transações são criadas?_** O coração de cada transação do Bitcoin é uma linguagem script do tipo FORTH usada para bloquear a transação. Para reenviar o dinheiro, o destinatário fornece informações específicas ao script que prova que ele é o destinatário pretendido. + +No entanto, esses scripts do Bitcoin são o nível mais baixo de funcionalidade deste protocolo. Grande parte do trabalho do Bitcoin é feito através do `bitcoind` do Bitcoin, que é controlado por meio de comandos RPC. Muitas pessoas enviam esses comandos RPC por meio do programa chamado `bitcoin-cli`, que fornece uma interface ainda mais simples. Os não programadores nem mesmo se preocupam com essas minúcias, permitindo o uso de carteiras programáveis com interfaces mais simples. + +### Resumindo o Bitcoin + +Uma maneira de pensar no Bitcoin é como _uma sequência de transações atômicas_. Cada transação é autenticada por um remetente com a solução para um quebra-cabeça criptográfico anterior que foi armazenado como um script. A nova transação é bloqueada para o destinatário com um novo quebra-cabeça criptográfico que também é armazenado como um script. Cada transação é registrada no livro razão global imutável. + +## Sobre criptografia de chave pública + +A criptografia de chave pública é um sistema matemático para proteção de dados e comprovação de propriedade por meio de um par assimétrico de chaves que estão vinculadas entre si: a chave pública e a chave privada. + +É importante para o Bitcoin (e para a maioria dos sistemas que utilizam a blockchain) porque é a base de grande parte da criptografia que protege os fundos das criptomoedas. Uma transação de Bitcoin é normalmente enviada para um endereço que é um hash da chave pública. O destinatário pode então recuperar o dinheiro utilizando a chave pública e a chave privada. + +**_O que é uma chave pública?_** Uma chave pública é a chave fornecida as demais pessoas. Em um sistema de chave pública comum, um usuário gera uma chave pública e uma chave privada e, em seguida, dá a chave pública para as pessoas. Esses destinatários podem criptografar informações com a chave pública, mas não podem ser descriptografadas com a mesma chave devido à assimetria do par de chaves. + +**_O que é uma chave privada?_** Uma chave privada está vinculada a uma chave pública em um par de chaves. Em um sistema de chave pública comum, um usuário mantém sua chave privada segura e a usa para descriptografar as mensagens que foram criptografadas com sua chave pública antes de serem enviadas a ele. + +**_O que é uma assinatura?_** Uma mensagem (ou mais comumente, um hash de uma mensagem) pode ser assinada com uma chave privada, criando uma assinatura. Qualquer pessoa com a chave pública correspondente pode validar a assinatura, o que verifica se o assinante possui a chave privada associada à chave pública em questão. O _SegWit_ é um formato específico para armazenar uma assinatura na rede Bitcoin que falaremos mais especificamente no futuro. + +**_O que é uma função hash?_** Uma função hash é um algoritmo frequentemente usado com a criptografia. É uma maneira de mapear uma grande quantidade arbitrária de dados em uma quantidade pequena e fixa de dados. As funções hash usadas na criptografia são unilaterais e resistentes a colisões, o que significa que um hash pode ser vinculado de forma confiável aos dados originais, mas os dados originais não podem ser regenerados a partir do hash. Assim, os hashes permitem a transmissão de pequenas quantidades de dados para representar grandes quantidades de dados, o que pode ser importante para a eficiência e os requisitos de armazenamento. + +O Bitcoin aproveita a capacidade do hash de disfarçar os dados originais, o que permite ocultar a chave pública real do usuário, tornando as transações resistentes à computação quântica. + +### Resumindo a criptografia de chave pública + +Uma maneira de pensar na criptografia de chave pública é: _um jeito de qualquer pessoa proteger os dados de forma que apenas uma pessoa autorizada possa acessá-los e também possa provar que tem esse acesso._ + +## Sobre CCE + +O CCE é um acrônimo para criptografia de curva elíptica. É um ramo específico da criptografia de chave pública que depende de cálculos matemáticos usando curvas elípticas definidas sobre campos finitos. É mais complexo e difícil de explicar do que a criptografia de chave pública clássica (que usava números primos), mas tem algumas vantagens interessantes. + +O CCE não terá tanta atenção neste tutorial. Isso porque falaremos mais sobre a integração com servidores Bitcoin Core e Lightning, que já cuidaram da parte criptografia para você. Na verdade, a intenção deste tutorial é que você não precise se preocupar com a criptografia, porque isso é algo que você _realmente_ deseja que os especialistas lidem. + +**_O que é uma curva elíptica?_** Uma curva elíptica é uma curva geométrica que assume a forma ``y`` `` 2`` = ``x`` ``3`` `` + ax + b``. Uma curva elíptica específica é escolhida selecionando valores específicos de ``a`` e ``b``. A curva deve ser examinada cuidadosamente para determinar se funciona bem para criptografia. Por exemplo, a curva secp256k1 usada pelo Bitcoin é definida como ``a = 0`` e ``b = 7``. + +Qualquer linha que cruze uma curva elíptica o fará em 1 ou 3 pontos... e essa é a base da criptografia de curva elíptica. + +**_O que são campos finitos?_** Um campo finito é um conjunto finito de números, onde todas as adições, subtrações, multiplicações e divisões são definidas de forma que resultem em outros números que também estarão no mesmo campo finito. Uma maneira simples de criar um campo finito é por meio do uso da aritmética modular. + +**_Como uma curva elíptica é definida sobre um campo finito?_** Uma curva elíptica definida sobre um campo finito tem todos os pontos em sua curva desenhados a partir de um campo finito específico. Ele assume a forma: ``y````2````% tamanho-do-campo = (x````3```` + ax + b) % tamanho-do-campo``. O campo finito usado para secp256k1 é ``2````256````-2````32````-2````9````-2````8````-2````7````-2````6````-2````4````-1``. + +**_Como as curvas elípticas são usadas na criptografia?_** Na criptografia de curva elíptica, um usuário seleciona um número muito grande (256 bits) como sua chave privada. Ele então adiciona um ponto base definido na curva a si mesmo tantas vezes. (Na secp256k1, o ponto de base é ``G = 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8`` que prefixa as duas partes da tupla com um ``04`` para dizer que o ponto de dados está na forma descompactada. Se você preferir uma definição geométrica direta, é o ponto "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,0x483ADA7726A3C4655DA4FBFC0E1108A8FD0817B07029BFCDB2DCE28D959F2815B16F81798,0x483ADA7726A3C4655DA4FBFC0E1108A8FD0817B44810A"). O número resultante é uma chave pública. Várias fórmulas matemáticas podem então ser usadas para provar a propriedade da chave pública, dada a chave privada. Como acontece com qualquer função criptográfica, esta é uma armadilha: É fácil passar de uma chave privada para uma chave pública e praticamente impossível de passar de uma chave pública para uma chave privada. + +Essa metodologia específica também explica por que os campos finitos são usados ​​em curvas elípticas: Ela garante que a chave privada não ficará muito grande. Observe que o campo finito para secp256k1 é ligeiramente menor que 256 bits, o que significa que todas as chaves públicas terão 256 bits, assim como as chaves privadas. + +**_Quais são as vantagens do CCE?_** A principal vantagem do CCE é que ele permite a mesma segurança da criptografia de chave pública clássica com uma chave muito menor. Uma chave pública de curva elíptica de 256 bits corresponde a uma chave pública tradicional (RSA) de 3072 bits. + +### Resumindo o CCE + +Uma maneira de pensar no CCE é: _Um jeito de permitir a criptografia de chave pública usando chaves muito pequenas e uma matemática bem obscura._ + +## Sobre Blockchains + +A blockchain é a generalização da metodologia usada pelo Bitcoin para criar um livro razão distribuído globalmente. O Bitcoin é uma blockchain, assim como qualquer outra moeda alternativa, cada um dos quais vive em sua própria rede e grava em sua própria cadeia de blocos. As sidechains como a _Liquid_ são blockchains também. As blockchains não precisam necessariamente ser relacionadas com finanças. Por exemplo, existem várias discussões para implementar blockchains em soluções para proteger identidades autossoberanas. + +Embora precise entender os fundamentos de como uma blockchain funciona para entender como as transações funcionam no Bitcoin, não é necessário muito mais do que isso. Como as blockchains se tornaram uma ampla categoria de tecnologia, esses conceitos básicos provavelmente serão aplicáveis ​​a muitos outros projetos neste setor de tecnologia em crescimento. Porém, os comandos de programação específicos aprendidos neste livro não serão abrangentes a várias utilizações, já que são específicos para Bitcoin (e para a Lightning). + +**_Por que é chamado de cadeia de blocos?_** Cada bloco na blockchain armazena um hash do bloco anterior. Isso liga o bloco atual de volta ao "bloco de gênese" original por meio de uma cadeia de blocos ininterrupta. É uma forma de criar uma ordem absoluta entre os dados possivelmente conflitantes. Isso também fornece a segurança da blockchain, porque cada bloco é empilhado sobre um antigo tornando mais difícil recriar o bloco antigo devido aos algoritmos de prova de trabalho utilizados ​​na criação do bloco. Depois que vários blocos foram construídos sobre uma cadeia de blocos, ele é essencialmente irreversível. + +**_O que é um fork?_** Ocasionalmente, dois blocos são criados ao mesmo tempo. Isso cria, temporariamente, um fork de um bloco, onde qualquer um dos blocos atuais pode ser o "verdadeiro". De vez em quando, um fork pode se expandir para dois blocos, três blocos ou mesmo quatro blocos de comprimento, mas muito rapidamente um lado da bifurcação é determinado como o verdadeiro e o outro se torna o que chamamos de "órfão". Isso faz parte do processo estocástico de criação de bloco e demonstra por que vários blocos devem ser construídos sobre um bloco antes que ele possa ser considerado verdadeiramente confiável e não rejeitável. + +### Resumindo a blockchain + +Uma maneira de pensar na blockchain é: _Uma série vinculada de blocos de dados imutáveis, até o seu bloco inicial._ +Outra forma é: _Uma série de blocos vinculados para ordenar dados absolutos que podem ser conflitantes_. + +## A Blockchain é adequada para mim? + +Se você deseja negociar bitcoins, então obviamente a Bitcoin é adequada para você. No entanto, de forma mais ampla, a blockchain se tornou uma cultura pop da atualidade, embora não seja uma solução mágica para todos os problemas técnicos. Dito isso, existem muitas situações específicas em que a blockchain é uma tecnologia superior. + +Blockchains provavelmente _são_ úteis nos seguintes casos: + +* Os usuários não confiam uns nos outros. + * Ou: Os usuários estão em diferentes localidades. + * Os usuários não confiam nas autoridades centrais. + * E: Os usuários desejam controlar seus próprios destinos. + * Os usuários desejam uma tecnologia transparente. + * Os usuários desejam compartilhar algo. + * E: Os usuários desejam que o que é compartilhado seja registrado permanentemente. + * Os usuários desejam uma transação final rápida. + * Mas: Os usuários não precisam de uma transação final instantânea. + +Blockchains provavelmente _não_ serão úteis caso: + +* Os usuários sejam confiáveis: + * Por exemplo: As transações ocorrem dentro de uma empresa ou organização. + * Por exemplo: As transações são supervisionadas por uma autoridade central. + * O sigilo é obrigatório: + * Por exemplo: As informações devem ser secretas. + * Por exemplo: As transações devem ser secretas. + * Por exemplo: As pessoas que estão transacionando devem ser secretas. + * A menos que: uma metodologia para sigilo criptográfico seja cuidadosamente considerada, analisada e testada. + * Os usuários precisam de transações finais instantâneas: + * Por exemplo: Em menos de 10 minutos em uma rede semelhante a Bitcoin, em menos de 2,5 minutos em uma rede semelhante a Litecoin, em menos de 15 segundos em uma rede semelhante a Ethereum. + +Observe que ainda pode haver soluções para algumas dessas situações dentro do ecossistema Bitcoin. Por exemplo, os canais de pagamento estão lidando rapidamente com questões de liquidez e finalização do pagamento. + +## Sobre a Lightning (Network) + +A lightning é um protocolo de segunda camada que interage com o Bitcoin para permitir que os usuários troquem seus bitcoins "offchain" (fora da blockchain). Possui vantagens e desvantagens em relação ao uso da camada principal do Bitcoin. + +A lightning também é um dos focos deste tutorial. Embora o ponto principal seja sobre a interação direta com o Bitcoin (e o `bitcoind`), vamos falar um pouco sobre a lightning e o porque é uma tecnologia que está prestes a se tornar uma alternativa popular ao Bitcoin, em um futuro próximo. Este livro tem a mesma abordagem para a lightning e para o Bitcoin: Ele ensina como interagir diretamente com a Lightning de maneira confiável à partir da linha de comando. + +Ao contrário do Bitcoin, existem várias variantes da lightning. Este tutorial usa a implementação compatível do padrão [C-lightning](https://github.com/ElementsProject/lightning) como sendo seu servidor lightning confiável. + +**_O que é um protocolo de segunda camada?_** Um protocolo de segunda camada no Bitcoin funciona tendo como base o Bitcoin. Nesse caso, a lightning trabalha em cima do Bitcoin, interagindo com ele por meio de contratos inteligentes. + +**_O que é um canal lightning?_** Um canal Lightning é uma conexão entre dois usuários utilizando a lightning. Cada um dos usuários bloqueia uma quantidade de bitcoins na blockchain do Bitcoin usando uma assinatura multi-sig, criada e assinada por ambos. Os dois usuários podem, então, trocar bitcoins por meio do canal lightning sem precisar gravar nada na blockchain Bitcoin. Somente quando desejam fechar o canal, eles liquidam os bitcoins, com base na divisão no saldo final das partes. + +**_O que é a Lightning Network?_** A junção de todos os canais da lightning criam a Lightning Network. Isso permite que dois usuários que não tenham um canal entre si troquem bitcoins usando Lightning: O protocolo forma uma cadeia de canais entre os dois usuários e, em seguida, troca as moedas através da cadeia usando transações que chamamos de _time-locked transactions_. + +**_Quais são as vantagens da lightning?_** A lightning permite transações mais rápidas com taxas mais baixas. Isso cria a possibilidade real de micropagamentos usando bitcoin. Ela também oferece maior privacidade, uma vez que está fora da rede, com apenas o primeiro e o último estado da transação sendo gravados blockchain do Bitcoin. + +**_Quais são as desvantagens do Lightning?_** A lightning ainda é uma tecnologia muito nova e não foi testada tão exaustivamente quanto o Bitcoin. Isso não é apenas uma questão de implementação tecnológica, mas também se o design que pode ser manipulado de maneiras não pensadas anteriormente. + +### Resumindo a lightning + +Uma maneira de pensar na Lightning é: _Um jeito de transacionar bitcoins usando canais offchain entre duas pessoas, de modo que apenas o primeiro e o último estado precisem ser gravados na blockchain_. + +## Resumo: Apresentando o Bitcoin + +O Bitcoin é um sistema _peer-to-peer_ que permite a transferência de fundos por meio de transações bloqueadas por quebra-cabeças. Esses quebra-cabeças dependem da criptografia de curva elíptica de chave pública. Quando você generaliza as ideias por trás do Bitcoin, encontra-se as blockchains, uma tecnologia que atualmente está crescendo e inovando muitos setores. Quando você expande as ideias por trás do Bitcoin, obtém protocolos de segunda camada, como a lightning, que expandem o potencial da moeda. + +## O Que Vem Depois? + +Vamos avançar para "se preparar para o Bitcoin" com o [Capítulo Dois: Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md). \ No newline at end of file From 2c321c21e95ee5c114caaef0f2e16ace5da1e2b1 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 24 Jun 2021 21:42:10 -0300 Subject: [PATCH 003/155] Chapter 02 translated The file was revised by @lukedevj in the closed PR (#224) --- pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md diff --git a/pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md b/pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md new file mode 100644 index 0000000..5f5ae45 --- /dev/null +++ b/pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md @@ -0,0 +1,27 @@ + +# Capítulo 2: Configurando um Bitcoin-Core no VPS + +Para começar a usar o Bitcoin, primeiro precisamos configurar uma máquina que execute o Bitcoin. Os artigos neste capítulo descrevem como fazer isso, principalmente usando um VPS (Virtual Private Server). + +## Objetivos deste Capítulo + +Depois de passar por este capítulo, um desenvolvedor será capaz de: + +* Decidir entre os cinco principais tipos de nodes de Bitcoin; +* Criar um node Bitcoin para desenvolvimento; +* Crie uma instância local da Blockchain do Bitcoin. + +Os objetivos secundários incluem a capacidade de: + + * Compreender a configuração da rede básica do VPS; + * Decidir quais prioridades de segurança implementar; + * Entender a diferença entre os nodes prunados e os não prunados; + * Entender a diferença entre nodes Mainnet, Testnet e Regtest; + * Interpretar os fundamentos do arquivo de configuração do Bitcoin. + +## Tabela de Conteúdo + +Na verdade, não é preciso ler este capítulo inteiro. Decida se gostaria de executar um StackScript para configurar um node em um VPS Linode (§2.2); Ou você deseja configurar em um ambiente diferente, como em uma máquina AWS ou um Mac (§2.3). Em seguida, vá para a seção mais apropriada. Informações adicionais sobre nossas configurações sugeridas também podem ser encontradas no [Apêndice I](A1_0_Understanding_Bitcoin_Standup.md). + + * [Seção Um: Configurando um Bitcoin Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) + * [Seção Dois: Configurando uma máquina Bitcoin Core usando outros meios](02_2_Setting_Up_Bitcoin_Core_Other.md) \ No newline at end of file From 3d9d4eec1958a62cfa5f302df84cd0b6b5cc9b70 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 24 Jun 2021 21:44:30 -0300 Subject: [PATCH 004/155] Chapter 15 Translated The four files were revised by @lukedevj in the closed PR (#224) --- pt/15_0_Talking_to_Bitcoind.md | 27 ++ pt/15_1_Accessing_Bitcoind_with_C.md | 294 +++++++++++++++ pt/15_2_Programming_Bitcoind_with_C.md | 354 ++++++++++++++++++ ...Receiving_Bitcoind_Notifications_with_C.md | 155 ++++++++ 4 files changed, 830 insertions(+) create mode 100644 pt/15_0_Talking_to_Bitcoind.md create mode 100644 pt/15_1_Accessing_Bitcoind_with_C.md create mode 100644 pt/15_2_Programming_Bitcoind_with_C.md create mode 100644 pt/15_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/pt/15_0_Talking_to_Bitcoind.md b/pt/15_0_Talking_to_Bitcoind.md new file mode 100644 index 0000000..88bde29 --- /dev/null +++ b/pt/15_0_Talking_to_Bitcoind.md @@ -0,0 +1,27 @@ + +# Capítulo 15: Conversando com Bitcoind usando C + +Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. + +Esta seção se concentra em três diferentes bibliotecas que podem ser usadas como base de programação C sofisticada: Uma biblioteca RPC e uma biblioteca JSON que juntas permitem recriar muito do que fazemos nos scripts de shell, porém, usando C; enquanto uma biblioteca ZMQ nos conecta a notificações, algo que não conseguiríamos acessar até agora. (O próximo capítulo cobrirá uma biblioteca ainda mais sofisticada chamada Libwally, para finalizar esta introdução à programação do Bitcoin com C). + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Criar programas C que usam RPC para conversar com o Bitcoind; + * Criar programas C que usam ZMQ para conversar com o Bitcoind. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Entender como usar uma biblioteca RPC; + * Entender como usar uma biblioteca JSON; + * Compreender as capacidades do ZMQ; + * Entender como usar uma biblioteca ZMQ. + +## Tabela de conteúdo + + * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) + * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) + * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) + \ No newline at end of file diff --git a/pt/15_1_Accessing_Bitcoind_with_C.md b/pt/15_1_Accessing_Bitcoind_with_C.md new file mode 100644 index 0000000..2e97e1c --- /dev/null +++ b/pt/15_1_Accessing_Bitcoind_with_C.md @@ -0,0 +1,294 @@ + +# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. + +Você já viu uma maneira alternativa de acessar as portas RPC do Bitcoind: Usando o ``curl``, que cobrimos no [Capítulo 4 Prefácio](04_4__interlude_using_curl.md). Interagir com o ``Bitcoind`` através de uma biblioteca de RPC usando C não é diferente do que já vimos, só precisamos de boas bibliotecas para nos auxiliar. Esta seção introduz um pacote chamado ``libbitcoinrpc``, que permite acessar a porta JSON-RPC do ``bitcoind``. Ele usa uma biblioteca ``curl`` para acessar os dados e usa a biblioteca ``jansson`` para codificar e decodificar o JSON. + +## Configurando o libbitcoinrpc + +Para usar o ``libbitcoinrpc``, precisaremos instalar uma configuração básica C e os pacotes dependentes, que são ``libcurl``, ``libjansson``, e ``libuuid``. Depois faremos isso no seu servidor Standup Bitcoin (ou em qualquer outro servidor Ubuntu). + +``` +$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev +Suggested packages: + libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev +The following NEW packages will be installed: + libcurl4-openssl-dev libjansson-dev uuid-dev +0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. +Need to get 358 kB of archives. +After this operation, 1.696 kB of additional disk space will be used. +Do you want to continue? [Y/n] y +``` +Agora, podemos baixar o [libbitcoinrpc no github](https://github.com/gitmarek/libbitcoinrpc/blob/master/readme.md). Vamos clonar ou pegar um arquivo zip, do jeito que preferir. + +``` +$ sudo apt-get install git +$ git clone https://github.com/gitmarek/libbitcoinrpc +``` + +> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. + +### Compilando o libbitcoinrpc. + +Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: +``` +$ PATH="/sbin:$PATH" +``` + +Para o Ubuntu, também precisaremos ajustar o ``install_libpath`` no ``makefile`` do ``libbitcoinrpc`` para instalar no ``/usr/lib`` ao invés do ``/usr/local/lib``: + +``` +$ emacs ~/libbitcoinrpc/Makefile +... +INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib +``` + +(Se preferir não usar o ``/usr/lib``, precisará alterar o ``etc/ld.so.conf`` ou os arquivos dependentes de maneira apropriada... Porém, para uma configuração de teste em uma máquina de teste, acredito que isso não seja um problema). + +Da mesma forma, vamos precisar ajustar o ``install_headerpath`` no ``Makefile`` do ``libbitcoinrpc`` para instalar no caminho ``/usr/include`` ao invés do ``/usr/local/inclusve``: + +``` +... +INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include +``` + +Agora, podemos compilar: +``` +$ cd libbitcoinrpc +~/libbitcoinrpc$ make + +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ +src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ +-o .lib/libbitcoinrpc.so.0.2 \ +-Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl +ldconfig -v -n .lib +.lib: + libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) +ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so +``` +Se tudo correr bem, podemos instalar o pacote: +``` +$ sudo make install +Installing to +install .lib/libbitcoinrpc.so.0.2 /usr/local/lib +ldconfig -n /usr/local/lib +ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so +install -m 644 src/bitcoinrpc.h /usr/local/include +Installing docs to /usr/share/doc/bitcoinrpc +mkdir -p /usr/share/doc/bitcoinrpc +install -m 644 doc/*.md /usr/share/doc/bitcoinrpc +install -m 644 CREDITS /usr/share/doc/bitcoinrpc +install -m 644 LICENSE /usr/share/doc/bitcoinrpc +install -m 644 Changelog.md /usr/share/doc/bitcoinrpc +Installing man pages +install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 +``` + +## Preparando o código + +``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. + +Para usar o ``libbitcoinrpc``, é importante certificar de que nossos arquivos do código incluam os cabeçalhos apropriados: +``` c +#include +#include +``` + +Precisaremos também vincular as bibliotecas apropriadas sempre que possamos compilar: + +``` +$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode +``` + +## Construindo a conexão + +Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. + +Primeiro, inicialize a biblioteca: +``` +bitcoinrpc_global_init(); +``` +Em seguida, vamos conectar ao ``Bitcoind`` com ``bitcoinrpc_cl_init_params``. Os quatro argumentos necessários para o ``bitcoinrpc_cl_init_params`` são o nome de usuário, a senha, o endereço IP e a porta. A esta altura, você deve saber todas essas informações, já que foram necessárias para realizar o trabalho com o [curl](04_4__interlude_using_curl.md). Apenas para recordar, o endereço de IP é 127.0.0.1 e a porta 18332 devem estar corretos para a configuração padrão da testenet descrita neste documento, enquanto podemos encontrar o usuário e a senha no arquivo ``~/.bitcoin/bitcoin.conf``. +``` +$ cat bitcoin.conf +server=1 +dbcache=1536 +par=1 +maxuploadtarget=137 +maxconnections=16 +rpcuser=StandUp +rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba +rpcallowip=127.0.0.1 +debug=tor +prune=550 +testnet=1 +[test] +rpcbind=127.0.0.1 +rpcport=18332 +[main] +rpcbind=127.0.0.1 +rpcport=8332 +[regtest] +rpcbind=127.0.0.1 +rpcport=18443 +``` +Com essas informações, vamos colocá-las no ``bitcoinrpc_cl_init_params``: +``` c +bitcoinrpc_cl_t *rpc_client; +rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); +``` + +> **MAINNET VS TESTNET:** A porta seria a 8332 caso estivéssemos usando a configuração da rede principal. + +Se o ``rpc_client`` for inicializado com sucesso, poderemos enviar os comandos do RPC. + +Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fechar da seguinte maneira: +``` c +bitcoinrpc_global_cleanup(); +``` + +### Testando o código de teste + +O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). + +Podemos compilar e executar o código da seguinte maneira: +``` +$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin +$ ./testbitcoin +Successfully connected to server! +``` + +> :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. + +## Fazendo uma chamada ao RPC + +Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). +``` c +bitcoinrpc_method_t *getmininginfo = NULL; +getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); +``` +Normalmente definiríamos os parâmetros em seguida, mas o ``GetMiningInfo`` não requer parâmetros, por isso podemos pular essa parte. + +Também devemos criar outros dois objetos, um "objeto de resposta" e um "objeto de erro". Eles podem ser inicializados da seguinte forma: +``` c +bitcoinrpc_resp_t *btcresponse = NULL; +btcresponse = bitcoinrpc_resp_init(); + +bitcoinrpc_err_t btcerror; +``` +Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos adicionar nosso método ``getmininginfo`` e os outros dois objetos: +``` c +bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); +``` + +### Mostrando o retorno da chamada + +Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: +``` c +json_t *jsonresponse = NULL; +jsonresponse = bitcoinrpc_resp_get(btcresponse); +``` +Se quisermos gerar os resultados completos da chamada RPC no JSON, podemos fazer com uma simples invocação do ``json_dumps``, da biblioteca ``jansson``: +``` c +printf("%s\n", json_dumps(j, JSON_INDENT(2))); +``` +No entanto, como agora estamos escrevendo programas completos, provavelmente iremos querer fazer um trabalho mais sutil, como retirar valores individuais do JSON para algum uso específico. A [Referência do Jansson](https6//jansson.readthedocs.Io/en/2.10/apiref.html) traz detalhes de como fazer. + +Assim como estávamos usando o [curl](04_4__interlude_using_curl.md), descobrimos que o RPC retorna um objeto JSON contendo um ``ID``, um ``error`` e, mais importante, um objeto JSON do tipo ``result``. + +A função ``json_object_get`` permite recuperar um valor (como o ``result``) de um objeto JSON usando chaves: +``` c +json_t *jsonresult = NULL; +jsonresult = json_object_get(jsonresponse,"result"); +printf("%s\n", json_dumps(jsonresult, JSON_INDENT(2))); +``` + +No entanto, provavelmente iremos querer analisar informações ainda mais profundas, para obter uma variável específica. Depois de recuperar o valor apropriado, precisaremos convertê-lo em um objeto C padrão usando a função ``JSON_*_value``. Por exemplo, para acessar um integer usamos o ``json_integer_value``: +``` c +json_t *jsonblocks = NULL; +jsonblocks = json_object_get(jsonresult,"blocks"); + +int blocks; +blocks = json_integer_value(jsonblocks); +printf("Block Count: %d\n",blocks); +``` + +> :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. + +### Testando o código de informação + +Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). +``` +$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo +$ ./getmininginfo +Full Response: { + "result": { + "blocks": 1804406, + "difficulty": 4194304, + "networkhashps": 54842097951591.781, + "pooledtx": 127, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" + }, + "error": null, + "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" +} + +Just the Result: { + "blocks": 1804406, + "difficulty": 4194304, + "networkhashps": 54842097951591.781, + "pooledtx": 127, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" +} + +Block Count: 1804406 +``` + +## Fazendo uma chamada RPC usando argumentos + +Mas e se a sua chamada RPC tiver argumentos? + +### Criando uma matriz JSON + +Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. + +Vamos criar a matriz JSON usando a função ``json_array do`` do ``jansson``: +``` c +json_t *params = NULL; +params = json_array(); +``` +Vamos fazer o processo inverso que fizemos para acessar valores do JSON: Vamos converter objetos no C para objetos no JSON usando as funções ``JSON_*``. Depois, vamos anexar tudo à matriz: +``` c +json_array_append_new(params,json_string(tx_rawhex)); +``` + +Observe que existem duas variantes para o comando de anexação: ``json_array_apend_new``, que acrescenta uma variável recém-criada, e ``json_array_apend``, que anexa uma variável existente. + +Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. + +### Atribuindo os parâmetros + +Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: +``` c +bitcoinrpc_method_set_params(rpc_method, params) +``` +Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. + +## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC + +Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. + +* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. + +## O Que Vem Depois? + +Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). diff --git a/pt/15_2_Programming_Bitcoind_with_C.md b/pt/15_2_Programming_Bitcoind_with_C.md new file mode 100644 index 0000000..c1fdc38 --- /dev/null +++ b/pt/15_2_Programming_Bitcoind_with_C.md @@ -0,0 +1,354 @@ + +# 15.2: Programando o Bitcoind usando C com bibliotecas RPC + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. + +A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. + +## Planejando o código + +Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: + + 1. Solicitar um endereço e uma quantia; + 2. Definir uma taxa arbitrária; + 3. Preparar nosso RPC; + 4. Encontrar um UTXO que seja grande o suficiente para pagar o valor + a taxa; + 5. Criar uma mudança de endereço; + 6. Criar uma transação bruta que envie o UTXO para o endereço e altere o endereço; + 7. Assinar a transação; + 8. Enviar a transação. + +### Planejando para o futuro + +Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: + + 1. Testar e/ou higienizar as entradas; + 2. Calcular uma taxa automaticamente; + 3. Pensar logicamente sobre qual UTXO seria válido utilizar; + 4. Combinar vários UTXOs, caso seja necessário; + 5. Ficar atento a mais erros nos comandos ``libbitcoinrpc`` ou no ``jansson``; + 6. Observar se há erros nas respostas RPC. + +Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. + +## Escrevendo o sistema de transação + +Agora estamos prontos para realizar o passo a passo do nosso plano + +### Etapa 1: Solicitando um endereço e uma quantia + +Inserir as informações é bem simples se usarmos os argumentos na linha de comando: +``` c +if(argc != 3) { + + printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); + exit(-1); + +} + +char *tx_recipient = argv[1]; +float tx_amount = atof(argv[2]); + +printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); +``` + +> :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. + +### Etapa 2: Definindo uma taxa arbitrária + +Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: + +``` c +float tx_fee = 0.0005; +float tx_total = tx_amount + tx_fee; +``` + +> :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. + +### Etapa 3: Preparando nosso RPC + +Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: +``` c +bitcoinrpc_global_init(); +rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); +btcresponse = bitcoinrpc_resp_init(); +``` + +### Etapa 4: Encontrando um UTXO + +Para encontrar um UTXO, precisaremos chamar a função RPC ``listunspent``: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +``` + +No entanto, o verdadeiro trabalho consiste em decodificar a resposta. Na seção anterior vimos que a biblioteca ``jansson`` era "um tanto quanto desajeitada" e esta é a razão: Precisamos criar (e limpar) um conjunto muito grande de objetos ``json_t`` para descobrir o que queremos. + +Primeiro, precisamos nos recuperar o campo ``result`` do JSON: +``` c +json_t *lu_response = NULL; +json_t *lu_result = NULL; + +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); +``` + +> :warning: **ATENÇÃO:** Só obteremos um resultado se não houver nenhum erro. Aqui temos um momento para melhorar nossa verificação de erros no código que iremos colocar em produção. + +Em seguida, vamos fazer um laço, examinando cada transação que não foi gasta, que aparece como um elemento em sua matriz do resultado JSON: +``` c +int i; + +const char *tx_id = 0; +int tx_vout = 0; +double tx_value = 0.0; + +for(i = 0 ; i < json_array_size(lu_result) ; i++) { + + json_t *lu_data = NULL; + lu_data = json_array_get(lu_result, i); + + json_t *lu_value = NULL; + lu_value = json_object_get(lu_data,"amount"); + tx_value = json_real_value(lu_value); +``` + +O UTXO é grande o suficiente para pagar sua transação? Se sim, pegue-o! + +> :warning: **ATENÇÃO:** Um programa em produção pensaria com mais cuidado sobre qual UTXO utilizar, com base no tamanho e em outros fatores. Provavelmente não pegaria apenas o primeiro mais simples e pronto. + +``` c + if(tx_value > tx_total) { + + json_t *lu_txid = NULL; + lu_txid = json_object_get(lu_data,"txid"); + tx_id = strdup(json_string_value(lu_txid)); + + json_t *lu_vout = NULL; + lu_vout = json_object_get(lu_data,"vout"); + tx_vout = json_integer_value(lu_vout); + + json_decref(lu_value); + json_decref(lu_txid); + json_decref(lu_vout); + json_decref(lu_data); + break; + + } +``` +Você também deve limpar os principais elementos do JSON: +``` c +} + +json_decref(lu_result); +json_decref(lu_response); +``` + +> :warning: **ATENÇÃO:** Um programa em produção também se certificaria de que os UTXOs são passíveis de serem `gastos`. + +Se não encontramos nenhum UTXOs grande o suficiente, teremos que relatar este infortúnio ao usuário... E talvez, sugerir que ele deva usar um programa melhor, que irá mesclar os UTXOs de maneira correta. +``` c +if(!tx_id) { + + printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); + exit(-1); +} +``` + +> **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. + +### Etapa 5: Criando um endereço de troco + +Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); + +if(!rpc_method) { + + printf("ERROR: Unable to initialize listunspent method!\n"); + exit(-1); + +} + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); + +if(btcerror.code != BITCOINRPCE_OK) { + +printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); + + exit(-1); + +} + +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); +char *changeaddress = strdup(json_string_value(lu_result)); +``` +A única diferença é quais informações específicas são extraídas do objeto JSON. + +> :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. + +### Etapa 6: Criando uma transação bruta + +Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. + +Para criarmos esses parâmetros corretamente, precisaremos revisar o que o RPC ``createrawtransaction`` espera que passemos como argumento. Felizmente, isso é fácil de determinar usando a funcionalidade ``bitcoin-cli help``: +``` +$ bitcoin-cli help createrawtransaction +createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) +``` + +Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. + +#### Etapa 6.1: Criando os parâmetros de entrada + +Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): +``` c +json_t *inputtxid = NULL; +inputtxid = json_object(); + +json_object_set_new(inputtxid,"txid",json_string(tx_id)); +json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); +``` + +Pode-se notar que teremos que traduzir novamente cada tipo de variável C em um tipo de variável JSON usando a função apropriada, como ``json_string`` ou ``json_integer``. + +Para criar o array de entrada para todos os UTXOs, vamos usar o ``json_array`` e, em seguida, preenchê-lo com os objetos usando o ``json_array_append``: +``` c +json_t *inputparams = NULL; +inputparams = json_array(); +json_array_append(inputparams,inputtxid); +``` + +#### Etapa 6.2: Criando os parâmetros de saída + +Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: +``` c +json_t *outputparams = NULL; +outputparams = json_object(); + +char tx_amount_string[32]; +sprintf(tx_amount_string,"%.8f",tx_amount); +char tx_change_string[32]; +sprintf(tx_change_string,"%.8f",tx_value - tx_total); + +json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); +json_object_set(outputparams, changeaddress, json_string(tx_change_string)); +``` + +> :warning: **ATENÇÃO:** É possível pensar que teremos que inserir os valores do Bitcoin como sendo números, usando a função ``json_real``. Infelizmente, isso expõe um dos maiores problemas com a integração da biblioteca ``jansson`` e o Bitcoin. O Bitcoin só é válido até oito dígitos depois da casa decimal. Devemos nos lembrar que 0,00000001 BTC é um satoshi, e essa é a menor divisão possível de um Bitcoin. O tipo ``double`` no C oferecem mais dígitos do que precisamos, embora sejam frequentemente imprecisos depois das oito casas decimais. Se tentarmos convertê-los diretamente do nosso valor ``double`` no C (ou de um tipo ``float``, neste caso) para um valor Bitcoin, a imprecisão frequentemente criará um valor Bitcoin com mais de oito dígitos. Antes da versão Bitcoin Core 0.12, isso não era problema, e podíamos usar a função ``json_real``. Mas à partir dessa versão, se tentarmos usar a função ``createrawtransaction`` com mais do que oito dígitos, obteremos um erro e a transação não será criada. Como resultado, se o valor do Bitcoin _sempre_ se tornar um ``double`` ou ``float``, devemos deixar com apenas oito casas decimais antes de transformá-lo em uma ``string``. Obviamente, isso é um erro, portanto, certifique-se disso para que o código continue funcionando nas versões mais novas do Bitcoin Core. + +#### Etapa 6.3: Criando a Matriz de Parâmetros + +Para terminarmos de criar os parâmetros, só precisaremos agrupá-los em uma matriz JSON: +``` c +json_t *params = NULL; +params = json_array(); +json_array_append(params,inputparams); +json_array_append(params,outputparams); +``` + +#### Etapa 6.4: Fazendo a chamada ao RPC + +Vamos usar o método normal para criar uma chamada ao RPC: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); +``` +Agora, porém, devemos adicionar os nossos parâmetros. Isso pode ser feito facilmente com a função ``bitcoinrpc_method_set_params``: +``` c +if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf(stderr, "Error: Could not set params for createrawtransaction"); + +} +``` +Depois, é só executar o RPC e obter os resultados: +``` c +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); + +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); + +char *tx_rawhex = strdup(json_string_value(lu_result)); +``` +### Etapa 7. Assinando a transação + +É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: +``` c +params = json_array(); +json_array_append_new(params,json_string(tx_rawhex)); +``` +Por fim, vamos assinar a transação seguindo o rigamarole típico para criar uma chamada RPC: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); +if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf(stderr, "Error: Could not set params for signrawtransaction"); + +} + +json_decref(params); + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +lu_response = bitcoinrpc_resp_get(btcresponse); +``` +Novamente, usar a função ``jansson`` para acessar a saída pode ser complicado. Devemos lembrar que ``hex`` é parte de um objeto JSON, não um resultado independente, como era quando criamos a transação bruta. Claro, sempre podemos acessar essas informações a partir da ajuda da linha de comando: ``bitcoin-cli help signrawtransaction`` +``` c +lu_result = json_object_get(lu_response,"result"); +json_t *lu_signature = json_object_get(lu_result,"hex"); +char *tx_signrawhex = strdup(json_string_value(lu_signature)); +json_decref(lu_signature); +``` +> :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. + +### Etapa 8. Enviando a transação + +Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: +``` c +params = json_array(); +json_array_append_new(params,json_string(tx_signrawhex)); + +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); + +if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf(stderr, "Error: Could not set params for sendrawtransaction"); + +} + +json_decref(params); + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); + +char *tx_newid = strdup(json_string_value(lu_result)); + +printf("Txid: %s\n",tx_newid); +``` + +O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. + +## Testando o código + +O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). + +Compile-o como de costume: +``` +$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress +``` +Agora, é possível utilizá-lo para enviar fundos para um endereço: + +``` +./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 +Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 +``` +Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). + +## Resumo do Programando o Bitcoind usando C com bibliotecas RPC + +Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. + +## O Que Vem Depois? + +Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md new file mode 100644 index 0000000..fe166ac --- /dev/null +++ b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md @@ -0,0 +1,155 @@ + +# 15.3 Recebendo notificações usando C com a biblioteca ZMQ + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. + +As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. + +> :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). + +## Configurando o ZMQ + +Antes de podemos ouvir a blockchain, precisaremos configurar o ``bitcoind`` para permitir as notificações ZMQ. Por isso, precisamos instalar a biblioteca ZMQ para tirar proveito dessas notificações. + +### Configurando o ``bitcoind`` para usar o ZMQ + +O Bitcoin Core está pronto para ZMQ, mas devemos especificar os endpoints do ZMQ. O ZeroMQ publish-sockets prefixa cada item de dados com um prefixo de tópico arbitrário que permite aos clientes assinantes solicitarem apenas os itens com um prefixo correspondente. Existem atualmente quatro tópicos suportados pelo ``bitcoind``: +``` +$ bitcoind --help | grep zmq | grep address + -zmqpubhashblock=
+ -zmqpubhashtx=
+ -zmqpubrawblock=
+ -zmqpubrawtx=
+``` + +Podemos executar o ``bitcoind`` com argumentos de linha de comando para endpoints ZMQ, como mostrado acima, mas também podemos criar um endpoint acessível adicionando linhas apropriadas ao nosso arquivo ``~/.bitcoin/bitcoin.conf`` e reiniciando o sistema. + +``` +zmqpubrawblock=tcp://127.0.0.1:28332 +zmqpubrawtx=tcp://127.0.0.1:28333 +``` +Podemos então testar se os nossos endpoints estão funcionando usando o RPC ``getzmqnotifications``: + +``` +$ bitcoin-cli getzmqnotifications +[ + { + "type": "pubrawblock", + "address": "tcp://127.0.0.1:28332", + "hwm": 1000 + }, + { + "type": "pubrawtx", + "address": "tcp://127.0.0.1:28333", + "hwm": 1000 + } +] +``` +Nosso ``bitcoind`` agora irá emitir as notificações ZMQ + +### Instalando o ZMQ + +Para aproveitar essas notificações, precisamos de uma biblioteca ZMQ para usar com o C, portanto, estaremos usando uma nova biblioteca ZMQ ao invés da biblioteca ``libbitcoinrpc`` nesta seção, mas no futuro, podemos combinar ambas. + +Felizmente, as bibliotecas ZMQ estão disponíveis por meio de pacotes Debian padrão: +``` +$ sudo apt-get install libzmq3-dev +$ sudo apt-get install libczmq-dev +``` +Agora estamos pronto para escrever o código! + +## Escrevendo o programa de notificação + +O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. + +O programa requer dois parâmetros: O primeiro é o "servidor", que é o ponto de conexão TCP exposto pelo ``bitcoind``. O segundo é o "tópico", que atualmente é o ``zmqpubhashblock``,``zmqpubhashtx``, ``zmqpubrawblock`` ou ``zmqpubrawtx``. O tópico precisa ter suporte do ``bitcoin.conf`` e o endereço IP e a porta do servidor devem corresponder ao que está definido no arquivo de configuração. + +``` c +#include +int main(int argc, char ** argv) { + + char *zmqserver; + char *topic; + + if(argc < 3) { + printf("\nUSAGE:\nchainlistener \n\n"); + return 0; + } else { + zmqserver = argv[1]; + topic = argv[2]; + } +``` +Abriremos um soquete ZMQ para o servidor e para o tópico definido: +``` c + zsock_t *socket = zsock_new_sub(zmqserver, topic); + assert(socket); +``` +Depois, vamos esperar: +``` c + while(1) { + zmsg_t *msg; + int rc = zsock_recv(socket, "m", &msg); + assert(rc == 0); + + char *header = zmsg_popstr(msg); + zframe_t *zdata = zmsg_pop(msg); + unsigned int *no = (unsigned int*)zmsg_popstr(msg); + + char *data = zframe_strhex(zdata); + int len = zframe_size(zdata); + printf("Size: %d\n", len); + printf("Data: %s", data); + printf("\nNo: %d\n", *no); + + free(header); + free(data); + free(no); + free(zdata); + zmsg_destroy(&msg); + sleep(1); + } +``` +Enquanto esperamos, observamos as mensagens no soquete ZMQ. Sempre que recebermos uma mensagem, iremos retirá-la da pilha, relatando o número, comprimento e, o os dados que foram importante para nós. + +É isso! + +Claro, quando terminar o processo, precisamos limpar tudo: +``` c + zsock_destroy(&socket); + return 0; +} +``` + +### Testando o código de notificação + +O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: +``` +$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq +``` +Depois, podemos executá-lo com os tópicos e endereços que definimos no nosso ``bitcoin.conf``: +``` +$ ./chainlistener tcp://127.0.0.1:28333 rawtx +Size: 250 +Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 +No: 67 +Size: 249 +Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 +No: 68 +Size: 250 +Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 +No: 69 +Size: 250 +Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 +No: 70 +....... +``` + +### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ + +Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. + +> :fire: ***Qual é o poder das notificações?*** Com as notificações, não dependemos mais dos usuários para emitir os comandos. Ou seja, podemos criar programas que monitoram o blockchain do Bitcoin e tomar as ações apropriadas quando certas coisas ocorrem. Isso, por sua vez, pode ser utilizado juntamente com os comandos RPC que programamos nas seções anteriores. Este também é um grande passo além do que poderíamos fazer com os scripts shell: Certamente, podemos criar scripts shell que fica ouvindo infinitamente, mas existem outras linguagens de programação que possuem ferramentas melhores para isso. + +## O Que Vem Depois? + +Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file From f82b60e419eb5edb97706ffa1b4ace501a44e1f4 Mon Sep 17 00:00:00 2001 From: Luke Pavksy <85752004+lukedevj@users.noreply.github.com> Date: Fri, 25 Jun 2021 19:48:15 -0300 Subject: [PATCH 005/155] Chapter 15 Translated wait for review --- pt/03_0_Understanding_Your_Bitcoin_Setup.md | 31 ++ pt/03_1_Verifying_Your_Bitcoin_Setup.md | 103 ++++++ pt/03_2_Knowing_Your_Bitcoin_Setup.md | 315 ++++++++++++++++++ pt/03_3_Setting_Up_Your_Wallet.md | 131 ++++++++ ..._Interlude_Using_Command-Line_Variables.md | 40 +++ 5 files changed, 620 insertions(+) create mode 100644 pt/03_0_Understanding_Your_Bitcoin_Setup.md create mode 100644 pt/03_1_Verifying_Your_Bitcoin_Setup.md create mode 100644 pt/03_2_Knowing_Your_Bitcoin_Setup.md create mode 100644 pt/03_3_Setting_Up_Your_Wallet.md create mode 100644 pt/03_3__Interlude_Using_Command-Line_Variables.md diff --git a/pt/03_0_Understanding_Your_Bitcoin_Setup.md b/pt/03_0_Understanding_Your_Bitcoin_Setup.md new file mode 100644 index 0000000..865b693 --- /dev/null +++ b/pt/03_0_Understanding_Your_Bitcoin_Setup.md @@ -0,0 +1,31 @@ +# Capítulo três: Compreendendo a configuração do seu node Bitcoin + +Agora que você está pronto para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que você entenda a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. + +Neste e nos próximos capítulos, presumimos que você tenha uma VPS com Bitcoin instalado, executando `bitcoind`. Também presumimos que você está conectado à testnet, permitindo o acesso a bitcoins sem usar fundos reais. Você pode fazer isso com Bitcoin Standup em linode.com, por [2.1: Configurando um Bitcoin-Core no VPS c Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou por outros métodos, por [2.2: Configurando um node Bitcoin Core por outros métodos](02_2_Setting_Up_Bitcoin_Core_Other.md). + +## Objetivos deste Capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Demonstrar que o node Bitcoin está instalado e atualizado + * Criar um endereço para receber fundos de Bitcoin + * Usar os comandos básicos da carteira + * Criar um endereço a partir de um descritor + +Os objetivos de apoio incluem a capacidade de: + + * Compreender o layout básico do arquivo Bitcoin + * Usar comandos informativos básicos + * Entender o que é um endereço Bitcoin + * Entender o que é uma carteira + * Entender como importar endereços + +## Índice + +* [Seção Um: Verificando a configuração do seu node Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) +* [Seção Dois: conhecendo a configuração do seu node Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) +* [Seção Três: Configurando sua carteira](03_3_Setting_Up_Your_Wallet.md) + * [Usando variável de linha de comando](03_3__Interlude_Using_Command-Line_Variables.md) +* [Seção Quatro: Recebendo uma transação](03_4_Receiving_a_Transaction.md) +* [Seção Cinco: Entendendo um descritor](03_5_Understanding_the_Descriptor.md) \ No newline at end of file diff --git a/pt/03_1_Verifying_Your_Bitcoin_Setup.md b/pt/03_1_Verifying_Your_Bitcoin_Setup.md new file mode 100644 index 0000000..2997ef3 --- /dev/null +++ b/pt/03_1_Verifying_Your_Bitcoin_Setup.md @@ -0,0 +1,103 @@ +# 3.1: Verificando a configuração do seu node Bitcoin + +Antes de começar a brincar com Bitcoin, você deve se certificar de que tudo está configurado corretamente. + +## Crie seus aliases + +Sugerimos a criação de alguns aliases para facilitar o uso do Bitcoin + +Você pode fazer isso colocando-os em seu `.bash_profile`,` .bashrc` ou `.profile`. +``` +cat >> ~/.bash_profile < :book: ***O que é a altura do bloco?*** A altura do bloco é a distância que um bloco particular está do bloco de gênese. A altura do bloco atual é a altura do bloco mais recente adicionado a um blockchain. + +Você pode fazer isso olhando para um explorador, como [Mempool Space Explorer](https://mempool.space/pt/testnet). O número mais recente corresponde ao `getblockcount`? Se sim, você está atualizado. + +Se você quiser que um alias veja tudo de uma vez, o seguinte funciona atualmente para Testnet, mas pode desaparecer em algum momento no futuro: +``` +$ cat >> ~/.bash_profile << EOF +alias btcblock="echo \\\`bitcoin-cli getblockcount 2>&1\\\`/\\\`wget -O - https://blockstream.info/testnet/api/blocks/tip/height 2> /dev/null | cut -d : -f2 | rev | cut -c 1- | rev\\\`" +EOF +$ source .bash_profile +$ btcblock +1804372/1804372 +``` + +> :link: **TESTNET vs MAINNET:** Lembre-se de que este tutorial geralmente assume que você está usando testnet. Se você estiver usando a mainnet, pode recuperar a altura do bloco atual com: `wget -O - https://mempool.space/testnet/api/blocks/tip/height 2> /dev/ null`. Você pode substituir a última metade do alias `btblock` (após `/`) por isso. + +Se você não está atualizado, mas seu `getblockcount` está aumentando, não há problema. O tempo total de download pode levar de uma hora a várias horas, dependendo da configuração. + +## Opcional: Conheça os tipos de servidores + +> **TESTNET vs MAINNET:** Ao configurar seu node Bitcoin, você escolhe criá-lo como um Mainnet, Testnet ou Regtest. Embora este documento presuma uma configuração de rede de teste, vale a pena entender como você pode acessar e usar os outros tipos de configuração - mesmo todos na mesma máquina! Mas, se você for um usuário iniciante, pule isso, pois não é necessário para uma configuração básica. + +O tipo de configuração é controlado principalmente por meio do arquivo `~/.bitcoin/bitcoin.conf`. Se você estiver executando o testnet, provavelmente contém esta linha: +``` +testnet=1 +``` +Se você estiver executando o regtest, provavelmente contém esta linha: +``` +regtest=1 +``` +No entanto, se você deseja executar vários tipos diferentes de nós simultaneamente, deve deixar o sinalizador testnet (ou regtest) fora de seu arquivo de configuração. Você pode então escolher se está usando mainnet, testnet ou regtest toda vez que executar bitcoind ou bitcoin-cli. + +Aqui está um conjunto de aliases que tornariam isso mais fácil, criando um alias específico para iniciar e parar o bitcoind, para ir para o diretório bitcoin e para executar bitcoin-cli, para cada mainnet (que não tem sinalizadores extras), o testnet (que é -testnet), ou seu regtest (que é -regtest). +``` +cat >> ~/.bash_profile < :link: **TESTNET vs MAINNET:** Se você estiver usando mainnet, então _tudo_ será colocado no diretório principal `~/.bitcoin`. Então se você estiver usando mainnet, testnet e regtest, você verá que `~/.bitcoin` contém seu arquivo de configuração e seus dados mainnet, o diretório` ~/.bitcoin/testnet3` contém seus dados testnet, e o diretório `~/.bitcoin/regtest` contém seus dados de regtest. + +## Conheça os comandos do Bitcoin-cli + +A maior parte do seu trabalho inicial será feito com o comando `bitcoin-cli`, que oferece uma interface fácil para o `bitcoind`. Se você quiser mais informações sobre seu uso, basta executá-lo com o argumento `help`. Sem nenhum outro argumento, ele mostrara todos os comandos possíveis: +``` +$ bitcoin-cli help +== Blockchain == +getbestblockhash +getblock "blockhash" ( verbosity ) +getblockchaininfo +getblockcount +getblockfilter "blockhash" ( "filtertype" ) +getblockhash height +getblockheader "blockhash" ( verbose ) +getblockstats hash_or_height ( stats ) +getchaintips +getchaintxstats ( nblocks "blockhash" ) +getdifficulty +getmempoolancestors "txid" ( verbose ) +getmempooldescendants "txid" ( verbose ) +getmempoolentry "txid" +getmempoolinfo +getrawmempool ( verbose ) +gettxout "txid" n ( include_mempool ) +gettxoutproof ["txid",...] ( "blockhash" ) +gettxoutsetinfo +preciousblock "blockhash" +pruneblockchain height +savemempool +scantxoutset "action" ( [scanobjects,...] ) +verifychain ( checklevel nblocks ) +verifytxoutproof "proof" + +== Control == +getmemoryinfo ( "mode" ) +getrpcinfo +help ( "command" ) +logging ( ["include_category",...] ["exclude_category",...] ) +stop +uptime + +== Generating == +generatetoaddress nblocks "address" ( maxtries ) +generatetodescriptor num_blocks "descriptor" ( maxtries ) + +== Mining == +getblocktemplate ( "template_request" ) +getmininginfo +getnetworkhashps ( nblocks height ) +prioritisetransaction "txid" ( dummy ) fee_delta +submitblock "hexdata" ( "dummy" ) +submitheader "hexdata" + +== Network == +addnode "node" "command" +clearbanned +disconnectnode ( "address" nodeid ) +getaddednodeinfo ( "node" ) +getconnectioncount +getnettotals +getnetworkinfo +getnodeaddresses ( count ) +getpeerinfo +listbanned +ping +setban "subnet" "command" ( bantime absolute ) +setnetworkactive state + +== Rawtransactions == +analyzepsbt "psbt" +combinepsbt ["psbt",...] +combinerawtransaction ["hexstring",...] +converttopsbt "hexstring" ( permitsigdata iswitness ) +createpsbt [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime replaceable ) +createrawtransaction [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime replaceable ) +decodepsbt "psbt" +decoderawtransaction "hexstring" ( iswitness ) +decodescript "hexstring" +finalizepsbt "psbt" ( extract ) +fundrawtransaction "hexstring" ( options iswitness ) +getrawtransaction "txid" ( verbose "blockhash" ) +joinpsbts ["psbt",...] +sendrawtransaction "hexstring" ( maxfeerate ) +signrawtransactionwithkey "hexstring" ["privatekey",...] ( [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","witnessScript":"hex","amount":amount},...] "sighashtype" ) +testmempoolaccept ["rawtx",...] ( maxfeerate ) +utxoupdatepsbt "psbt" ( ["",{"desc":"str","range":n or [n,n]},...] ) + +== Util == +createmultisig nrequired ["key",...] ( "address_type" ) +deriveaddresses "descriptor" ( range ) +estimatesmartfee conf_target ( "estimate_mode" ) +getdescriptorinfo "descriptor" +signmessagewithprivkey "privkey" "message" +validateaddress "address" +verifymessage "address" "signature" "message" + +== Wallet == +abandontransaction "txid" +abortrescan +addmultisigaddress nrequired ["key",...] ( "label" "address_type" ) +backupwallet "destination" +bumpfee "txid" ( options ) +createwallet "wallet_name" ( disable_private_keys blank "passphrase" avoid_reuse ) +dumpprivkey "address" +dumpwallet "filename" +encryptwallet "passphrase" +getaddressesbylabel "label" +getaddressinfo "address" +getbalance ( "dummy" minconf include_watchonly avoid_reuse ) +getbalances +getnewaddress ( "label" "address_type" ) +getrawchangeaddress ( "address_type" ) +getreceivedbyaddress "address" ( minconf ) +getreceivedbylabel "label" ( minconf ) +gettransaction "txid" ( include_watchonly verbose ) +getunconfirmedbalance +getwalletinfo +importaddress "address" ( "label" rescan p2sh ) +importmulti "requests" ( "options" ) +importprivkey "privkey" ( "label" rescan ) +importprunedfunds "rawtransaction" "txoutproof" +importpubkey "pubkey" ( "label" rescan ) +importwallet "filename" +keypoolrefill ( newsize ) +listaddressgroupings +listlabels ( "purpose" ) +listlockunspent +listreceivedbyaddress ( minconf include_empty include_watchonly "address_filter" ) +listreceivedbylabel ( minconf include_empty include_watchonly ) +listsinceblock ( "blockhash" target_confirmations include_watchonly include_removed ) +listtransactions ( "label" count skip include_watchonly ) +listunspent ( minconf maxconf ["address",...] include_unsafe query_options ) +listwalletdir +listwallets +loadwallet "filename" +lockunspent unlock ( [{"txid":"hex","vout":n},...] ) +removeprunedfunds "txid" +rescanblockchain ( start_height stop_height ) +sendmany "" {"address":amount} ( minconf "comment" ["address",...] replaceable conf_target "estimate_mode" ) +sendtoaddress "address" amount ( "comment" "comment_to" subtractfeefromamount replaceable conf_target "estimate_mode" avoid_reuse ) +sethdseed ( newkeypool "seed" ) +setlabel "address" "label" +settxfee amount +setwalletflag "flag" ( value ) +signmessage "address" "message" +signrawtransactionwithwallet "hexstring" ( [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","witnessScript":"hex","amount":amount},...] "sighashtype" ) +unloadwallet ( "wallet_name" ) +walletcreatefundedpsbt [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime options bip32derivs ) +walletlock +walletpassphrase "passphrase" timeout +walletpassphrasechange "oldpassphrase" "newpassphrase" +walletprocesspsbt "psbt" ( sign "sighashtype" bip32derivs ) + +== Zmq == +getzmqnotifications +``` +Você também pode digitar `bitcoin-cli help [command]` para obter informações ainda mais detalhadas sobre aquele comando. Por exemplo: +``` +$ bitcoin-cli help 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/ +``` +> :book: ***What is RPC?*** `bitcoin-cli` is just a handy interface that lets you send commands to the `bitcoind`. More specifically, it's an interface that lets you send RPC (or Remote Procedure Protocol) commands to the `bitcoind`. Often, the `bitcoin-cli` command and the RPC command have identical names and interfaces, but some `bitcoin-cli` commands instead provide shortcuts for more complex RPC requests. Generally, the `bitcoin-cli` interface is much cleaner and simpler than trying to send RPC commands by hand, using `curl` or some other method. However, it also has limitations as to what you can ultimately do. + +## Opcional: Conheça as informações do seu node Bitcoin + +Uma variedade de comandos bitcoin-cli podem fornecer informações adicionais sobre seus node Bitcoin. Os mais gerais são: + +`bitcoin-cli -getinfo` retorna informações diferentes do RPC + +```diff +$ bitcoin-cli -getinfo + +! Chain: test +Blocks: 1977694 +Headers: 1977694 +Verification progress: 0.9999993275374796 +Difficulty: 1 + ++ Network: in 0, out 8, total 8 +Version: 219900 +Time offset (s): 0 +Proxy: N/A +Min tx relay fee rate (BTC/kvB): 0.00001000 + +@@ Wallet: ""@@ +Keypool size: 1000 +Unlocked until: 0 +Transaction fee rate (-paytxfee) (BTC/kvB): 0.00000000 + +# Balance: 0.02853102 + +- Warnings: unknown new rules activated (versionbit 28) + +``` + +Outros comandos para obter informações sobre blockchain, mineração, rede, carteira etc. + +``` +$ bitcoin-cli getblockchaininfo +$ bitcoin-cli getmininginfo +$ bitcoin-cli getnetworkinfo +$ bitcoin-cli getnettotals +$ bitcoin-cli getwalletinfo +``` +Por exemplo, `bitcoin-cli getnetworkinfo` fornece uma variedade de informações sobre sua configuração e seu acesso a outras redes: +``` +$ bitcoin-cli getnetworkinfo +{ + "version": 200000, + "subversion": "/Satoshi:0.20.0/", + "protocolversion": 70015, + "localservices": "0000000000000408", + "localservicesnames": [ + "WITNESS", + "NETWORK_LIMITED" + ], + "localrelay": true, + "timeoffset": 0, + "networkactive": true, + "connections": 10, + "networks": [ + { + "name": "ipv4", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "ipv6", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "onion", + "limited": false, + "reachable": true, + "proxy": "127.0.0.1:9050", + "proxy_randomize_credentials": true + } + ], + "relayfee": 0.00001000, + "incrementalfee": 0.00001000, + "localaddresses": [ + { + "address": "45.79.111.171", + "port": 18333, + "score": 1 + }, + { + "address": "2600:3c01::f03c:92ff:fecc:fdb7", + "port": 18333, + "score": 1 + }, + { + "address": "4wrr3ktm6gl4sojx.onion", + "port": 18333, + "score": 4 + } + ], + "warnings": "Warning: unknown new rules activated (versionbit 28)" +} +``` + +Sinta-se à vontade para consultar qualquer um deles e usar `bitcoin-cli help` se quiser mais informações sobre o que qualquer um deles faz. + +## Resumo: Conhecendo a configuração do seu node Bitcoin + +O diretório `~ /.bitcoin` contém todos os seus arquivos, enquanto `bitcoin-cli help` te retorna uma variedade de comandos, info podem ser usados para obter mais informações sobre como sua configuração e o Bitcoin funcionam. + +## Mas o que vem a seguir? + +Continue "Compreendendo sua configuração do seu node Bitcoin" com [3.3: Setting Up Your Wallet](03_3_Setting_Up_Your_Wallet.md). \ No newline at end of file diff --git a/pt/03_3_Setting_Up_Your_Wallet.md b/pt/03_3_Setting_Up_Your_Wallet.md new file mode 100644 index 0000000..1434ecb --- /dev/null +++ b/pt/03_3_Setting_Up_Your_Wallet.md @@ -0,0 +1,131 @@ +# 3.3: Configurando sua carteira + +Agora você está pronto para começar a trabalhar com Bitcoin. Para começar, você precisará criar um endereço para receber fundos. + +## Crie um endereço + +A primeira coisa que você precisa fazer é criar um endereço para recebimento de pagamentos. Isso é feito com o comando `bitcoin-cli getnewaddress`. Lembre-se que se você quiser mais informações sobre este comando, deve digitar `bitcoin-cli help getnewaddress`. Atualmente, existem três tipos de endereços: `legacy` e os dois tipos de endereço SegWit,` p2sh-segwit` e `bech32`. Se você não especificar de outra forma, você obterá o padrão, que atualmente é `bech32`. + +No entanto, para as próximas seções, em vez disso, usaremos endereços `legacy`, tanto porque `bitcoin-cli` teve alguns problemas iniciais com suas versões anteriores de endereços SegWit, e porque outras pessoas podem não ser capazes de enviar para endereços `bech32`. É improvável que tudo isso seja um problema para você agora, mas no momento queremos começar com exemplos de transações que (na maioria) têm garantia de funcionamento. + +Você pode exigir o endereço `legacy` como segundo argumento para `getnewaddress` ou com o argumento denominado `addresstype`. + +``` +$ bitcoin-cli getnewaddress -addresstype legacy +moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B +``` + +Observe que este endereço começa com um "m" (ou às vezes um "n") para significar um endereço legacy testnet. Seria um "2" para um endereço P2SH ou um "tb1" para um endereço Bech32. + +> :link: **TESTNET vs MAINNET:** O endereço mainnet equivalente começaria com "1" (para Legacy), "3" (para P2SH) ou "bc1" (para Bech32). + +Anote cuidadosamente o endereço. Você precisará entregá-lo a quem enviará os fundos. + +> :book: ***O que é um endereço Bitcoin?*** Um endereço Bitcoin é literalmente onde você recebe dinheiro. É como um endereço de e-mail, mas para fundos. Tecnicamente, é uma chave pública. No entanto, ao contrário de um endereço de e-mail, um endereço de Bitcoin deve ser considerado de uso único: use-o para receber fundos apenas _uma vez_. Quando você quiser receber fundos de outra pessoa ou em algum outro momento, gere um novo endereço. Isso é sugerido em grande parte para melhorar sua privacidade. Todo o blockchain é imutável, o que significa que os exploradores podem observar longas cadeias de transações ao longo do tempo, tornando possível determinar estatisticamente quem é você e quem são seus contatos, não importa o quão cuidadoso você seja. No entanto, se você continuar reutilizando o mesmo endereço, isso se tornará ainda mais fácil. + +> :book: ***O que é uma carteira Bitcoin?*** Ao criar seu primeiro endereço Bitcoin, você também começou a preencher sua carteira Bitcoin. Mais precisamente, você começou a preencher o arquivo `wallet.dat` em seu diretório `~/.bitcoin/testnet3/wallets`. O arquivo `wallet.dat` contém dados sobre preferências e transações, mas mais importante, contém todos os pares de chaves que você criou: a chave pública (que é a fonte do endereço onde você recebe fundos) e a chave privada (que é como você gasta esses fundos). Na maior parte, você não terá que se preocupar com a chave privada: `bitcoind` irá usá-la quando for necessário. No entanto, isso torna o arquivo `wallet.dat` extremamente importante: se você o perder, perderá suas chaves privadas e, se perder suas chaves privadas, perderá seus fundos! + +Com um único endereço em mãos, você pode pular direto para a próxima seção e começar a receber fundos. No entanto, antes de chegarmos lá, vamos discutir brevemente os outros tipos de endereços que você encontrará no futuro e falar sobre alguns outros comandos de carteira que você pode querer usar no futuro. + +### Conhecendo seus endereços de Bitcoin + +Existem três tipos de endereços Bitcoin que você pode criar com o comando RPC `getnewaddress`. Você usará um endereço `legacy` (P2PKH) aqui, enquanto se moverá para um endereço SegWit (P2SH-SegWit) ou Bech32 em [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md). + +Conforme observado acima, a base de um endereço de Bitcoin é uma chave pública: alguém envia fundos para sua chave pública e você usa sua chave privada para resgatá-la. Fácil? Exceto que colocar sua chave pública lá não é totalmente seguro. No momento, se alguém tiver sua chave pública, não poderá recuperar sua chave privada (e, portanto, seus fundos); essa é a base da criptografia, que usa uma função de trapdoor para garantir que você só possa passar da chave privada para a pública, e não vice-versa. Mas o problema é que não sabemos o que o futuro pode trazer. Exceto que sabemos que os sistemas de criptografia eventualmente são quebrados pelo avanço implacável da tecnologia, então é melhor não colocar chaves públicas brutas na rede, para preparar suas transações para o futuro. + +As transações clássicas de Bitcoin criaram endereços P2PKH que adicionaram uma etapa criptográfica adicional para proteger as chaves públicas. + +> :book: ***O que é um endereço legacy (P2PKH)?*** Este é um endereço legado do tipo usado pela antiga rede Bitcoin. Iremos usá-lo em exemplos nas próximas seções. É chamado de endereço Pay to PubKey Hash (ou P2PKH) porque o endereço é um hash de 160 bits de uma chave pública. Usar um hash de sua chave pública como seu endereço cria um processo de duas etapas onde gastar os fundos você precisa revelar a chave privada e a chave pública, e aumenta a segurança futura de acordo. Esse tipo de endereço continua sendo importante para receber fundos de pessoas com software de carteira desatualizado. + +Conforme descrito mais detalhadamente em [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md), a Block-Size Wars do final dos anos 10 do Bitcoin resultaram em um novo tipo de endereço: SegWit. Este é o tipo de endereço preferido atualmente e deve estar totalmente integrado ao Bitcoin-Core neste exato momento. + +SegWit significa simplesmente "testemunha segregada" e é uma maneira de separar as assinaturas da transação do resto da transação para reduzir o tamanho da transação. Alguns endereços SegWit entrarão em alguns de nossos exemplos anteriores a 4.6 como endereços de troco, que você verá como endereços que começam com "tb". Isso é bom porque o `bitcoin-cli` suporta inteiramente seu uso. + +Existem dois endereços desse tipo: + +> :book: ***O que é um endereço P2SH-SegWit (também conhecido como Nested SegWit)?*** Esta é a primeira geração do SegWit. Ele envolve o endereço SegWit em um hash de script para garantir a compatibilidade com versões anteriores. O resultado cria transações que são cerca de 25% + menores (com reduções correspondentes nas taxas de transação). + +> :book: ***O que é um endereço Bech32 (também conhecido como SegWit nativo, também conhecido como P2WPKH)?*** Esta é a segunda geração do SegWit. Está totalmente descrito em [BIP 173] (https://en.bitcoin.it/wiki/BIP_0173). Ele cria transações que são ainda menores, mas mais notavelmente também tem algumas vantagens na criação de endereços que são menos propensos a erro humano e têm alguma correção de erro implícita além disso. Ele * não * é compatível com versões anteriores como o P2SH-SegWit era e, portanto, algumas pessoas podem não ser capazes de enviar para ele. + +Existem outros tipos de endereços de Bitcoin, como P2PK (que paga a uma chave pública simples e está obsoleto devido à sua insegurança futura) e P2SH (que paga a um Hash de script e que é usado pelo SegWit e esta aninhado com a primeira geração endereços; vamos conhecê-lo mais detalhadamente em alguns capítulos). + +## Opcional: assine uma mensagem + +Às vezes, você precisará provar que controla um endereço Bitcoin (ou melhor, que controla sua chave privada). Isso é importante porque permite que as pessoas saibam que estão enviando fundos para a pessoa certa. Isso pode ser feito criando uma assinatura com o comando `bitcoin-cli signmessage`, na forma `bitcoin-cli signmessage [endereço] [mensagem]`. Por exemplo: + +``` +$ bitcoin-cli signmessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "Hello, World" +HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI= +``` +Você receberá a assinatura como um retorno. + +> :book: ***What is a signature?*** A digital signature is a combination of a message and a private key that can then be unlocked with a public key. Since there's a one-to-one correspendence between the elements of a keypair, unlocking with a public key proves that the signer controlled the corresponding private key. + +Another person can then use the `bitcoin-cli verifymessage` command to verify the signature. He inputs the address in question, the signature, and the message: +``` +$ bitcoin-cli verifymessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" +true +``` +Se todos eles corresponderem, a outra pessoa saberá que pode transferir fundos com segurança para a pessoa que assinou a mensagem enviando para o endereço. + +Se algum golpista estivesse criando assinaturas, isso produziria um invalido. +``` +$ bitcoin-cli verifymessage "FAKEV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" +error code: -3 +error message: +Invalid address +``` + +## Opcional: descarregar sua carteira + +Pode parecer perigoso ter todas as suas chaves privadas insubstituíveis em um único arquivo. É para isso que serve `bitcoin-cli dumpwallet`. Ele permite que você faça uma cópia de seu wallet.dat: +``` +$ bitcoin-cli dumpwallet ~/mywallet.txt +``` +O arquivo `mywallet.txt` em seu diretório home terá uma longa lista de chaves privadas, endereços e outras informações. Lembre-se, você não gostaria de colocar esses dados em um arquivo de texto simples, em uma configuração com fundos reais! + +Você pode então recuperá-lo com `bitcoin-cli importwallet`. +``` +$ bitcoin-cli importwallet ~/mywallet.txt +``` +Mas observe que isso requer um node não prunado. +``` +$ bitcoin-cli importwallet ~/mywallet.txt +error code: -4 +error message: +Importing wallets is disabled when blocks are pruned +``` + +## Opcional: Visualize suas chaves privadas + +Às vezes, você pode querer realmente olhar para as chaves privadas associadas aos seus endereços Bitcoin. Talvez você queira assinar uma mensagem ou gastar bitcoins em uma máquina diferente. Talvez você só queira fazer backup de algumas chaves privadas importantes. Você também pode fazer isso com seu arquivo de descarregado, já que ele pode ser lido por humanos. +``` +$ bitcoin-cli dumpwallet ~/mywallet.txt +{ + "filename": "/home/standup/mywallet.txt" +} +``` +Mais provavelmente, você deseja apenas examinar a chave privada associada a um endereço específico. Isso pode ser feito com o comando `bitcoin-cli dumpprivkey`. +``` +$ bitcoin-cli dumpprivkey "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" +cTv75T4B3NsG92tdSxSfzhuaGrzrmc1rJjLKscoQZXqNRs5tpYhH +``` +Você pode salvar essa chave em um local seguro, de preferência em algum lugar sem conexão com a Internet. + +Você também pode importar qualquer chave privada, de um despejo de carteira ou um despejo de chave individual, da seguinte maneira: +``` +$ bitcoin-cli importprivkey cW4s4MdW7BkUmqiKgYzSJdmvnzq8QDrf6gszPMC7eLmfcdoRHtHh +``` +Novamente, espere que isso exija um node não prunado. Espere que isso demore um pouco, já que o `bitcoind` precisa reler todas as transações anteriores, para ver se há alguma nova. + +> :information_source: **NOTA:** Muitas carteiras modernas preferem [códigos mnemônicos](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) para gerar as sementes necessárias para criar as chaves privadas. Esta metodologia não é usada `bitcoin-cli`, então você não será capaz de gerar listas de palavras úteis para lembrar suas chaves privadas. + +_Você digitou aquele endereço Bitcoin que gerou, enquanto assinava uma mensagens e agora esta descarregando as chaves. Se você acha que é muito complicado, concordamos. Também está sujeito a erros, um tópico que abordaremos na próxima seção._ + +## Resumo: Configurando sua carteira + +Você precisa criar um endereço para receber fundos. Seu endereço é armazenado em uma carteira, da qual você pode fazer backup. Você também pode fazer muito mais com um endereço, como descartar sua chave privada ou usá-la para assinar mensagens. Mas, realmente, criar esse endereço é _tudo_ que você precisa fazer para receber os fundos. + +## Mas oque vem a seguir? + +Um passo para trás em "Compreendendo a configuração do seu node Bitcoin" com [Usando variáveis de linha de comandos](03_3__Interlude_Using_Command-Line_Variables.md). \ No newline at end of file diff --git a/pt/03_3__Interlude_Using_Command-Line_Variables.md b/pt/03_3__Interlude_Using_Command-Line_Variables.md new file mode 100644 index 0000000..0c74363 --- /dev/null +++ b/pt/03_3__Interlude_Using_Command-Line_Variables.md @@ -0,0 +1,40 @@ +# Usando variáveis de linha de comando + +A seção anterior demonstrou vários comandos de linha de comando usados sem ofuscação ou interferência. No entanto, geralmente essa não é a melhor maneira de executar Bitcoin na linha de comando. Como você está lidando com variáveis longas, complexas e ilegíveis, é fácil cometer um erro se você estiver copiando essas variáveis (ou, satoshi forfend, se você as estiver digitando manualmente). Como essas variáveis podem significar a diferença entre receber e perder dinheiro real, você não _quer_ cometer erros. Por esses motivos, sugerimos enfaticamente o uso de variáveis de linha de comando para salvar endereços, assinaturas ou outras cadeias de informações longas sempre que for razoável. + +Se estiver usando `bash`, você pode salvar as informações em uma variável como esta: +``` +$ VARIABLE=$(command) +``` + +Esta é uma substituição de comando simples, o equivalente a `VARIABLE = command`. O comando entre parênteses é executado e, em seguida, atribuído à VARIÁVEL. + +Para criar um novo endereço, seria assim: +``` +$ unset NEW_ADDRESS_1 +$ NEW_ADDRESS_1=$(bitcoin-cli getnewaddress "" legacy) +``` +Esses comandos limpam a variável NEW_ADDRESS_1, apenas para ter certeza, e então a preenchem com os resultados do comando `bitcoin-cli getnewaddress`. + +Você pode então usar o comando `echo` do seu shell para ver o seu (novo) endereço: +``` +$ echo $NEW_ADDRESS_1 +mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE +``` +Como seu endereço está em uma variável, agora você pode assinar facilmente uma mensagem para esse endereço, sem se preocupar em digitar o endereço incorretamente. É claro que você também salvará essa assinatura em uma variável! +``` +$ NEW_SIG_1=$(bitcoin-cli signmessage $NEW_ADDRESS_1 "Hello, World") +$ echo $NEW_SIG_1 +IPYIzgj+Rg4bxDwCyoPiFiNNcxWHYxgVcklhmN8aB2XRRJqV731Xu9XkfZ6oxj+QGCRmTe80X81EpXtmGUpXOM4= +``` +O restante deste tutorial usará esse estilo de armazenar informações em variáveis quando for prático. + +> :book: ***Quando não é prático usar variáveis de linha de comando?*** Variáveis de linha de comando não são práticas se você precisar usar as informações em algum lugar diferente da linha de comando. Por exemplo, salvar sua assinatura pode não ser útil se você apenas tiver que enviá-la a outra pessoa por e-mail. Além disso, alguns comandos futuros produzirão objetos JSON em vez de informações simples, e as variáveis não podem ser usadas para capturar essas informações ... pelo menos não sem um _pouco_ de mais trabalho. + +## Resumo: Usando variáveis de linha de comando + +Variáveis de shell podem ser usadas para manter longas strings, minimizando as chances de erros. + +## Mas o que vem a seguir? + +Continue "Compreendendo a configuração do seu node Bitcoin" com [3.4: Recebendo uma transação](03_4_Receiving_a_Transaction.md). \ No newline at end of file From cde0e237c3477b7d8b5eac49b10ccadebcc48e21 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 11:30:51 -0300 Subject: [PATCH 006/155] Chapter 15 Translated Translation : Finished Revision : Needed --- pt/04_0_Sending_Bitcoin_Transactions.md | 29 ++ 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, 1891 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..f906763 --- /dev/null +++ b/pt/04_0_Sending_Bitcoin_Transactions.md @@ -0,0 +1,29 @@ +# 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..a6957ac --- /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). \ No newline at end of file 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..91926ae --- /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..1064409 --- /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 6ba639af994b6e4425cff8a7a0ecfeb2e5520f0d Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 11:56:27 -0300 Subject: [PATCH 007/155] =?UTF-8?q?Revis=C3=A3o=20da=20introdu=C3=A7=C3=A3?= =?UTF-8?q?o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Teste de revisão. --- pt/03_0_Understanding_Your_Bitcoin_Setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pt/03_0_Understanding_Your_Bitcoin_Setup.md b/pt/03_0_Understanding_Your_Bitcoin_Setup.md index 865b693..275adef 100644 --- a/pt/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/pt/03_0_Understanding_Your_Bitcoin_Setup.md @@ -1,4 +1,4 @@ -# Capítulo três: Compreendendo a configuração do seu node Bitcoin +# Capítulo 3: Compreendendo a configuração do node Bitcoin Agora que você está pronto para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que você entenda a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. From 240f7ad010c51094b39a90d73099ba706b9a8ae3 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 11:57:57 -0300 Subject: [PATCH 008/155] =?UTF-8?q?Revert=20"Revis=C3=A3o=20da=20introdu?= =?UTF-8?q?=C3=A7=C3=A3o"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 6ba639af994b6e4425cff8a7a0ecfeb2e5520f0d. --- pt/03_0_Understanding_Your_Bitcoin_Setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pt/03_0_Understanding_Your_Bitcoin_Setup.md b/pt/03_0_Understanding_Your_Bitcoin_Setup.md index 275adef..865b693 100644 --- a/pt/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/pt/03_0_Understanding_Your_Bitcoin_Setup.md @@ -1,4 +1,4 @@ -# Capítulo 3: Compreendendo a configuração do node Bitcoin +# Capítulo três: Compreendendo a configuração do seu node Bitcoin Agora que você está pronto para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que você entenda a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. From b1529ebb70898a11a23d6c1b1dcc28144c257f2b Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 12:00:32 -0300 Subject: [PATCH 009/155] Chapter 3.0 Reviewed --- pt/03_0_Understanding_Your_Bitcoin_Setup.md | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pt/03_0_Understanding_Your_Bitcoin_Setup.md b/pt/03_0_Understanding_Your_Bitcoin_Setup.md index 865b693..5bea404 100644 --- a/pt/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/pt/03_0_Understanding_Your_Bitcoin_Setup.md @@ -1,27 +1,27 @@ -# Capítulo três: Compreendendo a configuração do seu node Bitcoin +# Capítulo 3: Compreendendo a configuração do node Bitcoin -Agora que você está pronto para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que você entenda a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. +Agora que estamos prontos para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que entendamos a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. -Neste e nos próximos capítulos, presumimos que você tenha uma VPS com Bitcoin instalado, executando `bitcoind`. Também presumimos que você está conectado à testnet, permitindo o acesso a bitcoins sem usar fundos reais. Você pode fazer isso com Bitcoin Standup em linode.com, por [2.1: Configurando um Bitcoin-Core no VPS c Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou por outros métodos, por [2.2: Configurando um node Bitcoin Core por outros métodos](02_2_Setting_Up_Bitcoin_Core_Other.md). +Neste e nos próximos capítulos, presumimos que uma VPS com Bitcoin instalado esteja sendo utilizada, e que iremos executar o `bitcoind`. Também presumimos que estamos conectados à testnet, permitindo o acesso a bitcoins sem usar fundos reais. Podemos fazer isso com Bitcoin Standup em linode.com, como vimos na sessão [2.1: Configurando um Bitcoin-Core no VPS c Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou usando os demais métodos, descritos na sessão [2.2: Configurando um node Bitcoin Core por outros métodos](02_2_Setting_Up_Bitcoin_Core_Other.md). ## Objetivos deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - * Demonstrar que o node Bitcoin está instalado e atualizado - * Criar um endereço para receber fundos de Bitcoin - * Usar os comandos básicos da carteira - * Criar um endereço a partir de um descritor + * Demonstrar que o node Bitcoin está instalado e atualizado; + * Criar um endereço para receber bitcoins; + * Usar os comandos básicos da carteira; + * Criar um endereço a partir de um descritor. -Os objetivos de apoio incluem a capacidade de: +Os objetivos secundários incluem a capacidade de: - * Compreender o layout básico do arquivo Bitcoin - * Usar comandos informativos básicos - * Entender o que é um endereço Bitcoin - * Entender o que é uma carteira - * Entender como importar endereços + * Compreender o layout básico do arquivo Bitcoin; + * Usar comandos informativos básicos; + * Entender o que é um endereço Bitcoin; + * Entender o que é uma carteira; + * Entender como importar endereços. -## Índice +## Tabela de Conteúdo * [Seção Um: Verificando a configuração do seu node Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) * [Seção Dois: conhecendo a configuração do seu node Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) From 2a062b6a938d6fb86dc94856bf7b29f139df9299 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 12:30:28 -0300 Subject: [PATCH 010/155] Session 03.1 reviewed --- pt/03_1_Verifying_Your_Bitcoin_Setup.md | 59 +++++++++++++------------ 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/pt/03_1_Verifying_Your_Bitcoin_Setup.md b/pt/03_1_Verifying_Your_Bitcoin_Setup.md index 2997ef3..528af90 100644 --- a/pt/03_1_Verifying_Your_Bitcoin_Setup.md +++ b/pt/03_1_Verifying_Your_Bitcoin_Setup.md @@ -1,12 +1,13 @@ -# 3.1: Verificando a configuração do seu node Bitcoin -Antes de começar a brincar com Bitcoin, você deve se certificar de que tudo está configurado corretamente. +# 3.1: Verificando a configuração do node Bitcoin -## Crie seus aliases +Antes de começarmos a brincar com Bitcoin, devemos nos certificar de que tudo está configurado corretamente. -Sugerimos a criação de alguns aliases para facilitar o uso do Bitcoin +## Crie os aliases -Você pode fazer isso colocando-os em seu `.bash_profile`,` .bashrc` ou `.profile`. +Sugerimos a criação de alguns aliases (um tipo de atalho) para facilitar o uso do Bitcoin. + +Podemos fazer isso colocando-os em nosso `.bash_profile`, `.bashrc` ou no `.profile`. ``` cat >> ~/.bash_profile < :book: ***O que é a altura do bloco?*** A altura do bloco é a distância que um bloco particular está do bloco de gênese. A altura do bloco atual é a altura do bloco mais recente adicionado a um blockchain. +> :book: ***O que é a altura do bloco?*** A altura do bloco é a distância que um bloco particular está do bloco de gênese. A altura do bloco atual é a altura do bloco mais recente adicionado a blockchain. -Você pode fazer isso olhando para um explorador, como [Mempool Space Explorer](https://mempool.space/pt/testnet). O número mais recente corresponde ao `getblockcount`? Se sim, você está atualizado. +Podemos fazer isso olhando um explorador, como o [Mempool Space Explorer](https://mempool.space/pt/testnet). É o número mais recente corresponde ao `getblockcount`? Se sim, nossa blockchain está atualizada. -Se você quiser que um alias veja tudo de uma vez, o seguinte funciona atualmente para Testnet, mas pode desaparecer em algum momento no futuro: +Se quisermos que um alias veja tudo de uma vez, o código abaixo funciona normalmente no Testnet, mas pode desaparecer em algum momento no futuro: ``` $ cat >> ~/.bash_profile << EOF alias btcblock="echo \\\`bitcoin-cli getblockcount 2>&1\\\`/\\\`wget -O - https://blockstream.info/testnet/api/blocks/tip/height 2> /dev/null | cut -d : -f2 | rev | cut -c 1- | rev\\\`" @@ -54,25 +55,25 @@ $ btcblock 1804372/1804372 ``` -> :link: **TESTNET vs MAINNET:** Lembre-se de que este tutorial geralmente assume que você está usando testnet. Se você estiver usando a mainnet, pode recuperar a altura do bloco atual com: `wget -O - https://mempool.space/testnet/api/blocks/tip/height 2> /dev/ null`. Você pode substituir a última metade do alias `btblock` (após `/`) por isso. +> :link: **TESTNET vs MAINNET:** Lembre-se de que este tutorial geralmente assume que estamos usando a Testnet. Se estivermos usando a mainnet, podemos recuperar a altura do bloco atual usando a seguinte linha de comando: `wget -O - https://mempool.space/testnet/api/blocks/tip/height 2> /dev/ null`. Podemos substituir a última metade do alias `btblock` (após `/`) por isso. -Se você não está atualizado, mas seu `getblockcount` está aumentando, não há problema. O tempo total de download pode levar de uma hora a várias horas, dependendo da configuração. +Se a nossa blockchain não estiver atualizada, mas nosso `getblockcount` estiver aumentando, não há problema. O tempo total de download pode levar de uma a várias horas, dependendo da configuração. -## Opcional: Conheça os tipos de servidores +## Opcional: Conhecendo os tipos de servidores -> **TESTNET vs MAINNET:** Ao configurar seu node Bitcoin, você escolhe criá-lo como um Mainnet, Testnet ou Regtest. Embora este documento presuma uma configuração de rede de teste, vale a pena entender como você pode acessar e usar os outros tipos de configuração - mesmo todos na mesma máquina! Mas, se você for um usuário iniciante, pule isso, pois não é necessário para uma configuração básica. +> **TESTNET vs MAINNET:** Ao configurar o node Bitcoin, precisamos escolher se vamos criá-lo como sendo um Mainnet, Testnet ou Regtest. Embora este documento presuma uma configuração de Testnet, vale a pena entender como podemos acessar e usar os outros tipos de configuração, inclusive, como ter todos na mesma máquina! Mas, se formos iniciantes, podemos pular isso, pois não é necessário para uma configuração básica. -O tipo de configuração é controlado principalmente por meio do arquivo `~/.bitcoin/bitcoin.conf`. Se você estiver executando o testnet, provavelmente contém esta linha: +O tipo de configuração é controlado principalmente por meio do arquivo `~/.bitcoin/bitcoin.conf`. Se estivermos executando o Testnet, provavelmente teremos a seguinte linha: ``` testnet=1 ``` -Se você estiver executando o regtest, provavelmente contém esta linha: +Se estivermos executando a Regtest, provavelmente teremos essa linha: ``` regtest=1 ``` -No entanto, se você deseja executar vários tipos diferentes de nós simultaneamente, deve deixar o sinalizador testnet (ou regtest) fora de seu arquivo de configuração. Você pode então escolher se está usando mainnet, testnet ou regtest toda vez que executar bitcoind ou bitcoin-cli. +No entanto, se desejarmos executar vários tipos diferentes de nós simultaneamente, devemos deixar o um sinalizador Testnet (ou Regtest) fora do nosso arquivo de configuração. Podemos então escolher se estamos usando a Mainnet, Testnet ou Regtest toda vez que executarmos o bitcoind ou o bitcoin-cli. -Aqui está um conjunto de aliases que tornariam isso mais fácil, criando um alias específico para iniciar e parar o bitcoind, para ir para o diretório bitcoin e para executar bitcoin-cli, para cada mainnet (que não tem sinalizadores extras), o testnet (que é -testnet), ou seu regtest (que é -regtest). +Aqui está um conjunto de aliases que tornariam isso mais fácil, criando um alias específico para iniciar e parar o bitcoind, para ir para o diretório bitcoin e para executar o bitcoin-cli, na Mainnet (que não tem sinalizadores extras), no Testnet (que é -testnet), ou no nosso Regtest (que é -regtest). ``` cat >> ~/.bash_profile < Date: Sat, 26 Jun 2021 12:45:21 -0300 Subject: [PATCH 011/155] Session 3.2 reviewed --- pt/03_2_Knowing_Your_Bitcoin_Setup.md | 51 ++++++++++++++------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/pt/03_2_Knowing_Your_Bitcoin_Setup.md b/pt/03_2_Knowing_Your_Bitcoin_Setup.md index ba064c8..a1123a7 100644 --- a/pt/03_2_Knowing_Your_Bitcoin_Setup.md +++ b/pt/03_2_Knowing_Your_Bitcoin_Setup.md @@ -1,31 +1,32 @@ -# 3.2: Conhecendo a configuração do seu node Bitcoin -Antes de começar o jogo com Bitcoin, você pode sempre querer entender melhor sua configuração. +# 3.2: Conhecendo a configuração do node Bitcoin -## Conhecendo o seu diretório Bitcoin +Antes de começarmos a brincar com Bitcoin, é sempre bom entender melhor nossa configuração. -Para começar, você deve entender onde tudo é guardado: o diretório `~/.bitcoin`. +## Conhecendo o diretório do Bitcoin -O diretório principal contém apenas seu arquivo de configuração e o diretório testnet: +Para começar, devemos entender onde tudo está guardado: O diretório `~/.bitcoin`. + +O diretório principal contém apenas nosso arquivo de configuração e o diretório Testnet: ``` $ ls ~/.bitcoin bitcoin.conf testnet3 ``` -Os guias de configuração em [Capítulo dois: Criando um VPS Bitcoin-Core](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) estabelecem um arquivo de configuração padronizado. [3.1: Verificando sua configuração do seu node Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) Sugeri como alterá-lo para oferecer suporte a configurações mais avançadas. Se você estiver interessado em aprender ainda mais sobre o arquivo de configuração, você pode consultar [Jameson Lopp's Bitcoin Core gerador de configuração](https://jlopp.github.io/bitcoin-core-config-generator/). +Os guias de configuração no [Capítulo dois: Criando um VPS Bitcoin-Core](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) estabelecem um arquivo de configuração padronizado. Na sessão [3.1: Verificando a configuração do node Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) sugerimos como alterá-la para oferecer suporte a configurações mais avançadas. Se estivermos interessados em aprender ainda mais sobre o arquivo de configuração, podemos consultar o [Gerador de Configuração do Bitcoin Core escrito por Jameson Lopp's](https://jlopp.github.io/bitcoin-core-config-generator/). -Voltando para o diretório `~/.bitcoin`, você descobrirá que o diretório testnet3 contém todos os elementos: +Voltando para o diretório `~/.bitcoin`, iremos descobrir que o diretório testnet3 contém todos os elementos: ``` $ ls ~/.bitcoin/testnet3 -banlist.dat blocks debug.log mempool.dat peers.dat -bitcoind.pid chainstate fee_estimates.dat onion_private_key wallets +banlist.dat blocks debug.log mempool.dat peers.dat +bitcoind.pid chainstate fee_estimates.dat onion_private_key wallets ``` -Você não deve mexer com a maioria desses arquivos e diretórios - particularmente não com os diretórios `blocks` e` chainstate`, que contêm todos os dados do blockchain, e as informações em seu diretório `wallets`, que contém sua carteira pessoal. No entanto, preste atenção ao arquivo `debug.log`, que você deve consultar se tiver problemas com sua configuração. +Não deve mexer com a maioria desses arquivos e diretórios, particularmente os diretórios `blocks` e `chainstate` não devem ser tocados, pois contêm todos os dados da blockchain, e as informações do nosso diretório `wallets`, que contém nossa carteira. No entanto, podemos prestar atenção ao arquivo `debug.log`, que devemos consultar se começarmos a ter problemas com nossa configuração. -> :link: **TESTNET vs MAINNET:** Se você estiver usando mainnet, então _tudo_ será colocado no diretório principal `~/.bitcoin`. Então se você estiver usando mainnet, testnet e regtest, você verá que `~/.bitcoin` contém seu arquivo de configuração e seus dados mainnet, o diretório` ~/.bitcoin/testnet3` contém seus dados testnet, e o diretório `~/.bitcoin/regtest` contém seus dados de regtest. +> :link: **TESTNET vs MAINNET:** Se estivermos usando a Mainnet, então _tudo_ será colocado no diretório principal `~/.bitcoin`. Então se estivermos usando a Mainnet, Testnet e a Regtest, veremos que o `~/.bitcoin` contém nosso arquivo de configuração e nossos dados da mainnet, o diretório `~/.bitcoin/testnet3` contém nossos dados da Testnet, e o diretório `~/.bitcoin/regtest` contém os dados do regtest. -## Conheça os comandos do Bitcoin-cli +## Conhecendo os comandos do Bitcoin-cli -A maior parte do seu trabalho inicial será feito com o comando `bitcoin-cli`, que oferece uma interface fácil para o `bitcoind`. Se você quiser mais informações sobre seu uso, basta executá-lo com o argumento `help`. Sem nenhum outro argumento, ele mostrara todos os comandos possíveis: +A maior parte do nosso trabalho inicial será feito com o comando `bitcoin-cli`, que oferece uma interface simples para o `bitcoind`. Se quisermos mais informações sobre como utilizá-lo, basta executá-lo com o argumento `help`. Sem nenhum outro argumento, ele mostrara todos os possíveis comandos: ``` $ bitcoin-cli help == Blockchain == @@ -178,7 +179,7 @@ walletprocesspsbt "psbt" ( sign "sighashtype" bip32derivs ) == Zmq == getzmqnotifications ``` -Você também pode digitar `bitcoin-cli help [command]` para obter informações ainda mais detalhadas sobre aquele comando. Por exemplo: +Podemos digitar também `bitcoin-cli help [command]` para obtermos informações ainda mais detalhadas sobre aquele comando. Por exemplo: ``` $ bitcoin-cli help getmininginfo ... @@ -199,13 +200,13 @@ 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/ ``` -> :book: ***What is RPC?*** `bitcoin-cli` is just a handy interface that lets you send commands to the `bitcoind`. More specifically, it's an interface that lets you send RPC (or Remote Procedure Protocol) commands to the `bitcoind`. Often, the `bitcoin-cli` command and the RPC command have identical names and interfaces, but some `bitcoin-cli` commands instead provide shortcuts for more complex RPC requests. Generally, the `bitcoin-cli` interface is much cleaner and simpler than trying to send RPC commands by hand, using `curl` or some other method. However, it also has limitations as to what you can ultimately do. +> :book: ***O que é o RPC?*** O`bitcoin-cli` é apenas uma interface útil que permite enviar comandos para o`bitcoind`. Mais especificamente, é uma interface que permite enviar comandos RPC (Remote Procedure Protocol ou, protocolo de procedimento remoto, no português) para o `bitcoind`. Frequentemente, o comando `bitcoin-cli` e o comando RPC possuem nomes e interfaces idênticos, mas alguns comandos no `bitcoin-cli` fornecem atalhos para solicitações RPC mais complexas. Geralmente, a interface `bitcoin-cli` é muito mais limpa e simples do que tentar enviar comandos RPC manualmente, usando `curl` ou algum outro método. No entanto, ele também tem limitações quanto ao que podemos fazer. -## Opcional: Conheça as informações do seu node Bitcoin +## Opcional: Conhecendo as informações do node Bitcoin -Uma variedade de comandos bitcoin-cli podem fornecer informações adicionais sobre seus node Bitcoin. Os mais gerais são: +Uma variedade de comandos bitcoin-cli podem fornecer informações adicionais sobre nossos node Bitcoin. Os mais comuns são: -`bitcoin-cli -getinfo` retorna informações diferentes do RPC +`bitcoin-cli -getinfo` retorna informações do RPCs mais fáceis de serem lidas. ```diff $ bitcoin-cli -getinfo @@ -233,7 +234,7 @@ Transaction fee rate (-paytxfee) (BTC/kvB): 0.00000000 ``` -Outros comandos para obter informações sobre blockchain, mineração, rede, carteira etc. +Abaixo apresentamos outros comandos para obter informações sobre blockchain, mineração, rede, carteira etc. ``` $ bitcoin-cli getblockchaininfo @@ -242,7 +243,7 @@ $ bitcoin-cli getnetworkinfo $ bitcoin-cli getnettotals $ bitcoin-cli getwalletinfo ``` -Por exemplo, `bitcoin-cli getnetworkinfo` fornece uma variedade de informações sobre sua configuração e seu acesso a outras redes: +Por exemplo, `bitcoin-cli getnetworkinfo` fornece uma variedade de informações sobre nossa configuração e nosso acesso a outras redes: ``` $ bitcoin-cli getnetworkinfo { @@ -304,12 +305,12 @@ $ bitcoin-cli getnetworkinfo } ``` -Sinta-se à vontade para consultar qualquer um deles e usar `bitcoin-cli help` se quiser mais informações sobre o que qualquer um deles faz. +Vamos testar à vontade qualquer um deles e usar `bitcoin-cli help` se quisermos saber mais informações sobre o que qualquer um deles faz. -## Resumo: Conhecendo a configuração do seu node Bitcoin +## Resumo do Conhecendo a configuração do seu node Bitcoin -O diretório `~ /.bitcoin` contém todos os seus arquivos, enquanto `bitcoin-cli help` te retorna uma variedade de comandos, info podem ser usados para obter mais informações sobre como sua configuração e o Bitcoin funcionam. +O diretório `~/.bitcoin` contém todos os arquivos, enquanto o `bitcoin-cli help` nos retorna uma variedade de informações de comandos que podem ser usados para obter mais informações sobre como nossa configuração e o Bitcoin funcionam. -## Mas o que vem a seguir? +## O Que Vem Depois? -Continue "Compreendendo sua configuração do seu node Bitcoin" com [3.3: Setting Up Your Wallet](03_3_Setting_Up_Your_Wallet.md). \ No newline at end of file +Vamos continuar "Compreendendo a configuração do node Bitcoin" na sessão [3.3: Configurando nossa carteira](03_3_Setting_Up_Your_Wallet.md). \ No newline at end of file From 835aa32238a04199c8e9366f57a08e8ec4b8aee3 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 12:53:51 -0300 Subject: [PATCH 012/155] Session 3.3 reviewed --- ..._Interlude_Using_Command-Line_Variables.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pt/03_3__Interlude_Using_Command-Line_Variables.md b/pt/03_3__Interlude_Using_Command-Line_Variables.md index 0c74363..5c1f67b 100644 --- a/pt/03_3__Interlude_Using_Command-Line_Variables.md +++ b/pt/03_3__Interlude_Using_Command-Line_Variables.md @@ -1,13 +1,13 @@ # Usando variáveis de linha de comando -A seção anterior demonstrou vários comandos de linha de comando usados sem ofuscação ou interferência. No entanto, geralmente essa não é a melhor maneira de executar Bitcoin na linha de comando. Como você está lidando com variáveis longas, complexas e ilegíveis, é fácil cometer um erro se você estiver copiando essas variáveis (ou, satoshi forfend, se você as estiver digitando manualmente). Como essas variáveis podem significar a diferença entre receber e perder dinheiro real, você não _quer_ cometer erros. Por esses motivos, sugerimos enfaticamente o uso de variáveis de linha de comando para salvar endereços, assinaturas ou outras cadeias de informações longas sempre que for razoável. +A sessão anterior demonstrou vários comandos de linha de comando usados sem ofuscação ou interferência. No entanto, geralmente essa não é a melhor maneira de executar o Bitcoin usando a linha de comando. Como estamos lidando com variáveis longas, complexas e difíceis de serem lidas, é fácil cometer um erro se estivermos copiando essas variáveis (ou, perder alguns satoshis, se as digitarmos manualmente). Como essas variáveis podem significar a diferença entre receber e perder dinheiro quando usarmos a Mainnet, não _queremos_ cometer erros. Por esses motivos, sugerimos enfaticamente o uso de variáveis de linha de comando para salvar endereços, assinaturas ou outras cadeias de informações longas sempre que isso for razoável. -Se estiver usando `bash`, você pode salvar as informações em uma variável como esta: +Se estiver usando `bash`, podemos salvar as informações em uma variável como esta: ``` $ VARIABLE=$(command) ``` -Esta é uma substituição de comando simples, o equivalente a `VARIABLE = command`. O comando entre parênteses é executado e, em seguida, atribuído à VARIÁVEL. +Esta é uma substituição de um comando simples, o equivalente a `VARIABLE = command`. O comando entre parênteses é executado e, em seguida, atribuído à VARIABLE. Para criar um novo endereço, seria assim: ``` @@ -16,25 +16,25 @@ $ NEW_ADDRESS_1=$(bitcoin-cli getnewaddress "" legacy) ``` Esses comandos limpam a variável NEW_ADDRESS_1, apenas para ter certeza, e então a preenchem com os resultados do comando `bitcoin-cli getnewaddress`. -Você pode então usar o comando `echo` do seu shell para ver o seu (novo) endereço: +Podemos então usar o comando `echo` do shell para vermos nosso (novo) endereço: ``` $ echo $NEW_ADDRESS_1 mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE ``` -Como seu endereço está em uma variável, agora você pode assinar facilmente uma mensagem para esse endereço, sem se preocupar em digitar o endereço incorretamente. É claro que você também salvará essa assinatura em uma variável! +Como nosso endereço está em uma variável, agora podemos assinar facilmente uma mensagem para esse endereço, sem nos preocupar em digitar o endereço incorretamente. É claro que também salvaremos essa assinatura em uma variável! ``` $ NEW_SIG_1=$(bitcoin-cli signmessage $NEW_ADDRESS_1 "Hello, World") $ echo $NEW_SIG_1 IPYIzgj+Rg4bxDwCyoPiFiNNcxWHYxgVcklhmN8aB2XRRJqV731Xu9XkfZ6oxj+QGCRmTe80X81EpXtmGUpXOM4= ``` -O restante deste tutorial usará esse estilo de armazenar informações em variáveis quando for prático. +O restante deste tutorial usará esse estilo de armazenamento de informações quando for mais prático. -> :book: ***Quando não é prático usar variáveis de linha de comando?*** Variáveis de linha de comando não são práticas se você precisar usar as informações em algum lugar diferente da linha de comando. Por exemplo, salvar sua assinatura pode não ser útil se você apenas tiver que enviá-la a outra pessoa por e-mail. Além disso, alguns comandos futuros produzirão objetos JSON em vez de informações simples, e as variáveis não podem ser usadas para capturar essas informações ... pelo menos não sem um _pouco_ de mais trabalho. +> :book: ***Quando não é prático usar variáveis de linha de comando?*** Variáveis de linha de comando não são práticas se precisarmos usar as informações em algum lugar diferente da linha de comando. Por exemplo, salvar a assinatura pode não ser útil se tivermos que enviá-la a outra pessoa por e-mail. Além disso, alguns comandos futuros produzirão objetos JSON ao invés de informações simples, e as variáveis não podem ser usadas para capturar essas informações, ao menos não sem um _pouco_ mais de mais trabalho. -## Resumo: Usando variáveis de linha de comando +## Resumo do Usando variáveis de linha de comando Variáveis de shell podem ser usadas para manter longas strings, minimizando as chances de erros. -## Mas o que vem a seguir? +## O Que Vem Depois? -Continue "Compreendendo a configuração do seu node Bitcoin" com [3.4: Recebendo uma transação](03_4_Receiving_a_Transaction.md). \ No newline at end of file +Vamos continuar "Compreendendo a configuração do node Bitcoin" na sessão [3.4: Recebendo uma transação](03_4_Receiving_a_Transaction.md). \ No newline at end of file From a0fcae116c176a1c14277f272169e2cc7de26c13 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 13:54:13 -0300 Subject: [PATCH 013/155] Session 3.3 reviewed --- pt/03_3_Setting_Up_Your_Wallet.md | 91 ++++++++++++++++--------------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/pt/03_3_Setting_Up_Your_Wallet.md b/pt/03_3_Setting_Up_Your_Wallet.md index 1434ecb..724eeac 100644 --- a/pt/03_3_Setting_Up_Your_Wallet.md +++ b/pt/03_3_Setting_Up_Your_Wallet.md @@ -1,74 +1,75 @@ -# 3.3: Configurando sua carteira -Agora você está pronto para começar a trabalhar com Bitcoin. Para começar, você precisará criar um endereço para receber fundos. +# 3.3: Configurando nossa carteira -## Crie um endereço +Agora estamos prontos para começar a brincar com o Bitcoin. Para começar, precisaremos criar um endereço para receber fundos. -A primeira coisa que você precisa fazer é criar um endereço para recebimento de pagamentos. Isso é feito com o comando `bitcoin-cli getnewaddress`. Lembre-se que se você quiser mais informações sobre este comando, deve digitar `bitcoin-cli help getnewaddress`. Atualmente, existem três tipos de endereços: `legacy` e os dois tipos de endereço SegWit,` p2sh-segwit` e `bech32`. Se você não especificar de outra forma, você obterá o padrão, que atualmente é `bech32`. +## Criando um endereço -No entanto, para as próximas seções, em vez disso, usaremos endereços `legacy`, tanto porque `bitcoin-cli` teve alguns problemas iniciais com suas versões anteriores de endereços SegWit, e porque outras pessoas podem não ser capazes de enviar para endereços `bech32`. É improvável que tudo isso seja um problema para você agora, mas no momento queremos começar com exemplos de transações que (na maioria) têm garantia de funcionamento. +A primeira coisa que precisamos fazer é criar um endereço para recebimento de pagamentos. Podemos fazer isso usando o comando `bitcoin-cli getnewaddress`. Temos que lembrar que se quisermos mais informações sobre este comando, podemos digitar `bitcoin-cli help getnewaddress`. Atualmente, existem três tipos de endereços: Os `legacy` e os dois tipos de endereço SegWit, `p2sh-segwit` e `bech32`. Se não especificarmos qual queremos criar, sempre teremos por padrão o `bech32`. -Você pode exigir o endereço `legacy` como segundo argumento para `getnewaddress` ou com o argumento denominado `addresstype`. +No entanto, nas próximas sessões, usaremos endereços `legacy`, porque o `bitcoin-cli` teve alguns problemas com suas versões anteriores usando os endereços SegWit e, porque algumas pessoas podem não ser capazes de enviar seus saldos para endereços `bech32`. É improvável que tudo isso seja um problema para nós neste exato momento, mas vamos começar com exemplos de transações que (na maioria das vezes) temos a garantia que irá funcionar. + +Podemos exigir um endereço `legacy` como segundo argumento para `getnewaddress` ou com o argumento denominado `addresstype`. ``` $ bitcoin-cli getnewaddress -addresstype legacy moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B ``` -Observe que este endereço começa com um "m" (ou às vezes um "n") para significar um endereço legacy testnet. Seria um "2" para um endereço P2SH ou um "tb1" para um endereço Bech32. +Observe que este endereço começa com "m" (ou às vezes um "n") para significar um endereço legacy na rede Testnet. Seria um "2" para um endereço P2SH ou um "tb1" para um endereço Bech32. -> :link: **TESTNET vs MAINNET:** O endereço mainnet equivalente começaria com "1" (para Legacy), "3" (para P2SH) ou "bc1" (para Bech32). +> :link: **TESTNET vs MAINNET:** O endereço Mainnet equivalente começaria com "1" (para Legacy), "3" (para P2SH) ou "bc1" (para Bech32). -Anote cuidadosamente o endereço. Você precisará entregá-lo a quem enviará os fundos. +Anote cuidadosamente o endereço. Precisaremos utilizá-lo para quando recebermos bitcoins. -> :book: ***O que é um endereço Bitcoin?*** Um endereço Bitcoin é literalmente onde você recebe dinheiro. É como um endereço de e-mail, mas para fundos. Tecnicamente, é uma chave pública. No entanto, ao contrário de um endereço de e-mail, um endereço de Bitcoin deve ser considerado de uso único: use-o para receber fundos apenas _uma vez_. Quando você quiser receber fundos de outra pessoa ou em algum outro momento, gere um novo endereço. Isso é sugerido em grande parte para melhorar sua privacidade. Todo o blockchain é imutável, o que significa que os exploradores podem observar longas cadeias de transações ao longo do tempo, tornando possível determinar estatisticamente quem é você e quem são seus contatos, não importa o quão cuidadoso você seja. No entanto, se você continuar reutilizando o mesmo endereço, isso se tornará ainda mais fácil. +> :book: ***O que é um endereço Bitcoin?*** Um endereço Bitcoin é literalmente onde receberemos as moedas. É como um endereço de e-mail, mas para bitcoin. Tecnicamente, é uma chave pública. No entanto, ao contrário de um endereço de e-mail, um endereço Bitcoin deve ser considerado de uso único: Vamos usar para receber fundos apenas _uma vez_. Quando quisermos receber fundos de outra pessoa ou em algum outro momento, precisaremos gerar um novo endereço. Isso é sugerido em grande parte para melhorar nossa privacidade. Toda a blockchain é imutável, o que significa que os exploradores podem observar longas cadeias de transações ao longo do tempo, tornando possível determinar estatisticamente quem é você e quem são os nossos contatos, não importa o quão cuidadoso sejamos. No entanto, se continuarmos reutilizando o mesmo endereço, isso se tornará ainda mais fácil. -> :book: ***O que é uma carteira Bitcoin?*** Ao criar seu primeiro endereço Bitcoin, você também começou a preencher sua carteira Bitcoin. Mais precisamente, você começou a preencher o arquivo `wallet.dat` em seu diretório `~/.bitcoin/testnet3/wallets`. O arquivo `wallet.dat` contém dados sobre preferências e transações, mas mais importante, contém todos os pares de chaves que você criou: a chave pública (que é a fonte do endereço onde você recebe fundos) e a chave privada (que é como você gasta esses fundos). Na maior parte, você não terá que se preocupar com a chave privada: `bitcoind` irá usá-la quando for necessário. No entanto, isso torna o arquivo `wallet.dat` extremamente importante: se você o perder, perderá suas chaves privadas e, se perder suas chaves privadas, perderá seus fundos! +> :book: ***O que é uma carteira Bitcoin?*** Ao criar nosso primeiro endereço Bitcoin, também começamos a preencher nossa carteira Bitcoin. Mais precisamente, começamos a preencher o arquivo `wallet.dat` no nosso diretório `~/.bitcoin/testnet3/wallets`. O arquivo `wallet.dat` contém dados sobre preferências e transações, mas mais importante, contém todos os pares de chaves que criamos: A chave pública (que é a fonte do endereço onde receberemos as moedas) e a chave privada (que é como gastamos esses fundos). Na maior parte, não teremos que nos preocupar com a chave privada: O `bitcoind` irá usá-la quando for necessário. No entanto, isso torna o arquivo `wallet.dat` extremamente importante: Se o perdermos, perderemos nossas chaves privadas e, se perdermos as chaves privadas, perderemos nossos fundos! -Com um único endereço em mãos, você pode pular direto para a próxima seção e começar a receber fundos. No entanto, antes de chegarmos lá, vamos discutir brevemente os outros tipos de endereços que você encontrará no futuro e falar sobre alguns outros comandos de carteira que você pode querer usar no futuro. +Com um único endereço em mãos, podemos pular direto para a próxima seção e começar a receber alguns satoshinhos. No entanto, antes de chegarmos lá, vamos discutir brevemente os outros tipos de endereços que encontraremos no futuro e falar sobre alguns outros comandos de carteira que podemos querer usar mais pra frente. -### Conhecendo seus endereços de Bitcoin +### Conhecendo os endereços do Bitcoin -Existem três tipos de endereços Bitcoin que você pode criar com o comando RPC `getnewaddress`. Você usará um endereço `legacy` (P2PKH) aqui, enquanto se moverá para um endereço SegWit (P2SH-SegWit) ou Bech32 em [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md). +Existem três tipos de endereços Bitcoin que podemos criar com o comando RPC `getnewaddress`. Usaremos um endereço `legacy` (P2PKH) aqui, mas iremos utilizar um endereço SegWit (P2SH-SegWit) ou Bech32 na sessão [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md). -Conforme observado acima, a base de um endereço de Bitcoin é uma chave pública: alguém envia fundos para sua chave pública e você usa sua chave privada para resgatá-la. Fácil? Exceto que colocar sua chave pública lá não é totalmente seguro. No momento, se alguém tiver sua chave pública, não poderá recuperar sua chave privada (e, portanto, seus fundos); essa é a base da criptografia, que usa uma função de trapdoor para garantir que você só possa passar da chave privada para a pública, e não vice-versa. Mas o problema é que não sabemos o que o futuro pode trazer. Exceto que sabemos que os sistemas de criptografia eventualmente são quebrados pelo avanço implacável da tecnologia, então é melhor não colocar chaves públicas brutas na rede, para preparar suas transações para o futuro. +Conforme observado acima, a base de um endereço de Bitcoin é uma chave pública: Alguém envia fundos para nossa chave pública e usamos a nossa chave privada para resgatá-la. Simples, não? Exceto que colocar nossa chave pública lá não é algo seguro. No momento, se alguém tiver nossa chave pública, não poderemos recuperar nossa chave privada (e, portanto, nossos fundos). Essa é a base da criptografia, que usa uma função de _trapdoor_ para garantir que só possamos passar da chave privada para a pública, e não vice-versa. Mas o problema é que não sabemos o que o futuro pode nos trazer. Exceto que sabemos que os sistemas de criptografia eventualmente são quebrados pelo avanço implacável da tecnologia, então é melhor não colocar chaves públicas brutas na rede, para prepararmos nossas transações para o futuro. -As transações clássicas de Bitcoin criaram endereços P2PKH que adicionaram uma etapa criptográfica adicional para proteger as chaves públicas. +As transações clássicas do Bitcoin criaram endereços P2PKH que adicionaram uma etapa criptográfica adicional para proteger as chaves públicas. -> :book: ***O que é um endereço legacy (P2PKH)?*** Este é um endereço legado do tipo usado pela antiga rede Bitcoin. Iremos usá-lo em exemplos nas próximas seções. É chamado de endereço Pay to PubKey Hash (ou P2PKH) porque o endereço é um hash de 160 bits de uma chave pública. Usar um hash de sua chave pública como seu endereço cria um processo de duas etapas onde gastar os fundos você precisa revelar a chave privada e a chave pública, e aumenta a segurança futura de acordo. Esse tipo de endereço continua sendo importante para receber fundos de pessoas com software de carteira desatualizado. +> :book: ***O que é um endereço legacy (P2PKH)?*** Este é um endereço legado do tipo usado pela antiga rede Bitcoin. Iremos usá-lo em exemplos nas próximas seções. É chamado de endereço Pay to PubKey Hash (ou P2PKH) porque o endereço é um hash de 160 bits de uma chave pública. Usar um hash de sua chave pública como endereço cria um processo de duas etapas onde para gastar os fundos precisamos revelar a chave privada e a chave pública, aumentando assim a segurança futura. Esse tipo de endereço continua sendo importante para receber fundos de pessoas com softwares desatualizados. -Conforme descrito mais detalhadamente em [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md), a Block-Size Wars do final dos anos 10 do Bitcoin resultaram em um novo tipo de endereço: SegWit. Este é o tipo de endereço preferido atualmente e deve estar totalmente integrado ao Bitcoin-Core neste exato momento. +Conforme descrito mais detalhadamente na sessão [4.6: Criando uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md), a Guerra pelo Tamanho dos Blocos do final dos anos 10 do Bitcoin resultaram em um novo tipo de endereço: O SegWit. Este é o tipo de endereço preferido atualmente e deve estar totalmente integrado ao Bitcoin-Core neste exato momento. -SegWit significa simplesmente "testemunha segregada" e é uma maneira de separar as assinaturas da transação do resto da transação para reduzir o tamanho da transação. Alguns endereços SegWit entrarão em alguns de nossos exemplos anteriores a 4.6 como endereços de troco, que você verá como endereços que começam com "tb". Isso é bom porque o `bitcoin-cli` suporta inteiramente seu uso. +O SegWit significa simplesmente "Segregated Witness" e é uma maneira de separar as assinaturas da transação do resto dela para reduzir o tamanho da mesma. Alguns endereços SegWit entrarão em alguns de nossos exemplos como endereços de troco, que veremos como endereços que começam com "tb". Isso é bom porque o `bitcoin-cli` suporta inteiramente o seu uso. Existem dois endereços desse tipo: -> :book: ***O que é um endereço P2SH-SegWit (também conhecido como Nested SegWit)?*** Esta é a primeira geração do SegWit. Ele envolve o endereço SegWit em um hash de script para garantir a compatibilidade com versões anteriores. O resultado cria transações que são cerca de 25% + menores (com reduções correspondentes nas taxas de transação). +> :book: ***O que é um endereço P2SH-SegWit (também conhecido como Nested SegWit)?*** Esta é a primeira geração do SegWit. Ele envolve o endereço SegWit em um hash de script para garantir a compatibilidade com versões anteriores. O resultado cria transações que são cerca de 25% menores (com reduções correspondentes nas taxas de transação). -> :book: ***O que é um endereço Bech32 (também conhecido como SegWit nativo, também conhecido como P2WPKH)?*** Esta é a segunda geração do SegWit. Está totalmente descrito em [BIP 173] (https://en.bitcoin.it/wiki/BIP_0173). Ele cria transações que são ainda menores, mas mais notavelmente também tem algumas vantagens na criação de endereços que são menos propensos a erro humano e têm alguma correção de erro implícita além disso. Ele * não * é compatível com versões anteriores como o P2SH-SegWit era e, portanto, algumas pessoas podem não ser capazes de enviar para ele. +> :book: ***O que é um endereço Bech32 (também conhecido como SegWit nativo ou como P2WPKH)?*** Esta é a segunda geração do SegWit. Está totalmente descrito em [BIP 173](https://en.bitcoin.it/wiki/BIP_0173). Ele cria transações que são ainda menores, mas mais notavelmente também tem algumas vantagens na criação de endereços que são menos propensos a erro humano e têm algumas correções de erro implícita. Ele _não_ é compatível com versões anteriores como o P2SH-SegWit era e, portanto, algumas pessoas podem não ser capazes de enviar bitcoins para ele. -Existem outros tipos de endereços de Bitcoin, como P2PK (que paga a uma chave pública simples e está obsoleto devido à sua insegurança futura) e P2SH (que paga a um Hash de script e que é usado pelo SegWit e esta aninhado com a primeira geração endereços; vamos conhecê-lo mais detalhadamente em alguns capítulos). +Existem outros tipos de endereços de Bitcoin, como P2PK (que paga a uma chave pública simples e está obsoleto devido à sua insegurança futura) e P2SH (que paga a um Hash de script e que é usado pelo SegWit e esta aninhado com a primeira geração endereços. Vamos conhecê-lo mais detalhadamente nos próximos capítulos). -## Opcional: assine uma mensagem +## Opcional: Assinando uma mensagem -Às vezes, você precisará provar que controla um endereço Bitcoin (ou melhor, que controla sua chave privada). Isso é importante porque permite que as pessoas saibam que estão enviando fundos para a pessoa certa. Isso pode ser feito criando uma assinatura com o comando `bitcoin-cli signmessage`, na forma `bitcoin-cli signmessage [endereço] [mensagem]`. Por exemplo: +Às vezes, precisamos provar que controlamos um endereço Bitcoin (ou melhor, que controlamos a chave privada). Isso é importante porque permite que as pessoas saibam que estão enviando fundos para a pessoa certa. Isso pode ser feito criando uma assinatura com o comando `bitcoin-cli signmessage`, na forma `bitcoin-cli signmessage [endereço] [mensagem]`. Por exemplo: ``` $ bitcoin-cli signmessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "Hello, World" HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI= ``` -Você receberá a assinatura como um retorno. +O resultado é uma assinatura como um retorno. -> :book: ***What is a signature?*** A digital signature is a combination of a message and a private key that can then be unlocked with a public key. Since there's a one-to-one correspendence between the elements of a keypair, unlocking with a public key proves that the signer controlled the corresponding private key. +> :book: ***O que é uma assinatura?*** Uma assinatura digital é uma combinação de uma mensagem e uma chave privada que pode ser desbloqueada com uma chave pública. Como há uma correspondência um-para-um entre os elementos de um par de chaves, o desbloqueio com uma chave pública prova que o assinante controlou a chave privada correspondente. -Another person can then use the `bitcoin-cli verifymessage` command to verify the signature. He inputs the address in question, the signature, and the message: +Outra pessoa pode usar o comando `bitcoin-cli verifymessage` para verificar a assinatura. Ela insere o endereço em questão, a assinatura e a mensagem: ``` $ bitcoin-cli verifymessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" true ``` Se todos eles corresponderem, a outra pessoa saberá que pode transferir fundos com segurança para a pessoa que assinou a mensagem enviando para o endereço. -Se algum golpista estivesse criando assinaturas, isso produziria um invalido. +Se algum golpista estivesse criando assinaturas, isso produziria um erro. ``` $ bitcoin-cli verifymessage "FAKEV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" error code: -3 @@ -76,19 +77,19 @@ error message: Invalid address ``` -## Opcional: descarregar sua carteira +## Opcional: Fazendo o dump da nossa carteira -Pode parecer perigoso ter todas as suas chaves privadas insubstituíveis em um único arquivo. É para isso que serve `bitcoin-cli dumpwallet`. Ele permite que você faça uma cópia de seu wallet.dat: +Pode parecer perigoso ter todas as chaves privadas insubstituíveis em um único arquivo. É para isso que serve o comando `bitcoin-cli dumpwallet`. Ele permite que façamos uma cópia do nosso arquivo `wallet.dat`: ``` $ bitcoin-cli dumpwallet ~/mywallet.txt ``` -O arquivo `mywallet.txt` em seu diretório home terá uma longa lista de chaves privadas, endereços e outras informações. Lembre-se, você não gostaria de colocar esses dados em um arquivo de texto simples, em uma configuração com fundos reais! +O arquivo `mywallet.txt` em nosso diretório home terá uma longa lista de chaves privadas, endereços e outras informações. Lembre-se, ninguém gostaria de colocar esses dados em um arquivo de texto simples, em uma configuração com saldos reais! -Você pode então recuperá-lo com `bitcoin-cli importwallet`. +Podemos então recuperá-los com o `bitcoin-cli importwallet`. ``` $ bitcoin-cli importwallet ~/mywallet.txt ``` -Mas observe que isso requer um node não prunado. +É importante observar que isso requer um node não prunado. ``` $ bitcoin-cli importwallet ~/mywallet.txt error code: -4 @@ -96,36 +97,36 @@ error message: Importing wallets is disabled when blocks are pruned ``` -## Opcional: Visualize suas chaves privadas +## Opcional: Visualizando as chaves privadas -Às vezes, você pode querer realmente olhar para as chaves privadas associadas aos seus endereços Bitcoin. Talvez você queira assinar uma mensagem ou gastar bitcoins em uma máquina diferente. Talvez você só queira fazer backup de algumas chaves privadas importantes. Você também pode fazer isso com seu arquivo de descarregado, já que ele pode ser lido por humanos. +Às vezes, podemos querer realmente olhar para as chaves privadas associadas aos nossos endereços Bitcoin. Talvez queremos assinar uma mensagem ou gastar bitcoins em uma máquina diferente. Talvez só estamos querendo fazer backup de algumas chaves privadas importantes. Também pode fazer isso com nosso arquivo criado acima, já que ele pode ser lido por humanos. ``` $ bitcoin-cli dumpwallet ~/mywallet.txt { "filename": "/home/standup/mywallet.txt" } ``` -Mais provavelmente, você deseja apenas examinar a chave privada associada a um endereço específico. Isso pode ser feito com o comando `bitcoin-cli dumpprivkey`. +Mais provavelmente, desejamos apenas examinar a chave privada associada a um endereço específico. Isso pode ser feito com o comando `bitcoin-cli dumpprivkey`. ``` $ bitcoin-cli dumpprivkey "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" cTv75T4B3NsG92tdSxSfzhuaGrzrmc1rJjLKscoQZXqNRs5tpYhH ``` -Você pode salvar essa chave em um local seguro, de preferência em algum lugar sem conexão com a Internet. +Podemos salvar essa chave em um local seguro, de preferência em algum lugar sem conexão com a Internet. -Você também pode importar qualquer chave privada, de um despejo de carteira ou um despejo de chave individual, da seguinte maneira: +Também podemos importar qualquer chave privada, de um dump de carteira ou um dump da chave individual, da seguinte maneira: ``` $ bitcoin-cli importprivkey cW4s4MdW7BkUmqiKgYzSJdmvnzq8QDrf6gszPMC7eLmfcdoRHtHh ``` -Novamente, espere que isso exija um node não prunado. Espere que isso demore um pouco, já que o `bitcoind` precisa reler todas as transações anteriores, para ver se há alguma nova. +Novamente, é esperado que isso exija um node não prunado. Isso provavelmente vai demorar um pouco, já que o `bitcoind` precisa reler todas as transações anteriores, para ver se há alguma nova. -> :information_source: **NOTA:** Muitas carteiras modernas preferem [códigos mnemônicos](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) para gerar as sementes necessárias para criar as chaves privadas. Esta metodologia não é usada `bitcoin-cli`, então você não será capaz de gerar listas de palavras úteis para lembrar suas chaves privadas. +> :information_source: **NOTA:** Muitas carteiras modernas preferem [códigos mnemônicos](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) para gerar as seeds necessárias para criar as chaves privadas. Esta metodologia não é usada pelo `bitcoin-cli`, então não seremos capazes de gerar listas de palavras para lembrar das nossas chaves privadas. -_Você digitou aquele endereço Bitcoin que gerou, enquanto assinava uma mensagens e agora esta descarregando as chaves. Se você acha que é muito complicado, concordamos. Também está sujeito a erros, um tópico que abordaremos na próxima seção._ +_Nós digitamos aquele endereço Bitcoin que gerou, enquanto assinávamos uma mensagem e agora estamos fazendo o dump as chaves. Se por acaso achar que isso é muito complicado, os autores e tradutores também concordam com isso. Também estamos sujeitos a erros, um tópico que abordaremos na próxima sessão._ -## Resumo: Configurando sua carteira +## Resumo do Configurando nossa carteira -Você precisa criar um endereço para receber fundos. Seu endereço é armazenado em uma carteira, da qual você pode fazer backup. Você também pode fazer muito mais com um endereço, como descartar sua chave privada ou usá-la para assinar mensagens. Mas, realmente, criar esse endereço é _tudo_ que você precisa fazer para receber os fundos. +Precisamos criar um endereço para receber fundos. Nosso endereço é armazenado em uma carteira, da qual podemos fazer o backup. Podemos fazer muito coisas com nosso endereço, como fazer o dump da nossa chave privada ou usá-la para assinar mensagens. Mas, realmente, criar esse endereço é _tudo_ que precisaremos fazer para receber alguns satoshinhos. -## Mas oque vem a seguir? +## O Que Vem Depois? -Um passo para trás em "Compreendendo a configuração do seu node Bitcoin" com [Usando variáveis de linha de comandos](03_3__Interlude_Using_Command-Line_Variables.md). \ No newline at end of file +Vamos dar uma pausa no capítulo "Compreendendo a configuração do node Bitcoin" na sessão [Usando variáveis de linha de comando](03_3__Interlude_Using_Command-Line_Variables.md). \ No newline at end of file From 797229d52283095c49007f05c12e4753debbf59a Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 29 Jun 2021 12:27:15 -0300 Subject: [PATCH 014/155] Add translated README --- pt/README.md | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 222 insertions(+), 1 deletion(-) diff --git a/pt/README.md b/pt/README.md index ec090a7..ffb21c3 100644 --- a/pt/README.md +++ b/pt/README.md @@ -1 +1,222 @@ -_directory for the Portuguese translation._ +# Aprendendo Bitcoin pela Linha de Comando 2.0.1 +### _por Christopher Allen e Shannon Appelcline_ + +![](https://www.blockchaincommons.com/images/projects/lbtc-screen.png) + +Aprendendo Bitcoin pela Linha de Comando é a versão em português de [Learning Bitcoin from the Command Line](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line), um tutorial para trabalhar com Bitcoin (e Lightning) que ensina interação direta com os servidores como a maneira mais robusta e segura de começar a trabalhar com criptomoedas. + +> NOTA: Este é um rascunho em progresso, para que eu possa receber algum feedback de revisores iniciais. Ainda não está pronto para uso. + +_Este tutorial assume que você tenha um mínimo background em como utilizar a linha de comando. Caso contrário, vários tutoriais estão disponíveis, e eu tenho um para usuários de Mac em https://github.com/ChristopherA/intro-mac-command-line._ + +## Traduções + +* [Espanhol](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/spanish-translation/es) - em progresso + +Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuindo](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master#contributing) abaixo. + +## Índice + +### PARTE UM: PREPARANDO PARA O BITCOIN + +**Estado**: Finalizado. Atualizado para 0.20. + +* [1.0: Introdução à Programação com Bitcoin Core e Lightning](01_0_Introduction.md) + * [Prefácio: Introduzindo o Bitcoin](01_1_Introducing_Bitcoin.md) +* [2.0: Configurando um Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) + * [2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) + * [2.2: Configurando uma Máquina Bitcoin-Core de Outras Formas](02_2_Setting_Up_Bitcoin_Core_Other.md) + +### PARTE DOIS: USANDO BITCOIN-CLI + +**Estado:** Finalizado. Atualizado para 0.20. + +* [3.0: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md) + * [3.1: Verificando Sua Configuração do Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) + * [3.2: Conhecendo Sua Configuração do Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) + * [3.3: Configurando Sua Carteira](03_3_Setting_Up_Your_Wallet.md) + * [Prefácio: Usando Variáveis de Linha de Comando](03_3__Interlude_Using_Command-Line_Variables.md) + * [3.4: Recebendo uma Transação](03_4_Receiving_a_Transaction.md) + * [3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md) +* [4.0: Enviando Transações no Bitcoin](04_0_Sending_Bitcoin_Transactions.md) + * [4.1: Enviando Moedas da Maneira Fácil](04_1_Sending_Coins_The_Easy_Way.md) + * [4.2: Criando uma Transação Bruta](04_2_Creating_a_Raw_Transaction.md) + * [Prefácio: Usando JQ](04_2__Interlude_Using_JQ.md) + * [4.3: Criando uma Transação Bruta com Argumentos Nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) + * [4.4: Enviando Moedas com Transações Brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md) + * [Prefácio: Usando Curl](04_4__Interlude_Using_Curl.md) + * [4.5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) + * [4.6: Criando uma Transação SegWit](04_6_Creating_a_Segwit_Transaction.md) +* [5.0: Controlando Transações no Bitcoin](05_0_Controlling_Bitcoin_Transactions.md) + * [5.1 Atentando-se para Transações Presas](05_1_Watching_for_Stuck_Transactions.md) + * [5.2: Re-enviando uma Transação com RBF](05_2_Resending_a_Transaction_with_RBF.md) + * [5.3: Financiando uma Transação com CPFP](05_3_Funding_a_Transaction_with_CPFP.md) +* [6.0: Expandindo Transações no Bitcoin com Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md) + * [6.1: Enviando uma Transação com Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [6.2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [6.3: Enviando & Gastando um Multisig Automatizado](06_3_Sending_an_Automated_Multisig.md) +* [7.0: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md) + * [7.1: Criando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) + * [7.2: Usando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) + * [7.3: Integrando com Carteiras de Hardware](07_3_Integrating_with_Hardware_Wallets.md) +* [8.0: Expandindo Transações no Bitcoin de Outras Maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md) + * [8.1: Enviando uma Transação com um Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) + * [8.2: Enviando uma Transação com Dados](08_2_Sending_a_Transaction_with_Data.md) + +### PARTE TRÊS: PROGRAMANDO NO BITCOIN + +**Estado:** Finalizado. Atualizado para 0.20 e btcdeb. + +* [9.0: Introduzindo Scripts no Bitcoin](09_0_Introducing_Bitcoin_Scripts.md) + * [9.1: Compreendendo a Fundação de Transações](09_1_Understanding_the_Foundation_of_Transactions.md) + * [9.2: Rodando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md) + * [9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md) + * [9.4: Programando um P2PKH](09_4_Scripting_a_P2PKH.md) + * [9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md) +* [10.0: Embutindo Scripts em Transações P2SH no Bitcoin](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md) + * [10.1: Compreendendo a Fundação do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) + * [10.2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md) + * [10.3: Rodando um Script no Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) + * [10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md) + * [10.5: Programando um Script Segwit](10_5_Scripting_a_Segwit_Script.md) + * [10.6: Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md) +* [11.0: Capacitando Timelock com Scripts no Bitcoin](11_0_Empowering_Timelock_with_Bitcoin_Scripts.md) + * [11.1: Compreendendo Opções de Timelock](11_1_Understanding_Timelock_Options.md) + * [11.2: Usando CLTV em Scripts](11_2_Using_CLTV_in_Scripts.md) + * [11.3: Usando CSV em Scripts](11_3_Using_CSV_in_Scripts.md) +* [12.0: Expandindo Scripts no Bitcoin](12_0_Expanding_Bitcoin_Scripts.md) + * [12.1: Usando Condicionais de Script](12_1_Using_Script_Conditionals.md) + * [12.2: Usando Outros Comandos de Script](12_2_Using_Other_Script_Commands.md) +* [13.0: Projetando Scripts Reais no Bitcoin](13_0_Designing_Real_Bitcoin_Scripts.md) + * [13.1: Escrevendo Scripts de Quebra-Cabeças](13_1_Writing_Puzzle_Scripts.md) + * [13.2: Escrevendo Scripts Complexos de Multisig](13_2_Writing_Complex_Multisig_Scripts.md) + * [13.3: Capacitando o Bitcoin com Scripts](13_3_Empowering_Bitcoin_with_Scripts.md) + +### PARTE QUATRO: USANDO TOR + +**Estado:** Finalizado. + +* [14.0: Usando Tor](14_0_Using_Tor.md) + * [14.1: Verificando Sua Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) + * [14.2: Mudando Seus Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) + * [14.3: Adicionando SSH aos Seus Serviços Ocultos](14_3_Adding_SSH_Hidden_Services.md) + +### PARTE CINCO: PROGRAMANDO COM RPC + +**Estado:** Finalizado. + +* [15.0: Conversando com o Bitcoind com C](15_0_Talking_to_Bitcoind.md) + * [15.1: Acessando o Bitcoind em C com Livrarias RPC](15_1_Accessing_Bitcoind_with_C.md) + * [15.2: Programando o Bitcoind em C com Livrarias RPC](15_2_Programming_Bitcoind_with_C.md) + * [15.3: Recebendo Notificações em C com Livrarias ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) +* [16.0: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md) + * [16.1: Configurando a Libwally](16_1_Setting_Up_Libwally.md) + * [16.2: Usando BIP39 na Libwally](16_2_Using_BIP39_in_Libwally.md) + * [16.3: Usando BIP32 na Libwally](16_3_Using_BIP32_in_Libwally.md) + * [16.4: Usando PSBTs na Libwally](16_4_Using_PSBTs_in_Libwally.md) + * [16.5: Usando Scripts na Libwally](16_5_Using_Scripts_in_Libwally.md) + * [16.6: Usando Outras Funções na Libwally](16_6_Using_Other_Functions_in_Libwally.md) + * [16.7: Integrando Libwally e Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md) +* [17.0: Conversando com o Bitcoind com Outras Linguagens](17_0_Talking_to_Bitcoind_Other.md) + * [17.1: Acessando o Bitcoind com Go](17_1_Accessing_Bitcoind_with_Go.md) + * [17.2: Acessando o Bitcoind com Java](17_2_Accessing_Bitcoind_with_Java.md) + * [17.3: Acessando o Bitcoind com Node JS](17_3_Accessing_Bitcoind_with_NodeJS.md) + * [17.4: Acessando o Bitcoind com Python](17_4_Accessing_Bitcoind_with_Python.md) + * [17.5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md) + * [17.6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md) + +### PARTE SEIS: USANDO LIGHTNING-CLI + +**Estado:** Finalizado. + +* [18.0: Compreendendo Sua Configuração Lightning](18_0_Understanding_Your_Lightning_Setup.md) + * [18.1: Verificando Sua Configuração c-lightning](18_1_Verifying_Your_Lightning_Setup.md) + * [18.2: Conhecendo Sua Configuração c-lightning](18_2_Knowing_Your_lightning_Setup.md) + * [Prefácio: Acessando um Segundo Node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md) + * [18.3: Criando um Canal Lightning](18_3_Setting_Up_a_Channel.md) +* [19.0: Usando Lightning](19_0_Using_Lightning.md) + * [19.1: Gerando um Pedido de Pagamento](19_1_Generate_a_Payment_Request.md) + * [19.2: Pagando uma Fatura](19_2_Paying_a_Invoice.md) + * [19.3: Fechando um Canal Lighnting]((19_3_Closing_a_Channel.md)) + * [19.4: Expandindo a Rede Lightning](19_4_Lightning_Network_Review.md) + +### APÊNDICES + +**Estado:** Finalizado. + +* [Apêndices](A0_Appendices.md) + * [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md) + * [Apêndice II: Compilando Bitcoin da Fonte](A2_0_Compiling_Bitcoin_from_Source.md) + * [Apêndice III: Usando o Regtest do Bitcoin](A3_0_Using_Bitcoin_Regtest.md) + +## Estado - Beta + +v2.0.1 do **Aprendendo Bitcoin pela Linha de Comando** é uma beta. Pode ainda estar sendo sujeito a revisões ou edições de terceiros, mas já pode ser utilizado para o aprendizado. + +Nós também estamos considerando o que poderíamos incluir em uma [v3.0](TODO-30.md) do curso. Se você gostaria de apoiar um trabalho desse tipo, torne-se um [Patrocinador no GitHub](https://github.com/sponsors/BlockchainCommons) ou nos apoie pelo nosso [Servidor BTCPay](https://btcpay.blockchaincommons.com/), e nos informe que **Aprendendo Bitcoin** foi o motivo. + +## Origem, Autores, Copyright & Licenças + +A não ser que indicado o contrário (ou neste [/README.md](./README.md) ou nos comentários nos cabeçalhos dos aquivos), os conteúdos deste repositório são Copyright © 2020 por Blockchain Commons, LLC, e licenciados sob [CC-BY](./LICENSE-CC-BY-4.0.md). + +## Apoio Financeiro + +*Aprendendo Bitcoin pela Linha de Comando* é um projeto da [Blockchain Commons](https://www.blockchaincommons.com/). Nós somos, com orgulho, uma organização de benefício social sem fins lucrativos comprometida ao desenvolvimento aberto e open source. O nosso trabalho é financiado inteiramente por doações e parcerias colaborativas com pessoas como você. Toda contribuição será gasta na construção de ferramenta abertas, tecnologias e técnicas que sustentam e avançam segurança do blockchain e da internet e promovem uma rede aberta. + +Para apoiar financeiramente o desenvolvimento futuro de `$projectname` e outros projetos, por favor considere se tornar um Patrocinador da Blockchain Commons por meio de patrocínios mensais contínuos como um [Patrocinador no GitHub](https://github.com/sponsors/BlockchainCommons). Você também pode apoiar a Blockchain Commons com bitcoins através do nosso [Servidor BTCPay](https://btcpay.blockchaincommons.com/). + +## Contribuindo + +Nós encorajamos contribuições públicas por meio de issues e pull requests! Por favor revise [CONTRIBUTING.md](./CONTRIBUTING.md) para detalhes sobre o nosso processo de desenvolvimento. Todas as contribuições para este repositório requerem um [Contrato de Licença do Contribuidor](./CLA.md) assinado por GPG. + +Se você gostaria de providenciar uma tradução de Aprendendo Bitcoin para outra língua, por favor veja também [TRANSLATING.md](./TRANSLATING.md). + +### Discussões + +O melhor lugar para conversar sobre a Blockchain Commons e seus projetos é na nossa área de Discussões no GitHub. + +[**Discussões Sobre Blockchain Commons**](https://github.com/BlockchainCommons/Community/discussions). Para desenvolvedores, estagiários a patrocinadores da Blockchain Commons, por favor utilize a área de discussões do [repositório da Comunidade](https://github.com/BlockchainCommons/Community) para falar sobre questões gerais da Blockchain Commons, o programa de estágio ou outros tópicos que não sejam o [Gordian System](https://github.com/BlockchainCommons/Gordian/discussions) ou os [padrões de carteira](https://github.com/BlockchainCommons/AirgappedSigning/discussions), pois cada um destes tem sua área de discussão própria. + +### Outras Questões & Problemas + +Como uma comunidade open-source e de desenvolvimento aberto, a Blockchain Commons não tem os recursos para fornecer apoio direto dos nossos projetos. Por favor considere a área de discussões como um local onde você pode receber respostas a perguntas. Alternativamente, por favor use o campo de [issues](./issues) deste repositório. Infelizmente, não podemos fazer promessas em relação ao tempo de resposta. + +Se a sua empresa requer apoio para usar os nossos projetos, por favor nos contacte diretamente para opcões. Nós podemos ser capazes de te oferecer um contrato para apoio por um de nossos contribuidores, ou poderemos te indicar outra entidade que possa oferecer o apoio contratual que você precisa. + +### Créditos + +As pessoas a seguir contribuíram diretamente para este repositório. Você pode adicionar o seu nome aqui ao se envolver. O primeiro passo é aprender como contribuir por meio da nossa documentação em [CONTRIBUTING.md](./CONTRIBUTING.md). + + +| Nome | Função | Github | Email | GPG Fingerprint | +| ----------------- | ------------------- | ------------------------------------------------- | ------------------------------------- | -------------------------------------------------- | +| Christopher Allen | Autor Líder | [@ChristopherA](https://github.com/ChristopherA) | \ | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | +| Shannon Appelcline | Autor Líder | [@shannona](https://github.com/shannona) | \ | 7EC6 B928 606F 27AD | + + +Contribuições adicionais estão listadas abaixo: + +| Função | Nomes | +| ------------------- | ---------------------------------------- | +| ***Contribuidores:*** | [gg2001](https://github.com/gg2001) (seções Go, Node.js), [gorazdko](https://github.com/gorazdko) (seção Rust), [Javier Vargas](https://github.com/javiervargas) (seções C, Java, Lightning, Tor), [jodobear](https://github.com/jodobear) (Apêndice: Compilando Bitcoin, seção Python) | +| ***Revisores:*** | Glen Willem [@gwillem](https://github.com/gwillem) | +| ***Patrocinadores:*** | Blockstream Corporation | + + +## Revelação Responsável + +Nós queremos manter todo o nosso software seguro para todos. Se você descobriu uma vulnerabilidade de segurança, nós agradeceríamos a sua ajuda em nos revelá-la de forma responsável. Infelizmente, nós não conseguimos oferecer programas de recompensa (bug bounty) no momento. + +Nós pedimos que você seja honesto e que, ao melhor de sua capacidade, não vaze informações ou prejudique qualquer usuário, seus dados, ou a comunidade de desenvolvedores. Por favor nos dê uma quantidade de tempo razoável para consertar o problema antes de publicá-lo. Não defraude nossos usuários ou nós mesmos no processo de descoberta. Nós prometemos não entrar com um processo contra pesquisadores que apontem um problema, dado que dêem o seu melhor para seguir estas diretrizes. + +### Reportando uma Vulnerabilidade + +Por favor reporte suspeitas de vulnerabilidades de segurança em um email privado para ChristopherA@BlockchainCommons.com (não utilize esse email para suporte). Por favor NÃO crie issues públicos para suspeitas de vulnerabilidades de segurança. + +As seguintes chaves podem ser utilizadas para comunicar informação confidencial para desenvolvedores: + +| Nome | Fingerprint | +| ----------------- | -------------------------------------------------- | +| Christopher Allen | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | + +Você pode importar uma chave rodando o seguinte comando com a fingerprint daquele indivíduo: `gpg --recv-keys ""` Se certifique de colocar o fingerprint entre aspas caso o mesmo contenha espaços. \ No newline at end of file From 7a791e5e62e8e9daba297cd0b95859b165654ee6 Mon Sep 17 00:00:00 2001 From: Luke Pavksy <85752004+lukedevj@users.noreply.github.com> Date: Tue, 29 Jun 2021 15:27:10 -0300 Subject: [PATCH 015/155] README.md reviewed --- pt/README.md | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 224 insertions(+), 1 deletion(-) diff --git a/pt/README.md b/pt/README.md index ec090a7..2d23cdb 100644 --- a/pt/README.md +++ b/pt/README.md @@ -1 +1,224 @@ -_directory for the Portuguese translation._ +# Aprendendo Bitcoin pela Linha de Comando 2.0.1 +### _por Christopher Allen e Shannon Appelcline_ + +![](https://www.blockchaincommons.com/images/projects/lbtc-screen.png) + +"Aprendendo Bitcoin pela Linha de Comando", esta é a versão em português de [Learning Bitcoin from the Command Line](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line), um tutorial para trabalhar com Bitcoin (e Lightning) que ensina a interação direta com os servidores da maneira mais robusta e segura, para começar a trabalhar com criptomoedas. + +> NOTA: Este é um rascunho em progresso, para que eu possa receber algum feedback de revisores iniciais. Ainda não está pronto para uso. + +_Este tutorial assume que você tenha um mínimo de background em como utilizar a linha de comando. Caso contrário, a vários tutoriais que estão disponíveis na internet, e eu possui um curso para usuários de Mac em: https://github.com/ChristopherA/intro-mac-command-line._ + +## Traduções + +* [Espanhol](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/spanish-translation/es) - em progresso + +* [Portugues](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/portuguese-translation/pt) - em progresso + +Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuindo](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master#contributing) abaixo. + +## Índice + +### PARTE UM: SE PREPARANDO PARA O BITCOIN + +**Estado**: Finalizado. Atualizado para 0.20. + +* [1.0: Introdução à Programação com Bitcoin Core e Lightning](01_0_Introduction.md) + * [Prefácio: Introduzindo o Bitcoin](01_1_Introducing_Bitcoin.md) +* [2.0: Configurando um Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) + * [2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) + * [2.2: Configurando uma Máquina Bitcoin-Core de Outras Formas](02_2_Setting_Up_Bitcoin_Core_Other.md) + +### PARTE 2: USANDO BITCOIN-CLI + +**Estado:** Finalizado. Atualizado para 0.20. + +* [3.0: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md) + * [3.1: Verificando Sua Configuração do Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) + * [3.2: Conhecendo Sua Configuração do Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) + * [3.3: Configurando Sua Carteira](03_3_Setting_Up_Your_Wallet.md) + * [Prefácio: Usando Variáveis de Linha de Comando](03_3__Interlude_Using_Command-Line_Variables.md) + * [3.4: Recebendo uma Transação](03_4_Receiving_a_Transaction.md) + * [3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md) +* [4.0: Enviando Transações no Bitcoin](04_0_Sending_Bitcoin_Transactions.md) + * [4.1: Enviando Moedas da Maneira Fácil](04_1_Sending_Coins_The_Easy_Way.md) + * [4.2: Criando uma Transação Bruta](04_2_Creating_a_Raw_Transaction.md) + * [Prefácio: Usando JQ](04_2__Interlude_Using_JQ.md) + * [4.3: Criando uma Transação Bruta com Argumentos Nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) + * [4.4: Enviando Moedas com Transações Brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md) + * [Prefácio: Usando Curl](04_4__Interlude_Using_Curl.md) + * [4.5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) + * [4.6: Criando uma Transação SegWit](04_6_Creating_a_Segwit_Transaction.md) +* [5.0: Controlando Transações no Bitcoin](05_0_Controlling_Bitcoin_Transactions.md) + * [5.1 Atentando-se para Transações Presas](05_1_Watching_for_Stuck_Transactions.md) + * [5.2: Re-enviando uma Transação com RBF](05_2_Resending_a_Transaction_with_RBF.md) + * [5.3: Financiando uma Transação com CPFP](05_3_Funding_a_Transaction_with_CPFP.md) +* [6.0: Expandindo Transações no Bitcoin com Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md) + * [6.1: Enviando uma Transação com Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [6.2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [6.3: Enviando & Gastando um Multisig Automatizado](06_3_Sending_an_Automated_Multisig.md) +* [7.0: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md) + * [7.1: Criando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) + * [7.2: Usando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) + * [7.3: Integrando com Carteiras de Hardware](07_3_Integrating_with_Hardware_Wallets.md) +* [8.0: Expandindo Transações no Bitcoin de Outras Maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md) + * [8.1: Enviando uma Transação com um Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) + * [8.2: Enviando uma Transação com Dados](08_2_Sending_a_Transaction_with_Data.md) + +### PARTE 3: PROGRAMANDO NO BITCOIN + +**Estado:** Finalizado. Atualizado para 0.20 e btcdeb. + +* [9.0: Introduzindo Scripts no Bitcoin](09_0_Introducing_Bitcoin_Scripts.md) + * [9.1: Compreendendo a Fundação de Transações](09_1_Understanding_the_Foundation_of_Transactions.md) + * [9.2: Rodando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md) + * [9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md) + * [9.4: Programando um P2PKH](09_4_Scripting_a_P2PKH.md) + * [9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md) +* [10.0: Embutindo Scripts em Transações P2SH no Bitcoin](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md) + * [10.1: Compreendendo a Fundação do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) + * [10.2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md) + * [10.3: Rodando um Script no Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) + * [10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md) + * [10.5: Programando um Script Segwit](10_5_Scripting_a_Segwit_Script.md) + * [10.6: Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md) +* [11.0: Capacitando Timelock com Scripts no Bitcoin](11_0_Empowering_Timelock_with_Bitcoin_Scripts.md) + * [11.1: Compreendendo Opções de Timelock](11_1_Understanding_Timelock_Options.md) + * [11.2: Usando CLTV em Scripts](11_2_Using_CLTV_in_Scripts.md) + * [11.3: Usando CSV em Scripts](11_3_Using_CSV_in_Scripts.md) +* [12.0: Expandindo Scripts no Bitcoin](12_0_Expanding_Bitcoin_Scripts.md) + * [12.1: Usando Condicionais de Script](12_1_Using_Script_Conditionals.md) + * [12.2: Usando Outros Comandos de Script](12_2_Using_Other_Script_Commands.md) +* [13.0: Projetando Scripts Reais no Bitcoin](13_0_Designing_Real_Bitcoin_Scripts.md) + * [13.1: Escrevendo Scripts de Quebra-Cabeças](13_1_Writing_Puzzle_Scripts.md) + * [13.2: Escrevendo Scripts Complexos de Multisig](13_2_Writing_Complex_Multisig_Scripts.md) + * [13.3: Capacitando o Bitcoin com Scripts](13_3_Empowering_Bitcoin_with_Scripts.md) + +### PARTE 4: USANDO TOR + +**Estado:** Finalizado. + +* [14.0: Usando Tor](14_0_Using_Tor.md) + * [14.1: Verificando Sua Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) + * [14.2: Mudando Seus Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) + * [14.3: Adicionando SSH aos Seus Serviços Ocultos](14_3_Adding_SSH_Hidden_Services.md) + +### PARTE 5: PROGRAMANDO COM RPC + +**Estado:** Finalizado. + +* [15.0: Conversando com o Bitcoind com C](15_0_Talking_to_Bitcoind.md) + * [15.1: Acessando o Bitcoind em C com Livrarias RPC](15_1_Accessing_Bitcoind_with_C.md) + * [15.2: Programando o Bitcoind em C com Livrarias RPC](15_2_Programming_Bitcoind_with_C.md) + * [15.3: Recebendo Notificações em C com Livrarias ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) +* [16.0: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md) + * [16.1: Configurando a Libwally](16_1_Setting_Up_Libwally.md) + * [16.2: Usando BIP39 na Libwally](16_2_Using_BIP39_in_Libwally.md) + * [16.3: Usando BIP32 na Libwally](16_3_Using_BIP32_in_Libwally.md) + * [16.4: Usando PSBTs na Libwally](16_4_Using_PSBTs_in_Libwally.md) + * [16.5: Usando Scripts na Libwally](16_5_Using_Scripts_in_Libwally.md) + * [16.6: Usando Outras Funções na Libwally](16_6_Using_Other_Functions_in_Libwally.md) + * [16.7: Integrando Libwally e Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md) +* [17.0: Conversando com o Bitcoind com Outras Linguagens](17_0_Talking_to_Bitcoind_Other.md) + * [17.1: Acessando o Bitcoind com Go](17_1_Accessing_Bitcoind_with_Go.md) + * [17.2: Acessando o Bitcoind com Java](17_2_Accessing_Bitcoind_with_Java.md) + * [17.3: Acessando o Bitcoind com Node JS](17_3_Accessing_Bitcoind_with_NodeJS.md) + * [17.4: Acessando o Bitcoind com Python](17_4_Accessing_Bitcoind_with_Python.md) + * [17.5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md) + * [17.6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md) + +### PARTE 6: USANDO LIGHTNING-CLI + +**Estado:** Finalizado. + +* [18.0: Compreendendo Sua Configuração Lightning](18_0_Understanding_Your_Lightning_Setup.md) + * [18.1: Verificando Sua Configuração c-lightning](18_1_Verifying_Your_Lightning_Setup.md) + * [18.2: Conhecendo Sua Configuração c-lightning](18_2_Knowing_Your_lightning_Setup.md) + * [Prefácio: Acessando um Segundo Node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md) + * [18.3: Criando um Canal Lightning](18_3_Setting_Up_a_Channel.md) +* [19.0: Usando Lightning](19_0_Using_Lightning.md) + * [19.1: Gerando um Pedido de Pagamento](19_1_Generate_a_Payment_Request.md) + * [19.2: Pagando uma Fatura](19_2_Paying_a_Invoice.md) + * [19.3: Fechando um Canal Lighnting]((19_3_Closing_a_Channel.md)) + * [19.4: Expandindo a Rede Lightning](19_4_Lightning_Network_Review.md) + +### APÊNDICES + +**Estado:** Finalizado. + +* [Apêndices](A0_Appendices.md) + * [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md) + * [Apêndice II: Compilando Bitcoin da Fonte](A2_0_Compiling_Bitcoin_from_Source.md) + * [Apêndice III: Usando o Regtest do Bitcoin](A3_0_Using_Bitcoin_Regtest.md) + +## Estado - Beta + +v2.0.1 do **Aprendendo Bitcoin pela Linha de Comando** é uma beta. Pode ainda estar sendo sujeito a revisões ou edições de terceiros, mas já pode ser utilizado para o aprendizado. + +Nós também estamos considerando o que poderíamos incluir em uma [v3.0](TODO-30.md) do curso. Se você gostaria de apoiar um trabalho desse tipo, torne-se um [Patrocinador no GitHub](https://github.com/sponsors/BlockchainCommons) ou nos apoie pelo nosso [Servidor BTCPay](https://btcpay.blockchaincommons.com/), e nos informe que **Aprendendo Bitcoin** foi o motivo. + +## Origem, Autores, Copyright & Licenças + +A não ser que indicado o contrário (ou neste [/README.md](./README.md) ou nos comentários nos cabeçalhos dos aquivos), os conteúdos deste repositório são Copyright © 2020 por Blockchain Commons, LLC, e licenciados sob [CC-BY](./LICENSE-CC-BY-4.0.md). + +## Apoio Financeiro + +*Aprendendo Bitcoin pela Linha de Comando* é um projeto da [Blockchain Commons](https://www.blockchaincommons.com/). Nós somos, com orgulho, uma organização de benefício social sem fins lucrativos comprometida ao desenvolvimento aberto e open source. O nosso trabalho é financiado inteiramente por doações e parcerias colaborativas com pessoas como você. Toda contribuição será gasta na construção de ferramenta abertas, tecnologias e técnicas que sustentam e avançam segurança do blockchain e da internet e promovem uma rede aberta. + +Para apoiar financeiramente o desenvolvimento futuro de `$projectname` e outros projetos, por favor considere se tornar um Patrocinador da Blockchain Commons por meio de patrocínios mensais contínuos como um [Patrocinador no GitHub](https://github.com/sponsors/BlockchainCommons). Você também pode apoiar a Blockchain Commons com bitcoins através do nosso [Servidor BTCPay](https://btcpay.blockchaincommons.com/). + +## Contribuindo + +Nós encorajamos contribuições públicas por meio de issues e pull requests! Por favor revise [CONTRIBUTING.md](./CONTRIBUTING.md) para detalhes sobre o nosso processo de desenvolvimento. Todas as contribuições para este repositório requerem um [Contrato de Licença do Contribuidor](./CLA.md) assinado por GPG. + +Se você gostaria de providenciar uma tradução de Aprendendo Bitcoin para outra língua, por favor veja também [TRANSLATING.md](./TRANSLATING.md). + +### Discussões + +O melhor lugar para conversar sobre a Blockchain Commons e seus projetos é na nossa área de Discussões no GitHub. + +[**Discussões Sobre Blockchain Commons**](https://github.com/BlockchainCommons/Community/discussions). Para desenvolvedores, estagiários a patrocinadores da Blockchain Commons, por favor utilize a área de discussões do [repositório da Comunidade](https://github.com/BlockchainCommons/Community) para falar sobre questões gerais da Blockchain Commons, o programa de estágio ou outros tópicos que não sejam o [Gordian System](https://github.com/BlockchainCommons/Gordian/discussions) ou os [padrões de carteira](https://github.com/BlockchainCommons/AirgappedSigning/discussions), pois cada um destes tem sua área de discussão própria. + +### Outras Questões & Problemas + +Como uma comunidade open-source e de desenvolvimento aberto, a Blockchain Commons não tem os recursos para fornecer apoio direto dos nossos projetos. Por favor considere a área de discussões como um local onde você pode receber respostas a perguntas. Alternativamente, por favor use o campo de [issues](./issues) deste repositório. Infelizmente, não podemos fazer promessas em relação ao tempo de resposta. + +Se a sua empresa requer apoio para usar os nossos projetos, por favor nos contacte diretamente para opcões. Nós podemos ser capazes de te oferecer um contrato para apoio por um de nossos contribuidores, ou poderemos te indicar outra entidade que possa oferecer o apoio contratual que você precisa. + +### Créditos + +As pessoas a seguir contribuíram diretamente para este repositório. Você pode adicionar o seu nome aqui ao se envolver. O primeiro passo é aprender como contribuir por meio da nossa documentação em [CONTRIBUTING.md](./CONTRIBUTING.md). + + +| Nome | Função | Github | Email | GPG Fingerprint | +| ----------------- | ------------------- | ------------------------------------------------- | ------------------------------------- | -------------------------------------------------- | +| Christopher Allen | Autor Líder | [@ChristopherA](https://github.com/ChristopherA) | \ | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | +| Shannon Appelcline | Autor Líder | [@shannona](https://github.com/shannona) | \ | 7EC6 B928 606F 27AD | + + +Contribuições adicionais estão listadas abaixo: + +| Função | Nomes | +| ------------------- | ---------------------------------------- | +| ***Contribuidores:*** | [gg2001](https://github.com/gg2001) (seções Go, Node.js), [gorazdko](https://github.com/gorazdko) (seção Rust), [Javier Vargas](https://github.com/javiervargas) (seções C, Java, Lightning, Tor), [jodobear](https://github.com/jodobear) (Apêndice: Compilando Bitcoin, seção Python) | +| ***Revisores:*** | Glen Willem [@gwillem](https://github.com/gwillem) | +| ***Patrocinadores:*** | Blockstream Corporation | + + +## Revelação Responsável + +Nós queremos manter todo o nosso software seguro para todos. Se você descobriu uma vulnerabilidade de segurança, nós agradeceríamos a sua ajuda em nos revelá-la de forma responsável. Infelizmente, nós não conseguimos oferecer programas de recompensa (bug bounty) no momento. + +Nós pedimos que você seja honesto e que, ao melhor de sua capacidade, não vaze informações ou prejudique qualquer usuário, seus dados, ou a comunidade de desenvolvedores. Por favor nos dê uma quantidade de tempo razoável para consertar o problema antes de publicá-lo. Não defraude nossos usuários ou nós mesmos no processo de descoberta. Nós prometemos não entrar com um processo contra pesquisadores que apontem um problema, dado que dêem o seu melhor para seguir estas diretrizes. + +### Reportando uma Vulnerabilidade + +Por favor reporte suspeitas de vulnerabilidades de segurança em um email privado para ChristopherA@BlockchainCommons.com (não utilize esse email para suporte). Por favor NÃO crie issues públicos para suspeitas de vulnerabilidades de segurança. + +As seguintes chaves podem ser utilizadas para comunicar informação confidencial para desenvolvedores: + +| Nome | Fingerprint | +| ----------------- | -------------------------------------------------- | +| Christopher Allen | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | + +Você pode importar uma chave rodando o seguinte comando com a fingerprint daquele indivíduo: `gpg --recv-keys ""` Se certifique de colocar o fingerprint entre aspas caso o mesmo contenha espaços. \ No newline at end of file From 3fe95b214a4a24b094bca9d0b8b5df3a52e29d5c Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 30 Jun 2021 15:56:21 -0300 Subject: [PATCH 016/155] Review 04_0 --- pt/04_0_Sending_Bitcoin_Transactions.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pt/04_0_Sending_Bitcoin_Transactions.md b/pt/04_0_Sending_Bitcoin_Transactions.md index f906763..1443bd3 100644 --- a/pt/04_0_Sending_Bitcoin_Transactions.md +++ b/pt/04_0_Sending_Bitcoin_Transactions.md @@ -1,14 +1,14 @@ -# Capítulo 4: Enviando transações no Bitcoin +# 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 +## 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. + * Usar aritmética para calcular as taxas. Os objetivos secundários incluem a capacidade de: @@ -20,10 +20,10 @@ Os objetivos secundários incluem a capacidade de: ## 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 + * [Seção 1: Enviando Moedas da Maneira Fácil](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 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 Moedas com Transações Brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md) + * [Seção 5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) + * [Seção 6: Criando uma Transação SegWit](04_6_Creating_a_Segwit_Transaction.md) \ No newline at end of file From 7f643a44784d4db44274169b62775a965b4bd4f9 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 30 Jun 2021 16:20:11 -0300 Subject: [PATCH 017/155] Review 04_1 --- pt/04_1_Sending_Coins_The_Easy_Way.md | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pt/04_1_Sending_Coins_The_Easy_Way.md b/pt/04_1_Sending_Coins_The_Easy_Way.md index 6131040..c99e251 100644 --- a/pt/04_1_Sending_Coins_The_Easy_Way.md +++ b/pt/04_1_Sending_Coins_The_Easy_Way.md @@ -1,16 +1,16 @@ -# 4.1: Enviando bitcoins no modo easy +# 4.1: Enviando Moedas da Maneira Fácil -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. +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 uma possui seus prós e contras. Este primeiro método de envio será o mais simples. -## Definindo sua taxa de transação +## 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)). +> :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. +Ao usar métodos simples e automatizados para criar transações, conforme descrito aqui e na sessão [§4.5: Enviando Moedas com 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. +Podemos ter um controle dessas informações colocando os valores racionais no nosso arquivo ```~/.bitcoin/bitcoin.conf```. Os valores de baixo custo a seguir garantiríam que houvesse uma taxa de transação mínima de 10.000 satoshis por kByte de dados em nossa transação e solicitaríam que as taxas flutuantes calculassem uma boa quantia para colocar a nossa transação nos próximos seis blocos. ``` mintxfee=0.0001 txconfirmtarget=6 @@ -20,7 +20,7 @@ No entanto, como iremos partir do pressuposto que ninguém que esteja fazendo es 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]```. +Devemos inserí-los no arquivo ```~/.bitcoin/bitcoin.conf```, na seção principal, no início do arquivo ou se quisermos ter a certeza que nunca iremos utilizá-lo em outro lugar, podemos colocar na seçã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. @@ -30,13 +30,13 @@ $ bitcoin-cli stop $ bitcoind -daemon ``` -## Obtendo um endereço +## 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. +Precisamos encontrar algum endereço para qual enviar nossas moedas. Normalmente, alguém nos envia um endereço e talvez nos dê uma assinatura para provar que é o proprietário desse endereço. Como alternativa, podemos 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 faucet 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 +## 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: ``` @@ -51,13 +51,13 @@ Precisamos nos certificar de que o endereço digitado é o lugar para onde desej 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. +> ❕ 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 dentre as corretoras mais populares. > :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. +> :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 tivermos 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 +## Examinando Nossa Transação Podemos ver nossa transação usando o ID de transação: ``` @@ -89,14 +89,14 @@ Você pode ver não apenas o valor transferido (0,001 BTC), mas também uma taxa 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 +## Resumo: Enviando Moedas da Maneira Fácil 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. +> :fire: ***Qual é o poder de enviar moedas da maneira fácil?*** +> _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 a maneira fácil é 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 +Vamos continuar "Enviando Transações no Bitcoin" na sessão [§4.2 Criando Uma Transação Bruta](04_2_Creating_a_Raw_Transaction.md). \ No newline at end of file From 36613e34510042b8363c3841b239845521fb64ae Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 30 Jun 2021 16:44:42 -0300 Subject: [PATCH 018/155] Review 04_2 --- pt/04_2_Creating_a_Raw_Transaction.md | 47 +++++++++++++-------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/pt/04_2_Creating_a_Raw_Transaction.md b/pt/04_2_Creating_a_Raw_Transaction.md index 4a5f0b6..64399ff 100644 --- a/pt/04_2_Creating_a_Raw_Transaction.md +++ b/pt/04_2_Creating_a_Raw_Transaction.md @@ -1,18 +1,18 @@ -# 4.2 Criando uma transação bruta +# 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. +Agora estamos prontos para criar transações brutas no Bitcoin. Isso permite que enviemos dinheiro, mas que 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 +## 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. +> :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 conhecido 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 +## 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```: ``` @@ -66,14 +66,13 @@ Quando quisermos gastar um UTXO, não é suficiente apenas saber o id da transa Portanto, o txid+vout=UTXO. Essa será a base de qualquer transação bruta. -## Escrevendo uma transação bruta com uma saída +## 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. +Agora estamos prontos para escrever um exemplo simples de transação bruta que mostra como enviar um UTXO inteiro para outra pessoa. 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. +> :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 tivéssemos cerca de 10 vezes mais. Quase tudo isso foi enviado para os mineradores.) -### Preparando a transação bruta +### 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. @@ -95,23 +94,23 @@ $ echo $utxo_vout $ 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. +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 +### 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. +> :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. +Nesse caso, isso significa que 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. Mas é 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. +> :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 +### 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. @@ -138,7 +137,7 @@ $ echo $rawtxhex 02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f3610100000000ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 ``` -### Verificando a transação bruta +### 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. ``` @@ -184,7 +183,7 @@ $ bitcoin-cli decoderawtransaction $rawtxhex > :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 +### 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. @@ -200,7 +199,7 @@ $ signedtx="02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01 ``` 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 +### 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: ``` @@ -261,14 +260,14 @@ Logo o ```listtransactions``` deve mostrar uma transação confirmada da categor "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. +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 a faria ser colocada em um bloco rapidamente. Parabéns! Estamos um pouco mais pobres agora! -## Resumo do Criando uma transação bruta +## Resumo: 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! +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? +## 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 +Vamos fazer uma pausa do "Enviando Transações no Bitcoin" para lermos o [Prefácio: Usando JQ](04_2__Interlude_Using_JQ.md). \ No newline at end of file From b0e25e7a8e7d8595f5d7def7830935855e0aa6ea Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 30 Jun 2021 17:39:32 -0300 Subject: [PATCH 019/155] Review 04_2__Interlude --- pt/04_2__Interlude_Using_JQ.md | 110 ++++++++++++++++----------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/pt/04_2__Interlude_Using_JQ.md b/pt/04_2__Interlude_Using_JQ.md index 00b46cf..0ec4618 100644 --- a/pt/04_2__Interlude_Using_JQ.md +++ b/pt/04_2__Interlude_Using_JQ.md @@ -1,8 +1,8 @@ -# Prefácio: Usando o JQ +# Prefácio: Usando 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. +A criação de uma transação bruta revelou como resultados mais complexos do ```bitcoin-cli``` não podem ser salvos facilmente em variáveis de linha de comando. A resposta para isso é usar o JQ, que permite filtrar elementos individuais de dados JSON mais complexos. -## Instalando o JQ +## Instalando 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. @@ -11,11 +11,11 @@ Depois de baixar o binário, podemos instalá-lo em nosso sistema. Se estivermos $ 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". +> :book: ***O que é JQ?*** O repositório explica melhor, dizendo "O jq é como o sed para dados JSON - você pode usá-lo para dividir, filtrar, mapear e transformar dados estruturados com a mesma facilidade que o sed, awk, e grep permitem que você brinque com o texto". -## Usando o JQ para acessar um valor do objeto JSON pelo índice +## Usando JQ Para Acessar o Valor de um Objeto JSON Pelo Índice -**Caso de uso:** _Capturando o hex de uma transação bruta assinada._ +**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: ``` @@ -27,14 +27,14 @@ $ bitcoin-cli signrawtransactionwithwallet $rawtxhex ``` 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 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 produzir uma 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: +Com essa ferramenta em mãos, podemos capturar as informações de objetos JSON para variáveis na linha de comando: ``` $ signedtx=$(bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex') $ echo $signedtx @@ -45,13 +45,13 @@ 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 +## Usando JQ Para Acessar Valores Únicos de um Objeto JSON em um Array Pelo Índice -**Caso de uso:** _Capturando o txid e o vout para um UTXO selecionado._ +**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? +Extrair dados de um objeto JSON é fácil, mas e se esse objeto JSON estiver em um array 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. +Ao trabalhar com um array JSON, a primeira coisa que precisamos fazer é informar ao JQ qual índice acessar. Por exemplo, podemos estar olhando nosswas 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]' { @@ -68,12 +68,12 @@ $ bitcoin-cli listunspent | jq -r '.[1]' "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```: +Podemos então capturar um valor individual desse array selecionado (1) usando um pipe _dentro_ dos argumentos JQ; e então (2) solicitando o valor específico posteriormente, como no exemplo anterior. Isso iria capturar o ```txid``` do primeiro objeto JSON no array JSON produzido pelo comando ```listunspent```: ``` $ bitcoin-cli listunspent | jq -r '.[1] | .txid' 91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c ``` -Observe cuidadosamente como os ```''``` circundam toda a expressão JQ _incluindo_ o pipe. +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: ``` @@ -86,20 +86,20 @@ $ echo $newvout ``` 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 +## Usando JQ Para Acessar Valores de Objetos JSON Correspondentes em um Array Por Índices -**Caso de uso:** _Listar o valor de todos os UTXOs._ +**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: +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 +## Usando JQ Para Cálculos Simples Por Índices -**Caso de uso:** _Adicionando o valor de todos os UTXOs não gastos._ +**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```: ``` @@ -109,13 +109,13 @@ $ bitcoin-cli getbalance 0.00032000 ``` -## Usando o JQ para exibir vários valores de um objeto JSON em um array usando vários índice +## Usando JQ Para Exibir Vários Valores de um Objeto JSON em um Array Por Vários Índices -**Caso de uso:** _Listar as informações de uso para todos os UTXOs._ +**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```): +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 @@ -127,7 +127,7 @@ ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36 ``` 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). +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 do novo índice 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: ``` @@ -157,13 +157,13 @@ $ bitcoin-cli listunspent | jq -r '.[] | { tx: .txid, output: .vout, bitcoins: . "bitcoins": 0.00022 } ``` -## Usando o JQ para acessar os objetos JSON usando um valor pesquisado +## Usando JQ Para Acessar Objetos JSON Por Valor Pesquisado -**Caso de uso:** _Pesquisando automaticamente os UTXOs que estão sendo usados em uma transação._ +**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. +As pesquisas JQ até agora têm sido 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 os 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```. +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 seçõ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 { @@ -224,9 +224,9 @@ $ bitcoin-cli decoderawtransaction $rawtxhex } ``` -### Recuperando o(s) valor(es) +### Recuperando 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: +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, então, ao valor .txid deste array. Posteriormente, poderíamos fazer o mesmo com o primeiro array e, em seguida, o mesmo com os dois valores .vout de .vin. Fácil: ``` $ usedtxid1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .txid') $ echo $usedtxid1 @@ -244,7 +244,7 @@ $ echo $usedvout2 ``` 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: +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]} @@ -258,13 +258,13 @@ $ echo ${usedvout[0]} $ 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). +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) +### 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. +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 incluam (```contains```) os txids. _Então_ selecionamos (```select```) as transações entre aquelas que _também_ contêm (```contain```) 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. @@ -293,7 +293,7 @@ $ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[1 "solvable": true } ``` -Ao invés disso, um simples bash usando um loop em ```for``` poderia nos dar _todos_ os nossos UTXOs: +Ao invés disso, um simples bash usando um loop ```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; { @@ -318,13 +318,13 @@ $ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i } ``` -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. +Observe que estamos deixando um pouquinho mais feio nosso array ```${#usedtxid[*]}``` para determinar o tamanho dele e, em seguida, acessamos cada valor no array ```usedtxid``` e cada valor no array ```usedvout``` em paralelo, colocando-os em variáveis mais simples para termos um acesso menos feio. -## Usando o JSON para cálculos simples usando os valores +## Usando JSON Para Cálculos Simples Por Valor -**Caso de uso:** _Calcular automaticamente o valor dos UTXOs usados em uma transação._ +**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. +Agora podemos ir um passo adiante e solicitar o .amount (ou qualquer outro par índice-valor do JSON) dos UTXOs que estamos recuperando. Este exemplo repete o uso dos arrays ```$usedtxid``` e ```$usedvout``` definidos da seguinte forma: @@ -348,13 +348,13 @@ $ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i 1.3 ``` -Perfeito! +Ufa! -## Usando o JQ para cálculos complexos +## Usando JQ Para Cálculos Complexos -**Caso de uso:** _Calcular a taxa de uma transação._ +**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```: +Descobrir a taxa completa de transação neste ponto requer apenas mais um pouco de matemática: basta determinar quanto dinheiro está passando pelo .vout. Este é um uso simples de JQ onde apenas usamos o ```awk``` para somar o ```value``` de todas as informações do ```vout```: ``` $ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}' @@ -362,7 +362,7 @@ $ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk ``` 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```: +Para fazer isso, precisaremos instalar ```bc```: ``` $ sudo apt-get intall bc @@ -379,15 +379,15 @@ $ 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! +E esse também é um bom exemplo de por que precisamos verificar nossas 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). +> :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. +Para mais magia usando o JQ (e se alguma coisa não estiver clara), leia o [Manual JQ](https://stedolan.github.io/jq/manual/) e o [Livro de Receitas do JQ](https://github.com/stedolan/jq/wiki/Cookbook). Estaremos usando o JQ regularmente nos exemplos futuros. -## Fazendo alguns aliases novos +## 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```. +Código em 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. @@ -395,11 +395,11 @@ Sempre que estivermos procurando por uma grande massa de informações em uma sa alias btcunspent="bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }'" ``` -## Executando o script de taxa de transação +## 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```. +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. +> :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: @@ -407,7 +407,7 @@ 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: +Podemos, então, executar o script da seguinte maneira: ``` $ ./txfee-calc.sh $rawtxhex @@ -420,10 +420,10 @@ Também podemos criar um alias: alias btctxfee="~/txfee-calc.sh" ``` -## Resumo do Usando o JQ +## Resumo: Usando 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? +## 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 +Continue "Enviando Transações no 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 From cac5dbc2435959eee629605cb85834474cd30d87 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 30 Jun 2021 17:45:31 -0300 Subject: [PATCH 020/155] Review 04_3 --- ..._a_Raw_Transaction_with_Named_Arguments.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) 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 index 2ff9957..529b821 100644 --- a/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md +++ b/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md @@ -1,10 +1,10 @@ -# 4.3 Criando uma transação bruta com argumentos nomeados +# 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. +À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 +## Criando um Alias de 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: ``` @@ -12,7 +12,7 @@ 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 +## 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. @@ -32,7 +32,7 @@ Com argumentos nomeados, podemos esclarecer o que estamos fazendo, o que também $ bitcoin-cli -named getbalance minconf=1 ``` -## Testando uma transação bruta +## Testando uma Transação Bruta Veja como seriam os comandos para enviar uma transação bruta com argumentos nomeados: ``` @@ -82,16 +82,16 @@ $ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex $ 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. +Pronto! Enviamos outra transação bruta, mas desta vez usando argumentos nomeados para 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. +> :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 estiver 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, este código deve funcionar normalmente. -## Resumo do Criando uma transação bruta com argumentos nomeados +## Resumo: 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. +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._ +_À 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? +## 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 +Continue "Enviando Transações no Bitcoin" na seção [§4.4: Enviando Moedas com Transações Brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md). \ No newline at end of file From eb78a37ffc822865e60b69254e3f869d4bd99f80 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 1 Jul 2021 11:35:29 -0300 Subject: [PATCH 021/155] Review 04_4 --- ..._4_Sending_Coins_with_a_Raw_Transaction.md | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md b/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md index 5a3b40e..d9d8ca9 100644 --- a/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md +++ b/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -1,32 +1,32 @@ -# 4.4: Enviando bitcoins usando transações brutas +# 4.4: Enviando Moedas com 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. +Conforme observado no início deste capítulo, a interface ```bitcoin-cli``` oferece três maneiras principais de enviar moedas. A seçã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 seçã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 JQ e a seçã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 +## Criando um 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? +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 corresponda 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 para a 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: +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ê-lo: ``` $ 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). +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 troco 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. Mas vamos mudar para Bech32 na seçã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 +## Escolhendo 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. +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 +## 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. +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, em 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: +Vamos usar nossos UTXOs de índice 0 e 2: ``` $ bitcoin-cli listunspent [ @@ -75,7 +75,7 @@ $ bitcoin-cli listunspent ``` 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 +### Configurando as Variáveis Já temos as variáveis ​​```$changeaddress``` e ```$recipient``` dos exemplos anteriores: ``` @@ -92,15 +92,15 @@ $ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') $ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') ``` -### Escrevendo a transação +### 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. +Escrever a transação bruta em si é surpreendentemente simples. Tudo o que precisamos fazer é incluir um objeto JSON adicional separado por vírgula no array JSON de entradas e um par de valores-chave adicional separado por vírgula em um objeto JSON de saída. 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_. +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 tivéssemos prestado atenção e definido nosso troco como 0,00009 BTC, essa quantidade de BTC adicional seria enviada 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: ``` @@ -110,7 +110,7 @@ $ ./txfee-calc.sh $rawtxhex2 ### Concluindo -Agora podemos assinar, selar e entregar nossa transação, e ela é sua (e do faucet): +Agora podemos assinar, selar e entregar nossa transação, e ela será sua (e do faucet): ``` $ signedtx2=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex2 | jq -r '.hex') $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx2 @@ -119,7 +119,7 @@ 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. +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 nos seja dado. Mas, em 10 minutos ou menos (provavelmente), teremos o dinheiro restante de volta e totalmente utilizável novamente. Por enquanto, ainda precisamos esperar: ``` @@ -170,18 +170,18 @@ E o troco eventualmente voltará para nós: } ] ``` -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). +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 taxas estão dispostas na transação: [e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d](https://mempool.space/pt/testnet/tx/e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d). -## Resumo do Enviando bitcoins usando transações brutas +## Resumo: Enviando Moedas com 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?*** +> :fire: ***Qual é o poder 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? +## O Que Vem Depois? -Veja uma forma alternativa de inserir comandos no [Prefácio: Usando o JQ] (04_4__Interlude_Using_Curl.md). +Veja uma forma alternativa de inserir comandos no [Prefácio: Usando 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 +Ou, se preferir pular o que é francamente uma digressão, podemos aprender mais uma forma de enviar transações no Bitcoin na seção [§4.5 Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file From 2dcf2b9d60d30262226f829ab2c2aab5485be2f2 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 1 Jul 2021 16:50:03 -0300 Subject: [PATCH 022/155] Review 04_4_Interlude --- pt/04_4__Interlude_Using_Curl.md | 76 ++++++++++++++++---------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/pt/04_4__Interlude_Using_Curl.md b/pt/04_4__Interlude_Using_Curl.md index a6957ac..f987b4a 100644 --- a/pt/04_4__Interlude_Using_Curl.md +++ b/pt/04_4__Interlude_Using_Curl.md @@ -1,17 +1,16 @@ -# Prefácio: Acessando o Bitcoind com Curl +# Prefácio: Usando 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```. +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 seçã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. +O ```curl```, abreviação de "ver URL" ("see URL" em inglês), é uma ferramenta que nos permite acessar URLs diretamente pela 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. +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 +### 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```: ``` @@ -35,13 +34,13 @@ 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```. +E ali está 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 +### 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`. @@ -73,7 +72,7 @@ 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. +> **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: ``` @@ -88,17 +87,17 @@ 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! +> **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 +### 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. +O segundo é o ```params```, que é uma array 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: +Esta é a aparência de alguns arrays de parâmetros: * `[]` — Um array vazio; * `["000b4430a7a2ba60891b01b718747eaf9665cb93fbc0c619c99419b5b5cf3ad2"]` — Um array com dados; @@ -107,7 +106,7 @@ Esta é a aparência de algumas matrizes de 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 +## Obtendo Informação Agora podemos enviar nosso primeiro comando ```curl``` acessando o RPC ```getmininginfo```: ``` @@ -115,10 +114,9 @@ $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc" {"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. +> **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 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```: +O resultado é outro array JSON, que infelizmente é ruim de 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 @@ -137,13 +135,13 @@ $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc" "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. +Você verá um pouco de relatório de conectividade à medida que os dados são baixados, então, quando os dados chegarem ao ```jq```, tudo será corretamente identado. Estaremos omitindo as informações do download nos próximos exemplos. -## Manipulando nossa carteira +## 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 +### Pesquisando Endereços Usando o RPC ```getaddressesbylabel``` para listar todos os nossos endereços atuais: ``` @@ -177,7 +175,7 @@ Este é o nosso primeiro exemplo de um parâmetro real, ```" "```. Este é o par O resultado é uma lista de todos os endereços que foram usados na nossa carteira. Alguns dos quais presumivelmente possuem saldo. -### Pesquisando pelos saldos +### Pesquisando Saldos Use o RPC ```listunspent``` para listar os saldos que temos disponíveis: ``` @@ -214,11 +212,11 @@ $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc" "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! +Esta é quase 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 +### 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```: +Depois de saber onde os saldos estão, a próxima etapa na elaboração de uma transação é obter um endereço de troco. 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 '.' { @@ -236,15 +234,15 @@ 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 +## Criando uma Transação Agora estamos prontos para criar uma transação com o ```curl```. -### Preparando as variáveis +### 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. +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 outra coisa qualquer. -Este exemplo configura nossas variáveis para usar o BTC de 1.2985 em fundos listados na primeira transação não gasta acima: +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') @@ -261,7 +259,7 @@ $ echo $changeaddress n2jf3MzeFpFGa7wq8rXKVnVuv5FoNSJZ1N ``` -### Criando a transação +### 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: ``` @@ -276,18 +274,18 @@ O coração da transação é, obviamente, o array JSON ```params```, que estamo 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. +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. +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 tivéssemos percebido isso obteríamos 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). +> **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: +Depois de verificarmos se as coisas estão funcionando, provavelmente desejaremos 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 +### Assinando e Enviando Assinar e enviar a nossa transação usando ```curl``` é bem simples, basta usar os seguintes comandos do RPC ```signrawtransactionwithwallet``` e ```sendrawtransaction```: @@ -301,14 +299,14 @@ $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc" "id": "curltest" } ``` -## Resumo do Acessando o Bitcoind com Curl +## Resumo: 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. +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```. E é 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. +_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. -## O que vem depois? +## 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). \ No newline at end of file +Aprenda mais uma maneira de enviar transações no Bitcoin com [§4.5 Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file From 676f753b68002219f43d1875876e4d387d2ed78f Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 1 Jul 2021 17:00:12 -0300 Subject: [PATCH 023/155] Review 04_5 --- ...g_Coins_with_Automated_Raw_Transactions.md | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md b/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md index 91926ae..6308054 100644 --- a/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md +++ b/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md @@ -1,25 +1,25 @@ -# 4.5: Enviando bitcoins usando transações brutas automatizadas +# 4.5: Enviando Moedas com 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. +Este capítulo apresenta três maneiras de enviar fundos por meio da interface cli do Bitcoin. A seção [§4.1](04_1_Sending_Coins_The_Easy_Way.md) descreveu como fazer isso com um comando simples e a seçã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 +## 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. +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. +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 seção [§4.1: Enviando Moedas da Maneira Fácil](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: +Para manter o tutorial em movimento (e para movimentarmos nosso dinheiro rapidamente), sugerimos o seguinte: ``` mintxfee=0.001 txconfirmtarget=1 ``` -## Criando uma transação bruta +## 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. ``` @@ -27,7 +27,7 @@ $ recipient=n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi $ unfinishedtx=$(bitcoin-cli -named createrawtransaction inputs='''[]''' outputs='''{ "'$recipient'": 0.0002 }''') ``` -## Financiando nossa transação bruta +## Financiando Nossa Transação Bruta Dizemos ao ```bitcoin-cli``` para financiar essa transação básica: ``` @@ -42,11 +42,11 @@ Isso fornece muitas informações úteis, mas uma vez que tenhamos certeza de co ``` $ rawtxhex3=$(bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx | jq -r '.hex') ``` -## Verificando nossa transação financiada +## 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: +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 troco: ``` $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 { @@ -98,14 +98,14 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 ] } ``` -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á. +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 seçã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): +Embora tenhamos visto a taxa na saída de ```fundrawtransaction```, ela não pode ser visível aqui. No entanto, podemos verificar isso com o script JQ ```txfee-calc.sh``` criado na seção [Prefácio: Usando 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: +Finalmente, podemos usar o ```getaddressinfo``` para ver se o endereço de troco gerado realmente nos pertence: ``` $ bitcoin-cli -named getaddressinfo address=tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r { @@ -129,9 +129,9 @@ $ bitcoin-cli -named getaddressinfo address=tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2z ] } ``` -Observe os conteúdo do `ismine`. +Observe o conteúdo do `ismine`. -## Enviando a transação financiada +## Enviando a Transação Financiada Neste ponto, podemos assinar e enviar a transação normalmente. ``` @@ -158,14 +158,14 @@ $ bitcoin-cli listunspent ] ``` -## Resumo do Enviando bitcoins usando transações brutas automatizadas +## Resumo: Enviando Moedas com 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. +> _As vantagens._ Proporciona um bom meio termo. 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 mistura. 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? +## 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 +Vamos concluir o capítulo "Enviando Transações no Bitcoin" com a seção [§4.6: Criando uma Transação SegWit](04_6_Creating_a_Segwit_Transaction.md). \ No newline at end of file From 30112af2ea20d9dba4bdccf64aca4ecf51e2c9f3 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 1 Jul 2021 17:20:22 -0300 Subject: [PATCH 024/155] Review 04_6 --- pt/04_6_Creating_a_Segwit_Transaction.md | 56 ++++++++++++------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/pt/04_6_Creating_a_Segwit_Transaction.md b/pt/04_6_Creating_a_Segwit_Transaction.md index 1064409..f037984 100644 --- a/pt/04_6_Creating_a_Segwit_Transaction.md +++ b/pt/04_6_Creating_a_Segwit_Transaction.md @@ -1,22 +1,22 @@ -# 4.6: Criando uma transação do tipo SegWit +# 4.6: Criando uma Transação 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. +Era uma vez, nos céus do Bitcoin, uma guerra entre os tamanhos de blocos. 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. 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 nodes 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. +A sacada? O SegWit usa endereços diferentes, alguns dos quais são compatíveis com nodes mais antigos, ao passo que 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). +> 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 ```legacy``` ou P2SH-SegWit para fazer a transação. (Muitos sites, principalmente as corretoras, 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 +## 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). +Em transações clássicas, as informações de assinatura (witness) eram armazenadas no meio da transação, enquanto nas transações SegWit, elas ficam 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 clássicos, 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. +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. A este ponto, os detalhes não são mais relevantes do que os detalhes de como grande parte do Bitcoin funciona. -## Criando um endereço SegWit +## Criando um Endereço SegWit Criamos um endereço SegWit da mesma maneira que qualquer outro endereço, com os comandos ```getnewaddress``` e ```getrawchangeaddress```. @@ -27,14 +27,14 @@ $ bitcoin-cli -named getnewaddress address_type=p2sh-segwit ``` Se conseguirmos ver um endereço com o prefixo "2" significa que fizemos tudo certo. -> :link: **TESTNET vs MAINNET:** "3" no caso da mainnet. +> :link: **TESTNET vs MAINNET:** "3" para a 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: +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 para usar o sinalizador ```legacy``` lá também: ``` $ bitcoin-cli getrawchangeaddress tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff @@ -42,9 +42,9 @@ 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. +> :link: **TESTNET vs MAINNET:** "bc1" para a 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: +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 [ @@ -109,11 +109,11 @@ $ bitcoin-cli listaddressgroupings ] ``` -## Enviando uma transação SegWit no modo easy +## Enviando uma Transação SegWit da Maneira Fácil -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). +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 legacy 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: +Aqui está um exemplo de um envio para um endereço SegWit, da maneira fácil: ``` $ bitcoin-cli sendtoaddress tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005 854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42 @@ -202,9 +202,9 @@ $ bitcoin-cli gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c10 } } ``` -Na verdade, ambos os ```vouts``` usam endereços Bech32: O nosso destinatário e o endereço de troco gerado automaticamente. +Na verdade, ambos ```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: +Mas quando retrocedemos nosso ```vin```, descobrimos que veio de um endereço legacy. Porque isso não importa: ``` $ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7" { @@ -233,7 +233,7 @@ $ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f743 } ``` -## Enviando uma transação SegWit o modo hard +## Enviando uma Transação SegWit da Maneira Difícil 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: ``` @@ -269,20 +269,20 @@ e02568b706b21bcb56fcf9c4bb7ba63fdbdec1cf2866168c4f50bc0ad693f26c ``` Tudo funciona exatamente da mesma forma que outros tipos de transações! -### Reconhecendo o novo descritor +### 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" `. +Se olharmos o campo ```desc```, notaremos que o endereço SegWit tem um descritor de estilo diferente daqueles encontrados na seção [§3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md). Um descritor legacy descrito nessa seçã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. +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. Isto destaca o :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 em seu tipo. -## Resumo do Criando uma transação do tipo SegWit +## Resumo: Criando uma Transação 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. +Realmente não há complexidade para criar transações SegWit. Internamente, elas são estruturadas de forma diferente das transações legacy, mas na linha de comando não existe diferença: apenas 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. +> :fire: ***Qual é o poder de enviar transações com SegWit?*** +> _As vantagens._ As transações SegWit são menores e, portanto, serão mais baratas de serem enviadas do que as transações legacy 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 perderem seus bitcoins. +> _As desvantagens._ Os endereços SegWit não tem suporte em nodes Bitcoin obsoletos. Em particular, as pessoas podem não conseguir enviar para o nosso endereço Bech32. -## O que vem depois? +## 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 +Vamos avançar mais um pouco no "bitcoin-cli" com o [Capítulo 5: Controlando Transações no Bitcoin](05_0_Controlling_Bitcoin_Transactions.md). \ No newline at end of file From 463e1570eadbe80536fc74059ec26ed153bc73bb Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Fri, 2 Jul 2021 09:42:44 -0300 Subject: [PATCH 025/155] Finished translation of chapter 06 --- ...xpanding_Bitcoin_Transactions_Multisigs.md | 19 ++ ...6_1_Sending_a_Transaction_to_a_Multisig.md | 206 ++++++++++++++++ ..._2_Spending_a_Transaction_to_a_Multisig.md | 229 ++++++++++++++++++ pt/06_3_Sending_an_Automated_Multisig.md | 120 +++++++++ 4 files changed, 574 insertions(+) create mode 100644 pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md create mode 100644 pt/06_1_Sending_a_Transaction_to_a_Multisig.md create mode 100644 pt/06_2_Spending_a_Transaction_to_a_Multisig.md create mode 100644 pt/06_3_Sending_an_Automated_Multisig.md diff --git a/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md b/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md new file mode 100644 index 0000000..66cea7e --- /dev/null +++ b/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md @@ -0,0 +1,19 @@ +# Capítulo 6: Expandindo as transações de Bitcoin com multisigs + +Transações básicas de Bitcoin: (1) Envia fundos; (2) Para um único destinatário P2PKH ou SegWit; (3) A partir de uma única máquina; (4) Imediatamente. No entanto, todas essas quatro partes desta definição podem ser expandidas usando transações Bitcoin mais complexas. Este primeiro capítulo sobre "Expansão" mostra como variar os pontos (2) e (3), enviando saldos para um endereço que representa vários destinatários (ou, pelo menos, vários assinantes). + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + * Criar endereços de Bitcoin multi assinados (multisigs) usando os fundamentos do Bitcoin; + * Crie endereços de Bitcoin com várias assinaturas (multisigs) usando mecanismos fáceis. + +Os objetivos secundários do capítulo incluem a capacidade de: + * Entender como gastar fundos enviados em uma transação multisig; + * Planejar para obter o máximo do poder das multisigs. + +## Tabela de conteúdo + + * [Seção 1: Enviando uma Transação Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [Seção 2: Gastando uma Transação Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [Seção 3: Enviando e Gastando uma Transação Multisig de Maneira Automatizada](06_3_Sending_an_Automated_Multisig.md) \ No newline at end of file diff --git a/pt/06_1_Sending_a_Transaction_to_a_Multisig.md b/pt/06_1_Sending_a_Transaction_to_a_Multisig.md new file mode 100644 index 0000000..f54d828 --- /dev/null +++ b/pt/06_1_Sending_a_Transaction_to_a_Multisig.md @@ -0,0 +1,206 @@ +# 6.1: Enviando uma Transação Multsig + +A primeira maneira de variar a forma como enviamos uma transação básica é usando uma multisig. Isso nos dá a capacidade de exigir que várias pessoas (ou, ao menos, várias chaves privadas) autorizem o uso dos fundos. + +## Entendendo como Funcionam as Multisigs + +Em uma transação P2PKH ou SegWit padrão, os bitcoins são enviados para um endereço baseado na chave pública, o que significa que a chave privada relacionada é necessária para desbloquear a transação, resolvendo o quebra-cabeça criptográfico e permitindo que reutilizemos o saldo. Mas e se pudéssemos bloquear uma transação com _múltiplas_ chaves privadas? Isso efetivamente permitiria que os fundos fossem enviados a um grupo de pessoas, onde todas teriam que concordar em reutilizar o saldo. + +> :book: ***O que é uma multisignature ou multisig?*** Uma _multisignature_ é uma metodologia que permite que mais de uma pessoa crie uma assinatura digital em conjunto. É uma técnica para o uso criptográfico de chaves que vai muito além do Bitcoin. + +Tecnicamente, um quebra-cabeça criptográfico com várias assinaturas é criado pelo Bitcoin usando o comando OP_CHECKMULTISIG e, normalmente, é encapsulado em um endereço P2SH. A seção [§10.4: Fazendo um scripto multisig](10_4_Scripting_a_Multisig.md) irá detalhar como isso funciona com mais precisão. Por enquanto, tudo que precisamos saber é que podemos usar o comando ```bitcoin-cli``` para criar endereços multi assinados. Os fundos podem ser enviados para esses endereços como qualquer endereço P2PKH ou Segwit normal, mas várias chaves privadas serão necessárias para que o saldo seja enviado. + +> :book: ***O que é uma transação multisig?*** Uma transação com várias assinaturas é uma transação Bitcoin enviada para um endereço com várias assinaturas, exigindo assim que as pessoas de um grupo com várias assinaturas precisem assinar a transação para poder ter acesso ao saldo. + +As multisigs simples exigem que todos no grupo assinem o UTXO quando estiver gasto. No entanto, há mais complexidade possível. As assinaturas múltiplas são geralmente descritas como sendo "M de N". Isso significa que a transação está presa com um grupo de chaves "N", mas apenas "M" delas são necessárias para desbloquear a transação. + +> :book: ***O que é uma multisg M-de-N? *** Em uma multisig, as assinaturas "M" de um grupo de "N" são necessárias para formar a assinatura, onde "M ≤ N". + +## Criando um Endereço Multisig + +Para bloquear um UTXO com várias chaves privadas, devemos primeiro criar um endereço com várias assinaturas. Os exemplos usados ​​aqui mostram a criação (e uso) de uma multisig 2 de 2 (normalmente é assim que falamos quando nos referimos a um endereço multisg, descrevemos a quantidade de chaves e a quantidade necessária para desbloquear o saldo). + +### Criando os Endereços + +Para criar um endereço multisig, devemos primeiro preparar os endereços que o multisig irá combinar. A prática recomendada sugere que sempre criemos novos endereços. Isso significa que cada participante irá executar o comando ```getnewaddress``` em sua própria máquina: +``` +machine1$ address1=$(bitcoin-cli getnewaddress) +``` +E: +``` +machine2$ address2=$(bitcoin-cli getnewaddress) +``` +Posteriormente, um dos destinatários (ou talvez algum terceiro) precisará combinar ambos endereços. + +#### Coletando as Chaves Públicas + +No entanto, não podemos criar um multisig com os endereços, pois esses são os hashes das chaves públicas: Ao invés disso, precisamos das próprias chaves públicas. + +Esta informação está disponível facilmente com o comando ```getaddressinfo```. + +Na máquina remota, que assumimos aqui é ```machine2```, podemos obter as informações em uma lista. +``` +machine2$ bitcoin-cli -named getaddressinfo address=$address2 +{ + "address": "tb1qr2tkjh8rs9xn5xaktf5phct0wxqufplawrfd9q", + "scriptPubKey": "00141a97695ce3814d3a1bb65a681be16f7181c487fd", + "ismine": true, + "solvable": true, + "desc": "wpkh([fe6f2292/0'/0'/1']02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3)#zc64l8dw", + "iswatchonly": false, + "isscript": false, + "iswitness": true, + "witness_version": 0, + "witness_program": "1a97695ce3814d3a1bb65a681be16f7181c487fd", + "pubkey": "02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3", + "ischange": false, + "timestamp": 1592957904, + "hdkeypath": "m/0'/0'/1'", + "hdseedid": "1dc70547f2b80e9bb5fde5f34fb3d85f8d8d1dab", + "hdmasterfingerprint": "fe6f2292", + "labels": [ + "" + ] +} +``` +O endereço ```pubkey``` (` 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3`) é o que precisamos. Vamos copiá-lo para nossa máquina local por qualquer meio que acharmos mais eficiente e _que seja menos sujeito a erros_. + +Este processo precisa ser realizado para _cada_ endereço de uma máquina diferente daquela onde o multisig está sendo construída. Obviamente, se algum terceiro estiver criando o endereço, precisaremos fazer isso para cada endereço. + +> :warning: **Atenção:** O uso de hashes de chave pública pelo Bitcoin como endereços, ao invés de chaves públicas, na verdade representa uma camada adicional de segurança. Porém, o envio de uma chave pública aumenta ligeiramente a vulnerabilidade do endereço associado, para alguma possibilidade no futuro distante de um comprometimento devido a curva elíptica. Não devemos nos preocupar em termos que enviar ocasionalmente uma chave pública para um uso como esse, mas devemos estar cientes de que os hashes de chave pública representam segurança e, portanto, as chaves públicas reais não devem ser enviadas de qualquer jeito para qualquer pessoa. + +Se um dos endereços foi criado em nossa máquina local, que assumimos aqui que seja ```machine1```, podemos simplesmente colocar o endereço ```pubkey``` em uma nova variável. +``` +machine1$ pubkey1=$(bitcoin-cli -named getaddressinfo address=$address1 | jq -r '.pubkey') +``` + +### Criando o Endereço + +Uma multisig agora pode ser criada com o comando ```createmultisig```: +``` +machine1$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3"]''' +{ + "address": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr", + "redeemScript": "522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae", + "descriptor": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y" +} +``` +> :warning: **AVISO DE VERSÃO:** Algumas versões do ```createmultisig``` permitem a entrada de chaves públicas ou endereços, algumas requerem apenas as chaves públicas. Atualmente, ambas parecem funcionar. + +Ao criar o endereço multisig, listamos quantas assinaturas são necessárias com o argumento ```nrequired``` (que é o "M" quando falamos _uma multisig "M de N"_), então listamos o conjunto total de assinaturas possíveis com a argumento ```keys``` (que é o "N"). Observe que as entradas ```keys``` provavelmente vieram de lugares diferentes. Nesse caso, incluímos ```$pubkey1``` da máquina local e ```02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3``` de uma máquina remota. + +> :information_source: **NOTA - M de N vs N de N:** Este exemplo mostra a criação de um multisig simples 2 de 2 . Se quisermos criar uma assinatura M de N onde "M :link: **TESTNET vs MAINNET:** Na Testenet, o prefixo para endereços P2SH é ```2```, enquanto na Mainnet é ```3```. + +O _redeemScript_ é o que precisaremos para resgatar os fundos (junto com as chaves privadas de "M" dos "N" endereços). Este script é outro recurso especial dos endereços P2SH e será explicado com mais detalhes na seção [§8.1: Construindo um Script Bitcoin com P2SH](08_1_Building_a_Bitcoin_Script_with_P2SH.md). Por enquanto, precisamos apenas saber que alguns dados são necessários para podemos gastar nosso dinheiro. + +O _descritor_ é a descrição padronizada para um endereço que encontramos na seção [§3.5: Compreendendo o descriptor](03_5_Understanding_the_Descriptor.md). Ele fornece uma maneira de importar esse endereço de volta para a outra máquina, usando o RPC ```importmulti```. + +> :book: ***O que é um endereço P2SH?*** O P2SH significa Pay-To-Script-Hash. É um tipo de destinatário diferente de um endereço P2PKH padrão ou mesmo de um Bech32, usado para fundos cujo resgate é baseado em scripts de Bitcoin mais complexos. O ```bitcoin-cli``` usa o encapsulamento P2SH para ajudar a padronizar e simplificar os multisigs como "multisigs P2SH ", assim como P2SH-SegWit estava usando o P2SH para padronizar os endereços SegWit e torná-los totalmente compatíveis com as versões legadas. + +> :warning: **Atenção:** endereços P2SH multisig, como os criados pelo ```bitcoin-cli```, têm um limite para "M" e "N" nos multisigs com base no tamanho máximo do script de resgate, que atualmente é de 520 bytes. Praticamente, não vamos chegar a isso, a menos que estejamos nos excedendo em algo. + +### Salvando Nosso Trabalho + +Aqui está uma informação importante: Nada sobre nosso multisig é salvo em nossa carteira usando essas técnicas básicas. Para resgatar o saldo enviado para este endereço multisig no futuro, precisaremos reter duas informações cruciais: + + * Uma lista dos endereços Bitcoin usados ​​no multisig, e; + * A saída ```redeemScript``` criada pelo comando ```createmultsig```. + +Tecnicamente, o ```redeemScript``` pode ser recriado executando novamente o ```createmultisig``` com a lista completa de chaves públicas _na mesma ordem_ e com a contagem correta de M e de N. Mas, é melhor agarrar-se a ela e evitar qualquer tipo de estresse futuro. + +### Observando a Ordem + +Aqui está mais uma coisa que devemos tomar muito cuidado: A _ordem é muito importante_. A ordem das chaves usadas para criar um multisig cria um hash único, ou seja, se colocarmos as chaves em uma ordem diferente, elas irão produzir um endereço diferente, conforme mostrado abaixo: +``` +$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]''' +{ + "address": "2NFBQvz57UzKWDr2Vx5D667epVZifjGixkm", + "redeemScript": "52210342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da0321039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b352ae", + "descriptor": "sh(multi(2,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3))#8l6hvjsk" +} +standup@btctest20:~$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey2'","'$pubkey1'"]''' +{ + "address": "2N5bC4Yc5Pqept1y8nPRqvWmFSejkVeRb1k", + "redeemScript": "5221039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3210342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da0352ae", + "descriptor": "sh(multi(2,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03))#audl88kg" +} +``` +Mais notavelmente, cada ordem cria um _redeemScript_ diferente. Isso significa que se usamos essas técnicas básicas e não conseguimos salvar o redemScript conforme as instruções, teremos que percorrer um número cada vez maior de variações para encontrar aquela correta quando tentarmos gastar os fundos! + +O [BIP67](https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki) sugere uma maneira de ordenar lexicograficamente as chaves, de modo que sempre gerem as mesmas multisigs. A ColdCard e a Electrum estão entre as carteiras que já possuem suporte a isso. Claro, isso pode causar problemas por si só se não soubermos se um endereço multisig foi criado com chaves classificadas ou não classificadas. Mais uma vez, os [descritores](03_5_Understanding_the_Descriptor.md) vem ao nosso resgate. Se uma multisig não for classificada, ele será construído com a função ```multi``` e se for classificada, será construída com a função ```sortedmulti```. + +Se olharmos o ```desc``` da multisig que criamos acima, veremos que o Bitcoin Core atualmente não classifica os multisigs: +``` + "descriptor": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y" +``` +Porém, se ele importa um endereço do tipo ```sortedmulti```, ele fará o processo correto, que é o ponto principal dos descritores! + +> :warning: **AVISO DE VERSÃO:** O Bitcoin Core só entende a função do descritor ```sortedmulti``` após a versão 0.20.0. Podemos tentar acessar o descritor em uma versão anterior do Bitcoin Core e obteremos um erro como ```A function is needed within P2WSH```. + +## Enviando Fundos para um Endereço Multisig + +Se tivermos uma multisig em um formato P2SH conveniente, como o gerado pelo ```bitcoin-cli```, podemos enviar como um endereço normal. +``` +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ recipient="2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.000065}''') +$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex +{ + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "hash": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "version": 2, + "size": 83, + "vsize": 83, + "weight": 332, + "locktime": 0, + "vin": [ + { + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00006500, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", + "hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + ] + } + } + ] +} + +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 +``` +Como podemos ver, não houve nada de incomum na criação da transação e ela parece normal, embora com um endereço com um prefixo diferente do normal (```2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr```). Sem surpresa, como também não vimos diferença quando enviamos para endereços Bech32 pela primeira vez na seção [§4.6](04_6_Creating_a_Segwit_Transaction.md). + +## Resumo: Enviando uma Transação Multsig + +Os endereços do Multisig trancam os fundos usando várias chaves privadas, possivelmente exigindo todas essas chaves privadas para resgate e, possivelmente, exigindo apenas algumas do conjunto. Eles são fáceis de serem criadas com o ```bitcoin-cli``` e são simples para serem enviadas. Essa facilidade se deve em grande parte ao uso invisível de endereços P2SH (Pay-To-Script-Hash), um tópico extenso que já falamos duas vezes, com endereços P2SH-SegWit e agora com as multisig, e um outro que receberá mais atenção no futuro. + +> :fire: ***Qual é o poder das multisig?*** As multisig permitem a modelagem de uma variedade de arranjos financeiros, como corporações, parcerias, comitês e outros grupos. Uma multisig 1 de 2 pode ser a conta bancária conjunta de um casal, enquanto uma multisig 2 de 2 pode ser usado para grandes despesas por uma parceria de responsabilidade limitada. As multisigs também constituem uma das bases dos Smart Contracts. Por exemplo, um negócio imobiliário pode ser fechado com um multisig 2 de 3, onde as assinaturas são enviadas pelo comprador, pelo vendedor e por um agente de custódia. Depois que o agente de custódia concorda que todas as condições foram atendidas, ele libera os fundos para o vendedor, ou, alternativamente, o comprador e o vendedor podem liberar os fundos em conjunto. + +## O Que Vem Depois? + +Vamos continuar "Expandindo as transações de Bitcoin com multisigs" na seção [§6.2: Gastando uma transação Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md). \ No newline at end of file diff --git a/pt/06_2_Spending_a_Transaction_to_a_Multisig.md b/pt/06_2_Spending_a_Transaction_to_a_Multisig.md new file mode 100644 index 0000000..f916780 --- /dev/null +++ b/pt/06_2_Spending_a_Transaction_to_a_Multisig.md @@ -0,0 +1,229 @@ +# 6.2: Gastando uma Transação Multsig + +A maneira clássica e complexa de gastar fundos enviados para um endereço com várias assinaturas usando o ```bitcoin-cli``` requer que suemos bastante a camisa. + +## Encontrando os fundos + +Para começar, precisamos encontrar nossos fundos. Nosso computador não sabe procurá-los, porque não estão associados a nenhum endereço da nossa carteira. Podemos alertar o ```bitcoind``` para fazer isso usando o comando ```importaddress```: +``` +$ bitcoin-cli -named importaddress address=2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz +``` +Se temos um node prunado (e provavelmente temos), ao invés desse jeito, precisaremos dizer não para verificar novamente: +``` +$ bitcoin-cli -named importaddress address=2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz rescan="false" +``` +Se preferirmos, podemos importar o endereço usando nosso descritor (e esta é geralmente a melhor resposta, porque é mais padronizada): +``` +$ bitcoin-cli importmulti '[{"desc": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y", "timestamp": "now", "watchonly": true}]' +[ + { + "success": true + } +] +``` +Depois, os fundos devem aparecer quando usarmos o comando ```listunspent```, porém, ainda não podemos gastar facilmente. Na verdade, nossa carteira pode alegar que não podemos gastá-los de forma alguma! + +Se por algum motivo não puder incorporar o endereço da nossa carteira, podemos usar o comando ```gettransaction``` para obtermos mais informações (ou olharmos em um block explorer). +``` +$ bitcoin-cli -named gettransaction txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 verbose=true +{ + "amount": -0.00006500, + "fee": -0.00001000, + "confirmations": 3, + "blockhash": "0000000000000165b5f602920088a7e36b11214161d6aaebf5229e3ed4f10adc", + "blockheight": 1773282, + "blockindex": 9, + "blocktime": 1592959320, + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "walletconflicts": [ + ], + "time": 1592958753, + "timereceived": 1592958753, + "bip125-replaceable": "no", + "details": [ + { + "address": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr", + "category": "send", + "amount": -0.00006500, + "vout": 0, + "fee": -0.00001000, + "abandoned": false + } + ], + "hex": "020000000001011b95a6055174ec64b82ef05b6aefc38f34d0e57197e40281ecd8287b4260dec60000000000ffffffff01641900000000000017a914a5d106eb8ee51b23cf60d8bd98bc285695f233f38702473044022070275f81ac4129e1d167ef7e700739f2899ea4c7f1adef3a4da29436f14fb97e02207310d4ec449eba49f0fa404ae45b9c82431d883490c7a0ed882ad0b5d7a623d0012102883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb00000000", + "decoded": { + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "hash": "bdf4e3bc5d354a5dfa5528f172480976321d989d7e5806ac14f1fe9b0b1c093a", + "version": 2, + "size": 192, + "vsize": 111, + "weight": 441, + "locktime": 0, + "vin": [ + { + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "txinwitness": [ + "3044022070275f81ac4129e1d167ef7e700739f2899ea4c7f1adef3a4da29436f14fb97e02207310d4ec449eba49f0fa404ae45b9c82431d883490c7a0ed882ad0b5d7a623d001", + "02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb" + ], + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00006500, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", + "hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + ] + } + } + ] + } +} +``` + +## Configurando as nossas variáveis + +Quando estivermos prontos para gastar os fundos recebidos por um endereço multisig, precisaremos coletar _muitos_ dados: Muito mais do que precisamos quando fazemos uma transação usando um UTXO de um P2PKH normal ou SegWit. Isso ocorre em parte porque as informações sobre o endereço multisig não estão em nossa posse e em parte porque estamos gastando dinheiro que foi enviado para um endereço P2SH (Pay-To-Script-Hash) e isso é muito mais exigente. + +No total, precisaremos coletar três coisas: Informações estendidas sobre o UTXO; O redemScript e; Todas as chaves privadas envolvidas. Obviamente, também iremos precisar de um novo endereço de destinatário. As chaves privadas precisam aguardar a etapa de assinatura, mas tudo pode ser feito agora. + +### Acessando as informações do UTXO + +Para começar, vamos pegar o ```txid``` e o ```vout``` para a transação que desejamos gastar, como de costume. Nesse caso, os dados foram recuperados das informações ```gettransaction``` acima: +``` +$ utxo_txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 +$ utxo_vout=0 +``` +No entanto, precisamos também acessar um terceiro bit de informação sobre o UTXO, nosso ```scriptPubKey```/```hex```, que é o script que travamos a transação. Novamente, podemos fazer isso observando os detalhes da transação: +``` +$ utxo_spk=a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387 +``` + +### Gravando o script de resgate + +Felizmente, salvamos nosso ```redeemScript```. Agora devemos registrá-lo em uma variável. + +O valor foi extraído da criação de endereço na seção anterior. +``` +redeem_script="522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae" +``` +### Decidindo o destinatário + +Vamos apenas enviar o dinheiro de volta para nós mesmos. Isso é útil porque libera os fundos do multisig, convertendo-os em uma transação P2PKH normal que pode ser posteriormente confirmada por uma única chave privada: +``` +$ recipient=$(bitcoin-cli getrawchangeaddress) +``` +## Criando nossa transação + +Agora podemos criar nossa transação. Essa parte é parecida com as transações normais. +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''') +$ echo $rawtxhex +020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b10000000000ffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 +``` + +## Assinando a nossa transação + +Agora estamos prontos para assinar a transação. Este é um processo de várias etapas porque precisaremos fazer em várias máquinas, cada uma das quais contribuirá com suas próprias chaves privadas. + +### Carregando a primeira chave privada + +Como essa transação não está fazendo uso total da nossa carteira, precisaremos acessar diretamente as chaves privadas. Começando com a ```máquina1```, onde devemos recuperar qualquer uma das chaves privadas do usuário que estavam envolvidas no multisig: +``` +machine1$ bitcoin-cli -named dumpprivkey address=$address1 +cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR +``` +> :warning: **Atenção:** Acessar diretamente as chaves privadas do shell é um comportamento muito perigoso e deve ser feito com extremo cuidado se estivermos em um ambiente produtivo. No mínimo, é importante não salvar as informações em uma variável que possa ser acessada pela nossa máquina. Remover o histórico do shell é outro grande passo. No máximo, podemos evitar de fazer isso. + +### Fazendo a nossa primeira assinatura + +Agora podemos fazer nossa primeira assinatura com o comando ```signrawtransactionwithkey```. É aqui que as coisas ficam diferentes das normais: Precisaremos treinar o comando sobre como assinar. Podemos fazer isso adicionando as seguintes informações novas: + +* Incluir um argumento ```prevtxs``` que tenha o ```txid```, o ```vout```, o ```scriptPubKey``` e o ```redeemScript``` que gravamos, cada um deles um par individual do valor-chave no objeto JSON. +* Incluir um argumento ```privkeys``` que lista as chaves privadas que pegamos nesta máquina. + +``` +machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR"]' +{ + "hex": "020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000", + "complete": false, + "errors": [ + { + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "vout": 0, + "witness": [ + ], + "scriptSig": "0047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae", + "sequence": 4294967295, + "error": "CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)" + } + ] +} + +``` +Isso produz erros assustadores e mostra um status de ```failing```. Tudo bem. Podemos ver que a assinatura foi parcialmente bem-sucedida porque o ```hex``` ficou mais longo. Embora a transação tenha sido parcialmente assinada, ela não foi concluída porque precisa de mais assinaturas. + +### Repetindo para os outros assinantes + +Agora podemos passar a transação adiante, para ser assinada novamente por nós, que temos a outra parte da multisig. Eles fazem isso executando o mesmo comando de assinatura que fizemos, porém: (1) com o ```hex``` maior que produzimos anteriormente (```bitcoin-cli -named signrawtransactionwithkey hexstring = $ rawtxhex prevtxs = '' '[{"txid": " '$ utxo_txid'", "vout": '$ utxo_vout', "scriptPubKey": " '$ utxo_spk'", "redeemScript": " '$ redeem_script'"}] '' 'privkeys =' [ "cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"] '| jq -r'. | .hex'```) e; (2) com nossa própria chave privada. + +> :information_source: **NOTA - M de N vs N de N:** Obviamente, se tivermos uma assinatura N de N (como a multisig 2 de 2 do exemplo), todas as partes precisarão assinar, mas se tiviermos uma multisignatura M de N onde "M :warning: **AVISO DE VERSÃO:** O comando ```addmultisigaddress``` está disponível no Bitcoin Core v0.10 ou superior. + +## Criando um endereço Multisig em nossa carteira + +Para tornar os fundos enviados para endereços multisig mais fáceis de serem gastos, só precisamos fazer algumas pré-configurações usando o comando ```addmultisigaddress```. Não é o que gostaríamos de fazer se estivéssemos escrevendo programas de carteiras que utilizam multisig, mas se estivesse apenas tentando receber alguns fundos, isso poderia evitar alguns problemas. + +### Coletando as chaves + +Vamos começar criando os endereços P2PKH e recuperando as chaves públicas, como de costume, para cada usuário que fará parte do multisig: +``` +machine1$ address3=$(bitcoin-cli getnewaddress) +machine1$ echo $address3 +tb1q4ep2vmakpkkj6mflu94x5f94q662m0u5ad0t4w +machine1$ bitcoin-cli -named getaddressinfo address=$address3 | jq -r '. | .pubkey' +0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc + +machine2$ address4=$(bitcoin-cli getnewaddress) +machine2$ echo $address4 +tb1qa9v5h6zkhq8wh0etnv3ae9cdurkh085xufl3de +machine2$ bitcoin-cli -named getaddressinfo address=$address4 | jq -r '. | .pubkey' +02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f +``` + +### Criando o endereço Multisig em qualquer lugar + +Em seguida, vamos criar o multisig em _cada máquina que contribuiu com as assinaturas_ usando um novo comando, ```addmultisigaddress```, ao invés de ```createmultisig```. Este novo comando salva algumas das informações da nossa carteira, tornando muito mais fácil gastar o dinheiro no futuro. +``` +machine1$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$address3'","02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f"]''' +{ + "address": "tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex", + "redeemScript": "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae", + "descriptor": "wsh(multi(2,[d6043800/0'/0'/15']0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc,[e9594be8]02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f))#wxn4tdju" +} + +machine2$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc","'$address4'"]''' +{ + "address": "tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex", + "redeemScript": "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae", + "descriptor": "wsh(multi(2,[ae42a66f]0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc,[fe6f2292/0'/0'/2']02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f))#cc96c5n6" +} +``` +Conforme observado na seção anterior, atualmente não importa se usamos endereços ou chaves públicas, então mostramos o outro mecanismo aqui, misturando os dois. Iremos obter o mesmo endereço multisig de qualquer maneira. No entanto, _devemos usar a mesma ordem sempre_. Portanto, é melhor que os membros do multisig verifiquem entre si a ordem dos dados para ter certeza de que todos obtiveram o mesmo resultado. + +### Esperando para receber os fundos + +Depois disso, os membros do multisig ainda precisarão executar o comando ```importaddress``` para observar os fundos recebidos no endereço multisig: +``` +machine1$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 rescan="false" + +machine2$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 rescan="false" +``` + +## Gastando novamente com uma transação automatizada + +Posteriormente, podemos receber os fundos no endereço com várias assinaturas sem nenhum problema. O uso do ```addmultisigaddress``` é simplesmente uma questão burocrática por parte dos destinatários: Um pouco de contabilidade para facilitar a vida deles quando desejarem gastar os saldos. + +Mas, isso torna a vida muito mais fácil. Como as informações foram salvas na carteira, os assinantes poderão gastar os fundos enviados para o endereço com várias assinaturas exatamente como qualquer outro endereço, ao invés de assinar sempre em várias máquinas diferentes. + +Podemos começar coletando as variáveis, mas não precisamos mais nos preocupar com o ```scriptPubKey``` ou com o ```redeemScript```. + +Aqui está uma nova transação enviada para nosso novo endereço multisig: +``` +machine1$ utxo_txid=b9f3c4756ef8159d6a66414a4317f865882ee04beb57a0f8349dafcc98f5acbc +machine1$ utxo_vout=0 +machine1$ recipient=$(bitcoin-cli getrawchangeaddress) +``` +Vamos criar uma transação bruta: +``` +machine1$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''') +``` +E depois, assiná-la: +``` +machine1$ bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex +{ + "hex": "02000000000101bcacf598ccaf9d34f8a057eb4be02e8865f817434a41666a9d15f86e75c4f3b90000000000ffffffff0188130000000000001600144f93c831ec739166ea425984170f4dc6bac75829040047304402205f84d40ba16ff49e60a7fc9228ef5917473aae1ab667dad01e113ca0fef3008b02201a50da2c65f38798aea94bcbd5bbf065bc1e38de44bacee69d525dcddcc11bba01004752210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae00000000", + "complete": false, + "errors": [ + { + "txid": "b9f3c4756ef8159d6a66414a4317f865882ee04beb57a0f8349dafcc98f5acbc", + "vout": 0, + "witness": [ + "", + "304402205f84d40ba16ff49e60a7fc9228ef5917473aae1ab667dad01e113ca0fef3008b02201a50da2c65f38798aea94bcbd5bbf065bc1e38de44bacee69d525dcddcc11bba01", + "", + "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae" + ], + "scriptSig": "", + "sequence": 4294967295, + "error": "CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)" + } + ] +} + +``` +Observe que não precisamos mais da ajuda extra do comando ```signrawtransactionwithkey```, porque todas essas informações já estão em nossa carteira. Mais importante, não tornamos nossas chaves privadas vulneráveis ​​ao manipulá-las diretamente. Ao invés disso, o processo é _exatamente_ o mesmo que gastar um UTXO normal, exceto que a transação não foi totalmente assinada no final. + +### Assinando em outras máquinas + +A etapa final é exportar o ```hex``` parcialmente assinado para a outra máquina e assinar a transação novamente: +``` +machine2$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=02000000014ecda61c45f488e35c613a7c4ae26335a8d7bfd0a942f026d0fb1050e744a67d000000009100473044022025decef887fe2e3eb1c4b3edaa155e5755102d1570716f1467bb0b518b777ddf022017e97f8853af8acab4853ccf502213b7ff4cc3bd9502941369905371545de28d0147522102e7356952f4bb1daf475c04b95a2f7e0d9a12cf5b5c48a25b2303783d91849ba421030186d2b55de166389aefe209f508ce1fbd79966d9ac417adef74b7c1b5e0777652aeffffffff0130e1be07000000001976a9148dfbf103e48df7d1993448aa387dc31a2ebd522d88ac00000000 | jq -r '.hex') +``` +Quando todos os os assinantes confirmaram a assinatura, estaremos prontos para enviar a transação para a rede: +``` +machine2$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +3ce88839ac6165aeadcfb188c490e1b850468eff571b4ca78fac64342751510d +``` +Tal como acontece com o atalho discutido na seção [§4.5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), o resultado é muito mais fácil, mas perdemos certo controle no processo. + +## Resumo: Enviando e Gastando uma Transação Multisig de Maneira Automatizada + +Existe uma maneira mais fácil de gastar fundos enviados para os nossos endereços multisig que simplesmente requerem o uso do comando ```addmultisigaddress``` quando criamos nosso endereço. Ele não demonstra os meandros do gasto do P2SH e não nos dará um controle abrangente, mas se queremos apenas receber nossas moedas, este pode ser o melhor caminho. + +## O Que Vem Depois? + +Saiba mais sobre "Expandindo as transações de Bitcoin com multisigs" no [Capítulo 7: Expandindo as transações do Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md). \ No newline at end of file From 004fb7a88ebd74f9f5b301e86820116756d4c28f Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 8 Jul 2021 09:03:02 -0300 Subject: [PATCH 026/155] Finished traslation chapter 7 --- ..._0_Expanding_Bitcoin_Transactions_PSBTs.md | 24 + ..._a_Partially_Signed_Bitcoin_Transaction.md | 509 +++++++++++++++ ..._a_Partially_Signed_Bitcoin_Transaction.md | 602 ++++++++++++++++++ pt/07_3_Integrating_with_Hardware_Wallets.md | 470 ++++++++++++++ 4 files changed, 1605 insertions(+) create mode 100644 pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md create mode 100644 pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md create mode 100644 pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md create mode 100644 pt/07_3_Integrating_with_Hardware_Wallets.md diff --git a/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md b/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md new file mode 100644 index 0000000..e8b2222 --- /dev/null +++ b/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md @@ -0,0 +1,24 @@ +# Capítulo Sete: Expandindo as Transações de Bitcoin com PSBTs + +No capítulo anterior, discutimos como usar os multisigs para determinar colaborativamente o consentimento entre várias partes. Essa não é a única forma de colaborar na criação de transações no Bitcoin. Os PSBTs são uma tecnologia muito mais recente que permite que colaboremos em vários estágios, incluindo a criação, financiamento e autenticação de uma transação Bitcoin. + +## Objetivos para esta seção + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Criar transações com PSBTs; + * Usas ferramentas da linha de comando para completar PSBTs; + * Usar o HWI para interagir com uma hardware wallet. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Entender como os PSBTs diferem dos multisig; + * Compreender o completamente o fluxo de trabalho com os PSBTs; + * Planejar todo o poder dos PSBTs; + * Compreender o uso de uma hardware wallet. + +## Tabela de Conteúdo + + * [Seção Um: Criando uma Transação Bitcoin Parcialmente Assinada](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) + * [Seção Dois: Usando uma transação Bitcoin parcialmente assinada](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) + * [Seção Três: Integração com hardware wallets](07_3_Integrating_with_Hardware_Wallets.md) \ No newline at end of file diff --git a/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md b/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md new file mode 100644 index 0000000..6308690 --- /dev/null +++ b/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md @@ -0,0 +1,509 @@ +# 7.1: Criando uma Transação Bitcoin Parcialmente Assinada + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +As Transações Bitcoin Parcialmente Assinadas (Partially Signed Bitcoin Transactions ou mais conhecidas como PSBTs) são a forma mais recente de variar a criação de transações básicas do Bitcoin. Eles fazem isso introduzindo a colaboração em todas as etapas do processo, permitindo que as pessoas (ou sistemas) não apenas autentiquem as transações juntas (como nas multisigs), mas também criem, financiem e transmitam facilmente, de forma colaborativa. + +> :aviso: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v 0.17.0. As versões anteriores do Bitcoin Core não funcionarão com o PSBT enquanto estiver em andamento (apesar de consiguir reconhecer a transação final). Algumas atualizações e upgrades para PSBTs continuaram até a versão 0.20.0. + +## Entendendo como funcionam os PSBTs + +O multisig são ótimos para o caso específico de manter fundos em conjunto e definir regras para quem, entre os signatários conjuntos, poderia autenticar o uso do saldo. Existem muitos casos de uso, como: Uma conta conjunta entre cônjuges (uma assinatura um de dois); Um requisito fiduciário para duplo controle (uma assinatura 2 de 2); e um depósito (uma assinatura 2 de 3). + +> :book: ***O que é um PSBT?*** Como o nome sugere, um PSBT é uma transação que não foi totalmente assinada. Isso é importante porque, uma vez que uma transação é assinada, seu conteúdo está travado. O [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) definiu uma metodologia abstrata para colocar os PSBTs juntos que descreve e padroniza funções de criação colaborativa. Um *Criador* propõe uma transação; um ou mais *Atualizadores* o complementam; e um ou mais *Assinantes* o autenticam. Antes de um *Finalizador* concluir o processo e, um *Extrator* o transformar em uma transação na rede Bitcoin. Também pode haver um *Combinador* que mescla os PSBTs paralelos de vários usuários. + +Os PSBTs podem, inicialmente, ter a mesma aparência que os multisigs porque têm um único bit de funcionalidade sobreposto: A capacidade de assinar uma transação em conjunto. No entanto, eles foram criados para um caso de uso totalmente diferente. Os PSBTs reconhecem a necessidade de vários programas criarem uma transação em conjunto por vários motivos diferentes e fornecem um formato regularizado para isso. Eles são especialmente úteis para casos de uso envolvendo hardware wallets (Se quisermos saber mais basta consultarmos a seção [§7.3](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_3_Integrating_with_Hardware_Wallets.md )), que são protegidos contra acesso total à Internet e tendem a ter um histórico mínimo, quando não zero, de transações. + +Em geral, os PSBTs fornecem vários elementos funcionais que aprimoram esse caso de uso: + +1. Eles fornecem um _padrão_ para criar transações de forma colaborativa, enquanto as metodologias anteriores (incluindo o multisig do capítulo anterior) dependiam de implementação; +2. Eles oferecem suporte a uma _variedade mais ampla de casos de uso_, incluindo financiamento simples em conjunto; +3. Eles suportam _hardware wallets_ e outros casos em que um node pode não ter um histórico completo das transações; +4. Eles opcionalmente permitem a combinação de _transações não serializadas_, não exigindo que um código hexadecimal cada vez maior seja passado de usuário para usuário. + +Os PSBTs fazem nosso trabalho complementando as informações normais da transação com um conjunto de entradas e saídas, cada uma delas definindo tudo o que precisamos saber sobre os UTXOs, de forma que mesmo uma carteira com airgap possa tomar uma decisão informada sobre as assinaturas. Assim, quando confrontado com uma entrada com listas de saldos em um UTXO a carteira offline sabe o que precisa ser feito para gastá-los, enquanto o resultado faz o mesmo para os UTXOs que estão sendo criados. + +Esta primeira seção descreverá o processo PSBT padrão com as seguintes funções: Criador, Atualizador, Assinante, Finalizador, Extrator. Faremos isso em uma máquina só, o que irá parecer uma forma complicada de criar uma transação bruta. Mas, tenha fé, há um motivo para isso! Nas seções [§7.2](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) e [§7.3](07_3_Integrating_with_Hardware_Wallets.md) vamos ver alguns exemplos reais de como utilizar o PSBTs e vamos transformar este sistema simples em um processo colaborativo compartilhado entre várias máquinas que tem efeitos reais e cria oportunidades reais. + +## Criando um PSBT à moda antiga +#### Função do PSBT: Criador + +A maneira mais fácil de criar um PSBT é pegando uma transação existente e usando o comando ```converttopsbt``` para transformá-la em um PSBT. Certamente, esta não é a _melhor_ maneira, uma vez que requer que façamos uma transação usando um formato (uma transação bruta) e depois convertendo-a para outro (PSBT), mas se tivermos um software antigo que só pode gerar uma transação bruta, podemos precisar utilizá-lo. + +Acabamos de criar uma transação bruta normalmente: + +``` +$ 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 '.[1] | .txid') +$ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') +$ echo $utxo_txid_1 $utxo_vout_1 $utxo_txid_2 $utxo_vout_2 +c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b 1 8748eff5f12ca886e3603d9e30227dcb3f0332e0706c4322fec96001f7c7f41c 0 +$ recipient=tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.0000065 }''') +``` +Então agora, a convertemos: +``` +$ psbt=$(bitcoin-cli -named converttopsbt hexstring=$rawtxhex) +$ echo $psbt +cHNidP8BAHsCAAAAAhuVpgVRdOxkuC7wW2rvw4800OVxl+QCgezYKHtCYN7GAQAAAAD/////HPTH9wFgyf4iQ2xw4DIDP8t9IjCePWDjhqgs8fXvSIcAAAAAAP////8BigIAAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBQAAAAAAAAAA +``` +É possível notar que a codificação PSBT é muito diferente da transação hexadecimal que estamos acostumados. + +Mas se pudermos, podemos criar o PSBT diretamente. + +## Criando um PSBT da maneira mais difícil +#### Função do PSBT: Criador + +A primeira metodologia de criação de um PSBT sem passar por outro formato é usando o comando PSBT análogo ao ```createrawtransaction```. Usando o ```createpsbt``` teremos o controle máximo ao custo do máximo trabalho e da oportunidade máxima de erros. + +A CLI deve parecer bastante familiar, a diferença é que agora usamos um novo comando RPC: +``` +$ psbt_1=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.0000065 }''') +``` +A equipe do Bitcoin Core certificou-se de que ```createpsbt``` funcionasse de maneira muito parecida com a```createrawtransaction```, portanto não precisamos aprender uma nova sintaxe diferente. + +Podemos verificar se o novo PSBT é o mesmo criado pelo ```converttopsbt```: +``` +$ echo $psbt_1 +cHNidP8BAHsCAAAAAhuVpgVRdOxkuC7wW2rvw4800OVxl+QCgezYKHtCYN7GAQAAAAD/////HPTH9wFgyf4iQ2xw4DIDP8t9IjCePWDjhqgs8fXvSIcAAAAAAP////8BigIAAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBQAAAAAAAAAA +$ if [ "$psbt" == "$psbt_1" ]; then echo "PSBTs are equal"; else echo "PSBTs are not equal"; fi +PSBTs are equal +``` + +## Examinando um PSBT +#### Função do PSBT: Qualquer uma + +Então, como o nosso PSBT realmente se parece? Podemos ver isso com o comando ```decodepsbt```: +``` +$ bitcoin-cli -named decodepsbt psbt=$psbt +{ + "tx": { + "txid": "ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3", + "hash": "ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3", + "version": 2, + "size": 123, + "vsize": 123, + "weight": 492, + "locktime": 0, + "vin": [ + { + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "8748eff5f12ca886e3603d9e30227dcb3f0332e0706c4322fec96001f7c7f41c", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00000650, + "n": 0, + "scriptPubKey": { + "asm": "0 c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "hex": "0014c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + }, + { + } + ], + "outputs": [ + { + } + ] +} +``` +É importante notar que, embora tenhamos definido os fundamentos da transação: Os ```vins``` de onde o dinheiro está vindo e os ```vouts``` de onde está saindo, ainda não definimos as ```entradas``` e as ```saídas``` que são o coração do PSBT e que são necessários para os usuários offline avaliá-los. Isso já é esperado: O papel do Criador conforme definido no [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) é delinear a transação, enquanto o papel do Atualizador é começar a preencher os dados específicos do PSBT. (Outros comandos combinam as funções de Criador e Atualizador, mas o ```createpsbt``` não porque não tem acesso à nossa carteira). + +Também podemos usar o comando ```analyzeepsbt``` para verificar nosso estado atual: +``` +standup@btctest20:~$ bitcoin-cli -named analyzepsbt psbt=$psbt +{ + "inputs": [ + { + "has_utxo": false, + "is_final": false, + "next": "updater" + }, + { + "has_utxo": false, + "is_final": false, + "next": "updater" + } + ], + "next": "updater" +} +``` +Da mesma forma, o comando ```analysepsbt``` nos mostra um PSBT que precisa ser trabalhado. Damos uma olhada em cada uma das duas `entradas` (correspondendo aos dois ```vins```), e nenhuma delas possui as informações de que precisamos. + +## Finalizando um PSBT +#### Funções dos PSBT: Atualizador, Assinante e Finalizador + +Existe o comando ```utxoupdatepsbt``` que pode ser usado para atualizar o UTXOs, importando as informações do descritor manualmente, mas não queremos usá-lo a menos que tenhamos um caso de uso em que não tenhamos todas as informações nas carteiras de todos que irão assinar o PSBT. + +> :information_source: **NOTA:** Se escolhermos Atualizar o PSBT com o ```utxoupdatepsbt```, ainda precisaremos usar o ```walletprocesspsbt``` para assiná-lo: É o único comando que a função Assinante possui no PSBTs que está disponível no `bitcoin-cli`. + +Ao invés disso, devemos usar o ```walletprocesspsbt```, que irá atualizar, assinar e finalizar: +``` +$ bitcoin-cli walletprocesspsbt $psbt +{ + "psbt": "cHNidP8BAHsCAAAAAhuVpgVRdOxkuC7wW2rvw4800OVxl+QCgezYKHtCYN7GAQAAAAD/////HPTH9wFgyf4iQ2xw4DIDP8t9IjCePWDjhqgs8fXvSIcAAAAAAP////8BigIAAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBQAAAAAAAQEfAQAAAAAAAAAWABRsRdOvqHYghsS9dtinGsfJduGRlgEIawJHMEQCIAqJbxz6dBzNpfaDu4XZXb+DbDkM3UWnhezh9UdmeVghAiBRxMlW2o0wEtphtUZRWIiJOaGtXfsQbB4lovkvE4eRIgEhArrDpkX9egpTfGJ6039faVBYxY0ZzrADPpE/Gpl14A3uAAEBH0gDAAAAAAAAFgAU1ZEJG4B0ojde2ZhanEsY7+z9QWUBCGsCRzBEAiB+sNNCO4xiFQ+DoHVrqqk9yM0V4H9ZSyExx1PW7RbjsgIgUeWkQ3L7aAv1xIe7h+8PZb8ECsXg1UzbtPW8wd2qx0UBIQKIO7VGPjfVUlLYs9XCFBsAezfIp9tiEfdclVrMXqMl6wAA", + "complete": true +} +``` +Obviamente, não precisaremos salvar as informações do ```psbt``` usando```JQ```: +``` +$ psbt_f=$(bitcoin-cli walletprocesspsbt $psbt | jq -r '.psbt') +``` +Podemos ver que as `entradas` foram preenchidas: +``` +$ bitcoin-cli decodepsbt $psbt_f +{ + "tx": { + "txid": "ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3", + "hash": "ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3", + "version": 2, + "size": 123, + "vsize": 123, + "weight": 492, + "locktime": 0, + "vin": [ + { + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "8748eff5f12ca886e3603d9e30227dcb3f0332e0706c4322fec96001f7c7f41c", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00000650, + "n": 0, + "scriptPubKey": { + "asm": "0 c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "hex": "0014c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.00000001, + "scriptPubKey": { + "asm": "0 6c45d3afa8762086c4bd76d8a71ac7c976e19196", + "hex": "00146c45d3afa8762086c4bd76d8a71ac7c976e19196", + "type": "witness_v0_keyhash", + "address": "tb1qd3za8tagwcsgd39awmv2wxk8e9mwryvktqmkkg" + } + }, + "final_scriptwitness": [ + "304402200a896f1cfa741ccda5f683bb85d95dbf836c390cdd45a785ece1f54766795821022051c4c956da8d3012da61b5465158888939a1ad5dfb106c1e25a2f92f1387912201", + "02bac3a645fd7a0a537c627ad37f5f695058c58d19ceb0033e913f1a9975e00dee" + ] + }, + { + "witness_utxo": { + "amount": 0.00000840, + "scriptPubKey": { + "asm": "0 d591091b8074a2375ed9985a9c4b18efecfd4165", + "hex": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "type": "witness_v0_keyhash", + "address": "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh" + } + }, + "final_scriptwitness": [ + "304402207eb0d3423b8c62150f83a0756baaa93dc8cd15e07f594b2131c753d6ed16e3b2022051e5a44372fb680bf5c487bb87ef0f65bf040ac5e0d54cdbb4f5bcc1ddaac74501", + "02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb" + ] + } + ], + "outputs": [ + { + } + ], + "fee": 0.00000191 +} +``` +Ou para ser mais preciso: (1) O PSBT foi atualizado com as informações de ```witness_utxo```; (2) O PSBT foi assinado; e (3) O PSBT foi finalizado. + +## Criando um PSBT da maneira mais fácil +#### Função do PSBT: Criador e Atualizador + +Se estamos esperamos que haja um comando equivalente ao ```fundrawtransaction```, ficaremos satisfeitos em saber que existe: Ele é o ```walletcreatefundedpsbt```. Podemos usá-lo da mesma forma que ```createpsbt```: +``` +$ bitcoin-cli -named walletcreatefundedpsbt inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.0000065 }''' +{ + "psbt": "cHNidP8BAOwCAAAABBuVpgVRdOxkuC7wW2rvw4800OVxl+QCgezYKHtCYN7GAQAAAAD/////HPTH9wFgyf4iQ2xw4DIDP8t9IjCePWDjhqgs8fXvSIcAAAAAAP/////uFwerANKjyVK6WaR7gzlX+lOf+ORsfjP5LYCSNIbhaAAAAAAA/v///4XjOeey0NyGpJYpszNWF8AFNiuFaWsjkOrk35Jp+9kKAAAAAAD+////AtYjEAAAAAAAFgAUMPsier2ey1eH48oGqrbbYGzNHgKKAgAAAAAAABYAFMdy1vlVQuEe8R6O/Hx6aYMK04oFAAAAAAABAR8BAAAAAAAAABYAFGxF06+odiCGxL122Kcax8l24ZGWIgYCusOmRf16ClN8YnrTf19pUFjFjRnOsAM+kT8amXXgDe4Q1gQ4AAAAAIABAACADgAAgAABAR9IAwAAAAAAABYAFNWRCRuAdKI3XtmYWpxLGO/s/UFlIgYCiDu1Rj431VJS2LPVwhQbAHs3yKfbYhH3XJVazF6jJesQ1gQ4AAAAAIABAACADAAAgAABAIwCAAAAAdVmsvkSBmfeHqNAe/wDCQ5lEp9F/587ftzCD1UL60nMAQAAABcWABRzFxRJfFPl8FJ6SxjAJzy3mCAMXf7///8CQEIPAAAAAAAZdqkUf0NzebzGbEB0XtwYkeprODDhl12IrMEwLQAAAAAAF6kU/d+kMX6XijmD+jWdUrLZlJUnH2iHPhQbACIGA+/e40wACf0XXzsgteWlUX/V0WdG8uY1tEYXra/q68OIENYEOAAAAACAAAAAgBIAAIAAAQEfE4YBAAAAAAAWABTVkQkbgHSiN17ZmFqcSxjv7P1BZSIGAog7tUY+N9VSUtiz1cIUGwB7N8in22IR91yVWsxeoyXrENYEOAAAAACAAQAAgAwAAIAAIgICKMavAB+71Adqsbf+XtC1g/OlmLEuTp3U0axyeu/LAI0Q1gQ4AAAAAIABAACAGgAAgAAA", + "fee": 0.00042300, + "changepos": 0 +} +``` +No entanto, a grande vantagem é que podemos usá-lo para se autofinanciar, deixando de fora os ```inputs```, assim como o ```fundrawtransaction```. +``` +$ psbt_new=$(bitcoin-cli -named walletcreatefundedpsbt inputs='''[]''' outputs='''{ "'$recipient'": 0.0000065 }''' | jq -r '.psbt') +$ bitcoin-cli decodepsbt $psbt_new +{ + "tx": { + "txid": "9f2c6205ac797c1020f7f261e3ab71cd0699ff4b1a8934f68b273c71547e235f", + "hash": "9f2c6205ac797c1020f7f261e3ab71cd0699ff4b1a8934f68b273c71547e235f", + "version": 2, + "size": 154, + "vsize": 154, + "weight": 616, + "locktime": 0, + "vin": [ + { + "txid": "8748eff5f12ca886e3603d9e30227dcb3f0332e0706c4322fec96001f7c7f41c", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + }, + { + "txid": "68e1863492802df9337e6ce4f89f53fa5739837ba459ba52c9a3d200ab0717ee", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.00971390, + "n": 0, + "scriptPubKey": { + "asm": "0 09a74ef0bae4d68b0b2ec9a7c4557a2b5c85bd8b", + "hex": "001409a74ef0bae4d68b0b2ec9a7c4557a2b5c85bd8b", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qpxn5au96untgkzewexnug4t69dwgt0vtfahcv6" + ] + } + }, + { + "value": 0.00000650, + "n": 1, + "scriptPubKey": { + "asm": "0 c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "hex": "0014c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.00000840, + "scriptPubKey": { + "asm": "0 d591091b8074a2375ed9985a9c4b18efecfd4165", + "hex": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "type": "witness_v0_keyhash", + "address": "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh" + } + }, + "bip32_derivs": [ + { + "pubkey": "02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb", + "master_fingerprint": "d6043800", + "path": "m/0'/1'/12'" + } + ] + }, + { + "non_witness_utxo": { + "txid": "68e1863492802df9337e6ce4f89f53fa5739837ba459ba52c9a3d200ab0717ee", + "hash": "68e1863492802df9337e6ce4f89f53fa5739837ba459ba52c9a3d200ab0717ee", + "version": 2, + "size": 140, + "vsize": 140, + "weight": 560, + "locktime": 1774654, + "vin": [ + { + "txid": "cc49eb0b550fc2dc7e3b9fff459f12650e0903fc7b40a31ede670612f9b266d5", + "vout": 1, + "scriptSig": { + "asm": "0014731714497c53e5f0527a4b18c0273cb798200c5d", + "hex": "160014731714497c53e5f0527a4b18c0273cb798200c5d" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01000000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 7f437379bcc66c40745edc1891ea6b3830e1975d OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9147f437379bcc66c40745edc1891ea6b3830e1975d88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ" + ] + } + }, + { + "value": 0.02961601, + "n": 1, + "scriptPubKey": { + "asm": "OP_HASH160 fddfa4317e978a3983fa359d52b2d99495271f68 OP_EQUAL", + "hex": "a914fddfa4317e978a3983fa359d52b2d99495271f6887", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2NGParh82hE2Zif5PVK3AfLpYhfwF5FyRGr" + ] + } + } + ] + }, + "bip32_derivs": [ + { + "pubkey": "03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388", + "master_fingerprint": "d6043800", + "path": "m/0'/0'/18'" + } + ] + } + ], + "outputs": [ + { + "bip32_derivs": [ + { + "pubkey": "029bb586a52657dd98852cecef78552a4e21d081a7a30e4008ce9b419840d4deac", + "master_fingerprint": "d6043800", + "path": "m/0'/1'/27'" + } + ] + }, + { + } + ], + "fee": 0.00028800 +} +``` +Como podemos ver, criamos o PSBT e depois o atualizamos com todas as informações que encontramos localmente. + +A partir daí, precisamos usar o ```walletprocesspsbt``` para finalizar, como de costume: +``` +$ psbt_new_f=$(bitcoin-cli walletprocesspsbt $psbt_new | jq -r '.psbt') +``` +Posteriormente, uma análise mostrará que também está pronto: +``` +$ bitcoin-cli analyzepsbt $psbt_new_f +{ + "inputs": [ + { + "has_utxo": true, + "is_final": true, + "next": "extractor" + }, + { + "has_utxo": true, + "is_final": true, + "next": "extractor" + } + ], + "estimated_vsize": 288, + "estimated_feerate": 0.00100000, + "fee": 0.00028800, + "next": "extractor" +} +``` +Agora, realmente iremos querer usar o ```walletcreatefundedpsbt``` se estivermos criando um programa com o ```bitcoin-cli```? Provavelmente não. Mas é a mesma análise que fazemos com o ```fundrawtransaction```. Deixamos o Bitcoin Core fazer a análise, o cálculo e as decisões, ou nós mesmos fazemos? + +## Enviando um PSBT +#### Função do PSBT: Extrator + +Para finalizar o PSBT, usamos o ```finalizepsbt```, que irá transformar o PSBT novamente em um modelo hexadecimal. (Ele também assumirá a função de Finalizador, caso ainda não tenha acontecido). +``` +$ bitcoin-cli finalizepsbt $psbt_f +{ + "hex": "020000000001021b95a6055174ec64b82ef05b6aefc38f34d0e57197e40281ecd8287b4260dec60100000000ffffffff1cf4c7f70160c9fe22436c70e032033fcb7d22309e3d60e386a82cf1f5ef48870000000000ffffffff018a02000000000000160014c772d6f95542e11ef11e8efc7c7a69830ad38a050247304402200a896f1cfa741ccda5f683bb85d95dbf836c390cdd45a785ece1f54766795821022051c4c956da8d3012da61b5465158888939a1ad5dfb106c1e25a2f92f13879122012102bac3a645fd7a0a537c627ad37f5f695058c58d19ceb0033e913f1a9975e00dee0247304402207eb0d3423b8c62150f83a0756baaa93dc8cd15e07f594b2131c753d6ed16e3b2022051e5a44372fb680bf5c487bb87ef0f65bf040ac5e0d54cdbb4f5bcc1ddaac745012102883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb00000000", + "complete": true +} +``` +Como de costume, vamos querer salvar e depois enviar. +``` +$ psbt_hex=$(bitcoin-cli finalizepsbt $psbt_f | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$psbt_hex +ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3 +``` +## Revisando o fluxo de trabalho + +Ao criar o software ```bitcoin-cli```, é mais provável que iremos cumprir as cinco funções principais dos PSBTs usando os comandos ```createpsbt```, ```walletprocesspsbt``` e ```finalizepsbt```. Esta é a aparência desse fluxo: + +![](images/psbt-roles-for-cli-1.png) + +Se escolhermos usar o atalho de ```walletcreatefundedpsbt```, teremos um fluxo mais ou menos assim: + +![](images/psbt-roles-for-cli-2.png) + +Finally, if you instead need more control and choose to use `utxoupdatepsbt` (which is largely undocumented here), you instead have this workflow: +Finalmente, se precisarmos de mais controle e optarmos por usar o comando ```utxoupdatepsbt``` (que não está documentado aqui), teremos um fluxo de trabalho assim: + +![](images/psbt-roles-for-cli-3.png) + +## Resumo: Criando uma Transação Bitcoin Parcialmente Assinada + +A criação de um PSBT envolve um fluxo de trabalho um tanto complexo de criação, atualização, assinatura, finalização e extração de um PSBT, após o qual ele se converte novamente em uma transação bruta. Por que teríamos tanto trabalho? Porque deseja colaborar entre vários usuários ou vários programas. Agora que entendemos esse fluxo de trabalho, a próxima seção irá apresentar alguns exemplos reais de como fazer isso. + +## O Que Vem Depois? + +Vamos continuar "Expandindo as Transações de Bitcoin com PSBTs" na seção [§7.2: Usando uma transação Bitcoin parcialmente assinada](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md). diff --git a/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md b/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md new file mode 100644 index 0000000..9da3b3a --- /dev/null +++ b/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md @@ -0,0 +1,602 @@ +# 7.2: Usando uma transação Bitcoin parcialmente assinada + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Agora que aprendemos o fluxo de trabalho básico para gerar um PSBT, provavelmente desejamos fazer algo com ele. O que os PSBTs podem fazer que os multisigs (e as transações brutas normais) não podem? Para começar, temos a facilidade de usar um formato padronizado, o que significa que podemos usar nossas transações do ```bitcoin-cli``` e combiná-las com transações geradas por pessoas (ou programas) em outras plataformas. Além disso, podemos fazer algumas coisas que simplesmente não eram fáceis usando outros mecanismos. + +A seguir estão três exemplos do uso dos PSBTs para: Multisigs, financiamentos e CoinJoins. + +> :aviso: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.17.0. As versões anteriores do Bitcoin Core não funcionarão com o PSBT enquanto ele estiver em andamento (embora ainda consigam reconhecer a transação final). + +## Usando um PSBT para gastar fundos MultiSig + +Suponha que tenhamos criado um endereço multisig, assim como fizemos na seção [§6.3](06_3_Sending_an_Automated_Multisig.md). +``` +machine1$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]''' +{ + "address": "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0", + "redeemScript": "5221038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e2103789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd063652ae", + "descriptor": "wsh(multi(2,[d6043800/0'/0'/26']038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e,[be686772]03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636))#07zyayfk" +} +machine1$ bitcoin-cli -named importaddress address="tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0" rescan=false + +machine2$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]''' +{ + "address": "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0", + "redeemScript": "5221038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e2103789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd063652ae", + "descriptor": "wsh(multi(2,[d6043800/0'/0'/26']038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e,[be686772]03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636))#07zyayfk" +} +machine2$ bitcoin-cli -named importaddress address="tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0" rescan=false +``` +E que tenhamos algumas moedas: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5", + "vout": 0, + "address": "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0", + "label": "", + "witnessScript": "5221038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e2103789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd063652ae", + "scriptPubKey": "0020224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "amount": 0.01999800, + "confirmations": 2, + "spendable": false, + "solvable": true, + "desc": "wsh(multi(2,[d6043800/0'/0'/26']038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e,[be686772]03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636))#07zyayfk", + "safe": true + } +] +``` +Nós _poderíamos_ gastá-las usando os mecanismos no [Capítulo 6](06_0_Expanding_Bitcoin_Transactions_Multisigs.md), onde assinamos serialmente uma transação, mas ao invés disso, vamos mostrar a vantagem do PSBTs para o uso das multisigs. Podemos gerar um único PSBT, permitir que todos o assinem em paralelo e depois podemos combinar todos resultados! Não há mais como passar o arquivo hexadecimal em constante expansão de pessoa para pessoa, o que acelera as coisas e reduz as chances de erros. + +Para demonstrar essa metodologia, vamos extrair aquele BTC 0,02 do multisig e dividi-lo entre os dois assinantes, cada um deles gerando um novo endereço com esse propósito: +``` +machine1$ bitcoin-cli getnewaddress +tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma +machine2$ bitcoin-cli getnewaddress +tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp +``` +A primeira coisa que fazemos é criar um PSBT em uma máquina. Não importa onde. Precisamos usar o ```createpsbt``` da seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) para isso, não iremos usar o método mais simples que é o comando ```walletcreatefundedpsbt```, porque precisamos do controle extra de selecionar o dinheiro protegido pelo multisig. Esse será o caso para todos os três exemplos nesta seção, o que demonstra porque geralmente precisemos usar o ```createpsbt``` para coisas mais complexas. +``` +machine1$ utxo_txid=53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5 +machine1$ utxo_vout=0 +machine1$ split1=tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma +machine1$ split2=tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp +machine1$ psbt=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$split1'": 0.009998,"'$split2'": 0.009998 }''') +``` +Em seguida, precisamos enviar esse $psbt a todas as partes do multisig para que assinem: +``` +machine1$ echo $psbt +cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAAAAAA= +``` +Mas você só precisa enviar uma vez! E você faz isso simultaneamente. + +Aqui está o resultado da primeira máquina, onde geramos o PSBT: +``` +machine1$ psbt_p1=$(bitcoin-cli walletprocesspsbt $psbt | jq -r '.psbt') +machine1$ bitcoin-cli decodepsbt $psbt_p1 +{ + "tx": { + "txid": "1687e89fcb9dd3067f75495b4884dc1d4d1cf05a6c272b783cfe29eb5d22e985", + "hash": "1687e89fcb9dd3067f75495b4884dc1d4d1cf05a6c272b783cfe29eb5d22e985", + "version": 2, + "size": 113, + "vsize": 113, + "weight": 452, + "locktime": 0, + "vin": [ + { + "txid": "25e8a26f60cf485768a1e6953b983675c867b7ab126b02e753c47b7db0c4be5e", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00499900, + "n": 0, + "scriptPubKey": { + "asm": "0 cee9f88288a5f4980191a28d7ae08ff584050da7", + "hex": "0014cee9f88288a5f4980191a28d7ae08ff584050da7", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma" + ] + } + }, + { + "value": 0.00049990, + "n": 1, + "scriptPubKey": { + "asm": "0 8d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "hex": "00148d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.01000000, + "scriptPubKey": { + "asm": "0 2abb5d49ce7e753cbf5a9ffa8cdaf815bf1074f5c0bf495a93df8eb5112f65aa", + "hex": "00202abb5d49ce7e753cbf5a9ffa8cdaf815bf1074f5c0bf495a93df8eb5112f65aa", + "type": "witness_v0_scripthash", + "address": "tb1q92a46jww0e6ne066nlagekhczkl3qa84czl5jk5nm78t2yf0vk4qte328m" + } + }, + "partial_signatures": { + "03f52980d322acaf084bcef3216f3d84bfb672d1db26ce2861de3ec047bede140d": "304402203abb95d1965e4cea630a8b4890456d56698ff2dd5544cb79303cc28cb011cbb40220701faa927f8a19ca79b09d35c78d8d0a2187872117d9308805f7a896b07733f901" + }, + "witness_script": { + "asm": "2 033055ec2da9bbb34c2acb343692bfbecdef8fab8d114f0036eba01baec3888aa0 03f52980d322acaf084bcef3216f3d84bfb672d1db26ce2861de3ec047bede140d 2 OP_CHECKMULTISIG", + "hex": "5221033055ec2da9bbb34c2acb343692bfbecdef8fab8d114f0036eba01baec3888aa02103f52980d322acaf084bcef3216f3d84bfb672d1db26ce2861de3ec047bede140d52ae", + "type": "multisig" + }, + "bip32_derivs": [ + { + "pubkey": "033055ec2da9bbb34c2acb343692bfbecdef8fab8d114f0036eba01baec3888aa0", + "master_fingerprint": "c1fdfe64", + "path": "m" +{ + "tx": { + "txid": "ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16", + "hash": "ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16", + "version": 2, + "size": 113, + "vsize": 113, + "weight": 452, + "locktime": 0, + "vin": [ + { + "txid": "53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00999800, + "n": 0, + "scriptPubKey": { + "asm": "0 cee9f88288a5f4980191a28d7ae08ff584050da7", + "hex": "0014cee9f88288a5f4980191a28d7ae08ff584050da7", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma" + ] + } + }, + { + "value": 0.00999800, + "n": 1, + "scriptPubKey": { + "asm": "0 8d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "hex": "00148d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.01999800, + "scriptPubKey": { + "asm": "0 224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "hex": "0020224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "type": "witness_v0_scripthash", + "address": "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0" + } + }, + "partial_signatures": { + "038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e": "3044022040aae4f2ba37b1526524195f4a325d97d1317227b3c82aea55c5abd66810a7ec0220416e7c03e70a31232044addba454d6b37b6ace39ab163315d3293e343ae9513301" + }, + "witness_script": { + "asm": "2 038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e 03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636 2 OP_CHECKMULTISIG", + "hex": "5221038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e2103789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd063652ae", + "type": "multisig" + }, + "bip32_derivs": [ + { + "pubkey": "03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636", + "master_fingerprint": "be686772", + "path": "m" + }, + { + "pubkey": "038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e", + "master_fingerprint": "d6043800", + "path": "m/0'/0'/26'" + } + ] + } + ], + "outputs": [ + { + "bip32_derivs": [ + { + "pubkey": "02fce26085452d07abc63bd389cb7dba9871e79bbecd08039291226be8232a9000", + "master_fingerprint": "d6043800", + "path": "m/0'/0'/24'" + } + ] + }, + { + } + ], + "fee": 0.00000200 +} +machine1$ bitcoin-cli analyzepsbt $psbt_p1 +{ + "inputs": [ + { + "has_utxo": true, + "is_final": false, + "next": "signer", + "missing": { + "signatures": [ + "be6867729bcc35ed065bb4c937557d371218a8e2" + ] + } + } + ], + "estimated_vsize": 168, + "estimated_feerate": 0.00001190, + "fee": 0.00000200, + "next": "signer" +} + +``` +Isso demonstra que as informações do UTXO foram importadas e que há uma _assinatura parcial_, mas que uma assinatura ainda não a deixa completa. + +Aqui temos o mesmo resultado na outra máquina: +``` +machine2$ psbt=cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAAAAAA= +machine2$ psbt_p2=$(bitcoin-cli walletprocesspsbt $psbt | jq -r '.psbt') +machine3$ echo $psbt_p2 +cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAABASu4gx4AAAAAACIAICJMtQOn94NXmbnCLuDDx9k9CQNW4w5wAVw+u/pRWjB0IgIDeJ9UNCNnDhaWZ/9+Hy2iqX3xsJEicuFC1YJFGs69BjZHMEQCIDJ71isvR2We6ym1QByLV5SQ+XEJD0SAP76fe1JU5PZ/AiB3V7ejl2H+9LLS6ubqYr/bSKfRfEqrp2FCMISjrWGZ6QEBBUdSIQONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDiEDeJ9UNCNnDhaWZ/9+Hy2iqX3xsJEicuFC1YJFGs69BjZSriIGA3ifVDQjZw4Wlmf/fh8toql98bCRInLhQtWCRRrOvQY2ENPtiCUAAACAAAAAgAYAAIAiBgONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDgRZu4lPAAAiAgNJzEMyT3rZS7QHqb8SvFCv2ee0MKRyVy8bY8tVUDT1KhDT7YglAAAAgAAAAIADAACAAA== +``` +Observe novamente que gerenciamos a assinatura deste multisig gerando um PSBT totalmente sem assinatura com o UTXO correto, permitindo que cada um dos usuários processe esse PSBT por conta própria, adicionando entradas e assinaturas. Como resultado, temos dois PSBTs, cada um contendo apenas uma assinatura. Isso não funcionaria no cenário multisig clássico, porque todas as assinaturas devem ser serializadas. Porém, podemos assinar em paralelo neste momento, e em seguida, usar a função Combinador para juntá-los. + +Vamos novamente em qualquer máquina e vamos nos certificar de que temos os dois PSBTs nas variáveis e, em seguida, vamos combiná-los: +``` +machine1$ psbt_p2="cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAABAIcCAAAAAtu5pTheUzdsTaMCEPj3XKboMAyYzABmIIeOWMhbhTYlAAAAAAD//////uSTLbibcqSd/Z9ieSBWJ2psv+9qvoGrzWEa60rCx9cAAAAAAP////8BuIMeAAAAAAAiACAiTLUDp/eDV5m5wi7gw8fZPQkDVuMOcAFcPrv6UVowdAAAAAAAACICA0nMQzJPetlLtAepvxK8UK/Z57QwpHJXLxtjy1VQNPUqENPtiCUAAACAAAAAgAMAAIAA" +machine2$ psbt_c=$(bitcoin-cli combinepsbt '''["'$psbt_p1'", "'$psbt_p2'"]''') +$ bitcoin-cli decodepsbt $psbt_c +{ + "tx": { + "txid": "ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16", + "hash": "ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16", + "version": 2, + "size": 113, + "vsize": 113, + "weight": 452, + "locktime": 0, + "vin": [ + { + "txid": "53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00999800, + "n": 0, + "scriptPubKey": { + "asm": "0 cee9f88288a5f4980191a28d7ae08ff584050da7", + "hex": "0014cee9f88288a5f4980191a28d7ae08ff584050da7", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma" + ] + } + }, + { + "value": 0.00999800, + "n": 1, + "scriptPubKey": { + "asm": "0 8d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "hex": "00148d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.01999800, + "scriptPubKey": { + "asm": "0 224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "hex": "0020224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "type": "witness_v0_scripthash", + "address": "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0" + } + }, + "partial_signatures": { + "038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e": "3044022040aae4f2ba37b1526524195f4a325d97d1317227b3c82aea55c5abd66810a7ec0220416e7c03e70a31232044addba454d6b37b6ace39ab163315d3293e343ae9513301", + "03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636": "30440220327bd62b2f47659eeb29b5401c8b579490f971090f44803fbe9f7b5254e4f67f02207757b7a39761fef4b2d2eae6ea62bfdb48a7d17c4aaba761423084a3ad6199e901" + }, + "witness_script": { + "asm": "2 038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e 03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636 2 OP_CHECKMULTISIG", + "hex": "5221038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e2103789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd063652ae", + "type": "multisig" + }, + "bip32_derivs": [ + { + "pubkey": "03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636", + "master_fingerprint": "be686772", + "path": "m" + }, + { + "pubkey": "038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e", + "master_fingerprint": "d6043800", + "path": "m/0'/0'/26'" + } + ] + } + ], + "outputs": [ + { + "bip32_derivs": [ + { + "pubkey": "02fce26085452d07abc63bd389cb7dba9871e79bbecd08039291226be8232a9000", + "master_fingerprint": "d6043800", + "path": "m/0'/0'/24'" + } + ] + }, + { + "bip32_derivs": [ + { + "pubkey": "0349cc43324f7ad94bb407a9bf12bc50afd9e7b430a472572f1b63cb555034f52a", + "master_fingerprint": "d3ed8825", + "path": "m/0'/0'/3'" + } + ] + } + ], + "fee": 0.00000200 +} +$ bitcoin-cli analyzepsbt $psbt_c +{ + "inputs": [ + { + "has_utxo": true, + "is_final": false, + "next": "finalizer" + } + ], + "estimated_vsize": 168, + "estimated_feerate": 0.00001190, + "fee": 0.00000200, + "next": "finalizer" +} +``` +Funcionou! Acabamos de finalizar, enviar e pronto: +``` +machine2$ psbt_c_hex=$(bitcoin-cli finalizepsbt $psbt_c | jq -r '.hex') +standup@btctest2:~$ bitcoin-cli -named sendrawtransaction hexstring=$psbt_c_hex +ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16 +``` +Obviamente, não houve uma grande melhoria no uso deste método em relação à assinatura em série de uma transação para um multisig 2 de 2 quando todos estavam usando o ```bitcoin-cli```: Poderíamos ter passado uma transação bruta com assinaturas parciais de um usuário para o outro tão facilmente quanto enviar o PSBT. Mas, este foi o caso mais simples. À medida que nos aprofundamos em multisigs mais complexas, essa metodologia se torna cada vez melhor, mas já podemos destacar alguns pontos importantes: + +Em primeiro lugar, é independente de plataforma. Enquanto todos estiverem usando um serviço compatível com o Bitcoin Core 0.17, todos poderão assinar essa transação, o que não é verdade quando os multisigs clássicos estão sendo repassados ​​entre diferentes plataformas. + +Em segundo lugar, é muito mais escalável. Considere um multisig 3 de 5. De acordo com a metodologia antiga, isso teria que ser transmitido de pessoa para pessoa, aumentando enormemente os problemas se alguém o corrompesse. Aqui, outros usuários precisam apenas enviar os PSBTs de volta ao Criador e, assim que tiver a quantidade suficiente, poderá gerar a transação final. + +## Usando um PSBT para financiamentos + +Os Multisigs como o usado no exemplo anterior são frequentemente usados ​​para receber pagamentos por trabalho colaborativo, seja royalties de um livro ou pagamentos feitos a uma empresa. Nessa situação, o exemplo acima funciona muito bem: Os dois participantes recebem seu dinheiro, que depois é dividido. Mas e quanto ao caso inverso, em que dois (ou mais) participantes desejam criar uma joint venture e precisam dividir o dinheiro? + +A resposta tradicional é criar um multisig e depois fazer com que os participantes enviem individualmente os fundos para lá. O problema é que o primeiro pagador depende da boa fé do segundo, e isso não é a base do Bitcoin, que diz que _não devemos confiar_. Felizmente, com o advento dos PSBTs, agora podemos fazer pagamentos sem confiança para podemos enviar fundos. + +> :book: ***O que significa a ideia de não podermos confiar?*** Quando dizemos, não devemos confiar, significa que nenhum participante precisa confiar em nenhum outro participante. Ao invés disso, eles esperam que os protocolos de software garantam que tudo seja executado de maneira justa, de maneira esperada. O Bitcoin é um protocolo que não depende de confiança porque não precisamos de ninguém para agir de boa fé. O sistema faz o gerenciamento. Da mesma forma, os PSBTs permitem a criação de transações que agrupam ou dividem fundos sem a necessidade de nenhuma parte confiar na outra. + +O exemplo a seguir mostra dois usuários que possuem 0,010 BTC e que desejam agrupar no endereço multisig `tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0`, criado acima. +``` +machine1$ bitcoin-cli listunspent +[ + { + "txid": "2536855bc8588e87206600cc980c30e8a65cf7f81002a34d6c37535e38a5b9db", + "vout": 0, + "address": "tb1qfg5y4fx979xkv4ezatc5eevufc8vh45553n4ut", + "label": "", + "scriptPubKey": "00144a284aa4c5f14d665722eaf14ce59c4e0ecbd694", + "amount": 0.01000000, + "confirmations": 2, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/0'/25']02bea222cf9ea1f49b392103058cc7c8741d76a553fe627c1c43fc3ef4404c9d54)#4hnkg9ml", + "safe": true + } +] +machine2$ bitcoin-cli listunspent +[ + { + "txid": "d7c7c24aeb1a61cdab81be6aefbf6c6a27562079629ffd9da4729bb82d93e4fe", + "vout": 0, + "address": "tb1qfqyyw6xrghm5kcrpkus3kl2l6dz4tpwrvn5ujs", + "label": "", + "scriptPubKey": "001448084768c345f74b6061b7211b7d5fd3455585c3", + "amount": 0.01000000, + "confirmations": 5363, + "spendable": true, + "solvable": true, + "desc": "wpkh([d3ed8825/0'/0'/0']03ff6b94c119582a63dbae4fb530efab0ed5635f7c3b2cf171264ca0af3ecef33a)#gtmd2e2k", + "safe": true + } +] +``` +Eles configuram variáveis para usarem essas transações: +``` +machine1$ utxo_txid_1=2536855bc8588e87206600cc980c30e8a65cf7f81002a34d6c37535e38a5b9db +machine1$ utxo_vout_1=0 +machine1$ utxo_txid_2=d7c7c24aeb1a61cdab81be6aefbf6c6a27562079629ffd9da4729bb82d93e4fe +machine1$ utxo_vout_2=0 +machine1$ multisig=tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0 + +``` +E criam um PSBT: +``` +machine1$ psbt=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$multisig'": 0.019998 }''') +``` +O resultado fica mais ou menos assim: +``` +machine1$ bitcoin-cli decodepsbt $psbt +{ + "tx": { + "txid": "53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5", + "hash": "53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5", + "version": 2, + "size": 135, + "vsize": 135, + "weight": 540, + "locktime": 0, + "vin": [ + { + "txid": "2536855bc8588e87206600cc980c30e8a65cf7f81002a34d6c37535e38a5b9db", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "d7c7c24aeb1a61cdab81be6aefbf6c6a27562079629ffd9da4729bb82d93e4fe", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.01999800, + "n": 0, + "scriptPubKey": { + "asm": "0 224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "hex": "0020224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "reqSigs": 1, + "type": "witness_v0_scripthash", + "addresses": [ + "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + }, + { + } + ], + "outputs": [ + { + } + ] +} +``` +Não importa se as transações sejam de propriedade de duas pessoas diferentes ou que as informações completas apareçam em duas máquinas diferentes. Este PSBT de financiamento funcionará exatamente da mesma forma que o PSBT multisig. Uma vez que todos os controladores tenham assinado, a transação pode ser finalizada. + +Aqui está o processo, desta vez passando o PSBT parcialmente assinado de um usuário para outro, ao invés de ter que combinar as coisas no final. +``` +machine1$ bitcoin-cli walletprocesspsbt $psbt +{ + "psbt": "cHNidP8BAIcCAAAAAtu5pTheUzdsTaMCEPj3XKboMAyYzABmIIeOWMhbhTYlAAAAAAD//////uSTLbibcqSd/Z9ieSBWJ2psv+9qvoGrzWEa60rCx9cAAAAAAP////8BuIMeAAAAAAAiACAiTLUDp/eDV5m5wi7gw8fZPQkDVuMOcAFcPrv6UVowdAAAAAAAAQEfQEIPAAAAAAAWABRKKEqkxfFNZlci6vFM5ZxODsvWlAEIawJHMEQCIGAiKIAWRXiw68o3pw61/cVNP7n2oH73S654XXgQ4kjHAiBtTBqmaF1iIzYGXrG4DadH8y6mTuCRVFDiPl+TLQDBJwEhAr6iIs+eofSbOSEDBYzHyHQddqVT/mJ8HEP8PvRATJ1UAAABAUdSIQONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDiEDeJ9UNCNnDhaWZ/9+Hy2iqX3xsJEicuFC1YJFGs69BjZSriICA3ifVDQjZw4Wlmf/fh8toql98bCRInLhQtWCRRrOvQY2BL5oZ3IiAgONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDhDWBDgAAAAAgAAAAIAaAACAAA==", + "complete": false +} + +machine2$ psbt_p="cHNidP8BAIcCAAAAAtu5pTheUzdsTaMCEPj3XKboMAyYzABmIIeOWMhbhTYlAAAAAAD//////uSTLbibcqSd/Z9ieSBWJ2psv+9qvoGrzWEa60rCx9cAAAAAAP////8BuIMeAAAAAAAiACAiTLUDp/eDV5m5wi7gw8fZPQkDVuMOcAFcPrv6UVowdAAAAAAAAQEfQEIPAAAAAAAWABRKKEqkxfFNZlci6vFM5ZxODsvWlAEIawJHMEQCIGAiKIAWRXiw68o3pw61/cVNP7n2oH73S654XXgQ4kjHAiBtTBqmaF1iIzYGXrG4DadH8y6mTuCRVFDiPl+TLQDBJwEhAr6iIs+eofSbOSEDBYzHyHQddqVT/mJ8HEP8PvRATJ1UAAABAUdSIQONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDiEDeJ9UNCNnDhaWZ/9+Hy2iqX3xsJEicuFC1YJFGs69BjZSriICA3ifVDQjZw4Wlmf/fh8toql98bCRInLhQtWCRRrOvQY2BL5oZ3IiAgONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDhDWBDgAAAAAgAAAAIAaAACAAA==" +machine2$ psbt_f=$(bitcoin-cli walletprocesspsbt $psbt_p | jq -r '.psbt') +machine2$ bitcoin-cli analyzepsbt $psbt_f +{ + "inputs": [ + { + "has_utxo": true, + "is_final": true, + "next": "extractor" + }, + { + "has_utxo": true, + "is_final": true, + "next": "extractor" + } + ], + "estimated_vsize": 189, + "estimated_feerate": 0.00001058, + "fee": 0.00000200, + "next": "extractor" +} +machine2$ psbt_hex=$(bitcoin-cli finalizepsbt $psbt_f | jq -r '.hex') +machine2$ bitcoin-cli -named sendrawtransaction hexstring=$psbt_hex +53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5 +``` +Usamos um PSBT para reunir o dinheiro usando um multisig sem precisar de confiança! + +## Useando um PSBT para CoinJoin + +O CoinJoin é outro aplicativo Bitcoin que não requer confiança. Aqui, temos uma variedade de entes que não se conhecem juntando dinheiro e recebendo de volta. + +A metodologia para gerenciá-lo com PSBTs é exatamente a mesma que vimos nos exemplos acima, como o seguinte pseudocódigo demonstra: +``` +$ psbt=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' }, { "txid": "'$utxo_txid_3'", "vout": '$utxo_vout_3' } ]''' outputs='''{ "'$split1'": 1.7,"'$split2'": 0.93,"'$split3'": 1.4 }''') +``` +Cada usuário coloca o próprio UTXO e cada um recebe uma saída correspondente. + +A melhor maneira de gerenciar um CoinJoin é enviar o PSBT básico para todas as partes (que podem ser inúmeras) e, em seguida, fazer com que cada uma assine o PSBT e envie de volta para uma única parte que irá combinar, finalizar e enviar. + +## Resumo: Usando uma transação Bitcoin parcialmente assinada + +Agora vimos o processo PSBT que aprendemos na seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) em uso em três exemplos da vida real: Criando um multisig, um financiamento e fazendo o CoinJoin. Tudo isso era teoricamente possível no Bitcoin por ter várias pessoas assinando transações cuidadosamente construídas, mas os PSBTs tornam isso padronizado e simples. + +> :fire: ***Qual é o poder de um PSBT?*** Um PSBT permite a criação de transações sem necessidade de confiança entre várias partes e várias máquinas. Se mais de uma parte precisar financiar uma transação, se mais de uma parte precisar assinar uma transação, ou se uma transação precisar ser criada em uma máquina e assinada em outra, um PSBT torna isso simples, sem depender do mecanismos de assinatura parcial não padronizados que existiam antes do PSBT. + +Esse último ponto, ao criar uma transação em uma máquina e assinar em outra, é um elemento dos PSBTs que ainda não chegamos. Ele está no centro das carteiras de hardware, onde geralmente desejamos criar uma transação em um full node e, em seguida, passá-la para uma hardware wallet quando uma assinatura for necessária. Esse é o tópico da nossa última seção (e do nosso quarto exemplo da vida real) deste capítulo sobre PSBTs. + +## O Que Vem Depois? + +Continue "Expanding Bitcoin Transactions with PSBTs" with [§7.3: Inegrating with Hardware Wallets](07_3_Integrating_with_Hardware_Wallets.md). +Vamos continuar "Expandindo as Transações de Bitcoin com PSBTs" na seção [§7.3: Integração com hardware wallets](07_3_Integrating_with_Hardware_Wallets.md). \ No newline at end of file diff --git a/pt/07_3_Integrating_with_Hardware_Wallets.md b/pt/07_3_Integrating_with_Hardware_Wallets.md new file mode 100644 index 0000000..f15f506 --- /dev/null +++ b/pt/07_3_Integrating_with_Hardware_Wallets.md @@ -0,0 +1,470 @@ +# 7.3: Integração com hardware wallets + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Leitor de advertência. + +Uma das principais vantagens dos PSBTs é a capacidade de transferir transações para hardware wallets. Esta será uma ótima ferramenta de desenvolvimento para nós continuarmos a programar usando o Bitcoin. No entanto, não podemos testá-la agora se estivermos usando uma das configurações que sugerimos para este curso, uma VM no Linode de acordo com a seção [§2.1](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) ou uma opção mais expansiva ainda como um AWS de acordo com a seção [§2.2](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_2_Setting_Up_Bitcoin_Core_Other.md), isso porque obviamente não teremos como conectar uma hardware wallet à nossa máquina virtual remota. + +> :book: ***O que é uma hardware wallet?*** Uma hardware wallet é um dispositivo eletrônico que melhora a segurança da criptomoeda mantendo todas as chaves privadas no dispositivo, ao invés de colocá-las em um computador conectado diretamente a internet. As carteiras de hardware têm protocolos específicos para fornecer interações online, geralmente gerenciadas por um programa que se comunica com o dispositivo por meio de uma porta USB. Neste capítulo, gerenciaremos uma carteira de hardware com o ```bitcoin-cli``` e o programa ```hwy.py```. + +Existem três opções de como passar por este capítulo: (1) Ler sem testar o código; (2) Instalar o Bitcoin em uma máquina local para testar todos esses comandos ou; (3) Pular direto para o [Capítulo 8: Expandindo as transações de Bitcoin usando outras maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md). Sugerimos a primeira opção, mas se quisermos colocar a mão na massa, iremos dar o suporte necessário para a segunda opção falando sobre o uso de um Macintosh (uma plataforma hardware que o [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup) dá suporte) para teste. + +> :warning: **AVISO DE VERSÃO:** Os PSBTs são uma inovação do Bitcoin Core v0.17.0. As versões anteriores do Bitcoin Core não funcionarão com o PSBT enquanto ele estiver em andamento (embora ainda consigam reconhecer a transação final). A interface HWI apareceu no Bitcoin Core v 0.18.0, mas, desde que estejamos usando nossa configuração sugerida com o Bitcoin Standup, ela deve funcionar. + +A metodologia descrita neste capítulo para integração com uma hardware wallet depende do [Bitcoin Hardware Wallet Interface](https://github.com/bitcoin-core/HWI) lançada através do Bitcoin Core e que se baseia na [instalação](https://github.com/bitcoin-core/HWI/blob/master/README.md) e [uso](https://hwi.readthedocs.io) das instruções contidas nele. + +> :warning: **AVISO DE NOVIDADE:** A interface HWI é muito nova e precisa de alguns ajustes ainda, mesmo depois usando a v0.20.0 do Bitcoin Core. Pode ser difícil instalá-la corretamente e pode conter erros não intuitivos. O que se segue é uma descrição de uma configuração de trabalho, mas foram necessárias várias tentativas para ter sucesso e sua configuração pode variar. + +## Instalando o Bitcoin Core em uma máquina local + +_Se pretendemos apenas ler esta seção e não testar os comandos, podemos pular esta subseção, que basicamente explicará como criar uma instalação Bitcoin Core em uma máquina local, como um Mac ou Máquina Linux._ + +Existem versões alternativas do script Bitcoin Standup que usamos para criar nossa VM que será instalada em um MacOS ou em uma máquina Linux que não seja o Linode. + +Se tivermos um MacOS, podemos instalar o [Bitcoin Standup MacOS](https://github.com/BlockchainCommons/Bitcoin-Standup-MacOS/blob/master/README.md). + +Se tivermos uma máquina Linux local, podemos instalar o [Bitcoin Standup Linux Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-MacOS/blob/master/README.md). + +Depois de colocar o Bitcoin Standup em execução em nossa máquina local, vamos desejar sincronizar o blockchain "Testnet", assumindo que já estamos seguindo o método padrão deste curso. + +Estaremos usando um Macintosh e um Testnet para os exemplos desta seção. + +### Criando um alias para o Bitcoin-CLI + +Criando um alias que execute o ```bitcoin-cli``` no diretório correto com quaisquer flags apropriadas. + +Aqui está um exemplo de um alias de um Mac: +``` +$ alias bitcoin-cli="~/StandUp/BitcoinCore/bitcoin-0.20.0/bin/bitcoin-cli -testnet" +``` +Podemos notar que ele nos dá não apenas o caminho completo, mas também garante que permaneçamos na Testnet. + +## Instalando o HWI em uma máquina local + +_As instruções a seguir novamente presumem um Mac e podemos pular novamente esta subseção se estivermos apenas lendo o capítulo._ + +O HWI é um programa do Bitcoin Core disponível em python que podemos usar para interagir com as hardware wallets. + +### Instalando o Python + +Como o HWI é escrito em ```python```, precisaremos instalá-lo, bem como alguns programas auxiliares. + +Se ainda não temos as ferramentas de linha de comando ```xcode```, iremos precisar delas: +``` +$ xcode-select --install +``` +Se ainda não temos o gerenciador de pacotes Homebrew, precisamos instalá-lo também. As instruções atuais estão disponíveis no [site do Homebrew](https://brew.sh/). No momento em que este livro foi escrito, basta utilizarmos o comando abaixo: +``` +$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" +``` + +Para uma instalação pela primeira vez, também devemos nos certificar de que nosso diretório ```/usr/local/Frameworks``` foi criado corretamente: +``` +$ sudo mkdir /usr/local/Frameworks +$ sudo chown $(whoami):admin /usr/local/Frameworks +``` +Se já fizemos tudo isso, podemos finalmente instalar o Python: +``` +$ brew install python +$ brew install libusb +``` + +### Instalando o HWI + +Agora estamos prontos para instalar o HWI, o que requer a clonagem de um repositório GitHub e a execução de um script de instalação. + +Se ainda não temos o ```git``` instalado em nosso Mac, podemos fazer isso apenas executando o comando: ```git --version```. + +Podemos então clonar o repositório HWI: +``` +$ cd ~/StandUp +$ git clone https://github.com/bitcoin-core/HWI.git +``` +Depois, precisaremos instalar o pacote e as dependências: +``` +$ cd HWI +HWI$ python3 setup.py install +``` +### Criando um alias para o HWI + +Iremos querer criar um alias aqui também, variando de acordo com o local de instalação real: +``` +$ alias hwi="~/Standup/HWI/hwi.py --testnet" +``` +Novamente, incluímos uma referência a testnet ao alias. + +## Preparando nossa Ledger + +_Precisamos escolher uma plataforma de hardware wallet para a demonstração de HWI. Nossa escolha foi a Ledger, que há muito tempo é onde fazemos os testes nestes casos. Podemos consultar as [informações de suporte do dispositivo do HWI](https://github.com/bitcoin-core/HWI/blob/master/README.md#device-support) para obter uma lista de outros dispositivos compatíveis. Se usarmos um dispositivo diferente de uma Ledger, precisaremos avaliar as nossas soluções para prepará-la para uso na Testnet, mas caso contrário, devemos ser capazes de continuar com o curso conforme escrito aqui._ + +Se estiver trabalhando com Bitcoins usando a Ledger, provavelmente precisaremos fazer nada. (Mas não sugerimos isso neste curso). + +Para trabalhar com moedas usando a Testnet, conforme sugerido aqui, precisaremos fazer algumas atualizações: + +1. Vamos em Configurações em nosso aplicativo Ledger Live (clicando na engrenagem), depois na guia "Recursos Experimentais" e vamos ativar o "Modo de Desenvolvedor"; +2. Vamos no "Gerenciar" para instalar o "Bitcoin Test". A versão atual requer que tenhamos o "Bitcoin" e o "Ethereum" instalados primeiro; +3. Vamos no "Gerenciar", para instalar o nosso novo "Bitcoin Test" e "Adicionar uma conta". + +## Acoplando na Ledger + +Para que um Razão esteja acessível, devemos fazer o login com o nosso PIN e, em seguida, acessar o aplicativo que desejamos usar, que no caso é o aplicativo "Bitcoin Test". Pode ser necessário repetir isso algumas vezes quando nossa Ledger ficar em stand-by. + +Depois, podemos solicitar que o HWI acesse a Ledger com o comando `enumerate`: +``` +$ hwi enumerate +[{"type": "ledger", "model": "ledger_nano_s", "path": "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/XHC1@14000000/HS05@14100000/Nano S@14100000/Nano S@0/IOUSBHostHIDDevice@14100000,0", "fingerprint": "9a1d520b", "needs_pin_sent": false, "needs_passphrase_sent": false}] +``` +Se recebermos algumas informações no nosso dispositivo, está tudo certo! Como podemos observar, ele verifica o tipo da hardware wallet, fornecendo outras informações de identificação e também informa como se comunicar com o dispositivo. A ```fingerprint``` (```9a1d520b```) é o que devemos prestar atenção especial, porque todas as interações com nossa hardware wallet irá exigir essa informação. + +Se, ao invés disso, obtivermos como resultado ```[]```, então (1) Não deixamos nosso dispositivo Ledger habilitado com o PIN correto e não escolhemos o aplicativo correto, ou (2) há algo errado com nossa configuração Python, provavelmente uma dependência esteja faltando: Devemos considerar usar o comando ```uninstall``` e tentar do zero novamente. + +## Importando os endereços + +A interação com uma hardware wallet geralmente ocorre em duas partes: Observar os saldos e gastá-los. + +Podemos monitorar os fundos importando os endereços da nossa hardware wallet para o full node, usando o HWI e o ```bitcoin-cli```. + +### Criando uma carteira + +Para usar nossa hardware wallet com o ```bitcoin-cli```, precisaremos criar uma carteira com nome específico no Bitcoin Core, usando o RPC ```createwallet```, que é um comando que não discutimos anteriormente. +``` +$ bitcoin-cli --named createwallet wallet_name="ledger" disable_private_keys="true" +{ + "name": "ledger", + "warning": "" +} +``` +Neste caso, estamos criando uma carteira chamada `ledger` sem chaves privadas (já que estas estarão no dispositivo da Ledger). + +> :book: ***Por que nomear as carteiras?*** Até agora, este curso usou uma carteira padrão ("") no Bitcoin Core. Isso é bom para muitos propósitos, mas é inadequado se tivermos uma situação mais complexa, como quando estamos usando as chaves de uma hardware wallet. Aqui, queremos ser capazes de diferenciar as chaves de locais (que são mantidas na carteira "") e as chaves da Ledger (que são mantidas na carteira "ledger"). + +Agora podemos observar que a nova carteira está em nossa lista de carteiras: +``` +$ bitcoin-cli listwallets +[ + "", + "ledger" +] +``` +Como criamos uma segunda carteira, alguns comandos exigirão um sinalizador ```-rpcwallet =```, para especificar qual delas estamos utilizando. + +### Importando as chaves + +Agora temos que importar uma lista de endereços de observação da hardware wallet. Isso é feito com o comando ```getkeypool``` do HWI: +``` +$ hwi -f 9a1d520b getkeypool --wpkh 0 1000 +[{"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/0/*)#qttxy592", "range": [0, 1000], "timestamp": "now", "internal": false, "keypool": true, "active": true, "watchonly": true}, {"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/1/*)#3lw8ep4j", "range": [0, 1000], "timestamp": "now", "internal": true, "keypool": true, "active": true, "watchonly": true}] +``` +Endereçamos o HWI com a ```fingerprint``` e solicitamos os primeiros 1000 endereços WPKH (Segwit nativo). Em troca, recebemos dois descritores para o conjunto de chaves: Um para receber endereços e outro para alterar endereços. + +> :book: ***O que é um conjunto de chaves?*** Um conjunto de chaves é um grupo de chaves pré-geradas. As hardware wallets modernas criam molhos de chaves usando novos endereços hierárquicos com base na seed original. A ideia destes molhos de chaves é facilitar os requisitos de backup das carteiras. Isso permitia que um usuário gerasse um conjunto de chaves e fizesse backup da carteira imediatamente, ao invés de exigir backups após a criação de cada novo endereço. O conceito também tem se mostrado muito útil na atualidade, pois permite a importação de todo um conjunto de endereços de um dispositivo para outro. + +Os valores retornados pelo comando ```getkeypool``` são os mesmos tipos de descritores que aprendemos na seção [§3.5: Compreendendo o descritor](03_5_Understanding_the_Descriptor.md). Na época, dissemos que eram úteis para mover endereços entre máquinas diferentes. Aqui está o exemplo da vida real: Mover endereços de uma hardware wallet para o node do Bitcoin Core, de modo que nossa máquina conectada à rede possa vigiar as chaves pertencentes à carteira da hardware wallet. + +Assim como aprendemos na seção [§3.5](03_5_Understanding_the_Descriptor.md), podemos examinar esses descritores com o comando RPC ```getdescriptorinfo```: +``` +$ bitcoin-cli getdescriptorinfo "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/0/*)#qttxy592" +{ + "descriptor": "wpkh([9a1d520b/84'/1'/0']tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/0/*)#n65e7wjf", + "checksum": "qttxy592", + "isrange": true, + "issolvable": true, + "hasprivatekeys": false +} +``` +Como seria de esperar, _não_ temos ```privatekeys```, porque as hardware wallets ficam com a posse. + +Com os descritores em mãos, podemos importar as chaves para nossa nova carteira ```ledger``` usando o comando RPC ```importmulti``` que já usamos na seção [§3.5](03_5_Understanding_the_Descriptor.md). Nesse caso, basta colocar toda a resposta que recebemos do HWI entre ```'``` s. +``` +$ bitcoin-cli -rpcwallet=ledger importmulti '[{"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/0/*)#qttxy592", "range": [0, 1000], "timestamp": "now", "internal": false, "keypool": true, "active": true, "watchonly": true}, {"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/1/*)#3lw8ep4j", "range": [0, 1000], "timestamp": "now", "internal": true, "keypool": true, "active": true, "watchonly": true}]' +[ + { + "success": true + }, + { + "success": true + } +] +``` +(Observe que HWI aproveita o caminho de derivação com ```h```s para mostrar as derivações ao invés dos ```'```s, além de ter calculado a soma da verificação corretamente, para que não tenhamos que fazer citações massivas como fizemos na seção §3.5.) + +Agora, _podemos_ listar todos os endereços apenas para observar que recebemos o valor, usando o comando ```getaddressesbylabel```. Todos os 1000 endereços de recebimento estão ali, na carteira ```ledger```! +``` +$ bitcoin-cli -rpcwallet=ledger getaddressesbylabel "" | more +{ + "tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y": { + "purpose": "receive" + }, + "tb1qqzvrm6hujdt93qctuuev5qc4499tq9fdk0prwf": { + "purpose": "receive" + }, +... +} +``` +## Recebendo uma transação + +Obviamente, receber uma transação é bem simples. Usamos o ```getnewaddress``` para solicitar um desses endereços importados: +``` +$ bitcoin-cli -rpcwallet=ledger getnewaddress +tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y +``` +Então enviamos o dinheiro para ele. + +O poder do HWI é que podemos observar os pagamentos do nosso node Bitcoin Core, ao invés de ter que conectar nossa hardware wallet e consultá-la. +``` +$ bitcoin-cli -rpcwallet=ledger listunspent +[ + { + "txid": "c733533eb1c052242f9ed89cd8927aedb41852156e684634ee7c74028774e595", + "vout": 1, + "address": "tb1q948388a23pfsf52kz6skd5k4z4627jja2evztr", + "label": "", + "scriptPubKey": "00142d4f139faa885304d15616a166d2d51574af4a5d", + "amount": 0.01000000, + "confirmations": 12, + "spendable": false, + "solvable": true, + "desc": "wpkh([9a1d520b/84'/1'/0'/0/0]02a013cf9c4b5f5689d9253036a3e477cf98689626f7814c94f092726f11b741ab)#9za8hlvk", + "safe": true + }, + { + "txid": "5b3c4aeb811f9a119fd633b12a6927415cc61b8654628df58e9141cab804bab8", + "vout": 0, + "address": "tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y", + "label": "", + "scriptPubKey": "001400193c8bf25ef056f8d4571a1c3f65123e5fe788", + "amount": 0.01000000, + "confirmations": 1, + "spendable": false, + "solvable": true, + "desc": "wpkh([9a1d520b/84'/1'/0'/0/569]030168d9482e2b02d7027fb4a89edc54adaa1adf709334f647d0a1b0533828aec5)#sx9haake", + "safe": true + } +] +``` +## Criando uma transação com o PSBT + +Observar e receber os pagamentos é apenas metade da batalha. Também podemos fazer pagamentos usando contas mantidas em nossa hardware wallet. Este é o quarto exemplo da vida real usando os PSBTs, de acordo com o processo descrito na seção [§7.1: Criando uma Transação Bitcoin Parcialmente Assinada](7_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md). + +Os comandos funcionam exatamente da mesma forma. Nesse caso, usamos o ```walletcreatefundedpsbt``` para formar nosso PSBT porque estamos em uma situação em que não nos importamos com quais UTXOs são usados: +``` +$ bitcoin-cli -named -rpcwallet=ledger walletcreatefundedpsbt inputs='''[]''' outputs='''[{"tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd":0.015}]''' +{ + "psbt": "cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giBgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxRiaHVILVAAAgAEAAIAAAACAAAAAADkCAAAAAQEfQEIPAAAAAAAWABQtTxOfqohTBNFWFqFm0tUVdK9KXSIGAqATz5xLX1aJ2SUwNqPkd8+YaJYm94FMlPCScm8Rt0GrGJodUgtUAACAAQAAgAAAAIAAAAAAAAAAAAAAIgID2UK1nupSfXC81nmB65XZ+pYlJp/W6wNk5FLt5ZCSx6kYmh1SC1QAAIABAACAAAAAgAEAAAABAAAAAA==", + "fee": 0.00000209, + "changepos": 1 +} +``` +Podemos observar os PSBT e verificar se ele parece correto: +``` +$ psbt="cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giBgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxRiaHVILVAAAgAEAAIAAAACAAAAAADkCAAAAAQEfQEIPAAAAAAAWABQtTxOfqohTBNFWFqFm0tUVdK9KXSIGAqATz5xLX1aJ2SUwNqPkd8+YaJYm94FMlPCScm8Rt0GrGJodUgtUAACAAQAAgAAAAIAAAAAAAAAAAAAAIgID2UK1nupSfXC81nmB65XZ+pYlJp/W6wNk5FLt5ZCSx6kYmh1SC1QAAIABAACAAAAAgAEAAAABAAAAAA==" + +$ bitcoin-cli decodepsbt $psbt +{ + "tx": { + "txid": "45f996d4ff8c9e9ab162f611c5b6ad752479ede9780f9903bdc80cd96619676d", + "hash": "45f996d4ff8c9e9ab162f611c5b6ad752479ede9780f9903bdc80cd96619676d", + "version": 2, + "size": 154, + "vsize": 154, + "weight": 616, + "locktime": 0, + "vin": [ + { + "txid": "5b3c4aeb811f9a119fd633b12a6927415cc61b8654628df58e9141cab804bab8", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + }, + { + "txid": "c733533eb1c052242f9ed89cd8927aedb41852156e684634ee7c74028774e595", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01500000, + "n": 0, + "scriptPubKey": { + "asm": "0 c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "hex": "0014c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd" + ] + } + }, + { + "value": 0.00499791, + "n": 1, + "scriptPubKey": { + "asm": "0 f4e8dde5db370898b57c84566e3f76098850817d", + "hex": "0014f4e8dde5db370898b57c84566e3f76098850817d", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q7n5dmewmxuyf3dtus3txu0mkpxy9pqtacuprak" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.01000000, + "scriptPubKey": { + "asm": "0 00193c8bf25ef056f8d4571a1c3f65123e5fe788", + "hex": "001400193c8bf25ef056f8d4571a1c3f65123e5fe788", + "type": "witness_v0_keyhash", + "address": "tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y" + } + }, + "bip32_derivs": [ + { + "pubkey": "030168d9482e2b02d7027fb4a89edc54adaa1adf709334f647d0a1b0533828aec5", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/0/569" + } + ] + }, + { + "witness_utxo": { + "amount": 0.01000000, + "scriptPubKey": { + "asm": "0 2d4f139faa885304d15616a166d2d51574af4a5d", + "hex": "00142d4f139faa885304d15616a166d2d51574af4a5d", + "type": "witness_v0_keyhash", + "address": "tb1q948388a23pfsf52kz6skd5k4z4627jja2evztr" + } + }, + "bip32_derivs": [ + { + "pubkey": "02a013cf9c4b5f5689d9253036a3e477cf98689626f7814c94f092726f11b741ab", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/0/0" + } + ] + } + ], + "outputs": [ + { + }, + { + "bip32_derivs": [ + { + "pubkey": "03d942b59eea527d70bcd67981eb95d9fa9625269fd6eb0364e452ede59092c7a9", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/1/1" + } + ] + } + ], + "fee": 0.00000209 +} +``` +And as usual, `analyzepsbt` will show how far you've gotten: +E, como de costume, `analisepsbt` mostrará o quão longe você chegou: +``` +$ bitcoin-cli analyzepsbt $psbt +{ + "inputs": [ + { + "has_utxo": true, + "is_final": false, + "next": "signer", + "missing": { + "signatures": [ + "00193c8bf25ef056f8d4571a1c3f65123e5fe788" + ] + } + }, + { + "has_utxo": true, + "is_final": false, + "next": "signer", + "missing": { + "signatures": [ + "2d4f139faa885304d15616a166d2d51574af4a5d" + ] + } + } + ], + "estimated_vsize": 208, + "estimated_feerate": 0.00001004, + "fee": 0.00000209, + "next": "signer" +} +``` +Como importamos aquele conjunto de chaves, o ```bitcoin-cli``` tem todas as informações de que precisa para preencher as entradas, porém, ele não pode assinar porque as chaves privadas são mantidas na hardware wallet. + +É aí que entra o HWI, com o comando ```signtx```. Basta que enviemos junto com o PSBT: +``` +$ hwi -f 9a1d520b signtx $psbt +``` +É provável que tenhamos de mexer em nossa hardware wallet neste momento. O dispositivo provavelmente pedirá a confirmação das entradas, as saídas e a taxa. Quando terminar, ele deve retornar um novo PSBT. + +``` +{"psbt": "cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giAgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxUcwRAIgAxkQlk2fqEMxvP54WWyiFhlfSul9sd4GzKDhfGpmlewCIHYej3zXWWMgWI6rixxQw9yzGozDaFPqQNNIvcFPk+lfASIGAwFo2UguKwLXAn+0qJ7cVK2qGt9wkzT2R9ChsFM4KK7FGJodUgtUAACAAQAAgAAAAIAAAAAAOQIAAAABAR9AQg8AAAAAABYAFC1PE5+qiFME0VYWoWbS1RV0r0pdIgICoBPPnEtfVonZJTA2o+R3z5holib3gUyU8JJybxG3QatHMEQCIH5t6T2yufUP7glYZ8YH0/PhDFpotSmjgZUhvj6GbCFIAiBcgXzyYl7IjYuaF3pJ7AgW1rLYkjeCJJ2M9pVUrq5vFwEiBgKgE8+cS19WidklMDaj5HfPmGiWJveBTJTwknJvEbdBqxiaHVILVAAAgAEAAIAAAACAAAAAAAAAAAAAACICA9lCtZ7qUn1wvNZ5geuV2fqWJSaf1usDZORS7eWQksepGJodUgtUAACAAQAAgAAAAIABAAAAAQAAAAA="} +$ psbt_f="cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giAgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxUcwRAIgAxkQlk2fqEMxvP54WWyiFhlfSul9sd4GzKDhfGpmlewCIHYej3zXWWMgWI6rixxQw9yzGozDaFPqQNNIvcFPk+lfASIGAwFo2UguKwLXAn+0qJ7cVK2qGt9wkzT2R9ChsFM4KK7FGJodUgtUAACAAQAAgAAAAIAAAAAAOQIAAAABAR9AQg8AAAAAABYAFC1PE5+qiFME0VYWoWbS1RV0r0pdIgICoBPPnEtfVonZJTA2o+R3z5holib3gUyU8JJybxG3QatHMEQCIH5t6T2yufUP7glYZ8YH0/PhDFpotSmjgZUhvj6GbCFIAiBcgXzyYl7IjYuaF3pJ7AgW1rLYkjeCJJ2M9pVUrq5vFwEiBgKgE8+cS19WidklMDaj5HfPmGiWJveBTJTwknJvEbdBqxiaHVILVAAAgAEAAIAAAACAAAAAAAAAAAAAACICA9lCtZ7qUn1wvNZ5geuV2fqWJSaf1usDZORS7eWQksepGJodUgtUAACAAQAAgAAAAIABAAAAAQAAAAA=" +``` +Ao analisá-lo, veremos que estamos prontos para finalizá-lo: +``` +$ bitcoin-cli analyzepsbt $psbt_f +{ + "inputs": [ + { + "has_utxo": true, + "is_final": false, + "next": "finalizer" + }, + { + "has_utxo": true, + "is_final": false, + "next": "finalizer" + } + ], + "estimated_vsize": 208, + "estimated_feerate": 0.00001004, + "fee": 0.00000209, + "next": "finalizer" +} +``` +Neste momento, estamos de volta a terras já conhecidas: +``` +$ bitcoin-cli finalizepsbt $psbt_f +{ + "hex": "02000000000102b8ba04b8ca41918ef58d6254861bc65c4127692ab133d69f119a1f81eb4a3c5b0000000000feffffff95e5748702747cee3446686e155218b4ed7a92d89cd89e2f2452c0b13e5333c70100000000feffffff0260e3160000000000160014c772d6f95542e11ef11e8efc7c7a69830ad38a054fa0070000000000160014f4e8dde5db370898b57c84566e3f76098850817d024730440220031910964d9fa84331bcfe78596ca216195f4ae97db1de06cca0e17c6a6695ec0220761e8f7cd7596320588eab8b1c50c3dcb31a8cc36853ea40d348bdc14f93e95f0121030168d9482e2b02d7027fb4a89edc54adaa1adf709334f647d0a1b0533828aec50247304402207e6de93db2b9f50fee095867c607d3f3e10c5a68b529a3819521be3e866c214802205c817cf2625ec88d8b9a177a49ec0816d6b2d8923782249d8cf69554aeae6f17012102a013cf9c4b5f5689d9253036a3e477cf98689626f7814c94f092726f11b741ab00000000", + "complete": true +} +$ hex=02000000000102b8ba04b8ca41918ef58d6254861bc65c4127692ab133d69f119a1f81eb4a3c5b0000000000feffffff95e5748702747cee3446686e155218b4ed7a92d89cd89e2f2452c0b13e5333c70100000000feffffff0260e3160000000000160014c772d6f95542e11ef11e8efc7c7a69830ad38a054fa0070000000000160014f4e8dde5db370898b57c84566e3f76098850817d024730440220031910964d9fa84331bcfe78596ca216195f4ae97db1de06cca0e17c6a6695ec0220761e8f7cd7596320588eab8b1c50c3dcb31a8cc36853ea40d348bdc14f93e95f0121030168d9482e2b02d7027fb4a89edc54adaa1adf709334f647d0a1b0533828aec50247304402207e6de93db2b9f50fee095867c607d3f3e10c5a68b529a3819521be3e866c214802205c817cf2625ec88d8b9a177a49ec0816d6b2d8923782249d8cf69554aeae6f17012102a013cf9c4b5f5689d9253036a3e477cf98689626f7814c94f092726f11b741ab00000000 +$ bitcoin-cli sendrawtransaction $hex +45f996d4ff8c9e9ab162f611c5b6ad752479ede9780f9903bdc80cd96619676d +``` +Pronto, enviamos um saldo com sucesso usando as chaves privadas de nossa hardware wallet! + +## Aprendendo outros comandos HWI + +Existem vários outros comandos disponíveis para usar com o HWI. No momento em que este artigo foi escrito, são eles: +``` +numerate,getmasterxpub,signtx,getxpub,signmessage,getkeypool,getdescriptors,displayaddress,setup,wipe,restore,backup,promptpin,togglepassphrase,sendpin +``` +## Resumo: Integração com hardware wallets + +As hardware wallets podem oferecer melhor proteção, mantendo nossas chaves privadas offline, protegidas no hardware. Felizmente, ainda há uma maneira de interagir com elas usando o ```bitcoin-cli```. Basta instalar o HWI e ele permitirá (1) Importar as chaves públicas para observarmos e; (2) Assinar transações usando nossa hardware wallet. + +> :fire: ***Qual é o poder do HWI?*** O HWI permite que possamos interagir com hardware wallets usando todos os comandos de ```bitcoin-cli``` que aprendemos até agora. Podemos fazer as transações brutas de qualquer tipo e enviar PSBTs para hardware wallets para serem assinadas. Assim, temos todo o poder do Bitcoin Core, mas também temos a segurança de um dispositivo hardware. + +## O Que Vem Depois? + +Vamos expandir ainda mais as transações de Bitcoin com o [Capítulo Oito: Expandindo transações de Bitcoin de outras maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md). \ No newline at end of file From 38cba921fca74ed8f41ec56a383952df522326d2 Mon Sep 17 00:00:00 2001 From: hgrams <77242934+hgrams@users.noreply.github.com> Date: Thu, 15 Jul 2021 14:47:35 -0300 Subject: [PATCH 027/155] Chapter 06 Translated Reviewed --- ...Expanding_Bitcoin_Transactions_Multisigs.md | 6 +++--- pt/06_1_Sending_a_Transaction_to_a_Multisig.md | 18 +++++++++--------- ...6_2_Spending_a_Transaction_to_a_Multisig.md | 6 +++--- pt/06_3_Sending_an_Automated_Multisig.md | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md b/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md index 66cea7e..9aa2c94 100644 --- a/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md +++ b/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md @@ -1,17 +1,17 @@ # Capítulo 6: Expandindo as transações de Bitcoin com multisigs -Transações básicas de Bitcoin: (1) Envia fundos; (2) Para um único destinatário P2PKH ou SegWit; (3) A partir de uma única máquina; (4) Imediatamente. No entanto, todas essas quatro partes desta definição podem ser expandidas usando transações Bitcoin mais complexas. Este primeiro capítulo sobre "Expansão" mostra como variar os pontos (2) e (3), enviando saldos para um endereço que representa vários destinatários (ou, pelo menos, vários assinantes). +Transações básicas de Bitcoin: (1) Enviar fundos; (2) Para um único destinatário P2PKH ou SegWit; (3) A partir de uma única máquina; (4) Imediatamente. No entanto, todas essas quatro partes desta definição podem ser expandidas usando transações Bitcoin mais complexas. Este primeiro capítulo sobre "Expansão" mostra como variar os pontos (2) e (3), enviando saldos para um endereço que representa vários destinatários (ou, pelo menos, vários assinantes). ## Objetivos deste capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: * Criar endereços de Bitcoin multi assinados (multisigs) usando os fundamentos do Bitcoin; * Crie endereços de Bitcoin com várias assinaturas (multisigs) usando mecanismos fáceis. - + Os objetivos secundários do capítulo incluem a capacidade de: * Entender como gastar fundos enviados em uma transação multisig; * Planejar para obter o máximo do poder das multisigs. - + ## Tabela de conteúdo * [Seção 1: Enviando uma Transação Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) diff --git a/pt/06_1_Sending_a_Transaction_to_a_Multisig.md b/pt/06_1_Sending_a_Transaction_to_a_Multisig.md index f54d828..e41eab7 100644 --- a/pt/06_1_Sending_a_Transaction_to_a_Multisig.md +++ b/pt/06_1_Sending_a_Transaction_to_a_Multisig.md @@ -2,17 +2,17 @@ A primeira maneira de variar a forma como enviamos uma transação básica é usando uma multisig. Isso nos dá a capacidade de exigir que várias pessoas (ou, ao menos, várias chaves privadas) autorizem o uso dos fundos. -## Entendendo como Funcionam as Multisigs +## Entendendo como funcionam as Multisigs Em uma transação P2PKH ou SegWit padrão, os bitcoins são enviados para um endereço baseado na chave pública, o que significa que a chave privada relacionada é necessária para desbloquear a transação, resolvendo o quebra-cabeça criptográfico e permitindo que reutilizemos o saldo. Mas e se pudéssemos bloquear uma transação com _múltiplas_ chaves privadas? Isso efetivamente permitiria que os fundos fossem enviados a um grupo de pessoas, onde todas teriam que concordar em reutilizar o saldo. > :book: ***O que é uma multisignature ou multisig?*** Uma _multisignature_ é uma metodologia que permite que mais de uma pessoa crie uma assinatura digital em conjunto. É uma técnica para o uso criptográfico de chaves que vai muito além do Bitcoin. -Tecnicamente, um quebra-cabeça criptográfico com várias assinaturas é criado pelo Bitcoin usando o comando OP_CHECKMULTISIG e, normalmente, é encapsulado em um endereço P2SH. A seção [§10.4: Fazendo um scripto multisig](10_4_Scripting_a_Multisig.md) irá detalhar como isso funciona com mais precisão. Por enquanto, tudo que precisamos saber é que podemos usar o comando ```bitcoin-cli``` para criar endereços multi assinados. Os fundos podem ser enviados para esses endereços como qualquer endereço P2PKH ou Segwit normal, mas várias chaves privadas serão necessárias para que o saldo seja enviado. +Tecnicamente, um quebra-cabeça criptográfico com várias assinaturas é criado pelo Bitcoin usando o comando OP_CHECKMULTISIG e, normalmente, é encapsulado em um endereço P2SH. A seção [§10.4: Fazendo um scripto multisig](10_4_Scripting_a_Multisig.md) irá detalhar como isso funciona com mais precisão. Por enquanto, tudo que precisamos saber é que podemos usar o comando ```bitcoin-cli``` para criar endereços multi assinados. Os fundos podem ser enviados para esses endereços como qualquer endereço P2PKH ou Segwit normal, mas várias chaves privadas serão necessárias para que o saldo seja retirado. > :book: ***O que é uma transação multisig?*** Uma transação com várias assinaturas é uma transação Bitcoin enviada para um endereço com várias assinaturas, exigindo assim que as pessoas de um grupo com várias assinaturas precisem assinar a transação para poder ter acesso ao saldo. -As multisigs simples exigem que todos no grupo assinem o UTXO quando estiver gasto. No entanto, há mais complexidade possível. As assinaturas múltiplas são geralmente descritas como sendo "M de N". Isso significa que a transação está presa com um grupo de chaves "N", mas apenas "M" delas são necessárias para desbloquear a transação. +As multisigs simples exigem que todos no grupo assinem o UTXO quando for usá-lo. No entanto, há mais complexidade possível. As assinaturas múltiplas são geralmente descritas como sendo "M de N". Isso significa que a transação está presa com um grupo de "N" chaves, mas apenas "M" delas são necessárias para desbloquear a transação. > :book: ***O que é uma multisg M-de-N? *** Em uma multisig, as assinaturas "M" de um grupo de "N" são necessárias para formar a assinatura, onde "M ≤ N". @@ -22,7 +22,7 @@ Para bloquear um UTXO com várias chaves privadas, devemos primeiro criar um end ### Criando os Endereços -Para criar um endereço multisig, devemos primeiro preparar os endereços que o multisig irá combinar. A prática recomendada sugere que sempre criemos novos endereços. Isso significa que cada participante irá executar o comando ```getnewaddress``` em sua própria máquina: +Para criar um endereço multisig, devemos primeiro preparar os endereços que o multisig irá combinar. A prática recomendada sugere que sempre criemos endereços novos. Isso significa que cada participante irá executar o comando ```getnewaddress``` em sua própria máquina: ``` machine1$ address1=$(bitcoin-cli getnewaddress) ``` @@ -30,7 +30,7 @@ E: ``` machine2$ address2=$(bitcoin-cli getnewaddress) ``` -Posteriormente, um dos destinatários (ou talvez algum terceiro) precisará combinar ambos endereços. +Posteriormente, um dos destinatários (ou talvez algum terceiro) precisará combinar ambos os endereços. #### Coletando as Chaves Públicas @@ -89,7 +89,7 @@ machine1$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","0 Ao criar o endereço multisig, listamos quantas assinaturas são necessárias com o argumento ```nrequired``` (que é o "M" quando falamos _uma multisig "M de N"_), então listamos o conjunto total de assinaturas possíveis com a argumento ```keys``` (que é o "N"). Observe que as entradas ```keys``` provavelmente vieram de lugares diferentes. Nesse caso, incluímos ```$pubkey1``` da máquina local e ```02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3``` de uma máquina remota. -> :information_source: **NOTA - M de N vs N de N:** Este exemplo mostra a criação de um multisig simples 2 de 2 . Se quisermos criar uma assinatura M de N onde "M :information_source: **NOTA - M de N vs N de N:** Este exemplo mostra a criação de um multisig simples 2 de 2. Se quisermos criar uma assinatura M de N onde "M :book: ***O que é um endereço P2SH?*** O P2SH significa Pay-To-Script-Hash. É um tipo de destinatário diferente de um endereço P2PKH padrão ou mesmo de um Bech32, usado para fundos cujo resgate é baseado em scripts de Bitcoin mais complexos. O ```bitcoin-cli``` usa o encapsulamento P2SH para ajudar a padronizar e simplificar os multisigs como "multisigs P2SH ", assim como P2SH-SegWit estava usando o P2SH para padronizar os endereços SegWit e torná-los totalmente compatíveis com as versões legadas. @@ -197,9 +197,9 @@ Como podemos ver, não houve nada de incomum na criação da transação e ela p ## Resumo: Enviando uma Transação Multsig -Os endereços do Multisig trancam os fundos usando várias chaves privadas, possivelmente exigindo todas essas chaves privadas para resgate e, possivelmente, exigindo apenas algumas do conjunto. Eles são fáceis de serem criadas com o ```bitcoin-cli``` e são simples para serem enviadas. Essa facilidade se deve em grande parte ao uso invisível de endereços P2SH (Pay-To-Script-Hash), um tópico extenso que já falamos duas vezes, com endereços P2SH-SegWit e agora com as multisig, e um outro que receberá mais atenção no futuro. +Os endereços Multisig bloqueiam os fundos usando várias chaves privadas, possivelmente exigindo todas essas chaves privadas para resgate e, possivelmente, exigindo apenas algumas do conjunto. Eles são fáceis de serem criadas com o ```bitcoin-cli``` e são simples para serem enviadas. Essa facilidade se deve em grande parte ao uso invisível de endereços P2SH (Pay-To-Script-Hash), um tópico extenso que já falamos duas vezes, agora com endereços P2SH-SegWit e multisig, e um outro que receberá mais atenção no futuro. -> :fire: ***Qual é o poder das multisig?*** As multisig permitem a modelagem de uma variedade de arranjos financeiros, como corporações, parcerias, comitês e outros grupos. Uma multisig 1 de 2 pode ser a conta bancária conjunta de um casal, enquanto uma multisig 2 de 2 pode ser usado para grandes despesas por uma parceria de responsabilidade limitada. As multisigs também constituem uma das bases dos Smart Contracts. Por exemplo, um negócio imobiliário pode ser fechado com um multisig 2 de 3, onde as assinaturas são enviadas pelo comprador, pelo vendedor e por um agente de custódia. Depois que o agente de custódia concorda que todas as condições foram atendidas, ele libera os fundos para o vendedor, ou, alternativamente, o comprador e o vendedor podem liberar os fundos em conjunto. +> :fire: ***Qual é o poder das multisigs?*** As multisigs permitem a modelagem de uma variedade de arranjos financeiros, como corporações, parcerias, comitês e outros grupos. Uma multisig 1 de 2 pode ser a conta bancária conjunta de um casal, enquanto uma multisig 2 de 2 pode ser usado para grandes despesas por uma parceria de responsabilidade limitada. As multisigs também constituem uma das bases dos Smart Contracts. Por exemplo, um negócio imobiliário pode ser fechado com um multisig 2 de 3, onde as assinaturas são enviadas pelo comprador, pelo vendedor e por um agente de custódia. Depois que o agente de custódia concorda que todas as condições foram atendidas, ele libera os fundos para o vendedor, ou, alternativamente, o comprador e o vendedor podem liberar os fundos em conjunto. ## O Que Vem Depois? diff --git a/pt/06_2_Spending_a_Transaction_to_a_Multisig.md b/pt/06_2_Spending_a_Transaction_to_a_Multisig.md index f916780..865feb5 100644 --- a/pt/06_2_Spending_a_Transaction_to_a_Multisig.md +++ b/pt/06_2_Spending_a_Transaction_to_a_Multisig.md @@ -97,7 +97,7 @@ $ bitcoin-cli -named gettransaction txid=b164388854f9701051809eed166d9f6cedba923 Quando estivermos prontos para gastar os fundos recebidos por um endereço multisig, precisaremos coletar _muitos_ dados: Muito mais do que precisamos quando fazemos uma transação usando um UTXO de um P2PKH normal ou SegWit. Isso ocorre em parte porque as informações sobre o endereço multisig não estão em nossa posse e em parte porque estamos gastando dinheiro que foi enviado para um endereço P2SH (Pay-To-Script-Hash) e isso é muito mais exigente. -No total, precisaremos coletar três coisas: Informações estendidas sobre o UTXO; O redemScript e; Todas as chaves privadas envolvidas. Obviamente, também iremos precisar de um novo endereço de destinatário. As chaves privadas precisam aguardar a etapa de assinatura, mas tudo pode ser feito agora. +No total, precisaremos coletar três coisas: Informações estendidas sobre o UTXO; O redemScript; e todas as chaves privadas envolvidas. Obviamente, também iremos precisar de um novo endereço de destinatário. As chaves privadas precisam aguardar a etapa de assinatura, mas tudo pode ser feito agora. ### Acessando as informações do UTXO @@ -145,7 +145,7 @@ Como essa transação não está fazendo uso total da nossa carteira, precisarem machine1$ bitcoin-cli -named dumpprivkey address=$address1 cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR ``` -> :warning: **Atenção:** Acessar diretamente as chaves privadas do shell é um comportamento muito perigoso e deve ser feito com extremo cuidado se estivermos em um ambiente produtivo. No mínimo, é importante não salvar as informações em uma variável que possa ser acessada pela nossa máquina. Remover o histórico do shell é outro grande passo. No máximo, podemos evitar de fazer isso. +> :warning: **Atenção:** Acessar diretamente as chaves privadas do shell é um comportamento muito perigoso e deve ser feito com extremo cuidado se estivermos em um ambiente produtivo. No mínimo, é importante não salvar as informações em uma variável que possa ser acessada pela nossa máquina. Remover o histórico do shell é outro grande passo. No máximo, podemos evitar de fazer isso. ### Fazendo a nossa primeira assinatura @@ -179,7 +179,7 @@ Isso produz erros assustadores e mostra um status de ```failing```. Tudo bem. Po Agora podemos passar a transação adiante, para ser assinada novamente por nós, que temos a outra parte da multisig. Eles fazem isso executando o mesmo comando de assinatura que fizemos, porém: (1) com o ```hex``` maior que produzimos anteriormente (```bitcoin-cli -named signrawtransactionwithkey hexstring = $ rawtxhex prevtxs = '' '[{"txid": " '$ utxo_txid'", "vout": '$ utxo_vout', "scriptPubKey": " '$ utxo_spk'", "redeemScript": " '$ redeem_script'"}] '' 'privkeys =' [ "cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"] '| jq -r'. | .hex'```) e; (2) com nossa própria chave privada. -> :information_source: **NOTA - M de N vs N de N:** Obviamente, se tivermos uma assinatura N de N (como a multisig 2 de 2 do exemplo), todas as partes precisarão assinar, mas se tiviermos uma multisignatura M de N onde "M :information_source: **NOTA - M de N vs N de N:** Obviamente, se tivermos uma assinatura N de N (como a multisig 2 de 2 do exemplo), todas as partes precisarão assinar, mas se tivermos uma multisig M de N onde "M Date: Mon, 19 Jul 2021 13:26:29 -0300 Subject: [PATCH 028/155] Review 06_0 --- ...xpanding_Bitcoin_Transactions_Multisigs.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md b/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md index 66cea7e..6bf524f 100644 --- a/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md +++ b/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md @@ -1,19 +1,19 @@ -# Capítulo 6: Expandindo as transações de Bitcoin com multisigs +# Capítulo 6: Expandindo Transações no Bitcoin com Multisigs -Transações básicas de Bitcoin: (1) Envia fundos; (2) Para um único destinatário P2PKH ou SegWit; (3) A partir de uma única máquina; (4) Imediatamente. No entanto, todas essas quatro partes desta definição podem ser expandidas usando transações Bitcoin mais complexas. Este primeiro capítulo sobre "Expansão" mostra como variar os pontos (2) e (3), enviando saldos para um endereço que representa vários destinatários (ou, pelo menos, vários assinantes). +Transações básicas no Bitcoin: (1) enviam fundos; (2) para um único destinatário P2PKH ou SegWit; (3) de uma única máquina; (4) imediatamente. No entanto, todas as quatro partes desta definição podem ser expandidas usando transações mais complexas no Bitcoin. Este primeiro capítulo sobre "Expansão" mostra como variar os pontos (2) e (3) enviando saldos para um endereço que representa vários destinatários (ou, pelo menos, vários assinantes). ## Objetivos deste capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - * Criar endereços de Bitcoin multi assinados (multisigs) usando os fundamentos do Bitcoin; - * Crie endereços de Bitcoin com várias assinaturas (multisigs) usando mecanismos fáceis. + * Criar endereços de Bitcoin multi-assinatura (multisig) usando os fundamentos do Bitcoin; + * Criar endereços de Bitcoin multi-assinatura (multisig) usando mecanismos mais fáceis. Os objetivos secundários do capítulo incluem a capacidade de: - * Entender como gastar fundos enviados em uma transação multisig; - * Planejar para obter o máximo do poder das multisigs. + * Entender como gastar fundos enviados para um multisig; + * Planejar para obter o máximo do poder dos multisigs. -## Tabela de conteúdo +## Tabela de Conteúdo - * [Seção 1: Enviando uma Transação Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) - * [Seção 2: Gastando uma Transação Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) - * [Seção 3: Enviando e Gastando uma Transação Multisig de Maneira Automatizada](06_3_Sending_an_Automated_Multisig.md) \ No newline at end of file + * [Seção 1: Enviando uma Transação com Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [Seção 2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [Seção 3: Enviando e Gastando um Multisig de Maneira Automatizada](06_3_Sending_an_Automated_Multisig.md) \ No newline at end of file From bc4705795f024b02ca435fa264c18f3d870508cc Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 19 Jul 2021 15:57:20 -0300 Subject: [PATCH 029/155] Review 06_1 --- ...6_1_Sending_a_Transaction_to_a_Multisig.md | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/pt/06_1_Sending_a_Transaction_to_a_Multisig.md b/pt/06_1_Sending_a_Transaction_to_a_Multisig.md index f54d828..e9c3f57 100644 --- a/pt/06_1_Sending_a_Transaction_to_a_Multisig.md +++ b/pt/06_1_Sending_a_Transaction_to_a_Multisig.md @@ -1,24 +1,24 @@ -# 6.1: Enviando uma Transação Multsig +# 6.1: Enviando uma Transação com Multisig -A primeira maneira de variar a forma como enviamos uma transação básica é usando uma multisig. Isso nos dá a capacidade de exigir que várias pessoas (ou, ao menos, várias chaves privadas) autorizem o uso dos fundos. +A primeira maneira de variar a forma como enviamos uma transação básica é usando um multisig. Isso nos dá a capacidade de exigir que várias pessoas (ou, ao menos, várias chaves privadas) autorizem o uso dos fundos. -## Entendendo como Funcionam as Multisigs +## Entendendo como Funcionam os Multisigs Em uma transação P2PKH ou SegWit padrão, os bitcoins são enviados para um endereço baseado na chave pública, o que significa que a chave privada relacionada é necessária para desbloquear a transação, resolvendo o quebra-cabeça criptográfico e permitindo que reutilizemos o saldo. Mas e se pudéssemos bloquear uma transação com _múltiplas_ chaves privadas? Isso efetivamente permitiria que os fundos fossem enviados a um grupo de pessoas, onde todas teriam que concordar em reutilizar o saldo. -> :book: ***O que é uma multisignature ou multisig?*** Uma _multisignature_ é uma metodologia que permite que mais de uma pessoa crie uma assinatura digital em conjunto. É uma técnica para o uso criptográfico de chaves que vai muito além do Bitcoin. +> :book: ***O que é uma multi-assinatura?*** Uma multi-assinatura é uma metodologia que permite que mais de uma pessoa crie uma assinatura digital em conjunto. É uma técnica geral para o uso criptográfico de chaves que vai muito além do Bitcoin. -Tecnicamente, um quebra-cabeça criptográfico com várias assinaturas é criado pelo Bitcoin usando o comando OP_CHECKMULTISIG e, normalmente, é encapsulado em um endereço P2SH. A seção [§10.4: Fazendo um scripto multisig](10_4_Scripting_a_Multisig.md) irá detalhar como isso funciona com mais precisão. Por enquanto, tudo que precisamos saber é que podemos usar o comando ```bitcoin-cli``` para criar endereços multi assinados. Os fundos podem ser enviados para esses endereços como qualquer endereço P2PKH ou Segwit normal, mas várias chaves privadas serão necessárias para que o saldo seja enviado. +Tecnicamente, um quebra-cabeça criptográfico com várias assinaturas é criado pelo Bitcoin usando o comando OP_CHECKMULTISIG e, normalmente, é encapsulado em um endereço P2SH. A seção [§10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md) irá detalhar como isso funciona com mais precisão. Por enquanto, tudo que precisamos saber é que podemos usar o comando ```bitcoin-cli``` para criar endereços multi-assinatura. Os fundos podem ser enviados para esses endereços como qualquer endereço P2PKH ou Segwit normal, mas várias chaves privadas serão necessárias para que o saldo seja resgatado. -> :book: ***O que é uma transação multisig?*** Uma transação com várias assinaturas é uma transação Bitcoin enviada para um endereço com várias assinaturas, exigindo assim que as pessoas de um grupo com várias assinaturas precisem assinar a transação para poder ter acesso ao saldo. +> :book: ***O que é uma transação multisig?*** Uma transação multisig é uma transação no Bitcoin enviada para um endereço com várias assinaturas, exigindo assim que certas pessoas do grupo multi-assinatura precisem assinar a transação para poder reutilizar o saldo. -As multisigs simples exigem que todos no grupo assinem o UTXO quando estiver gasto. No entanto, há mais complexidade possível. As assinaturas múltiplas são geralmente descritas como sendo "M de N". Isso significa que a transação está presa com um grupo de chaves "N", mas apenas "M" delas são necessárias para desbloquear a transação. +Multisigs simples exigem que todos no grupo assinem o UTXO quando for gasto. No entanto, há mais complexidade possível. Multisigs são geralmente descritos como sendo "m de n". Isso significa que a transação está trancada com um grupo de chaves "n", mas apenas "m" delas são necessárias para desbloquear a transação. -> :book: ***O que é uma multisg M-de-N? *** Em uma multisig, as assinaturas "M" de um grupo de "N" são necessárias para formar a assinatura, onde "M ≤ N". +> :book: ***O que é um multisg m-de-n?*** Em um multisig, "m" assinaturas de um grupo de "n" são necessárias para formar a assinatura, onde "m ≤ n". ## Criando um Endereço Multisig -Para bloquear um UTXO com várias chaves privadas, devemos primeiro criar um endereço com várias assinaturas. Os exemplos usados ​​aqui mostram a criação (e uso) de uma multisig 2 de 2 (normalmente é assim que falamos quando nos referimos a um endereço multisg, descrevemos a quantidade de chaves e a quantidade necessária para desbloquear o saldo). +Para trancar um UTXO com várias chaves privadas, devemos primeiro criar um endereço multi-assinatura. Os exemplos usados ​​aqui mostram a criação (e uso) de um multisig 2-de-2. ### Criando os Endereços @@ -32,13 +32,13 @@ machine2$ address2=$(bitcoin-cli getnewaddress) ``` Posteriormente, um dos destinatários (ou talvez algum terceiro) precisará combinar ambos endereços. -#### Coletando as Chaves Públicas +#### Coletando Chaves Públicas No entanto, não podemos criar um multisig com os endereços, pois esses são os hashes das chaves públicas: Ao invés disso, precisamos das próprias chaves públicas. Esta informação está disponível facilmente com o comando ```getaddressinfo```. -Na máquina remota, que assumimos aqui é ```machine2```, podemos obter as informações em uma lista. +Na máquina remota, que assumimos aqui que é ```machine2```, podemos obter as informações em uma lista. ``` machine2$ bitcoin-cli -named getaddressinfo address=$address2 { @@ -65,9 +65,9 @@ machine2$ bitcoin-cli -named getaddressinfo address=$address2 ``` O endereço ```pubkey``` (` 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3`) é o que precisamos. Vamos copiá-lo para nossa máquina local por qualquer meio que acharmos mais eficiente e _que seja menos sujeito a erros_. -Este processo precisa ser realizado para _cada_ endereço de uma máquina diferente daquela onde o multisig está sendo construída. Obviamente, se algum terceiro estiver criando o endereço, precisaremos fazer isso para cada endereço. +Este processo precisa ser realizado para _cada_ endereço de uma máquina diferente daquela onde o multisig está sendo construído. Obviamente, se algum terceiro estiver criando o endereço, precisaremos fazer isso para cada endereço. -> :warning: **Atenção:** O uso de hashes de chave pública pelo Bitcoin como endereços, ao invés de chaves públicas, na verdade representa uma camada adicional de segurança. Porém, o envio de uma chave pública aumenta ligeiramente a vulnerabilidade do endereço associado, para alguma possibilidade no futuro distante de um comprometimento devido a curva elíptica. Não devemos nos preocupar em termos que enviar ocasionalmente uma chave pública para um uso como esse, mas devemos estar cientes de que os hashes de chave pública representam segurança e, portanto, as chaves públicas reais não devem ser enviadas de qualquer jeito para qualquer pessoa. +> :warning: **ATENÇÃO:** O uso de hashes de chave pública pelo Bitcoin como endereços, ao invés de chaves públicas, na verdade representa uma camada adicional de segurança. Portanto, o envio de uma chave pública aumenta ligeiramente a vulnerabilidade do endereço associado, devido a alguma possibilidade do comprometimento da curva elíptica em um futuro distante. Não devemos nos preocupar em termos que enviar ocasionalmente uma chave pública para um uso como esse, mas devemos estar cientes de que os hashes de chave pública representam segurança e, portanto, as chaves públicas reais não devem ser enviadas de qualquer jeito para qualquer pessoa. Se um dos endereços foi criado em nossa máquina local, que assumimos aqui que seja ```machine1```, podemos simplesmente colocar o endereço ```pubkey``` em uma nova variável. ``` @@ -76,7 +76,7 @@ machine1$ pubkey1=$(bitcoin-cli -named getaddressinfo address=$address1 | jq -r ### Criando o Endereço -Uma multisig agora pode ser criada com o comando ```createmultisig```: +Um multisig agora pode ser criado com o comando ```createmultisig```: ``` machine1$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3"]''' { @@ -87,36 +87,36 @@ machine1$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","0 ``` > :warning: **AVISO DE VERSÃO:** Algumas versões do ```createmultisig``` permitem a entrada de chaves públicas ou endereços, algumas requerem apenas as chaves públicas. Atualmente, ambas parecem funcionar. -Ao criar o endereço multisig, listamos quantas assinaturas são necessárias com o argumento ```nrequired``` (que é o "M" quando falamos _uma multisig "M de N"_), então listamos o conjunto total de assinaturas possíveis com a argumento ```keys``` (que é o "N"). Observe que as entradas ```keys``` provavelmente vieram de lugares diferentes. Nesse caso, incluímos ```$pubkey1``` da máquina local e ```02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3``` de uma máquina remota. +Ao criar o endereço multisig, listamos quantas assinaturas são necessárias com o argumento ```nrequired``` (que é o "m" em um multisig "m-de-n"), então listamos o conjunto total de assinaturas possíveis com a argumento ```keys``` (que é o "n"). Observe que as entradas ```keys``` provavelmente vieram de lugares diferentes. Nesse caso, incluímos ```$pubkey1``` da máquina local e ```02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3``` de uma máquina remota. -> :information_source: **NOTA - M de N vs N de N:** Este exemplo mostra a criação de um multisig simples 2 de 2 . Se quisermos criar uma assinatura M de N onde "M :information_source: **NOTA –– M-DE-N VS N-DE-N:** Este exemplo mostra a criação de um multisig simples 2-de-2 . Se quisermos criar uma assinatura m-de-n onde "m < n", precisamos apenas ajustar o campo ```nrequired``` e/ou o número de assinaturas ```keys``` no objeto JSON. Para um multisig 1-de-2, seria definido como ```nrequired = 1``` e também listaria duas chaves, enquanto para um multisig 2-de-3, seria necessário um ```nrequired = 2```, mas adicionaria mais uma chave pública à lista de ```keys```. Quando usado corretamente, o ```createmultisig``` retorna três resultados, todos criticamente importantes. O _endereço_ é o que iremos distribuir para as pessoas que desejam enviar os fundos. Podemos notar que ele tem um novo prefixo ```2```, exatamente como os endereços P2SH-SegWit. Isso porque, como eles, o comando ```createmultisig``` está na verdade criando um tipo de endereço totalmente novo chamado endereço P2SH. Ele funciona exatamente como um endereço P2PKH padrão para envio de fundos, mas como este foi criado para exigir vários endereços, precisaremos trabalhar um pouco mais para utilizá-los. -> :link: **TESTNET vs MAINNET:** Na Testenet, o prefixo para endereços P2SH é ```2```, enquanto na Mainnet é ```3```. +> :link: **TESTNET vs MAINNET:** Na testenet, o prefixo para endereços P2SH é ```2```, enquanto na Mainnet é ```3```. -O _redeemScript_ é o que precisaremos para resgatar os fundos (junto com as chaves privadas de "M" dos "N" endereços). Este script é outro recurso especial dos endereços P2SH e será explicado com mais detalhes na seção [§8.1: Construindo um Script Bitcoin com P2SH](08_1_Building_a_Bitcoin_Script_with_P2SH.md). Por enquanto, precisamos apenas saber que alguns dados são necessários para podemos gastar nosso dinheiro. +O _redeemScript_ é o que precisaremos para resgatar os fundos (junto com as chaves privadas de "m" dos "n" endereços). Este script é outro recurso especial dos endereços P2SH e será explicado com mais detalhes na seção [§10.3: Rodando um Script no Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md). Por enquanto, precisamos apenas saber que alguns dados são necessários para podemos gastar nosso dinheiro. -O _descritor_ é a descrição padronizada para um endereço que encontramos na seção [§3.5: Compreendendo o descriptor](03_5_Understanding_the_Descriptor.md). Ele fornece uma maneira de importar esse endereço de volta para a outra máquina, usando o RPC ```importmulti```. +O _descritor_ é a descrição padronizada para um endereço que encontramos na seção [§3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md). Ele fornece uma maneira de importar esse endereço de volta para a outra máquina, usando o RPC ```importmulti```. -> :book: ***O que é um endereço P2SH?*** O P2SH significa Pay-To-Script-Hash. É um tipo de destinatário diferente de um endereço P2PKH padrão ou mesmo de um Bech32, usado para fundos cujo resgate é baseado em scripts de Bitcoin mais complexos. O ```bitcoin-cli``` usa o encapsulamento P2SH para ajudar a padronizar e simplificar os multisigs como "multisigs P2SH ", assim como P2SH-SegWit estava usando o P2SH para padronizar os endereços SegWit e torná-los totalmente compatíveis com as versões legadas. +> :book: ***O que é um endereço P2SH?*** O P2SH significa Pay-To-Script-Hash. É um tipo de destinatário diferente de um endereço P2PKH padrão ou mesmo de um Bech32, usado para fundos cujo resgate é baseado em scripts de Bitcoin mais complexos. O ```bitcoin-cli``` usa o encapsulamento P2SH para ajudar a padronizar e simplificar os multisigs como "multisigs P2SH", assim como P2SH-SegWit estava usando o P2SH para padronizar os endereços SegWit e torná-los totalmente compatíveis com as versões antigas. -> :warning: **Atenção:** endereços P2SH multisig, como os criados pelo ```bitcoin-cli```, têm um limite para "M" e "N" nos multisigs com base no tamanho máximo do script de resgate, que atualmente é de 520 bytes. Praticamente, não vamos chegar a isso, a menos que estejamos nos excedendo em algo. +> :warning: **ATENÇÃO:** endereços P2SH multisig, como os criados pelo ```bitcoin-cli```, têm um limite para "m" e "n" nos multisigs com base no tamanho máximo do script de resgate, que atualmente é de 520 bytes. Praticamente, não vamos chegar a isso, a menos que estejamos nos excedendo em algo. ### Salvando Nosso Trabalho -Aqui está uma informação importante: Nada sobre nosso multisig é salvo em nossa carteira usando essas técnicas básicas. Para resgatar o saldo enviado para este endereço multisig no futuro, precisaremos reter duas informações cruciais: +Aqui está uma informação importante: nada sobre nosso multisig é salvo em nossa carteira usando essas técnicas básicas. Para resgatar o saldo enviado para este endereço multisig no futuro, precisaremos reter duas informações cruciais: * Uma lista dos endereços Bitcoin usados ​​no multisig, e; * A saída ```redeemScript``` criada pelo comando ```createmultsig```. -Tecnicamente, o ```redeemScript``` pode ser recriado executando novamente o ```createmultisig``` com a lista completa de chaves públicas _na mesma ordem_ e com a contagem correta de M e de N. Mas, é melhor agarrar-se a ela e evitar qualquer tipo de estresse futuro. +Tecnicamente, o ```redeemScript``` pode ser recriado executando novamente o ```createmultisig``` com a lista completa de chaves públicas _na mesma ordem_ e com a contagem m-de-n correta. Mas, é melhor agarrar-se a ela e evitar qualquer tipo de estresse futuro. -### Observando a Ordem +### Observe a Ordem -Aqui está mais uma coisa que devemos tomar muito cuidado: A _ordem é muito importante_. A ordem das chaves usadas para criar um multisig cria um hash único, ou seja, se colocarmos as chaves em uma ordem diferente, elas irão produzir um endereço diferente, conforme mostrado abaixo: +Aqui está mais uma coisa que devemos tomar muito cuidado: _a ordem importa_. A ordem das chaves usadas para criar um multisig cria um hash único, ou seja, se colocarmos as chaves em uma ordem diferente, elas irão produzir um endereço diferente, conforme mostrado abaixo: ``` $ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]''' { @@ -131,11 +131,11 @@ standup@btctest20:~$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$p "descriptor": "sh(multi(2,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03))#audl88kg" } ``` -Mais notavelmente, cada ordem cria um _redeemScript_ diferente. Isso significa que se usamos essas técnicas básicas e não conseguimos salvar o redemScript conforme as instruções, teremos que percorrer um número cada vez maior de variações para encontrar aquela correta quando tentarmos gastar os fundos! +Mais notavelmente, cada ordem cria um _redeemScript_ diferente. Isso significa que se usamos essas técnicas básicas e não salvarmos o redemScript conforme as instruções, teremos que percorrer um número cada vez maior de variações para encontrar a correta quando tentarmos gastar os fundos! -O [BIP67](https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki) sugere uma maneira de ordenar lexicograficamente as chaves, de modo que sempre gerem as mesmas multisigs. A ColdCard e a Electrum estão entre as carteiras que já possuem suporte a isso. Claro, isso pode causar problemas por si só se não soubermos se um endereço multisig foi criado com chaves classificadas ou não classificadas. Mais uma vez, os [descritores](03_5_Understanding_the_Descriptor.md) vem ao nosso resgate. Se uma multisig não for classificada, ele será construído com a função ```multi``` e se for classificada, será construída com a função ```sortedmulti```. +O [BIP67](https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki) sugere uma maneira de ordenar lexicograficamente as chaves, de modo que sempre gerem as mesmas multisigs. A ColdCard e a Electrum estão entre as carteiras que já possuem suporte a isso. Claro, isso pode causar problemas por si só se não soubermos se um endereço multisig foi criado com chaves classificadas ou não classificadas. Mais uma vez, os [descritores](03_5_Understanding_the_Descriptor.md) vêm ao nosso resgate. Se um multisig não for classificado, ele será construído com a função ```multi```, e se for classificado, será construído com a função ```sortedmulti```. -Se olharmos o ```desc``` da multisig que criamos acima, veremos que o Bitcoin Core atualmente não classifica os multisigs: +Se olharmos o ```desc``` do multisig que criamos acima, veremos que o Bitcoin Core atualmente não classifica os multisigs: ``` "descriptor": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y" ``` @@ -143,9 +143,9 @@ Porém, se ele importa um endereço do tipo ```sortedmulti```, ele fará o proce > :warning: **AVISO DE VERSÃO:** O Bitcoin Core só entende a função do descritor ```sortedmulti``` após a versão 0.20.0. Podemos tentar acessar o descritor em uma versão anterior do Bitcoin Core e obteremos um erro como ```A function is needed within P2WSH```. -## Enviando Fundos para um Endereço Multisig +## Enviando para um Endereço Multisig -Se tivermos uma multisig em um formato P2SH conveniente, como o gerado pelo ```bitcoin-cli```, podemos enviar como um endereço normal. +Se tivermos um multisig em um formato P2SH conveniente, como o gerado pelo ```bitcoin-cli```, podemos enviar como um endereço normal. ``` $ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') $ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') @@ -195,12 +195,12 @@ b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 ``` Como podemos ver, não houve nada de incomum na criação da transação e ela parece normal, embora com um endereço com um prefixo diferente do normal (```2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr```). Sem surpresa, como também não vimos diferença quando enviamos para endereços Bech32 pela primeira vez na seção [§4.6](04_6_Creating_a_Segwit_Transaction.md). -## Resumo: Enviando uma Transação Multsig +## Resumo: Enviando uma Transação Multisig -Os endereços do Multisig trancam os fundos usando várias chaves privadas, possivelmente exigindo todas essas chaves privadas para resgate e, possivelmente, exigindo apenas algumas do conjunto. Eles são fáceis de serem criadas com o ```bitcoin-cli``` e são simples para serem enviadas. Essa facilidade se deve em grande parte ao uso invisível de endereços P2SH (Pay-To-Script-Hash), um tópico extenso que já falamos duas vezes, com endereços P2SH-SegWit e agora com as multisig, e um outro que receberá mais atenção no futuro. +Os endereços multisig trancam os fundos usando várias chaves privadas, possivelmente exigindo todas essas chaves privadas para resgate e, possivelmente, exigindo apenas algumas do conjunto. Eles são fáceis de serem criados com o ```bitcoin-cli``` e são simples para serem enviados. Essa facilidade se deve em grande parte ao uso invisível de endereços P2SH (Pay-To-Script-Hash), um tópico extenso que já falamos duas vezes, com endereços P2SH-SegWit e agora com os multisigs, e um outro que receberá mais atenção no futuro. -> :fire: ***Qual é o poder das multisig?*** As multisig permitem a modelagem de uma variedade de arranjos financeiros, como corporações, parcerias, comitês e outros grupos. Uma multisig 1 de 2 pode ser a conta bancária conjunta de um casal, enquanto uma multisig 2 de 2 pode ser usado para grandes despesas por uma parceria de responsabilidade limitada. As multisigs também constituem uma das bases dos Smart Contracts. Por exemplo, um negócio imobiliário pode ser fechado com um multisig 2 de 3, onde as assinaturas são enviadas pelo comprador, pelo vendedor e por um agente de custódia. Depois que o agente de custódia concorda que todas as condições foram atendidas, ele libera os fundos para o vendedor, ou, alternativamente, o comprador e o vendedor podem liberar os fundos em conjunto. +> :fire: ***Qual é o poder das multi-assinaturas?*** As multi-assinaturas permitem a modelagem de uma variedade de arranjos financeiros, como corporações, parcerias, comitês e outros grupos. Um multisig 1-de-2 pode ser a conta bancária conjunta de um casal, enquanto um multisig 2-de-2 pode ser usado para grandes despesas por uma parceria de responsabilidade limitada. Os multisigs também constituem uma das bases dos Smart Contracts. Por exemplo, um negócio imobiliário pode ser fechado com um multisig 2-de-3, onde as assinaturas são enviadas pelo comprador, pelo vendedor e por um agente de custódia. Depois que o agente de custódia concorda que todas as condições foram atendidas, ele libera os fundos para o vendedor, ou, alternativamente, o comprador e o vendedor podem liberar os fundos em conjunto. ## O Que Vem Depois? -Vamos continuar "Expandindo as transações de Bitcoin com multisigs" na seção [§6.2: Gastando uma transação Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md). \ No newline at end of file +Vamos continuar "Expandindo Transações no Bitcoin com Multisigs" na seção [§6.2: Gastando uma Transação com Multisig](06_2_Spending_a_Transaction_to_a_Multisig.md). \ No newline at end of file From d5fb91ac00fb1b39913eed8c054b45b8065ef080 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 19 Jul 2021 15:58:44 -0300 Subject: [PATCH 030/155] Fix typos --- pt/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pt/README.md b/pt/README.md index cd3ef49..2917302 100644 --- a/pt/README.md +++ b/pt/README.md @@ -52,8 +52,8 @@ Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuin * [5.2: Re-enviando uma Transação com RBF](05_2_Resending_a_Transaction_with_RBF.md) * [5.3: Financiando uma Transação com CPFP](05_3_Funding_a_Transaction_with_CPFP.md) * [6.0: Expandindo Transações no Bitcoin com Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md) - * [6.1: Enviando uma Transação com Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) - * [6.2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [6.1: Enviando uma Transação com Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [6.2: Gastando uma Transação com Multisig](06_2_Spending_a_Transaction_to_a_Multisig.md) * [6.3: Enviando & Gastando um Multisig Automatizado](06_3_Sending_an_Automated_Multisig.md) * [7.0: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md) * [7.1: Criando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) From 9ec21b57cd789f2335dbb7e8f45028670ccd2107 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 19 Jul 2021 16:20:58 -0300 Subject: [PATCH 031/155] Review 06_2 --- ..._2_Spending_a_Transaction_to_a_Multisig.md | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/pt/06_2_Spending_a_Transaction_to_a_Multisig.md b/pt/06_2_Spending_a_Transaction_to_a_Multisig.md index f916780..8114969 100644 --- a/pt/06_2_Spending_a_Transaction_to_a_Multisig.md +++ b/pt/06_2_Spending_a_Transaction_to_a_Multisig.md @@ -1,8 +1,8 @@ -# 6.2: Gastando uma Transação Multsig +# 6.2: Gastando uma Transação com Multsig A maneira clássica e complexa de gastar fundos enviados para um endereço com várias assinaturas usando o ```bitcoin-cli``` requer que suemos bastante a camisa. -## Encontrando os fundos +## Encontrando os Fundos Para começar, precisamos encontrar nossos fundos. Nosso computador não sabe procurá-los, porque não estão associados a nenhum endereço da nossa carteira. Podemos alertar o ```bitcoind``` para fazer isso usando o comando ```importaddress```: ``` @@ -93,25 +93,25 @@ $ bitcoin-cli -named gettransaction txid=b164388854f9701051809eed166d9f6cedba923 } ``` -## Configurando as nossas variáveis +## Configurando as Nossas Variáveis -Quando estivermos prontos para gastar os fundos recebidos por um endereço multisig, precisaremos coletar _muitos_ dados: Muito mais do que precisamos quando fazemos uma transação usando um UTXO de um P2PKH normal ou SegWit. Isso ocorre em parte porque as informações sobre o endereço multisig não estão em nossa posse e em parte porque estamos gastando dinheiro que foi enviado para um endereço P2SH (Pay-To-Script-Hash) e isso é muito mais exigente. +Quando estivermos prontos para gastar os fundos recebidos por um endereço multisig, precisaremos coletar _muitos_ dados: muito mais do que precisamos quando fazemos uma transação usando um UTXO de um P2PKH normal ou SegWit. Isso ocorre em parte porque as informações sobre o endereço multisig não estão em nossa posse e em parte porque estamos gastando dinheiro que foi enviado para um endereço P2SH (Pay-To-Script-Hash) e isso é muito mais exigente. -No total, precisaremos coletar três coisas: Informações estendidas sobre o UTXO; O redemScript e; Todas as chaves privadas envolvidas. Obviamente, também iremos precisar de um novo endereço de destinatário. As chaves privadas precisam aguardar a etapa de assinatura, mas tudo pode ser feito agora. +No total, precisaremos coletar três coisas: informações estendidas sobre o UTXO; o redemScript e; todas as chaves privadas envolvidas. Obviamente, também iremos precisar de um novo endereço de destinatário. As chaves privadas precisam aguardar a etapa de assinatura, mas tudo pode ser feito agora. -### Acessando as informações do UTXO +### Acessando as Informações do UTXO Para começar, vamos pegar o ```txid``` e o ```vout``` para a transação que desejamos gastar, como de costume. Nesse caso, os dados foram recuperados das informações ```gettransaction``` acima: ``` $ utxo_txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 $ utxo_vout=0 ``` -No entanto, precisamos também acessar um terceiro bit de informação sobre o UTXO, nosso ```scriptPubKey```/```hex```, que é o script que travamos a transação. Novamente, podemos fazer isso observando os detalhes da transação: +No entanto, precisamos também acessar um terceiro pedaço de informação sobre o UTXO, nosso ```scriptPubKey```/```hex```, que é o script que travou a transação. Novamente, podemos fazer isso observando os detalhes da transação: ``` $ utxo_spk=a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387 ``` -### Gravando o script de resgate +### Gravando o Script de Resgate Felizmente, salvamos nosso ```redeemScript```. Agora devemos registrá-lo em uma variável. @@ -119,13 +119,13 @@ O valor foi extraído da criação de endereço na seção anterior. ``` redeem_script="522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae" ``` -### Decidindo o destinatário +### Decidindo o Destinatário Vamos apenas enviar o dinheiro de volta para nós mesmos. Isso é útil porque libera os fundos do multisig, convertendo-os em uma transação P2PKH normal que pode ser posteriormente confirmada por uma única chave privada: ``` $ recipient=$(bitcoin-cli getrawchangeaddress) ``` -## Criando nossa transação +## Criando Nossa Transação Agora podemos criar nossa transação. Essa parte é parecida com as transações normais. ``` @@ -134,22 +134,22 @@ $ echo $rawtxhex 020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b10000000000ffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 ``` -## Assinando a nossa transação +## Assinando Nossa Transação Agora estamos prontos para assinar a transação. Este é um processo de várias etapas porque precisaremos fazer em várias máquinas, cada uma das quais contribuirá com suas próprias chaves privadas. -### Carregando a primeira chave privada +### Carregando a Primeira Chave Privada Como essa transação não está fazendo uso total da nossa carteira, precisaremos acessar diretamente as chaves privadas. Começando com a ```máquina1```, onde devemos recuperar qualquer uma das chaves privadas do usuário que estavam envolvidas no multisig: ``` machine1$ bitcoin-cli -named dumpprivkey address=$address1 cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR ``` -> :warning: **Atenção:** Acessar diretamente as chaves privadas do shell é um comportamento muito perigoso e deve ser feito com extremo cuidado se estivermos em um ambiente produtivo. No mínimo, é importante não salvar as informações em uma variável que possa ser acessada pela nossa máquina. Remover o histórico do shell é outro grande passo. No máximo, podemos evitar de fazer isso. +> :warning: **ATENÇÃO:** Acessar diretamente as chaves privadas do shell é um comportamento muito perigoso e deve ser feito com extremo cuidado se estivermos usando dinheiro de verdade. No mínimo, é importante não salvar as informações em uma variável que possa ser acessada pela nossa máquina. Remover o histórico do shell é outro grande passo. No máximo, podemos evitar de fazer isso. -### Fazendo a nossa primeira assinatura +### Fazendo Nossa Primeira Assinatura -Agora podemos fazer nossa primeira assinatura com o comando ```signrawtransactionwithkey```. É aqui que as coisas ficam diferentes das normais: Precisaremos treinar o comando sobre como assinar. Podemos fazer isso adicionando as seguintes informações novas: +Agora podemos fazer nossa primeira assinatura com o comando ```signrawtransactionwithkey```. É aqui que as coisas ficam diferentes: precisaremos treinar o comando sobre como assinar. Podemos fazer isso adicionando as seguintes informações novas: * Incluir um argumento ```prevtxs``` que tenha o ```txid```, o ```vout```, o ```scriptPubKey``` e o ```redeemScript``` que gravamos, cada um deles um par individual do valor-chave no objeto JSON. * Incluir um argumento ```privkeys``` que lista as chaves privadas que pegamos nesta máquina. @@ -175,18 +175,18 @@ machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevt ``` Isso produz erros assustadores e mostra um status de ```failing```. Tudo bem. Podemos ver que a assinatura foi parcialmente bem-sucedida porque o ```hex``` ficou mais longo. Embora a transação tenha sido parcialmente assinada, ela não foi concluída porque precisa de mais assinaturas. -### Repetindo para os outros assinantes +### Repetindo para os Outros Assinantes -Agora podemos passar a transação adiante, para ser assinada novamente por nós, que temos a outra parte da multisig. Eles fazem isso executando o mesmo comando de assinatura que fizemos, porém: (1) com o ```hex``` maior que produzimos anteriormente (```bitcoin-cli -named signrawtransactionwithkey hexstring = $ rawtxhex prevtxs = '' '[{"txid": " '$ utxo_txid'", "vout": '$ utxo_vout', "scriptPubKey": " '$ utxo_spk'", "redeemScript": " '$ redeem_script'"}] '' 'privkeys =' [ "cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"] '| jq -r'. | .hex'```) e; (2) com nossa própria chave privada. +Agora podemos passar a transação adiante, para ser assinada novamente por outros exigidos pelo multisig. Eles fazem isso executando o mesmo comando de assinatura que fizemos, porém: (1) com o ```hex``` maior que produzimos anteriormente (```bitcoin-cli -named signrawtransactionwithkey hexstring = $ rawtxhex prevtxs = '' '[{"txid": " '$ utxo_txid'", "vout": '$ utxo_vout', "scriptPubKey": " '$ utxo_spk'", "redeemScript": " '$ redeem_script'"}] '' 'privkeys =' [ "cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"] '| jq -r'. | .hex'```) e; (2) com sua própria chave privada. -> :information_source: **NOTA - M de N vs N de N:** Obviamente, se tivermos uma assinatura N de N (como a multisig 2 de 2 do exemplo), todas as partes precisarão assinar, mas se tiviermos uma multisignatura M de N onde "M :information_source: **NOTA - M-DE-N VS N-DE-N:** Obviamente, se tivermos uma assinatura N de N (como a multisig 2-de-2 do exemplo), todas as partes precisarão assinar, mas se tivermos uma multi-assinatura m-de-n onde "m < n", a assinatura estará completa quando apenas alguns ("m") tiverem assinado. -Para fazer isso, primeiro acessamos as chaves privadas: +Para fazer isso, primeiro eles acessam suas chaves privadas: ``` machine2$ bitcoin-cli -named dumpprivkey address=$address2 cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz ``` -Depois, assinamos o novo ```hex``` usando os mesmos valores ```prevtxs```: +Depois, assinam o novo ```hex``` usando os mesmos valores ```prevtxs```: ``` machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz"]' { @@ -194,11 +194,11 @@ machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=02000000012165 "complete": true } ``` -Por fim, podemos precisar enviar uma ```hexstring``` ainda mais longa que produzem para assinaturas adicionais. +Por fim, podem precisar enviar uma ```hexstring``` ainda mais longa que eles tenham produzido para assinantes adicionais. Mas, neste caso, podemos ver que a assinatura está `complete`! -## Enviando nossa transação +## Enviando Nossa Transação Quando terminarmos, devemos recorrer à metodologia ```JQ``` padrão para salvar nossa ```hexstring``` e, em seguida, enviá-la: ``` @@ -207,9 +207,9 @@ $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx 99d2b5717fed8875a1ed3b2827dd60ae3089f9caa7c7c23d47635f6f5b397c04 ``` -## Compreendendo a importância desta metodologia de assinatura expandida +## Compreendendo a Importância Desta Metodologia de Assinatura Expandida -Isso deu um belo trabalho e, como logo iremos aprender, existe uma tolice ao utilizar as chaves privadas, o redeem script e com a scriptpubkey pois eles não são realmente necessários para resgatar os endereços de multisg usando versões mais recentes do Bitcoin Core. Então qual era a questão? +Isto deu um belo trabalho e, como logo iremos aprender, existe uma tolice ao utilizar as chaves privadas, o redeem script e com a scriptpubkey pois eles não são realmente necessários para resgatar os endereços de multisg usando versões mais recentes do Bitcoin Core. Então, qual foi o ponto? Esta metodologia de resgate mostra uma maneira padrão de assinar e reutilizar transações P2SH. Em suma, para resgatar fundos P2SH, uma ```signrawtransactionwithkey``` precisa: @@ -220,10 +220,10 @@ Esta metodologia de resgate mostra uma maneira padrão de assinar e reutilizar t Aqui, vimos essa metodologia usada para resgatar os fundos multisig. No futuro, também podemos usá-la para resgatar os fundos que foram trancados com outros scripts P2SH mais complexos, conforme explicado no Capítulo 9. -## Resumo: Gastando uma Transação Multsig +## Resumo: Gastando uma Transação com Multisig Acontece que gastar dinheiro enviado para um endereço multisig pode dar um pouco de trabalho. Mas, contanto que tenhamos os endereços originais e nosso redemScript, podemos fazer isso assinando uma transação bruta com cada endereço diferente e fornecendo mais algumas informações ao longo do caminho. ## O Que Vem Depois? -Vamos continuar "Expandindo as transações de Bitcoin com multisigs" na seção [§6.3: Enviando e Gastando uma Transação Multisig de Maneira Automatizada](06_3_Sending_an_Automated_Multisig.md). \ No newline at end of file +Vamos continuar "Expandindo Transações no Bitcoin com Multisigs" na seção [§6.3: Enviando & Gastando um Multisig Automatizado](06_3_Sending_an_Automated_Multisig.md). \ No newline at end of file From a75034324ca297fd10d6d6105e2ede86fd52e9df Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 19 Jul 2021 16:32:10 -0300 Subject: [PATCH 032/155] Review 06_3 --- pt/06_3_Sending_an_Automated_Multisig.md | 36 ++++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pt/06_3_Sending_an_Automated_Multisig.md b/pt/06_3_Sending_an_Automated_Multisig.md index 20136c6..f07ba8c 100644 --- a/pt/06_3_Sending_an_Automated_Multisig.md +++ b/pt/06_3_Sending_an_Automated_Multisig.md @@ -1,14 +1,14 @@ -# 6.3: Enviando e Gastando uma Transação Multisig de Maneira Automatizada +# 6.3: Enviando & Gastando um Multisig Automatizado -A técnica padrão para criar endereços com várias assinaturas e gastar os fundos é complexa, mas é um exercício interessante para entender um pouco mais como funcionam e como podemos manipulá-los em um nível relativamente baixo. No entanto, o Bitcoin Core tornou os multisigs mais fáceis de serem manipulados nas novas versões. +A técnica padrão para criar endereços multi-assinatura e gastar os fundos é complexa, mas é um exercício interessante para entender um pouco mais como funcionam e como podemos manipulá-los em um nível relativamente baixo. No entanto, o Bitcoin Core tornou os multisigs mais fáceis de serem manipulados nas novas versões. > :warning: **AVISO DE VERSÃO:** O comando ```addmultisigaddress``` está disponível no Bitcoin Core v0.10 ou superior. -## Criando um endereço Multisig em nossa carteira +## Criando um Endereço Multisig em Nossa Carteira Para tornar os fundos enviados para endereços multisig mais fáceis de serem gastos, só precisamos fazer algumas pré-configurações usando o comando ```addmultisigaddress```. Não é o que gostaríamos de fazer se estivéssemos escrevendo programas de carteiras que utilizam multisig, mas se estivesse apenas tentando receber alguns fundos, isso poderia evitar alguns problemas. -### Coletando as chaves +### Coletando as Chaves Vamos começar criando os endereços P2PKH e recuperando as chaves públicas, como de costume, para cada usuário que fará parte do multisig: ``` @@ -25,9 +25,9 @@ machine2$ bitcoin-cli -named getaddressinfo address=$address4 | jq -r '. | .pubk 02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f ``` -### Criando o endereço Multisig em qualquer lugar +### Criando o Endereço Multisig em Todos os Lugares -Em seguida, vamos criar o multisig em _cada máquina que contribuiu com as assinaturas_ usando um novo comando, ```addmultisigaddress```, ao invés de ```createmultisig```. Este novo comando salva algumas das informações da nossa carteira, tornando muito mais fácil gastar o dinheiro no futuro. +Em seguida, vamos criar o multisig em _cada máquina que contribuiu com assinaturas_ usando um novo comando, ```addmultisigaddress```, ao invés de ```createmultisig```. Este novo comando salva algumas das informações na nossa carteira, tornando muito mais fácil gastar o dinheiro no futuro. ``` machine1$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$address3'","02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f"]''' { @@ -43,9 +43,9 @@ machine2$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["0297e681bf "descriptor": "wsh(multi(2,[ae42a66f]0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc,[fe6f2292/0'/0'/2']02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f))#cc96c5n6" } ``` -Conforme observado na seção anterior, atualmente não importa se usamos endereços ou chaves públicas, então mostramos o outro mecanismo aqui, misturando os dois. Iremos obter o mesmo endereço multisig de qualquer maneira. No entanto, _devemos usar a mesma ordem sempre_. Portanto, é melhor que os membros do multisig verifiquem entre si a ordem dos dados para ter certeza de que todos obtiveram o mesmo resultado. +Conforme observado na seção anterior, atualmente não importa se usamos endereços ou chaves públicas, então temos mostrado o outro mecanismo aqui, misturando os dois. Iremos obter o mesmo endereço multisig de qualquer maneira. No entanto, _devemos usar a mesma ordem sempre_. Portanto, é melhor que os membros do multisig verifiquem entre si a ordem dos dados para ter certeza de que todos obtiveram o mesmo resultado. -### Esperando para receber os fundos +### Atente-se aos Fundos Depois disso, os membros do multisig ainda precisarão executar o comando ```importaddress``` para observar os fundos recebidos no endereço multisig: ``` @@ -54,9 +54,9 @@ machine1$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAo machine2$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 rescan="false" ``` -## Gastando novamente com uma transação automatizada +## Gastando Novamente com uma Transação Automatizada -Posteriormente, podemos receber os fundos no endereço com várias assinaturas sem nenhum problema. O uso do ```addmultisigaddress``` é simplesmente uma questão burocrática por parte dos destinatários: Um pouco de contabilidade para facilitar a vida deles quando desejarem gastar os saldos. +Posteriormente, poderemos receber os fundos no endereço multisig normalmente. O uso do ```addmultisigaddress``` é simplesmente uma questão burocrática por parte dos destinatários: um pouco de contabilidade para facilitar a vida deles quando desejarem gastar os saldos. Mas, isso torna a vida muito mais fácil. Como as informações foram salvas na carteira, os assinantes poderão gastar os fundos enviados para o endereço com várias assinaturas exatamente como qualquer outro endereço, ao invés de assinar sempre em várias máquinas diferentes. @@ -68,11 +68,11 @@ machine1$ utxo_txid=b9f3c4756ef8159d6a66414a4317f865882ee04beb57a0f8349dafcc98f5 machine1$ utxo_vout=0 machine1$ recipient=$(bitcoin-cli getrawchangeaddress) ``` -Vamos criar uma transação bruta: +Criamos uma transação bruta: ``` machine1$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''') ``` -E depois, assiná-la: +E depois, a assinamos: ``` machine1$ bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex { @@ -96,25 +96,25 @@ machine1$ bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex } ``` -Observe que não precisamos mais da ajuda extra do comando ```signrawtransactionwithkey```, porque todas essas informações já estão em nossa carteira. Mais importante, não tornamos nossas chaves privadas vulneráveis ​​ao manipulá-las diretamente. Ao invés disso, o processo é _exatamente_ o mesmo que gastar um UTXO normal, exceto que a transação não foi totalmente assinada no final. +Observe que não precisamos mais dar ajuda extra ao comando ```signrawtransactionwithkey```, porque todas as informações extras já estavam em nossa carteira. Mais importante, não tornamos nossas chaves privadas vulneráveis ​​ao manipulá-las diretamente. Ao invés disso, o processo é _exatamente_ o mesmo que gastar um UTXO normal, exceto que a transação não foi totalmente assinada no final. -### Assinando em outras máquinas +### Assinando em Outras Máquinas A etapa final é exportar o ```hex``` parcialmente assinado para a outra máquina e assinar a transação novamente: ``` machine2$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=02000000014ecda61c45f488e35c613a7c4ae26335a8d7bfd0a942f026d0fb1050e744a67d000000009100473044022025decef887fe2e3eb1c4b3edaa155e5755102d1570716f1467bb0b518b777ddf022017e97f8853af8acab4853ccf502213b7ff4cc3bd9502941369905371545de28d0147522102e7356952f4bb1daf475c04b95a2f7e0d9a12cf5b5c48a25b2303783d91849ba421030186d2b55de166389aefe209f508ce1fbd79966d9ac417adef74b7c1b5e0777652aeffffffff0130e1be07000000001976a9148dfbf103e48df7d1993448aa387dc31a2ebd522d88ac00000000 | jq -r '.hex') ``` -Quando todos os os assinantes confirmaram a assinatura, estaremos prontos para enviar a transação para a rede: +Quando todos os assinantes confirmaram a assinatura, estaremos prontos para enviar a transação para a rede: ``` machine2$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx 3ce88839ac6165aeadcfb188c490e1b850468eff571b4ca78fac64342751510d ``` Tal como acontece com o atalho discutido na seção [§4.5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), o resultado é muito mais fácil, mas perdemos certo controle no processo. -## Resumo: Enviando e Gastando uma Transação Multisig de Maneira Automatizada +## Resumo: Enviando & Gastando um Multisig Automatizado -Existe uma maneira mais fácil de gastar fundos enviados para os nossos endereços multisig que simplesmente requerem o uso do comando ```addmultisigaddress``` quando criamos nosso endereço. Ele não demonstra os meandros do gasto do P2SH e não nos dará um controle abrangente, mas se queremos apenas receber nossas moedas, este pode ser o melhor caminho. +Existe uma maneira mais fácil de gastar fundos enviados para os nossos endereços multisig que simplesmente requerem o uso do comando ```addmultisigaddress``` quando criamos nosso endereço. Ele não demonstra as complexidades do gasto do P2SH e não nos dará um controle abrangente, mas se queremos apenas receber nossas moedas, este pode ser o melhor caminho. ## O Que Vem Depois? -Saiba mais sobre "Expandindo as transações de Bitcoin com multisigs" no [Capítulo 7: Expandindo as transações do Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md). \ No newline at end of file +Saiba mais sobre "Expandindo Transações no Bitcoin com Multisigs" no [Capítulo 7: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md). \ No newline at end of file From 48011d3c60400767a4e07bdfef84484a3d0bc250 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Tue, 20 Jul 2021 22:19:37 -0300 Subject: [PATCH 033/155] Chapter 8 translation finished --- ..._0_Expanding_Bitcoin_Transactions_Other.md | 21 +++ ...1_Sending_a_Transaction_with_a_Locktime.md | 135 ++++++++++++++++++ pt/08_2_Sending_a_Transaction_with_Data.md | 121 ++++++++++++++++ 3 files changed, 277 insertions(+) create mode 100644 pt/08_0_Expanding_Bitcoin_Transactions_Other.md create mode 100644 pt/08_1_Sending_a_Transaction_with_a_Locktime.md create mode 100644 pt/08_2_Sending_a_Transaction_with_Data.md diff --git a/pt/08_0_Expanding_Bitcoin_Transactions_Other.md b/pt/08_0_Expanding_Bitcoin_Transactions_Other.md new file mode 100644 index 0000000..6779937 --- /dev/null +++ b/pt/08_0_Expanding_Bitcoin_Transactions_Other.md @@ -0,0 +1,21 @@ +# Capítulo 8: Expandindo Transações de Bitcoin de Outras Maneiras + +A definição de transações básicas descrita no [Capítulo Seis](06_0_Expanding_Bitcoin_Transactions_Multisigs.md) diz que enviamos os _fundos_ _imediatamente_, mas esses são os dois elementos que podem ser alterados. Esta seção final sobre _Expandindo transações de Bitcoin_ fala sobre como enviar coisas que não sejam moedas e como fazer isso em um momento diferente do atual. + +## Objetivos deste Capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Criar transações com Locktimes; + * Criar transações com dados. + +Os objetivos secundários incluem a capacidade de: + + * Compreender os diferentes tipos de Timelocks; + * Planejar usando o poder do Locktime; + * Planejar usando o poder de OP_RETURN. + +## Tabela de conteúdo + + * [Seção Um: Enviando uma transação com Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) + * [Seção Dois: Enviando uma transação com dados](08_2_Sending_a_Transaction_with_Data.md) \ No newline at end of file diff --git a/pt/08_1_Sending_a_Transaction_with_a_Locktime.md b/pt/08_1_Sending_a_Transaction_with_a_Locktime.md new file mode 100644 index 0000000..bebfeef --- /dev/null +++ b/pt/08_1_Sending_a_Transaction_with_a_Locktime.md @@ -0,0 +1,135 @@ +# 8.1: Enviando uma transação com Locktime + +Os capítulos anteriores mostraram duas maneiras diferentes de enviar fundos de várias máquinas e também para vários destinatários. Mas, existem duas outras maneiras de alterar fundamentalmente as transações básicas. A primeira delas é variar o tempo escolhendo um tempo de bloqueio ou mais conhecido pela expressão em inglês locktime. Isso nos dá a capacidade de enviar transações brutas em algum momento no futuro. + +## Entendendo como o Locktime funciona + +Ao criar uma transação do tipo locktime, a bloqueamos com um número que representa a altura do bloco (se for um número pequeno) ou um carimbo de data/hora usando o padrão UNIX (se for um número grande). Isso informa à rede Bitcoin que a transação não pode ser colocada no bloco até que o tempo especificado chegue ou a blockchain tenha atingido a altura especificada. + +> :book: _O que é a altura do bloco?_ É a contagem total de blocos na blockchain, contado desde o bloco gênese até o último bloco minerado da blockchain do Bitcoin. + +Quando uma transação do tipo locktime está esperando para entrar em um bloco, ela pode ser cancelada. Isso significa que ainda não foi atingido a altura ou a data necessária. Na verdade, a capacidade de cancelar é todo o propósito de uma transação do tipo locktime. + +> :book: _O que é nLockTime?_ É a mesma coisa que o locktime. Mais especificamente, é como o locktime é chamado internamente no código-fonte do Bitcoin Core. + +> :book: _O que é o Timelock?_ O Locktime é apenas uma maneira de bloquear transações Bitcoin até algum ponto no futuro; o coletivo desses métodos são chamados de timelocks. O locktime é o método de timelock mais básico. Ele bloqueia uma transação inteira com um tempo absoluto e está disponível através do ```bitcoin-cli``` (é por isso que é o único timelock coberto nesta seção). Um método paralelo, que bloqueia uma transação com um tempo relativo, é definido no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) e abordado na seção [§11.3: Usando CSV em Scripts](11_3_Using_CSV_in_Scripts.md). + +> O Bitcoin Script capacita ainda mais os dois tipos de timelocks, permitindo o bloqueio de saídas individuais ao invés de toda a transação. Os timelocks absolutos (como Locktime) estão vinculados ao opcode Script OP_CHECKLOCKTIMEVERIFY, que é definido no [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) e que será estudado na seção [§11.2: Usando CLTV em Scripts](11_2_Using_CLTV_in_Scripts.md), enquanto os timelocks relativos (como o Timelock) estão vinculados ao opcode de Script OP_CHECKSEQUENCEVERIFY, que é definido no [BIP 112](https://github.com/bitcoin/bips /blob/master/bip-0112.mediawiki) e que também será abordado na seção [§11.3](11_3_Using_CSV_in_Scripts.md). + +## Criando uma transação de Locktime + +Para criar uma transação com locktime, precisamos primeiro determinar como definiremos o tempo. + +### Descobrindo nosso tempo de bloqueio usando o carimbo de data/hora do UNIX + +Provavelmente, iremos definir com muito mais frequência o nosso tempo de bloqueio usando um carimbo de data/hora do tipo UNIX que representa uma data e hora específica. Podemos calcular um carimbo de data/hora UNIX usando sites que fazem essa conversão, como o [UNIX Time Stamp](http://www.unixtimestamp.com/) ou o [Epoch Convertor](https://www.epochconverter.com/). No entanto, seria melhor [escrevermos nosso próprio script](https://www.epochconverter.com/#code) em nossa máquina local, para que saibamos que o carimbo de data/hora UNIX que recebemos está correto (lembre-se, não confie, verifique). Se não fizermos isso, pelo menos seria interessante verificar em dois sites diferentes para ter a certeza que tudo está correto. + +> :book: _Por que iríamos usar um carimbo de data/hora do UNIX?_ O uso de um carimbo de data/hora do UNIX facilita a vinculação definitiva de uma transação a um horário específico, sem se preocupar se a velocidade de criação do bloco mudar drasticamente até lá. Principalmente se estivermos criando um locktime em um futuro distante, é a coisa mais segura a ser feita. Entretanto, utilizar esse método é mais intuitivo, criando uma correlação direta entre alguma data do calendário e a hora em que a transação pode ser colocado na blockchain do Bitcoin. + +> :warning: **AVISO:** O Locktime com carimbos de data/hora tem menos flexibilidade, pois a liberação de blocos não é regular e os tempos de bloqueio podem ser duas horas antes do tempo real, então um locktime significa "mais ou menos nesta data e nesta hora". + +### Descobrir o locktime usando a altura do bloco + +Como alternativa, podemos definir o locktime usando um número menor, que representa a altura de um bloco. Para calcular a altura do bloco futuro, precisamos primeiro saber qual é a altura do bloco atual. O ```bitcoin-cli getblockcount``` nos dirá a altura do bloco atual baseado na blockchain da máquina local. Podemos verificar um explorador do Bitcoin como a [mempool.space](https://mempool.space/). + +Depois de descobrir a altura atual, podemos decidir até que ponto no futuro iremos configurar o locktime. É importante lembrar que, em média, um novo bloco será criado a cada 10 minutos. Então, por exemplo, se quisermos definir o tempo de bloqueio para uma semana no futuro, devemos escolher uma altura de bloco que é _6 x 24 x 7 = 1.008 blocos_ depois do atual. + +> :book: _Por que eu usaria a altura do bloco?_ Ao contrário dos carimbos de data/hora, não existe confusão nas alturas de bloco. Se definirmos uma altura de bloco de 120.000 para o nosso locktime, não haverá absolutamente nenhuma maneira dele entrar no bloco 119.999. Isso pode tornar o controlar no código mais fácil ao manipular nossa transação com locktime. A desvantagem é que não podemos ter certeza de quando exatamente será o locktime. + +> :warning: **AVISO:** Se desejamos definir um locktime usando a altura do bloco, devemos definir o tempo de bloqueio para menos de 500 milhões. Se definirmos como sendo 500 milhões ou mais, nosso número será interpretado como um carimbo de data/hora. Como o carimbo de data/hora usando o padrão UNIX com valor de 500 milhões era dia 5 de novembro de 1985, provavelmente significa que nossa transação será permitida a qualquer momento a entrar na blockchain. + +## Escrevendo a transação + +Depois de descobrir o locktime, tudo o que precisamos fazer é escrever uma transação bruta padrão, com uma terceira variável para o ```locktime```: +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.001, "'$changeaddress'": 0.00095 }''' locktime=1774650) +``` +Podemos observar que o uso do ```locktime``` está abaixo dos 500 milhões, o que significa que ele define a altura do bloco. Nesse caso, são apenas alguns blocos além da altura do bloco atual no momento em que este livro foi escrito, com o objetivo de exemplificar como o locktime funciona sem ficar sentado por muito tempo para esperar para ver o que acontece. + +A transação criada tem mais ou menos essa aparência: +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex +{ + "txid": "ba440b1dd87a7ccb6a200f087d2265992588284eed0ae455d0672aeb918cf71e", + "hash": "ba440b1dd87a7ccb6a200f087d2265992588284eed0ae455d0672aeb918cf71e", + "version": 2, + "size": 113, + "vsize": 113, + "weight": 452, + "locktime": 1774650, + "vin": [ + { + "txid": "0ad9fb6992dfe4ea90236b69852b3605c0175633b32996a486dcd0b2e739e385", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.00100000, + "n": 0, + "scriptPubKey": { + "asm": "0 f333554cc0830d03a9c1f26758e2e7e0f155539f", + "hex": "0014f333554cc0830d03a9c1f26758e2e7e0f155539f", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q7ve42nxqsvxs82wp7fn43ch8urc425ul5um4un" + ] + } + }, + { + "value": 0.00095000, + "n": 1, + "scriptPubKey": { + "asm": "0 a37718a3510958112b6a766e0023ff251b6c2bfb", + "hex": "0014a37718a3510958112b6a766e0023ff251b6c2bfb", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q5dm33g63p9vpz2m2wehqqglly5dkc2lmtmr98d" + ] + } + } + ] +} +``` +Observe que o número de sequência (```4294967294```) é menor que ```0xffffffff```. Esta é uma sinalização necessária para mostrar que a transação inclui um locktime. Também é feito automaticamente pelo ```bitcoin-cli```. Se o número da sequência for definido como ```0xffffffff```, nosso locktime será ignorado. + +> :information_source: **NOTA - SEQUÊNCIA:** Este é o segundo uso do valor ```nSequence``` em Bitcoin. Tal como acontece com o RBF, o ```nSequence``` é novamente usado como um opt-in, desta vez para o uso do locktime. O 0xffffffff-1 (4294967294) é o valor para sinalizar o tempo de bloqueio porque proíbe propositadamente o uso do RBF (que requer uma ```nSequence < 0xffffffff-1```) e do timelock relativo (que requer ```nSequence < 0xf0000000```), os outros dois usos do ```nSequence```. Se definirmos o ```nSequence``` abaixo de ```0xf0000000```, então também teremos um timelock relativo em nossa transação, o que provavelmente não é o desejado. + +> :warning: **ATENÇÃO:** Se estivermos criando uma transação bruta com locktime por algum outro meio que não seja o ```bitcoin-cli```, teremos que definir a sequência para um valor menor que ```0xffffffff``` manualmente. + +## Enviando a transação + +Agora, já estamos familiarizados com a parte final, que é enviar a transação para a rede: +``` +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +error code: -26 +error message: +non-final +``` +Eita! Que erro é esse!? + +Desde 2013, geralmente não podemos colocar a transação usando um timelock na mempool até que nosso bloqueio tenha expirado. No entanto, ainda podemos guardar nossa transação, ocasionalmente reenviando-a para a rede Bitcoin até que ela seja aceita na mempool. Uma outra opção é enviarmos a transação assinada (```$signedtx```) ao destinatário, para que ele possa colocá-la na mempool quando o tempo de bloqueio expirar. + +Assim que o bloqueio de tempo expirar, qualquer pessoa pode enviar a transação assinada para a rede, e o destinatário receberá o saldo como esperado... Desde que a transação não tenha sido cancelada. + +## Cancelando uma transação com timelock + +Cancelar uma transação de tempo de bloqueio é _muito_ simples: precisamos apenas enviar uma nova transação usando pelo menos um dos UTXOs. + +## Resumo: Enviando uma transação com Locktime + +O Locktime oferece uma maneira de criar uma transação que _precisa_ esperar e que _não será aceita_ até que um determinado bloco chegue ou um momento pré-definido passe. Enquanto isso, ela pode ser cancelada simplesmente reutilizando um dos UTXO da transação. + +> :fire: _Qual é o poder do locktime?_ O poder do locktime pode não ser imediatamente óbvio devido à capacidade de cancelá-lo com facilidade. No entanto, é outra das bases dos Smart Contracts, pois tem muita utilidade em uma variedade de aplicações de custódia ou contratuais. Por exemplo, considere uma situação em que um terceiro está fazendo o hold das nossas moedas. Para garantir a devolução dos nossos bitcoins caso o custodiante algum dia desaparecesse, ele poderia produzir uma transação com timelock para devolver as moedas para nós e, em seguida, atualizar isso de vez em quando com uma transação mais nova, no futuro. Se em algum momento ele não enviar a nova transação, as moedas retornarão para nós quando o timelock mais novo expirar. O timelock pode ser aplicado de forma semelhante a uma rede de pagamento, onde a rede mantém moedas enquanto estão sendo trocadas pelos participantes da rede. Finalmente, os timelocks oferecem um exemplo de contrato mais complexo, em que os pagamentos são enviados a várias pessoas. Esses pagamentos seriam baseados em transações com timelocks e seriam continuamente atualizados enquanto o proprietário continuasse a mostrar sinais de vida. (O fator unificador de todas essas aplicações é, obviamente, a _confiança_. Transações simples usando timelocks só funcionam se o detentor das moedas puder ser confiável para enviá-las sob as condições apropriadas). + +## O que vem depois? + +Vamos continuar "Expandindo transações de Bitcoin" na seção [§8.2: Enviando uma transação com dados](08_2_Sending_a_Transaction_with_Data.md). \ No newline at end of file diff --git a/pt/08_2_Sending_a_Transaction_with_Data.md b/pt/08_2_Sending_a_Transaction_with_Data.md new file mode 100644 index 0000000..0ab376f --- /dev/null +++ b/pt/08_2_Sending_a_Transaction_with_Data.md @@ -0,0 +1,121 @@ +# 8.2: Enviando uma transação com dados + +O último jeito de variar a forma como enviamos uma transação simples é usar a transação para enviar dados ao invés de saldos (ou, na prática, enviar algo além dos saldos). Isso nos dá a capacidade de inserir informações na blockchain. Isso é feito através de um comando especial, o ```OP_RETURN```. + +A pegadinha? Só podemos armazenar 80 bytes por vez! + +## Criando nossos dados + +A primeira coisa que precisamos fazer é criar os 80 bytes (ou menos) de dados que iremos gravar no nosso ```OP_RETURN```. Isso pode ser tão simples quanto preparar uma mensagem ou podemos usar o hash dos dados existentes. Por exemplo, o ```sha256sum``` produz 256 bits de dados, que são apenas 32 bytes, bem abaixo do nosso limite: +``` +$ sha256sum contract.jpg +b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75 contract.jpg +$ op_return_data="b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75" +``` +> :book: _O que é um OP_RETURN?_ Todas as transações Bitcoin são construídas com scripts que iremos ver mais a fundo no próximo capítulo. O ```OP_RETURN``` é um script simples que define o OUTPUT como sendo inválido. A convenção resultou no uso dele para incorporar dados na blockchain. + +## Separando algumas moedas + +Nosso objetivo ao criar uma transação de dados não é enviar dinheiro para alguém, mas colocar dados dentro da blockchain. No entanto, _devemos_ gastar algumas moedas para fazer isso. Só precisamos usar um endereço de troco como sendo nosso _ único_ destinatário. Em seguida, podemos identificar um UTXO e enviá-lo para nosso endereço de troco, sem esquecer da taxa de transação, ao mesmo tempo que usamos a mesma transação para criar um OP_RETURN. + +Esta é a configuração padrão: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "vout": 0, + "address": "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh", + "scriptPubKey": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "amount": 0.01463400, + "confirmations": 1392, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/12']02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb)#cjr03mru", + "safe": true + } +] + +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ changeaddress=$(bitcoin-cli getrawchangeaddress) +``` + +## Escrevendo uma transação bruta + +Agora podemos escrever uma nova transação bruta com duas saídas: uma é o nosso endereço de alteração para recuperar (a maior parte) do nosso saldo, a outra é um endereço de dados, que é uma variável ```bitcoin-cli``` para um OP_RETURN. +``` +rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "data": "'$op_return_data'", "'$changeaddress'": 0.0146 }''') +``` +Esta é a cara da transação: +``` +{ + "txid": "a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8", + "hash": "a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8", + "version": 2, + "size": 125, + "vsize": 125, + "weight": 500, + "locktime": 0, + "vin": [ + { + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00000000, + "n": 0, + "scriptPubKey": { + "asm": "OP_RETURN b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75", + "hex": "6a20b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75", + "type": "nulldata" + } + }, + { + "value": 0.01460000, + "n": 1, + "scriptPubKey": { + "asm": "0 998a9b0ed076bbdec1d88da4f475b9dde75e3620", + "hex": "0014998a9b0ed076bbdec1d88da4f475b9dde75e3620", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qnx9fkrksw6aaaswc3kj0gademhn4ud3q7cz4fm" + ] + } + } + ] +} + +``` +Como podemos observar, ela envia a maior parte do dinheiro de volta para o endereço de troco (`tb1qnx9fkrksw6aaaswc3kj0gademhn4ud3q7cz4fm`) menos a taxa de transação. Mais importante, a primeira saída mostra um OP_RETURN com os dados (`b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75`) logo depois. + +## Enviando uma transação bruta + +Assine a transação bruta e envie-a, e logo esse OP_RETURN será incorporado a blockchain! + +## Verificando nosso OP_RETURN + +Novamente, podemos olhar para essa transação usando um explorador da blockchain: +[https://mempool.space/pt/testnet/tx/a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8/] + +Podemos observar um aviso sobre os dados estarem em um "protocolo desconhecido". Se estivermos projetando algum uso regular dos dados ```OP_RETURN```, provavelmente iremos marcar com um prefixo especial, para marcar esse protocolo. Então, os dados OP_RETURN reais podem ser algo como "CONTRACTS3b110a164aa18d3a5ab064ba93fdce62". Este exemplo não usa um prefixo para evitar qualquer tipo de confusão com os espaços de dados. + +## Resumo: Enviando uma transação com dados + +Podemos usar o ```OP_RETURN``` para armazenar até 80 bytes de dados na blockchain. Fazemos isso com a palavra-código ```data``` em um ```vout```. Ainda precisaremos enviar alguns satoshinhos, mas basta enviá-lo de volta para um endereço de troco, retirando a taxa de transação. + +> :fire: _Qual é o poder do OP_RETURN?_ O OP_RETURN abre novas possibilidades para o blockchain, porque podemos inserir dados que provam que certas coisas aconteceram em determinados momentos. Várias organizações estão pensando em usar os OP_RETURNs como prova de existência, para direitos autorais, para moedas coloridas e [para outros fins](https://en.bitcoin.it/wiki/OP_RETURN). Embora 80 bytes possa não parecer muito, pode ser bastante eficaz se os OP_RETURNs forem usados ​​para armazenar hashes dos dados reais. Então, podemos provar a existência dos nossos dados digitais demonstrando que o hash deles corresponde ao hash na blockchain. + +Observe que há alguma controvérsia sobre o uso da blockchain do Bitcoin usando-a para este fim. + +## O que vem depois? + +Vamos conhecer mais sobre o "Script no Bitcoin" no [Capítulo Nove: Apresentando os Scripts no Bitcoin](09_0_Introducing_Bitcoin_Scripts.md). \ No newline at end of file From 27c8bfc7de4666f92704287b1c71292dab08fbd3 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Wed, 21 Jul 2021 18:25:29 -0300 Subject: [PATCH 034/155] Finished translation of chapter 09 --- pt/09_0_Introducing_Bitcoin_Scripts.md | 27 ++ ...standing_the_Foundation_of_Transactions.md | 142 +++++++ pt/09_2_Running_a_Bitcoin_Script.md | 125 ++++++ pt/09_3_Testing_a_Bitcoin_Script.md | 209 ++++++++++ pt/09_4_Scripting_a_P2PKH.md | 388 ++++++++++++++++++ pt/09_5_Scripting_a_P2WPKH.md | 119 ++++++ 6 files changed, 1010 insertions(+) create mode 100644 pt/09_0_Introducing_Bitcoin_Scripts.md create mode 100644 pt/09_1_Understanding_the_Foundation_of_Transactions.md create mode 100644 pt/09_2_Running_a_Bitcoin_Script.md create mode 100644 pt/09_3_Testing_a_Bitcoin_Script.md create mode 100644 pt/09_4_Scripting_a_P2PKH.md create mode 100644 pt/09_5_Scripting_a_P2WPKH.md diff --git a/pt/09_0_Introducing_Bitcoin_Scripts.md b/pt/09_0_Introducing_Bitcoin_Scripts.md new file mode 100644 index 0000000..097fc65 --- /dev/null +++ b/pt/09_0_Introducing_Bitcoin_Scripts.md @@ -0,0 +1,27 @@ +# Capítulo 9: Apresentando os Scripts no Bitcoin + +Até o momento, estamos interagindo com o Bitcoin em um nível relativamente alto de abstração. O programa ```Bitcoin-cli``` oferece acesso a uma variedade de comandos RPC que suportam a criação e controle de transações brutas de Bitcoin que incluem saldos, dados, timelocks e multisigs. + +No entanto, o Bitcoin oferece muito mais complexidade do que isso. O software oferece uma linguagem de script simples que pode ser usada para criar condições de resgate ainda mais complexas. Se as multisigs e os timelocks fornecerem as bases para os contratos inteligentes, o script do Bitcoin constrói os alicerces. É o próximo passo para nos capacitar no mundo do bitcoin. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Projetar um script do Bitcoin; + * Aplicar um script do Bitcoin. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Compreender o propósito dos scripts do Bitcoin; + * Entender os script P2PKH; + * Entender como o P2WPKH funciona com os scripts; + * Compreender as necessidades dos testes dos scripts do bitcoin. + +## Tabela de Conteúdo + +* [Seção 1: Entendendo o alicerce das transações](09_1_PriveStanding_the_foundation_of_transactions.md) +* [Seção 2: Executando um script do Bitcoin](09_2_running_a_bitcoin_script.md) +* [Seção 3: Testando um script do Bitcoin](09_3_testing_a_bitcoin_script.md) +* [Seção 4: Criando um script P2PKH](09_4_scripting_a_p2pkh.md) +* [Seção 5: Criando um script P2WPKH](09_5_scripting_a_p2wpkh.md) \ No newline at end of file diff --git a/pt/09_1_Understanding_the_Foundation_of_Transactions.md b/pt/09_1_Understanding_the_Foundation_of_Transactions.md new file mode 100644 index 0000000..c98291d --- /dev/null +++ b/pt/09_1_Understanding_the_Foundation_of_Transactions.md @@ -0,0 +1,142 @@ +# 9.1: Entendendo o alicerce das transações + +Os alicerces do Bitcoin são as capacidades de proteger as transações, algo que é feito com uma linguagem de scripts simples. + +## Conhecendo as partes do quebra-cabeça criptográfico + +Conforme descrito no [Capítulo 1](01_0_INTRODUCING_BITCOIN.MD), os saldos em cada transação Bitcoin estão travados com um quebra-cabeça criptográfico. Para sermos mais precisos, dissemos que o Bitcoin é composto de "uma sequência de transações atômicas". Observamos que: "Cada transação é autenticada por um remetente com a solução para um quebra-cabeça criptográfico anterior que foi armazenado como um script. A nova transação é bloqueada para o destinatário com um novo quebra-cabeça criptográfico que também é armazenado como um script". Esses scripts, que bloqueiam e desbloqueiam as transações, são escritos usando o script do bitcoin. + +> :book: ***O que é o script do Bitcoin?*** O script do Bitcoin é uma linguagem baseada na linguagem de programação Forth que propositadamente evita loops, o que significa que ela não passa no processo de Turing. É composto de opcodes individuais. Cada transação única no Bitcoin é bloqueada com um script do Bitcoin. Quando a transação de bloqueio para um UTXO é executada com as entradas corretas, esse UTXO pode ser gasto. + +O fato de que as transações estão bloqueadas com scripts significa que podem ser bloqueadas de várias maneiras diferentes, exigindo uma variedade de chaves diferentes. Na verdade, encontramos vários mecanismos de travamento diferentes até o momento, cada um dos quais usa diferentes opcodes: + + * OP_CHECKSIG, que verifica uma chave pública contra uma assinatura, é a base do endereço P2PKH clássico, como será totalmente detalhado na seção [§9.3: Criando um script P2PKH](09_3_scripting_a_p2pkh.md); + * OP_CHECKMULTISIG, faz a mesma coisa com as multisigs, como será totalmente detalhado na seção [§10.4: Criando um script multisig](10_4_scripting_a_multisig.md); + * OP_CHECKLOCKTIMEVERIFY e OP_SEQUENCEVERIFY formam a base dos timelocks mais complexos, como será totalmente detalhado nas seções [§11.2: Usando CLTV nos scripts](11_2_using_cltv_in_scripts) e [§11.3: Usando o CSV nos scripts](11_3_using_csv_in_scripts.md). + * OP_RETURN é a marca de uma transação não gasta, e é por isso que é usado para transportar dados, como falamos na seção [§8.2: Enviando uma transação com dados](08_2_sending_a_transaction_with_data.md). + +## Accessando os scripts em nossas transações + +Podemos não perceber, mas já vimos esses scripts de bloqueio e desbloqueio como parte das transações brutas que fizemos. A melhor maneira de analisar esses scripts com mais profundidade é, portanto, criar uma transação bruta e examiná-la. + +### Criando uma transação de teste + +Para examinar os scripts reais de desbloqueio e bloqueio, vamos criar uma transação bruta rapidamente, pegando um UTXO legado não gasto e reenviando-o a um endereço de troco legado, deixando uma parte para as taxas de transação: +``` +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') +$ recipient=$(bitcoin-cli -named getrawchangeaddress address_type=legacy) +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.0009 }''') +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +``` +Não precisamos enviá-la. O objetivo é simplesmente produzir uma transação para que possamos examiná-la. + +>**NOTA:** Por que usar endereços legados? Porque nossos scripts são mais significativos. No entanto, também ofereceremos um exemplo de um endereço nativo Segwit P2WPKH na seção [§9.5](09_5_scripting_a_p2wpkh.md). + +### Examinando nossa transação de teste + +Agora podemos examinar nossa transação com profundida necessária usando ```decodivawtransaction``` no ```$signedtx```: +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$signedtx +{ + "txid": "34151dac704d94a269cd33f80be34c122152edc9bfbb9323852966bf0ce937ed", + "hash": "34151dac704d94a269cd33f80be34c122152edc9bfbb9323852966bf0ce937ed", + "version": 2, + "size": 191, + "vsize": 191, + "weight": 764, + "locktime": 0, + "vin": [ + { + "txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa", + "vout": 0, + "scriptSig": { + "asm": "304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b", + "hex": "47304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c01210315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91406b5c6ba5330cdf738a2ce91152bfd0e71f9ec3988ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mg8S7F1gY3ivV9M9GrWwe6ziWvK2MFquCf" + ] + } + } + ] +} + +``` +Os dois scripts são encontrados nas duas partes diferentes da transação. + +O ```scriptSig``` está localizado no ```vin```. Este é o script de _desbloqueio_. É o que é executado para acessar o UTXO que está sendo usado para financiar esta transação. Haverá um ```scriptSig``` por UTXO em cada transação. + +O ```scriptpubkey``` está localizado no ```vout```. Este é o script de _bloqueio_. É o que bloqueia a nova saída da transação. Haverá um ```scriptPubKey``` por cada saída em cada transação. + +> :book: ***Como o scriptsig e o scriptpubkey interagem?*** O ```scriptSig``` de uma transação desbloqueia o UTXO anterior. A saída desta nova transação será bloqueada com um ```scriptPubKey```, que pode, por sua vez, ser desbloqueado pela ```scriptsig``` da transação que reutiliza esse UTXO. + +### Lendo os scripts da transação + +Se olharmos para os dois scripts e veremos que cada um possui duas representações diferentes: o ```hex``` é o que realmente é armazenado, mas a linguagem de montagem mais legível (```asm```) pode mostrar o que está acontecendo. + +Vamos dar uma olhada no ```asm``` do script de desbloqueio para podermos ver em primeira mão como o Script do Bitcoin se parece: +``` +04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +``` +Como acontece, essa bagunça de números é uma assinatura privada, seguida pela chave pública associada. Ou pelo menos isso é o esperado, porque é isso que é necessário para desbloquear o P2PKH UTXO que esta transação está usando. + +Vamos ler o script de bloqueio e veremos que é algo muito mais óbvio: +``` +OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG +``` +Esse é o método padrão do script do Bitcoin para bloquear uma transação P2PKH. + +Na seção [§9.4](09_4_scripting_a_p2pkh.md) será explicado como esses dois scripts andam juntos, mas primeiro precisamos saber como os scripts do Bitcoin são avaliados. + +## Examinando um tipo diferente de transação + +Antes de sairmos do alicerce, vamos olhar para um tipo diferente de script de bloqueio. Aqui está o ```scriptPubKey``` da transação multisig que criamos na seção [§6.1: Enviando uma Transação com Multisig](06_1_sending_a_transaction_to_a_multisig.md). +``` + "scriptPubKey": { + "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", + "hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + ] + } +``` + +Vamos comparar isso com o ```ScriptPubkey``` da nossa nova transação P2PKH: +``` + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91406b5c6ba5330cdf738a2ce91152bfd0e71f9ec3988ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mg8S7F1gY3ivV9M9GrWwe6ziWvK2MFquCf" + ] + } +``` + +Essas duas transações são _definitivamente_ trancadas de maneiras diferentes. O Bitcoin reconhece o primeiro como sendo ```scripthash``` (P2SH) e o segundo como sendo ```pubkeyhash``` (P2PKH), mas também devemos ser capazes de ver a diferença nos diferentes códigos ```asm```:```OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL``` quando comparado com o ```OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 Op_equalverify op_checksig```. Este é o poder do script. Podemos simplesmente produzir alguns dos tipos drasticamente diferentes de transações que aprendemos nos capítulos anteriores. + +## Resumo: Entendendo o alicerce das transações + +Cada transação do bitcoin inclui pelo menos um script de desbloqueio (```scriptSig```), que resolve um quebra-cabeça criptográfico anterior, e pelo menos um script de bloqueio (```scriptPubKey```), que cria um novo quebra-cabeça criptográfico. Há um ```scriptSig``` para cada entrada e um ```scriptPubKey``` para cada saída. Cada um desses scripts é escrito usando o script do Bitcoin, uma linguagem semelhante a linguagem de programação Forth que fortalece ainda mais o Bitcoin. + +> :fire: ***Qual é o poder dos scripts?*** Os scripts de desbloqueio são todo o poder dos contratos inteligentes. Com os opcodes apropriados, podemos tomar decisões muito precisas sobre quem pode resgatar os fundos, quando podem ser resgatados e como podem resgatá-los. Regras mais complexas para saldos corporativos, endereços de parceria, gastos com proxy e outras metodologias também podem ser codificados dentro de um script. Os scripts também conseguem capacitar serviços bitcoin mais complexos, como a lightning e as sidechains. + +## O que vem depois? + +Vamos continuar "Apresentando os Scripts no Bitcoin" na seção [§9.2: Executando um script do Bitcoin](09_2_running_a_bitcoin_script.md). diff --git a/pt/09_2_Running_a_Bitcoin_Script.md b/pt/09_2_Running_a_Bitcoin_Script.md new file mode 100644 index 0000000..54ddd21 --- /dev/null +++ b/pt/09_2_Running_a_Bitcoin_Script.md @@ -0,0 +1,125 @@ +# 9.2: Executando um script do Bitcoin + +Os scripts de Bitcoin podem não parecer tão intuitivos no começo, mas sua execução é bastante simples usando a notação polonesa reversa e uma pilha. + +## Compreendendo a linguagem do script + +Um script Bitcoin possui três partes: Uma linha de entrada; uma pilha para o armazenamento e; comandos específicos para execução. + +### Compreendendo o pedido + +Os scripts do Bitcoin são executados da esquerda para a direita. Para nós é fácil, porque é a mesma na qual lemos. No entanto, podemos ser o elemento mais não intuitivo do script do Bitcoin, porque significa que as funções não têm a aparência que nós esperávamos. Ao invés disso, _os operandos vêm antes do operador._ + +Por exemplo, se estivéssemos somando "1" e "2", nosso script do Bitcoin ficaria ```1 2 OP_ADD```, e _não_"1 + 2". Como sabemos que o operador OP_ADD recebe duas entradas, sabemos que as duas entradas anteriores são os operandos. + +> :warning: **ATENÇÃO:** Tecnicamente, tudo no script do Bitcoin é um opcode, portanto, seria mais apropriado registrar o exemplo acima como ```OP_1 OP_2 OP_ADD```. Em nossos exemplos, não nos preocupamos sobre como as constantes serão avaliadas, pois esse é um tópico de tradução, como é explicado no capítulo [§10.2: Construindo a estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md). Alguns escritores preferem também não usar o prefixo "OP" nos operadores, mas optamos por não fazê-lo. + +### Compreendendo a pilha + +Na verdade, não é correto dizer que um operador se aplica às entradas anteriores. Na verdade, um operador se aplica às entradas principais na pilha do Bitcoin. + +> :book: ***O que é uma pilha?*** Uma pilha é uma estrutura de dados LIFO (last in, first out, ou no português, primeiro a entrar, último a sair). Possui duas funções de acesso: Push e Pop. Empurrar (Push) coloca um novo objeto no topo da pilha, empurrando para baixo tudo que está abaixo dele. Retirar (Pop) remove o objeto superior da pilha. + +Sempre que o script do Bitcoin encontrar uma constante, ele a coloca na pilha. Portanto, o exemplo acima de ```1 2 OP_ADD``` seria realmente parecido com o que foi processado: +``` +Script: 1 2 OP_ADD +Stack: [ ] + +Script: 2 OP_ADD +Stack: [ 1 ] + +Script: OP_ADD +Stack: [ 1 2 ] +``` +_ Observe que, neste e nos exemplos seguintes, o topo da pilha está à direita e a parte inferior à esquerda._ + +### Compreendendo os Opcodes + +Quando um script do Bitcoin encontra um operador, ele o avalia. Cada operador retira zero ou mais elementos da pilha como entradas, geralmente um ou dois. Em seguida, ele os processa de uma maneira específica antes de colocar zero ou mais elementos de volta na pilha, geralmente um ou dois. + +> :book: ***O que é um Opcode?*** O Opcode significa "código de operação". É normalmente associado ao código de linguagem de máquina e é uma função simples (ou "operador"). + +OP_ADD retira dois itens da pilha (no nosso caso: 2 depois 1), adiciona-os e coloca o resultado de volta na pilha (no exemplo: 3). +``` +Script: +Running: 1 2 OP_ADD +Stack: [ 3 ] +``` + +## Colocando mais complexidade + +Scripts mais complexos são criados executando mais comandos em ordem. Eles precisam ser avaliados cuidadosamente da esquerda para a direita, para que possamos entender o estado da pilha conforme cada novo comando é executado. Ele mudará constantemente, como resultado de operadores anteriores: +``` +Script: 3 2 OP_ADD 4 OP_SUB +Stack: [ ] + +Script: 2 OP_ADD 4 OP_SUB +Stack: [ 3 ] + +Script: OP_ADD 4 OP_SUB +Stack: [ 3 2 ] + +Script: 4 OP_SUB +Running: 3 2 OP_ADD +Stack: [ 5 ] + +Script: OP_SUB +Stack: [ 5 4 ] + +Script: +Running: 5 4 OP_SUB +Stack: [ 1 ] +``` + +## Compreendendo o uso do script do Bitcoin + +Acima, você viu basicamente, o que é o script do Bitcoin... Além de algumas complexidades de como essa, a linguagem script interage com o próprio Bitcoin. + +### Compreendendo o scriptSig e scriptPubKey + +Como vimos anteriormente, cada entrada da transação de Bitcoin contém um ```scriptSig``` que é usado para desbloquear o ```scriptPubKey``` para o UTXO associado. Eles são _efetivamente_ concatenados, o que significa que o ```scriptSig``` e o ```scriptPubKey``` são executados juntos, nessa ordem. + +Então, podemos presumir que um UTXO foi bloqueado com um ```scriptPubKey``` que lê ```OP_ADD 99 OP_EQUAL```, exigindo como entrada dois números que somam noventa e nove, e podemos presumir que o ```scriptSig``` de ```1 98``` foi executado para desbloquear. Os dois scripts seriam efetivamente executados em ordem como ```1 98 OP_ADD 99 OP_EQUAL```. + +Avaliando o resultado: +``` +Script: 1 98 OP_ADD 99 OP_EQUAL +Stack: [] + +Script: 98 OP_ADD 99 OP_EQUAL +Stack: [ 1 ] + +Script: OP_ADD 99 OP_EQUAL +Stack: [ 1 98 ] + +Script: 99 OP_EQUAL +Running: 1 98 OP_ADD +Stack: [ 99 ] + +Script: OP_EQUAL +Stack: [ 99 99 ] + +Script: +Running: 99 99 OP_EQUAL +Stack: [ True ] +``` +Esta abstração não é muito precisa, já que, por razões de segurança, o ```scriptSig``` é executado, então o conteúdo da pilha é transferido para o ```scriptPubKey``` para ser executado, mas é preciso o suficiente para entender como a chave do ```scriptSig``` se encaixa o bloqueio de ```scriptPubKey```. + +> :warning: **AVISO:** O exemplo acima é um tipo de transação incomum. Na verdade, não seria aceito por nós que executamos o Bitcoin Core com as configurações padrões. Na seção [§10.1: Construindo um script do Bitcoin com P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) iremos discutir como realmente _podemos_ executar um Script Bitcoin como este, usando o poder do P2SH. + +### Obtendo os resultados + +O Bitcoin irá verificar uma transação e permitir que o UTXO possa ser gasto novamente se dois critérios forem atendidos ao executar o ```scriptSig``` e o ```scriptPubKey```: + + 1. A execução não foi marcada como inválida em nenhum ponto, por exemplo, com um OP_VERIFY com falha ou com o uso de um opcode desativado; + 2. O item no topo da pilha no final da execução é verdadeiro (diferente de zero). + +No exemplo acima, a transação seria bem-sucedida porque a pilha tem um ```True``` no final. Mas, seria igualmente permitido terminar com uma pilha completa e o número ```42``` no topo (os leitores do Guia do Mochileiro das Galáxias pegaram a referência). + +## Resumo: Executando um script do Bitcoin + +Para processar um script do Bitcoin, um ```scriptSig``` é executado seguido pelo ```scriptPubKey``` que está desbloqueando. Esses comandos são executados em ordem, da esquerda para a direita, com constantes sendo colocadas em uma pilha e os operadores retirando elementos dessa pilha e, em seguida, enviando os resultados de volta para ela. Se o Script não parar no meio e se o item no topo da pilha no final for diferente de zero, o UTXO será desbloqueado. + +## O que vem depois? + +Vamos continuar "Apresentando os Scripts no Bitcoin" na seção [§9.3: Testando o Script do Bitcoin](09_3_Testing_a_Bitcoin_Script.md). \ No newline at end of file diff --git a/pt/09_3_Testing_a_Bitcoin_Script.md b/pt/09_3_Testing_a_Bitcoin_Script.md new file mode 100644 index 0000000..e00e531 --- /dev/null +++ b/pt/09_3_Testing_a_Bitcoin_Script.md @@ -0,0 +1,209 @@ +# 9.3: Testando um script do Bitcoin + +O script do Bitcoin permite um controle adicional considerável sobre as transações do bitcoin, mas também é um tanto quanto perigoso. Como descreveremos na seção [§10.1](10_1_Understanding_the_Foundation_of_P2SH.md), os scripts reais são um tanto isolados da rede Bitcoin, o que significa que é possível escrever um script e a rede aceitá-lo, mesmo que seja impossível resgatar o script! Portanto, precisamos testar exaustivamente nossos scripts antes de colocarmos nosso saldo neles. + +Este capítulo, portanto, descreve um método primário para testar os scripts do Bitcoin, que também usaremos para os exemplos ocasionais que ocorrerem durante esta seção. + +## Instalando o btcdeb + +O Bitcoin Script Debugger (```btcdeb```) criado por @kallewoof é um dos métodos mais confiáveis ​​que encontramos para depurar os scripts do Bitcoin. No entanto, ele requer a configuração do C++ e algumas coisas mais em nossa máquina, portanto, também ofereceremos algumas outras opções no final do capítulo. + +Primeiro, precisamos clonar o repositório do ```btcdeb``` do GitHub, que também exigirá a instalação do ```git``` caso ainda não o tenhamos em nossa máquina. +``` +$ sudo apt-get install git +$ git clone https://github.com/bitcoin-core/btcdeb.git +``` +Note que quando executamos o ```git clone```, ele irá copiar o ```btcdeb``` para o nosso diretório atual. Vamos fazer isso no diretório ```~standup```. +``` +$ ls +bitcoin-0.20.0-x86_64-linux-gnu.tar.gz btcdeb laanwj-releases.asc SHA256SUMS.asc +``` +Posteriormente, devemos instalar o C++ e os demais pacotes. +``` +$ sudo apt-get install autoconf libtool g++ pkg-config make +``` +Também precisaremos instalar o readline, pois isso torna o depurador muito mais fácil de ser usado, suportando a utilização do histórico usando as setas para cima e para baixo, movimento da esquerda para a direita, além do preenchimento automático usando tab e outras interfaces boas para o usuário. +``` +$ sudo apt-get install libreadline-dev +``` +Agora estamos prontos para compilar e instalar o ```btcdeb```: +``` +$ cd btcdeb +$ ./autogen.sh +$ ./configure +$ make +$ sudo make install +``` +Depois de tudo isso, devemos ter uma cópia do ```btcdeb``` em nossa máquina: +``` +$ which btcdeb +/usr/local/bin/btcdeb +``` + +## Usando o btcdeb + +O ```btcdeb``` funciona como um depurador padrão. Ele pega um script (bem como qualquer número de entradas da pilha) como um argumento de inicialização. Em seguida, podemos percorrer o script usando o ```step```. + +Se ao invés disso nós querermos inicializá-lo sem argumentos, iremos obter simplesmente um interpretador onde podemos emitir comandos ```exec [opcode]``` para realizar ações diretas. + +### Usando o btcdeb para um exemplo de adição + +O exemplo a seguir mostra o uso do ```btcdeb``` usando como exemplo a adição da seção anterior, ```1 2 OP_ADD``` +``` +$ btcdeb '[1 2 OP_ADD]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +warning: ambiguous input 1 is interpreted as a numeric value; use OP_1 to force into opcode +warning: ambiguous input 2 is interpreted as a numeric value; use OP_2 to force into opcode +miniscript failed to parse script; miniscript support disabled +valid script +3 op script loaded. type `help` for usage information +script | stack +--------+-------- +1 | +2 | +OP_ADD | +#0000 1 +``` +Ele mostra nosso script inicial, rodando de cima para baixo, e também mostra o que será executado a seguir no script. + +Nós precisamos digitar ```step``` para ele avançar um passo pegando o primeiro item no script e colocando-o na pilha: +``` +btcdeb> step + <> PUSH stack 01 +script | stack +--------+-------- +2 | 01 +OP_ADD | +#0001 2 +``` +E novamente: +``` +btcdeb> step + <> PUSH stack 02 +script | stack +--------+-------- +OP_ADD | 02 + | 01 +#0002 OP_ADD +``` +Agora executamos o ```OP_ADD``` e há uma grande empolgação porque esse opcode tira os primeiros dois itens da pilha, faz a soma e, em seguida, coloca o resultado na pilha. +``` +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 03 +script | stack +--------+-------- + | 03 +``` +E é aí que nosso script termina, sem mais nada para executar e com um ```03``` no topo da pilha como resultado do script. + +> **NOTA:** O ```btcdeb``` permite que possamos repetir o comando anterior pressionando apenas a tecla enter. Faremos isso em exemplos subsequentes, então não fiquemos assustados com os prompts ```btcdeb>``` se não houver nenhum comando. Isso significa que apenas repetimos o comando anterior (geralmente usando o ```step```). + +### Usando o btcdeb com um exemplo de subtração + +A seção anterior também incluiu um exemplo de subtração um pouco mais complexa na criação do script: ```3 2 OP_ADD 4 OP_SUB```. Isso é o resultado: + +``` +$ btcdeb '[3 2 OP_ADD 4 OP_SUB]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +warning: ambiguous input 3 is interpreted as a numeric value; use OP_3 to force into opcode +warning: ambiguous input 2 is interpreted as a numeric value; use OP_2 to force into opcode +warning: ambiguous input 4 is interpreted as a numeric value; use OP_4 to force into opcode +miniscript failed to parse script; miniscript support disabled +valid script +5 op script loaded. type `help` for usage information +script | stack +--------+-------- +3 | +2 | +OP_ADD | +4 | +OP_SUB | +#0000 3 +btcdeb> step + <> PUSH stack 03 +script | stack +--------+-------- +2 | 03 +OP_ADD | +4 | +OP_SUB | +#0001 2 +btcdeb> + <> PUSH stack 02 +script | stack +--------+-------- +OP_ADD | 02 +4 | 03 +OP_SUB | +#0002 OP_ADD +btcdeb> + <> POP stack + <> POP stack + <> PUSH stack 05 +script | stack +--------+-------- +4 | 05 +OP_SUB | +#0003 4 +btcdeb> + <> PUSH stack 04 +script | stack +--------+-------- +OP_SUB | 04 + | 05 +#0004 OP_SUB +btcdeb> + <> POP stack + <> POP stack + <> PUSH stack 01 +script | stack +--------+-------- + | 01 +``` +Voltaremos ao ```btcdeb``` de tempos em tempos, e ele continuará sendo uma excelente ferramenta para testarmos nossos scripts. + +### Usando todo o poder do btcdeb + +O ```btcdeb``` também tem algumas funções mais poderosas, como ```print``` e ```stack```, que mostram o script e a pilha a qualquer momento da execução. + +Por exemplo, no script acima, depois de avançar para o comando ```OP_ADD```, podemos fazer o seguinte: +``` +btcdeb> print + #0000 3 + #0001 2 + -> #0002 OP_ADD + #0003 4 + #0004 OP_SUB +btcdeb> stack +<01> 02 (top) +<02> 03 +``` +Usar esses comandos tornará mais fácil observarmos o que está acontecendo e onde estamos no processo. + +## Testando um script online + +Existem também alguns simuladores web que podemos usar para testar os scripts online. Eles podem ser superiores a uma ferramenta de linha de comando, oferecendo uma saída gráfica melhor, mas também descobrimos que eles tendem a ter certas deficiências. + +No passado, tentamos fornecer diretrizes abrangentes sobre o uso de sites como o [Script Playground](http://www.crmarsh.com/script-playground/) ou o [Bitcoin Online Script Debugger](https: // bitcoin-script-debugger.visvirial.com/), mas eles estão desatualizados e/ou sumiram e não podemos mais acompanhá-los. + +O que podemos garantir é que esses depuradores possuem a vantagem de mostrar coisas visualmente e explicitamente informando se um script foi bem-sucedido (desbloqueado) ou que houve falha (permanece bloqueado). Porém eles possuem algumas desvantagens relacionadas as assinaturas, onde muitos deles sempre retornam ```true``` para testes de assinatura ou então possuem mecanismos muito complicados para incorporá-las. + +## Testando um script com Bitcoin + +Mesmo com uma ótima ferramenta como o ```btcdeb``` ou recursos transitórios como os diversos testadores de script online, não estamos trabalhando com a coisa real. Não podemos garantir que elas sigam as regras de consenso do Bitcoin, o que significa que não podemos garantir os resultados. Por exemplo, o Script Playground diz explicitamente que ignora um bug que está implícito quando usando o multisig do Bitcoin. Isso significa que qualquer código multisig que testarmos com sucesso no Script Playground irá dar erro no mundo real. + +Portanto, a única maneira de _realmente_ testar os scripts do Bitcoin é testá-los usando a Testnet. + +E como podemos faz isso? Acontece que esse é o tópico do [capítulo 10](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md), que examina a introdução desses scripts abstratos no mundo real do Bitcoin incorporando-os em transações P2SH. (Mas, mesmo assim, provavelmente, precisaremos de uma API para enviar nossa transação P2SH para a rede Bitcoin, então os testes que avaliam o processo completo ainda serão produzidos no futuro). + +_ Quaisquer que sejam_ os outros métodos de teste que usamos, testar um script na Testnet deve ser nosso teste final _antes_ de colocar nosso script em Mainnet. Não podemos confiar que nosso código está correto. Não podemos fazer isso apenas olhando para ele. Nem mesmo podemos confiar em quaisquer simuladores ou depuradores que estivermos utilizando. Fazer isso é outra ótima maneira de perder seu saldo no Bitcoin. + +## Resumo: Testando um script do Bitcoin + +Você deve instalar o ```btcdeb``` como uma ferramenta de linha de comando para testar os scripts do Bitcoin. No momento em que este livro foi escrito, produzimos resultados precisos que podem percorrer todo o processo do script. Também podemos procurar em alguns sites online uma representação mais visual. Quando estivermos com tudo pronto, vamos precisar usar a testnet para ter certeza de que as coisas estão funcionando com precisão, antes de implantarmos na Mainnet. + +## O que vem depois? + +Vamos continuar "Apresentando os Scripts no Bitcoin" com nosso primeiro exemplo real na seção [§9.4: Criando um script P2PKH](09_4_Scripting_a_P2PKH.md). \ No newline at end of file diff --git a/pt/09_4_Scripting_a_P2PKH.md b/pt/09_4_Scripting_a_P2PKH.md new file mode 100644 index 0000000..8d94e4f --- /dev/null +++ b/pt/09_4_Scripting_a_P2PKH.md @@ -0,0 +1,388 @@ +# 9.4: Criando um script P2PKH + +Os endereços P2PKH estão desaparecendo rapidamente devido ao advento do Segwit, porém, são importantes para entender o Bitcoin, e especialmente para entender os scripts do Bitcoin. Vamos dar uma olhada rápida como os scripts nativos do Segwit (P2WPKH) funcionam na próxima seção. + +## Entendendo o script de desbloqueio + +Dissemos que quando os fundos são enviados para um endereço de bitcoin, eles estão bloqueados juntamente com a chave privada associada a esse endereço. Isso é gerenciado através do ```scriptpubkey``` de uma transação P2PKH, que é projetado de forma que requer que o destinatário tenha a chave privada associada ao endereço bitcoin do tipo P2PKH. Para ser preciso, o destinatário deve fornecer tanto a chave pública ligada à chave privada quanto uma assinatura gerada pela chave privada. + +Vamos dar uma olhada novamente na transação que criamos na seção [§9.1](09_1_Understanding_the_Foundation_of_Transactions.md): +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$signedtx +{ + "txid": "34151dac704d94a269cd33f80be34c122152edc9bfbb9323852966bf0ce937ed", + "hash": "34151dac704d94a269cd33f80be34c122152edc9bfbb9323852966bf0ce937ed", + "version": 2, + "size": 191, + "vsize": 191, + "weight": 764, + "locktime": 0, + "vin": [ + { + "txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa", + "vout": 0, + "scriptSig": { + "asm": "304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b", + "hex": "47304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c01210315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91406b5c6ba5330cdf738a2ce91152bfd0e71f9ec3988ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mg8S7F1gY3ivV9M9GrWwe6ziWvK2MFquCf" + ] + } + } + ] +} +``` +Podemos ver que o script de desbloqueio do ```scriptSig``` tem dois valores, uma `````` (e um ```[ALL]```) e um ``````: +``` +304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +``` +Isso é tudo que um script de desbloqueio é! (No caso de um endereço P2PKH). + +## Entendendo o script de bloqueio + +Lembre-se de que cada script de desbloqueio desbloqueia um UTXO anterior. No exemplo acima, o ```vin``` revela que é realmente desbloqueado o vout ```0``` da txid ```bb4362dec15e67d366088f5493c789f22fbb4a6049f22fb4a604e767dae1f6a631687E2784aa```. + +Podemos examinar esse UTXO usando o comando ```gettransaction```. +``` +$ bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa" +{ + "amount": 0.00095000, + "confirmations": 12, + "blockhash": "0000000075a4c1519da5e671b15064734c42784eab723530a6ace83ca1e66d3f", + "blockheight": 1780789, + "blockindex": 132, + "blocktime": 1594841768, + "txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa", + "walletconflicts": [ + ], + "time": 1594841108, + "timereceived": 1594841108, + "bip125-replaceable": "no", + "details": [ + { + "address": "mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9", + "category": "receive", + "amount": 0.00095000, + "label": "", + "vout": 0 + } + ], + "hex": "020000000001011efcc3bf9950ac2ea08c53b43a0f8cc21e4b5564e205f996f7cadb7d13bb79470000000017160014c4ea10874ae77d957e170bd43f2ee828a8e3bc71feffffff0218730100000000001976a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac713b10000000000017a914b780fc2e945bea71b9ee2d8d2901f00914a25fbd8702473044022025ee4fd38e6865125f7c315406c0b3a8139d482e3be333727d38868baa656d3d02204b35d9b5812cb85894541da611d5cec14c374ae7a7b8ba14bb44495747b571530121033cae26cb3fa063c95e2c55a94bd04ab9cf173104555efe448b1bfc3a68c8f873342c1b00" +} +``` +Mas como podemos observar, não recebemos o ```scriptPubKey``` com o ```gettransaction```. Precisamos ter um passo adicional para recuperar essa informação, examinando as informações da transação bruta (que é o ```hex```) com o ```DecoderAwTransaction```: +``` +$ hex=$(bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa" | jq -r '.hex') +$ bitcoin-cli decoderawtransaction $hex +{ + "txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa", + "hash": "6866490b16a92d68179e1cf04380fd08f16ec80bf66469af8d5e78ae624ff202", + "version": 2, + "size": 249, + "vsize": 168, + "weight": 669, + "locktime": 1780788, + "vin": [ + { + "txid": "4779bb137ddbcaf796f905e264554b1ec28c0f3ab4538ca02eac5099bfc3fc1e", + "vout": 0, + "scriptSig": { + "asm": "0014c4ea10874ae77d957e170bd43f2ee828a8e3bc71", + "hex": "160014c4ea10874ae77d957e170bd43f2ee828a8e3bc71" + }, + "txinwitness": [ + "3044022025ee4fd38e6865125f7c315406c0b3a8139d482e3be333727d38868baa656d3d02204b35d9b5812cb85894541da611d5cec14c374ae7a7b8ba14bb44495747b5715301", + "033cae26cb3fa063c95e2c55a94bd04ab9cf173104555efe448b1bfc3a68c8f873" + ], + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.00095000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9" + ] + } + }, + { + "value": 0.01063793, + "n": 1, + "scriptPubKey": { + "asm": "OP_HASH160 b780fc2e945bea71b9ee2d8d2901f00914a25fbd OP_EQUAL", + "hex": "a914b780fc2e945bea71b9ee2d8d2901f00914a25fbd87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N9yWARt5E3TQsX2RjsauxSZaEZVhinAS4h" + ] + } + } + ] +} +``` +Podemos olhar agora para o ```vout``` ```0``` e ver que ele foi bloqueado com o ```scriptPubKey``` no ```OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG```. Essa é a metodologia de bloqueio padrão usada para um endereço P2PKH mais antigo com o `` preso no meio. + +Executando vamos demonstrar seu funcionamento. + +## Executando um script P2PKH + +Quando desbloqueamos um UTXO do tipo P2PKH, efetivamente concatenamos os scripts de desbloqueio e de bloqueio. Para um endereço P2PKH, como o exemplo que usamos neste capítulo, que produz o seguinte: +``` +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +``` +Com essas informações juntas, podemos examinar como um UTXO P2PKH é desbloqueado. + +Primeiro, colocamos as constantes iniciais na pilha, depois fazemos uma cópia do pubKey com o `OP_DUP`: +``` +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] + +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] + +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] + +Script: OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: OP_DUP +Stack: [ ] +``` +Por que duplicar? Porque é necessário verificar os dois elementos de desbloqueio, a chave pública e a assinatura. + +Em seguida, o ```OP_HASH160``` retira o `````` fora da pilha, cria um hash e coloca o resultado de volta na nela. +``` +Script: OP_EQUALVERIFY OP_CHECKSIG +Running: OP_HASH160 +Stack: [ ] +``` +Então, colocamos o `````` que estava no script de bloqueio na pilha: +``` +Script: OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] +``` +O ```OP_EQUALVERIFY``` é efetivamente dois opcodes: O ```OP_EQUAL```, que retira dois itens da pilha e coloca `True` ou `False` baseado na comparação de ambos elementos; e o ```OP_VERIFY``` que retira o resultado e imediatamente marca a transação como inválida se for ```False```. No capítulo 12 falaremos mais sobre o uso de ```OP_VERIFY``` como condicional. + +Assumindo que os dois `````` estão iguais, teremos o seguinte resultado: +``` +Script: OP_CHECKSIG +Running: OP_EQUALVERIFY +Stack: [ ] +``` +Neste momento, provamos os `````` fornecido nos hashes ```scriptSig``` para o endereço Bitcoin em questão, para que saibamos que o dono conhecia a chave pública. Mas, eles também precisam provar o conhecimento da chave privada, o que é feito com os ```OP_CHECKSIG```, que confirma que a assinatura do script de desbloqueio corresponde a essa chave pública. +``` +Script: +Running: OP_CHECKSIG +Stack: [ True ] +``` +O script agora termina e se foi bem sucedido, a transação é permitida para gastar novamente o UTXO em questão. + +### Usando o btcdeb em um exemplo P2PKH + +Testando transações de bitcoin reais com o ```btcdeb``` é um pouco mais complicado, porque precisamos conhecer a chave pública e uma assinatura para fazer todo o trabalho, e gerar o último é um pouco difícil. No entanto, uma maneira de testar as coisas é, deixar o Bitcoin fazer o trabalho para nós, gerando uma transação que _possa_ desbloquear um UTXO. Isso é o que fizemos acima, geramos a transação para gastar o UTXO criado pelo ```bitcoin-cli``` para calcular a `````` e o ``````. Podemos analisar as informações da transação bruta do UTXO para conhecer o script de bloqueio, incluindo o ``````. + +Podemos montar o script de bloqueio, a assinatura e o pubkey usando o `btcdeb`, mostrando como pode ser simples um script P2PKH . +``` +$ btcdeb '[304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +unknown key ID 41d83eaffbf80f82dee4c152de59a38ffd0b6021: returning fake key +valid script +7 op script loaded. type `help` for usage information +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... | +0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | +OP_DUP | +OP_HASH160 | +41d83eaffbf80f82dee4c152de59a38ffd0b6021 | +OP_EQUALVERIFY | +OP_CHECKSIG | + | + | +#0000 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c +``` +Colocamos a `````` e o `````` dentro da pilha: +``` +btcdeb> step + <> PUSH stack 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... +OP_DUP | +OP_HASH160 | +41d83eaffbf80f82dee4c152de59a38ffd0b6021 | +OP_EQUALVERIFY | +OP_CHECKSIG | + | + | + | + | + | +#0001 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +btcdeb> step + <> PUSH stack 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +OP_DUP | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +OP_HASH160 | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... +41d83eaffbf80f82dee4c152de59a38ffd0b6021 | +OP_EQUALVERIFY | +OP_CHECKSIG | + | + | + | + | + | + | + | +``` +Usamos o ```OP_DUP``` e o ```OP_HASH``` na ``````: + +``` +#0002 OP_DUP +btcdeb> step + <> PUSH stack 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +OP_HASH160 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +41d83eaffbf80f82dee4c152de59a38ffd0b6021 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +OP_EQUALVERIFY | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... +OP_CHECKSIG | + | + | + | + | + | + | + | + | + | +#0003 OP_HASH160 +btcdeb> step + <> POP stack + <> PUSH stack 41d83eaffbf80f82dee4c152de59a38ffd0b6021 +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +41d83eaffbf80f82dee4c152de59a38ffd0b6021 | 41d83eaffbf80f82dee4c152de59a38ffd0b6021 +OP_EQUALVERIFY | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +OP_CHECKSIG | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... + | + | + | + | + | + | + | + | + | + | +``` +Depois colocamos o `````` do script de bloqueio na pilha e o verificamos: +``` +#0004 41d83eaffbf80f82dee4c152de59a38ffd0b6021 +btcdeb> step + <> PUSH stack 41d83eaffbf80f82dee4c152de59a38ffd0b6021 +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +OP_EQUALVERIFY | 41d83eaffbf80f82dee4c152de59a38ffd0b6021 +OP_CHECKSIG | 41d83eaffbf80f82dee4c152de59a38ffd0b6021 + | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b + | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... + | + | + | + | + | + | + | + | + | + | +#0005 OP_EQUALVERIFY +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 01 + <> POP stack +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +OP_CHECKSIG | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b + | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... + | + | and_v( + | sig(304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c... + | and_v( + | pk(0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3... + | c:pk_h(030500000000000000000000000000000000000000000000... + | ) + | + | ) + | + +``` +E nesse ponto, tudo o que é necessário é o ```OP_CHECKSIG```: +``` +#0006 OP_CHECKSIG +btcdeb> step +error: Signature is found in scriptCode +``` +Infelizmente, esta verificação pode ou não estar funcionando no momento do teste devido a caprichos do Bitcoin Core e do `btcdeb`. + +Como mostramos, um P2PKH é bastante simples. Nossa proteção vem através da força da criptografia. + +### Como procurar uma Pub Key e uma Signature manualmente + +E se quiséssemos gerar a `````` e o ``````, informações necessárias para desbloquear um UTXO, sem usar o ```bitcoin-cli``` para criar uma transação? + +Acontece que é muito fácil obtermos uma ````````. Nós precisamos usar o ```getaddressinfo``` para examinar o endereço onde o UTXO está: +``` +$ bitcoin-cli getaddressinfo mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9 +{ + "address": "mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9", + "scriptPubKey": "76a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac", + "ismine": true, + "solvable": true, + "desc": "pkh([f004311c/0'/0'/2']0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b)#t3g5mjk9", + "iswatchonly": false, + "isscript": false, + "iswitness": false, + "pubkey": "0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b", + "iscompressed": true, + "ischange": false, + "timestamp": 1594835792, + "hdkeypath": "m/0'/0'/2'", + "hdseedid": "f058372260f71fea37f7ecab9e4c5dc25dc11eac", + "hdmasterfingerprint": "f004311c", + "labels": [ + "" + ] +} +``` +Descobrir essa assinatura, no entanto, requer que entendamos os meandros de como as transações do Bitcoin são criadas. Portanto, vamos deixar isso como sendo um estudo avançado para você leitor: criando uma transação de ```bitcoin-cli``` para "resolver" a UTXO é a melhor solução neste momento para conseguir essa informação. + +## Resumo: Criando um script P2PKH + +O envio para um endereço P2PKH foi relativamente fácil quando estávamos usando o ````bitcoin-cli````. Examinando o script do Bitcoin, pudemos ver que ele estabelece as funções criptográficas que estavam implícitas no financiamento da transação, ou seja, como o UTXO é desbloqueado com uma assinatura e uma chave pública. + +## O que vem depois? + +Vamos continuar "Apresentando os Scripts no Bitcoin" na seção [§9.4: Criando um script P2WPKH](09_4_Scripting_a_P2PKH.md). \ No newline at end of file diff --git a/pt/09_5_Scripting_a_P2WPKH.md b/pt/09_5_Scripting_a_P2WPKH.md new file mode 100644 index 0000000..df9f164 --- /dev/null +++ b/pt/09_5_Scripting_a_P2WPKH.md @@ -0,0 +1,119 @@ +# 9.5: Criando um script P2WPKH + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Os P2PKHs são bons para explicar a maneira fundamental como os scripts de Bitcoin funcionam, mas por que os scripts SegWit P2WPKH nativos estão se tornando cada vez mais a maioria das transações de Bitcoin? Acontece que os endereços P2WPKH não usam Scripts de Bitcoin como os endereços de Bitcoin tradicionais fazem e, portanto, esta seção é realmente uma digressão do script deste capítulo, mas ela é importante, porque descreve a _outra_ maneira principal pela qual os Bitcoins podem ser transacionados. + +## Observando um script P2WPKH + +É fácil ver a aparência de um script P2WPKH. A transação bruta abaixo foi criada gastando um UTXO P2WPKH e, em seguida, enviando o dinheiro para um endereço de troco P2WPKH, assim como fizemos com um endereço legado na seção [§9.1](09_1_Understanding_the_Foundation_of_Transactions.md). +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$signedtx +{ + "txid": "bdf8f12768a9870d41ac280f8bb4f8ecd9d2fa66fffc75606811f5751c17cb3a", + "hash": "ec09c84cae48694bec7fd3461b3c5b38a76829c56e9d876037bf2484d443174b", + "version": 2, + "size": 191, + "vsize": 110, + "weight": 437, + "locktime": 0, + "vin": [ + { + "txid": "3f5417bc7a3a4144d715f3f006d35ea2b405f06091cbb9ce492e04ccefe02b18", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "txinwitness": [ + "3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001", + "03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903" + ], + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "0 92a0db923b3a13eb576a40c4b35515aa30206cba", + "hex": "001492a0db923b3a13eb576a40c4b35515aa30206cba", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qj2sdhy3m8gf7k4m2grztx4g44gczqm96y6sszv" + ] + } + } + ] +} +``` +Provavelmente existem duas coisas surpreendentes aqui: (1) Não há ```scriptSig``` para desbloquear a transação anterior e; (2) o ```scriptPubKey``` para bloquear a nova transação é apenas ```0 92a0db923b3a13eb576a40c4b35515aa30206cb```. + +Isso é assim porque o P2WPKH funciona de forma totalmente diferente! + +## Compreendendo uma transação P2WPKH + +Uma transação P2WPKH contém todas as mesmas informações que uma transação P2PKH clássica, mas a coloca em lugares diferentes, não dentro de um script Bitcoin tradicional, e essa é a cereja do bolo das transações SegWit, pois coloca as informações nas "witness" (testemunhas), que é onde as chaves públicas e as assinaturas vão, ficando fora da transação, dando suporte para diminuir o tamanho da transação e aumentando a quantidade sem aumentar o tamanho bloco. + +Mas, se olharmos com cuidado, veremos que o ```scriptSig``` vazio foi substituído por duas entradas em uma nova seção chamada ```txinwitness```. Se examinarmos os tamanhos e formatações, eles devem parecer familiares, afinal, elas são uma assinatura e uma chave pública. Da mesma forma, se olharmos o `scriptPubKey`, veremos que é feito de um ```0``` (Na verdade, de um ```OP_0```, que é o número da versão do SegWit) e outro número longo, que é o hash de chave pública. + +Aqui está uma comparação dos nossos dois exemplos: +| Tipo | PubKeyHash | PubKey | Signature | +|----------------|----------|-------------|---------| +| SegWit | 92a0db923b3a13eb576a40c4b35515aa30206cba | 03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903 | 3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001 | +| SegWit | 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | 04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c | + +Então, como isso tudo funciona? Depende da interpretação do código antigo como uma transação válida e do conhecimento do novo código para verificar as novas informações da "witness". + +### Lendo um script SegWit em uma máquina antiga + +Se um node não foi atualizado para suportar SegWit, então ele faz o seu truque usual de concatenar o ```scriptSig``` e o ```scriptPubKey```. Isso produz o seguinte: ```0 92a0db923b3a13eb576a40c4b35515aa30206cba``` (porque há apenas um ```scriptPubKey```). Ao executar isso, iremos produzir uma pilha com tudo na ordem inversa: +``` +$ btcdeb '[0 92a0db923b3a13eb576a40c4b35515aa30206cba]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +miniscript failed to parse script; miniscript support disabled +valid script +2 op script loaded. type `help` for usage information +script | stack +-----------------------------------------+-------- +0 | +92a0db923b3a13eb576a40c4b35515aa30206cba | +#0000 0 +btcdeb> step + <> PUSH stack +script | stack +-----------------------------------------+-------- +92a0db923b3a13eb576a40c4b35515aa30206cba | 0x +#0001 92a0db923b3a13eb576a40c4b35515aa30206cba +btcdeb> step + <> PUSH stack 92a0db923b3a13eb576a40c4b35515aa30206cba +script | stack +-----------------------------------------+----------------------------------------- + | 92a0db923b3a13eb576a40c4b35515aa30206cba + | 0x +``` +Os scripts do Bitcoin são considerados bem-sucedidos se houver algo na pilha e ele for diferente de zero, portanto, os scripts SegWit são automaticamente bem-sucedidos nos nós antigos, desde que o ```scriptPubKey``` seja criado corretamente com um hash de uma pub-key diferente de zero. Isso é chamado de transação _"anyone-can-spend"_, ou no português, _"qualquer-um-pode-gastar"_, porque os nodes antigos os verificaram como corretos sem a necessidade de assinaturas. + +> :book: ***Os nodes antigos não podem roubar os UTXOs do SegWit?*** O SegWit foi habilitado na rede Bitcoin quando 95% dos mineradores sinalizaram que estavam prontos para começar a utilizá-lo. Isso significa que apenas 5% dos nodes naquele momento podem ter registrado transações SegWit que _qualquer-um-pode-gastar_ como sendo válidas, sem passar pelo trabalho adequado de verificação dos ```txinwitness```. Se incorporassem incorretamente um UTXO inválido que _qualquer-um-pode-gastar_ em um bloco, os outros 95% dos nodes se recusariam a validar esse bloco, e assim ele ficaria rapidamente órfão ao invés de ser adicionado a blockchain "principal". (Certamente, 51% dos nodes poderiam escolher parar de interpretar as transações SegWit corretamente, mas 51% dos nodes podem fazer qualquer coisa em uma rede de consenso, como uma blockchain). + +Como os nodes antigos sempre acham que os scripts SegWit estão corretos, eles sempre os verificam, mesmo sem entender seu conteúdo. + +### Lendo um script SegWit em uma máquina nova + +Uma máquina que entende como o SegWit funciona faz exatamente as mesmas coisas que faria com um script P2PKH antigo, mas não usa o script por si só. Ela apenas sabe que precisa fazer o hash da chave pública no ```txinwitness```, verificando-a usando a chave hash após o número da versão no ```scriptPubKey``` e, em seguida, executando o ```OP_CHECKSIG``` na assinatura e na chave pública do ```txinwitness```. + +Portanto, é outra maneira de fazer a mesma coisa, mas sem ter os scripts embutidos nas transações. Ao invés disso, o processo é integrado ao software do node. + +## Resumo: Criando um script P2WPKH + +Em grande parte, _não_ fazemos um script de um P2WPKH. Ao invés disso, o Bitcoin Core cria a transação de uma maneira diferente, colocando as informações da testemunha em um lugar diferente ao invés de um ```scriptSig``` tradicional. Isso significa que os P2WPKHs são uma digressão dos scripts de Bitcoin desta parte do livro, porque são uma expansão do Bitcoin que se distancia dos scripts tradicionais. + +No entanto, o SegWit também usa os scripts do Bitcoin de maneira inteligente. Sabendo que haveria nodes que não seriam atualizados e que precisariam permanecer compatíveis com versões anteriores, os desenvolvedores criaram o formato P2WPKH de forma que gerasse um script que sempre seria validado nos nodes antigos (embora ainda tivesse aquele script fornecendo informações para os nodes novos em uma forma de um número de versão e uma chave pública com hash). + +Quando estamos programando usando a linha de comando, fundamentalmente não precisamos nos preocupar com isso, a não ser com saber que não encontraremos os scripts tradicionais em transações brutas do tipo SegWit (o que, novamente, era o ponto desta seção). + +## O que vem depois? + +Vamos continuar "Criando scripts no Bitcoin" no [Capítulo 10: Incorporando scripts do bitcoin em transações P2SH](09_4_Scripting_a_P2PKH.md). \ No newline at end of file From 2452670750f1d45df93110a99258e590eb9c0f85 Mon Sep 17 00:00:00 2001 From: hgrams <77242934+hgrams@users.noreply.github.com> Date: Thu, 22 Jul 2021 13:49:58 -0300 Subject: [PATCH 035/155] Chapter 8 Revised Translation --- pt/08_1_Sending_a_Transaction_with_a_Locktime.md | 6 +++--- pt/08_2_Sending_a_Transaction_with_Data.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pt/08_1_Sending_a_Transaction_with_a_Locktime.md b/pt/08_1_Sending_a_Transaction_with_a_Locktime.md index bebfeef..6b4d446 100644 --- a/pt/08_1_Sending_a_Transaction_with_a_Locktime.md +++ b/pt/08_1_Sending_a_Transaction_with_a_Locktime.md @@ -1,6 +1,6 @@ # 8.1: Enviando uma transação com Locktime -Os capítulos anteriores mostraram duas maneiras diferentes de enviar fundos de várias máquinas e também para vários destinatários. Mas, existem duas outras maneiras de alterar fundamentalmente as transações básicas. A primeira delas é variar o tempo escolhendo um tempo de bloqueio ou mais conhecido pela expressão em inglês locktime. Isso nos dá a capacidade de enviar transações brutas em algum momento no futuro. +Os capítulos anteriores mostraram duas maneiras diferentes de enviar fundos de várias máquinas e para vários destinatários. Mas, existem duas outras maneiras de alterar fundamentalmente as transações básicas. A primeira delas é variar o tempo, escolhendo um tempo de bloqueio ou mais conhecido pela expressão em inglês locktime. Isso nos dá a capacidade de enviar transações brutas em algum momento no futuro. ## Entendendo como o Locktime funciona @@ -24,7 +24,7 @@ Para criar uma transação com locktime, precisamos primeiro determinar como def Provavelmente, iremos definir com muito mais frequência o nosso tempo de bloqueio usando um carimbo de data/hora do tipo UNIX que representa uma data e hora específica. Podemos calcular um carimbo de data/hora UNIX usando sites que fazem essa conversão, como o [UNIX Time Stamp](http://www.unixtimestamp.com/) ou o [Epoch Convertor](https://www.epochconverter.com/). No entanto, seria melhor [escrevermos nosso próprio script](https://www.epochconverter.com/#code) em nossa máquina local, para que saibamos que o carimbo de data/hora UNIX que recebemos está correto (lembre-se, não confie, verifique). Se não fizermos isso, pelo menos seria interessante verificar em dois sites diferentes para ter a certeza que tudo está correto. -> :book: _Por que iríamos usar um carimbo de data/hora do UNIX?_ O uso de um carimbo de data/hora do UNIX facilita a vinculação definitiva de uma transação a um horário específico, sem se preocupar se a velocidade de criação do bloco mudar drasticamente até lá. Principalmente se estivermos criando um locktime em um futuro distante, é a coisa mais segura a ser feita. Entretanto, utilizar esse método é mais intuitivo, criando uma correlação direta entre alguma data do calendário e a hora em que a transação pode ser colocado na blockchain do Bitcoin. +> :book: _Por que iríamos usar um carimbo de data/hora do UNIX?_ O uso de um carimbo de data/hora do UNIX facilita a vinculação definitiva de uma transação a um horário específico, sem se preocupar se a velocidade de criação do bloco mudara drasticamente até lá. Principalmente se estivermos criando um locktime em um futuro distante, é a coisa mais segura a ser feita. Entretanto, utilizar esse método é mais intuitivo, criando uma correlação direta entre alguma data do calendário e a hora em que a transação pode ser colocada na blockchain do Bitcoin. > :warning: **AVISO:** O Locktime com carimbos de data/hora tem menos flexibilidade, pois a liberação de blocos não é regular e os tempos de bloqueio podem ser duas horas antes do tempo real, então um locktime significa "mais ou menos nesta data e nesta hora". @@ -34,7 +34,7 @@ Como alternativa, podemos definir o locktime usando um número menor, que repres Depois de descobrir a altura atual, podemos decidir até que ponto no futuro iremos configurar o locktime. É importante lembrar que, em média, um novo bloco será criado a cada 10 minutos. Então, por exemplo, se quisermos definir o tempo de bloqueio para uma semana no futuro, devemos escolher uma altura de bloco que é _6 x 24 x 7 = 1.008 blocos_ depois do atual. -> :book: _Por que eu usaria a altura do bloco?_ Ao contrário dos carimbos de data/hora, não existe confusão nas alturas de bloco. Se definirmos uma altura de bloco de 120.000 para o nosso locktime, não haverá absolutamente nenhuma maneira dele entrar no bloco 119.999. Isso pode tornar o controlar no código mais fácil ao manipular nossa transação com locktime. A desvantagem é que não podemos ter certeza de quando exatamente será o locktime. +> :book: _Por que eu usaria a altura do bloco?_ Ao contrário dos carimbos de data/hora, não existe confusão nas alturas de bloco. Se definirmos uma altura de bloco de 120.000 para o nosso locktime, não haverá absolutamente nenhuma maneira dele entrar no bloco 119.999. Isso pode tornar o controle no código mais fácil ao manipular nossa transação com locktime. A desvantagem é que não podemos ter certeza de quando exatamente será o locktime. > :warning: **AVISO:** Se desejamos definir um locktime usando a altura do bloco, devemos definir o tempo de bloqueio para menos de 500 milhões. Se definirmos como sendo 500 milhões ou mais, nosso número será interpretado como um carimbo de data/hora. Como o carimbo de data/hora usando o padrão UNIX com valor de 500 milhões era dia 5 de novembro de 1985, provavelmente significa que nossa transação será permitida a qualquer momento a entrar na blockchain. diff --git a/pt/08_2_Sending_a_Transaction_with_Data.md b/pt/08_2_Sending_a_Transaction_with_Data.md index 0ab376f..a367ed7 100644 --- a/pt/08_2_Sending_a_Transaction_with_Data.md +++ b/pt/08_2_Sending_a_Transaction_with_Data.md @@ -112,7 +112,7 @@ Podemos observar um aviso sobre os dados estarem em um "protocolo desconhecido". Podemos usar o ```OP_RETURN``` para armazenar até 80 bytes de dados na blockchain. Fazemos isso com a palavra-código ```data``` em um ```vout```. Ainda precisaremos enviar alguns satoshinhos, mas basta enviá-lo de volta para um endereço de troco, retirando a taxa de transação. -> :fire: _Qual é o poder do OP_RETURN?_ O OP_RETURN abre novas possibilidades para o blockchain, porque podemos inserir dados que provam que certas coisas aconteceram em determinados momentos. Várias organizações estão pensando em usar os OP_RETURNs como prova de existência, para direitos autorais, para moedas coloridas e [para outros fins](https://en.bitcoin.it/wiki/OP_RETURN). Embora 80 bytes possa não parecer muito, pode ser bastante eficaz se os OP_RETURNs forem usados ​​para armazenar hashes dos dados reais. Então, podemos provar a existência dos nossos dados digitais demonstrando que o hash deles corresponde ao hash na blockchain. +> :fire: _Qual é o poder do OP_RETURN?_ O OP_RETURN abre novas possibilidades para o blockchain, porque podemos inserir dados que provam que certas coisas aconteceram em determinados momentos. Várias organizações estão pensando em usar os OP_RETURNs como prova de existência, para direitos autorais, para moedas coloridas e [para outros fins](https://en.bitcoin.it/wiki/OP_RETURN). Embora 80 bytes possam não parecer muito, pode ser bastante eficaz se os OP_RETURNs forem usados ​​para armazenar hashes dos dados reais. Então, podemos provar a existência dos nossos dados digitais demonstrando que o hash deles corresponde ao hash na blockchain. Observe que há alguma controvérsia sobre o uso da blockchain do Bitcoin usando-a para este fim. From d555f72e353df7522eb82c99322250ec2a41c964 Mon Sep 17 00:00:00 2001 From: namcios Date: Fri, 23 Jul 2021 11:04:05 -0300 Subject: [PATCH 036/155] Review 07_0 --- pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md b/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md index e8b2222..4ede529 100644 --- a/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md +++ b/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md @@ -1,8 +1,8 @@ -# Capítulo Sete: Expandindo as Transações de Bitcoin com PSBTs +# Capítulo Sete: Expandindo Transações no Bitcoin com PSBTs No capítulo anterior, discutimos como usar os multisigs para determinar colaborativamente o consentimento entre várias partes. Essa não é a única forma de colaborar na criação de transações no Bitcoin. Os PSBTs são uma tecnologia muito mais recente que permite que colaboremos em vários estágios, incluindo a criação, financiamento e autenticação de uma transação Bitcoin. -## Objetivos para esta seção +## Objetivos para Esta Seção Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: @@ -13,12 +13,12 @@ Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: Os objetivos secundários do capítulo incluem a capacidade de: * Entender como os PSBTs diferem dos multisig; - * Compreender o completamente o fluxo de trabalho com os PSBTs; - * Planejar todo o poder dos PSBTs; + * Compreender completamente o fluxo de trabalho com os PSBTs; + * Planejar para todo o poder dos PSBTs; * Compreender o uso de uma hardware wallet. ## Tabela de Conteúdo * [Seção Um: Criando uma Transação Bitcoin Parcialmente Assinada](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) - * [Seção Dois: Usando uma transação Bitcoin parcialmente assinada](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) - * [Seção Três: Integração com hardware wallets](07_3_Integrating_with_Hardware_Wallets.md) \ No newline at end of file + * [Seção Dois: Usando uma Transação Bitcoin Parcialmente Assinada](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) + * [Seção Três: Integrando com Hardware Wallets](07_3_Integrating_with_Hardware_Wallets.md) \ No newline at end of file From d3e8ca62470833621032082bc55896f7c570232c Mon Sep 17 00:00:00 2001 From: namcios Date: Fri, 23 Jul 2021 11:36:22 -0300 Subject: [PATCH 037/155] Review 07_1 --- ..._a_Partially_Signed_Bitcoin_Transaction.md | 101 +++++++++--------- 1 file changed, 53 insertions(+), 48 deletions(-) diff --git a/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md b/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md index 6308690..f1f7d58 100644 --- a/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md +++ b/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md @@ -2,35 +2,36 @@ > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -As Transações Bitcoin Parcialmente Assinadas (Partially Signed Bitcoin Transactions ou mais conhecidas como PSBTs) são a forma mais recente de variar a criação de transações básicas do Bitcoin. Eles fazem isso introduzindo a colaboração em todas as etapas do processo, permitindo que as pessoas (ou sistemas) não apenas autentiquem as transações juntas (como nas multisigs), mas também criem, financiem e transmitam facilmente, de forma colaborativa. +As Transações Bitcoin Parcialmente Assinadas (Partially Signed Bitcoin Transactions ou mais conhecidas como PSBTs) são a forma mais recente de variar a criação de transações básicas do Bitcoin. Eles fazem isso introduzindo a colaboração em todas as etapas do processo, permitindo que as pessoas (ou sistemas) não apenas autentiquem as transações em conjunto (como nas multisigs), mas também criem, financiem e transmitam facilmente de forma colaborativa. -> :aviso: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v 0.17.0. As versões anteriores do Bitcoin Core não funcionarão com o PSBT enquanto estiver em andamento (apesar de consiguir reconhecer a transação final). Algumas atualizações e upgrades para PSBTs continuaram até a versão 0.20.0. +> :aviso: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v 0.17.0. As versões anteriores do Bitcoin Core não funcionarão com o PSBT enquanto estiver em andamento (apesar de conseguir reconhecer a transação final). Algumas atualizações e upgrades para PSBTs continuaram até a versão 0.20.0. -## Entendendo como funcionam os PSBTs +## Entendendo Como PSBTs Funcionam -O multisig são ótimos para o caso específico de manter fundos em conjunto e definir regras para quem, entre os signatários conjuntos, poderia autenticar o uso do saldo. Existem muitos casos de uso, como: Uma conta conjunta entre cônjuges (uma assinatura um de dois); Um requisito fiduciário para duplo controle (uma assinatura 2 de 2); e um depósito (uma assinatura 2 de 3). +Os multisigs são ótimos para o caso específico de manter fundos em conjunto e definir regras para quem, entre os signatários conjuntos, poderia autenticar o uso do saldo. Existem muitos casos de uso, como: uma conta conjunta entre cônjuges (uma assinatura 1-de-2); um requisito fiduciário para duplo controle (uma assinatura 2-de-2); e um depósito (uma assinatura 2-de-3). -> :book: ***O que é um PSBT?*** Como o nome sugere, um PSBT é uma transação que não foi totalmente assinada. Isso é importante porque, uma vez que uma transação é assinada, seu conteúdo está travado. O [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) definiu uma metodologia abstrata para colocar os PSBTs juntos que descreve e padroniza funções de criação colaborativa. Um *Criador* propõe uma transação; um ou mais *Atualizadores* o complementam; e um ou mais *Assinantes* o autenticam. Antes de um *Finalizador* concluir o processo e, um *Extrator* o transformar em uma transação na rede Bitcoin. Também pode haver um *Combinador* que mescla os PSBTs paralelos de vários usuários. +> :book: ***O que é uma PSBT?*** Como o nome sugere, uma PSBT é uma transação que não foi totalmente assinada. Isso é importante porque, uma vez que uma transação é assinada, seu conteúdo está travado. O [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) definiu uma metodologia abstrata para colocar as PSBTs junto que descreve e padroniza funções de criação colaborativa. Um *Criador* propõe uma transação; um ou mais *Atualizadores* a complementam; e um ou mais *Assinantes* a autenticam; antes de um *Finalizador* concluir o processo; e um *Extrator* o transformar em uma transação na rede Bitcoin. Também pode haver um *Combinador* que mescla as PSBTs paralelas de vários usuários. -Os PSBTs podem, inicialmente, ter a mesma aparência que os multisigs porque têm um único bit de funcionalidade sobreposto: A capacidade de assinar uma transação em conjunto. No entanto, eles foram criados para um caso de uso totalmente diferente. Os PSBTs reconhecem a necessidade de vários programas criarem uma transação em conjunto por vários motivos diferentes e fornecem um formato regularizado para isso. Eles são especialmente úteis para casos de uso envolvendo hardware wallets (Se quisermos saber mais basta consultarmos a seção [§7.3](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_3_Integrating_with_Hardware_Wallets.md )), que são protegidos contra acesso total à Internet e tendem a ter um histórico mínimo, quando não zero, de transações. +As PSBTs podem, inicialmente, ter a mesma aparência que os multisigs porque têm um único pedaço de funcionalidade sobreposto: a capacidade de assinar uma transação em conjunto. No entanto, elas foram criadas para um caso de uso totalmente diferente. As PSBTs reconhecem a necessidade de vários programas criarem uma transação em conjunto por vários motivos diferentes e fornecem um formato regularizado para isso. Elas são especialmente úteis para casos de uso envolvendo hardware wallets (veja a seção [§7.3](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_3_Integrating_with_Hardware_Wallets.md )), que são protegidas contra acesso total à internet e tendem a ter um histórico mínimo, quando não zero, de transações. -Em geral, os PSBTs fornecem vários elementos funcionais que aprimoram esse caso de uso: +Em geral, as PSBTs fornecem vários elementos funcionais que aprimoram esse caso de uso: -1. Eles fornecem um _padrão_ para criar transações de forma colaborativa, enquanto as metodologias anteriores (incluindo o multisig do capítulo anterior) dependiam de implementação; -2. Eles oferecem suporte a uma _variedade mais ampla de casos de uso_, incluindo financiamento simples em conjunto; -3. Eles suportam _hardware wallets_ e outros casos em que um node pode não ter um histórico completo das transações; -4. Eles opcionalmente permitem a combinação de _transações não serializadas_, não exigindo que um código hexadecimal cada vez maior seja passado de usuário para usuário. +1. Elas fornecem um _padrão_ para criar transações de forma colaborativa, enquanto as metodologias anteriores (incluindo o multisig do capítulo anterior) dependiam de implementação; +2. Elas oferecem suporte a uma _variedade mais ampla de casos de uso_, incluindo financiamento simples em conjunto; +3. Elas suportam _hardware wallets_ e outros casos em que um node pode não ter um histórico completo das transações; +4. Elas opcionalmente permitem a combinação de _transações não serializadas_, não exigindo que um código hexadecimal cada vez maior seja passado de usuário para usuário. -Os PSBTs fazem nosso trabalho complementando as informações normais da transação com um conjunto de entradas e saídas, cada uma delas definindo tudo o que precisamos saber sobre os UTXOs, de forma que mesmo uma carteira com airgap possa tomar uma decisão informada sobre as assinaturas. Assim, quando confrontado com uma entrada com listas de saldos em um UTXO a carteira offline sabe o que precisa ser feito para gastá-los, enquanto o resultado faz o mesmo para os UTXOs que estão sendo criados. +As PSBTs fazem seu trabalho complementando as informações normais da transação com um conjunto de entradas e saídas, cada uma delas definindo tudo o que precisamos saber sobre os UTXOs, de forma que mesmo uma carteira com airgap possa tomar uma decisão informada sobre as assinaturas. Assim, uma entrada lista o saldo de um UTXO e o que precisa ser feito para gastá-lo, enquanto a saída faz o mesmo para os UTXOs que ela está criando. -Esta primeira seção descreverá o processo PSBT padrão com as seguintes funções: Criador, Atualizador, Assinante, Finalizador, Extrator. Faremos isso em uma máquina só, o que irá parecer uma forma complicada de criar uma transação bruta. Mas, tenha fé, há um motivo para isso! Nas seções [§7.2](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) e [§7.3](07_3_Integrating_with_Hardware_Wallets.md) vamos ver alguns exemplos reais de como utilizar o PSBTs e vamos transformar este sistema simples em um processo colaborativo compartilhado entre várias máquinas que tem efeitos reais e cria oportunidades reais. +Esta primeira seção descreverá o processo PSBT padrão com as seguintes funções: Criador, Atualizador, Assinante, Finalizador, Extrator. Faremos isso em uma máquina só, o que irá parecer uma forma complicada de criar uma transação bruta. Mas, tenha fé, há um motivo para isso! Nas seções [§7.2](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) e [§7.3](07_3_Integrating_with_Hardware_Wallets.md) vamos ver alguns exemplos reais de como utilizar as PSBTs e vamos transformar este sistema simples em um processo colaborativo compartilhado entre várias máquinas que tem efeitos reais e cria oportunidades reais. -## Criando um PSBT à moda antiga -#### Função do PSBT: Criador +## Criando uma PSBT à Moda Antiga -A maneira mais fácil de criar um PSBT é pegando uma transação existente e usando o comando ```converttopsbt``` para transformá-la em um PSBT. Certamente, esta não é a _melhor_ maneira, uma vez que requer que façamos uma transação usando um formato (uma transação bruta) e depois convertendo-a para outro (PSBT), mas se tivermos um software antigo que só pode gerar uma transação bruta, podemos precisar utilizá-lo. +#### Função na PSBT: Criador -Acabamos de criar uma transação bruta normalmente: +A maneira mais fácil de criar uma PSBT é pegando uma transação existente e usando o comando ```converttopsbt``` para transformá-la em uma PSBT. Certamente, esta não é a _melhor_ maneira, uma vez que requer que façamos uma transação usando um formato (uma transação bruta) e depois convertendo-a para outro (PSBT), mas se tivermos um software antigo que só pode gerar uma transação bruta, pode ser que precisemos utilizá-lo. + +Apenas criamos uma transação bruta normalmente: ``` $ utxo_txid_1=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') @@ -50,12 +51,13 @@ cHNidP8BAHsCAAAAAhuVpgVRdOxkuC7wW2rvw4800OVxl+QCgezYKHtCYN7GAQAAAAD/////HPTH9wFg ``` É possível notar que a codificação PSBT é muito diferente da transação hexadecimal que estamos acostumados. -Mas se pudermos, podemos criar o PSBT diretamente. +Mas, se pudermos, optaremos por criar o PSBT diretamente. -## Criando um PSBT da maneira mais difícil -#### Função do PSBT: Criador +## Criando uma PSBT da Maneira Difícil -A primeira metodologia de criação de um PSBT sem passar por outro formato é usando o comando PSBT análogo ao ```createrawtransaction```. Usando o ```createpsbt``` teremos o controle máximo ao custo do máximo trabalho e da oportunidade máxima de erros. +#### Função na PSBT: Criador + +A primeira metodologia de criação de uma PSBT sem passar por outro formato é usando o comando para PSBT análogo ao ```createrawtransaction```. Usando o ```createpsbt``` teremos o controle máximo a custo do máximo trabalho e da oportunidade máxima de erros. A CLI deve parecer bastante familiar, a diferença é que agora usamos um novo comando RPC: ``` @@ -63,7 +65,7 @@ $ psbt_1=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid_1'", ``` A equipe do Bitcoin Core certificou-se de que ```createpsbt``` funcionasse de maneira muito parecida com a```createrawtransaction```, portanto não precisamos aprender uma nova sintaxe diferente. -Podemos verificar se o novo PSBT é o mesmo criado pelo ```converttopsbt```: +Podemos verificar se a nova PSBT é a mesma criada pelo ```converttopsbt```: ``` $ echo $psbt_1 cHNidP8BAHsCAAAAAhuVpgVRdOxkuC7wW2rvw4800OVxl+QCgezYKHtCYN7GAQAAAAD/////HPTH9wFgyf4iQ2xw4DIDP8t9IjCePWDjhqgs8fXvSIcAAAAAAP////8BigIAAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBQAAAAAAAAAA @@ -71,10 +73,11 @@ $ if [ "$psbt" == "$psbt_1" ]; then echo "PSBTs are equal"; else echo "P PSBTs are equal ``` -## Examinando um PSBT -#### Função do PSBT: Qualquer uma +## Examinando uma PSBT -Então, como o nosso PSBT realmente se parece? Podemos ver isso com o comando ```decodepsbt```: +#### Função na PSBT: Qualquer Uma + +Então, como a nossa PSBT realmente se parece? Podemos ver isso com o comando ```decodepsbt```: ``` $ bitcoin-cli -named decodepsbt psbt=$psbt { @@ -136,9 +139,9 @@ $ bitcoin-cli -named decodepsbt psbt=$psbt ] } ``` -É importante notar que, embora tenhamos definido os fundamentos da transação: Os ```vins``` de onde o dinheiro está vindo e os ```vouts``` de onde está saindo, ainda não definimos as ```entradas``` e as ```saídas``` que são o coração do PSBT e que são necessários para os usuários offline avaliá-los. Isso já é esperado: O papel do Criador conforme definido no [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) é delinear a transação, enquanto o papel do Atualizador é começar a preencher os dados específicos do PSBT. (Outros comandos combinam as funções de Criador e Atualizador, mas o ```createpsbt``` não porque não tem acesso à nossa carteira). +É importante notar que, embora tenhamos definido os fundamentos da transação: os ```vins``` de onde o dinheiro está vindo e os ```vouts``` para onde está indo, ainda não definimos os ```inputs``` e os ```outputs``` que são o coração da PSBT e que são necessários para os usuários offline avaliá-las. Isso já é esperado: o papel do Criador conforme definido no [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) é delinear a transação, enquanto o papel do Atualizador é começar a preencher os dados específicos da PSBT. (Outros comandos combinam as funções de Criador e Atualizador, mas o ```createpsbt``` não, porque não tem acesso à nossa carteira). -Também podemos usar o comando ```analyzeepsbt``` para verificar nosso estado atual: +Também podemos usar o comando ```analyzepsbt``` para verificar nosso estado atual: ``` standup@btctest20:~$ bitcoin-cli -named analyzepsbt psbt=$psbt { @@ -157,14 +160,15 @@ standup@btctest20:~$ bitcoin-cli -named analyzepsbt psbt=$psbt "next": "updater" } ``` -Da mesma forma, o comando ```analysepsbt``` nos mostra um PSBT que precisa ser trabalhado. Damos uma olhada em cada uma das duas `entradas` (correspondendo aos dois ```vins```), e nenhuma delas possui as informações de que precisamos. +Da mesma forma, o comando ```analysepsbt``` nos mostra uma PSBT que precisa ser trabalhada. Damos uma olhada em cada um dos dois `inputs` (correspondendo aos dois ```vins```), e nenhum deles possui as informações de que precisamos. -## Finalizando um PSBT -#### Funções dos PSBT: Atualizador, Assinante e Finalizador +## Finalizando uma PSBT -Existe o comando ```utxoupdatepsbt``` que pode ser usado para atualizar o UTXOs, importando as informações do descritor manualmente, mas não queremos usá-lo a menos que tenhamos um caso de uso em que não tenhamos todas as informações nas carteiras de todos que irão assinar o PSBT. +#### Funções na PSBT: Atualizador, Assinante e Finalizador -> :information_source: **NOTA:** Se escolhermos Atualizar o PSBT com o ```utxoupdatepsbt```, ainda precisaremos usar o ```walletprocesspsbt``` para assiná-lo: É o único comando que a função Assinante possui no PSBTs que está disponível no `bitcoin-cli`. +Existe o comando ```utxoupdatepsbt``` que pode ser usado para atualizar UTXOs, importando as informações do descritor manualmente, mas não queremos usá-lo a menos que tenhamos um caso de uso em que não tenhamos todas as informações nas carteiras de todos que irão assinar a PSBT. + +> :information_source: **NOTA:** Se escolhermos Atualizar a PSBT com o ```utxoupdatepsbt```, ainda precisaremos usar o ```walletprocesspsbt``` para assiná-lo: é o único comando que a função Assinante possui em PSBTs que está disponível no `bitcoin-cli`. Ao invés disso, devemos usar o ```walletprocesspsbt```, que irá atualizar, assinar e finalizar: ``` @@ -174,11 +178,11 @@ $ bitcoin-cli walletprocesspsbt $psbt "complete": true } ``` -Obviamente, não precisaremos salvar as informações do ```psbt``` usando```JQ```: +Obviamente, precisaremos salvar as informações da ```psbt``` usando```JQ```: ``` $ psbt_f=$(bitcoin-cli walletprocesspsbt $psbt | jq -r '.psbt') ``` -Podemos ver que as `entradas` foram preenchidas: +Podemos ver que os `inputs` foram preenchidos: ``` $ bitcoin-cli decodepsbt $psbt_f { @@ -267,12 +271,13 @@ $ bitcoin-cli decodepsbt $psbt_f "fee": 0.00000191 } ``` -Ou para ser mais preciso: (1) O PSBT foi atualizado com as informações de ```witness_utxo```; (2) O PSBT foi assinado; e (3) O PSBT foi finalizado. +Ou para ser mais preciso: (1) a PSBT foi atualizada com as informações de ```witness_utxo```; (2) a PSBT foi assinada; e (3) a PSBT foi finalizada. -## Criando um PSBT da maneira mais fácil -#### Função do PSBT: Criador e Atualizador +## Criando uma PSBT da Maneira Fácil -Se estamos esperamos que haja um comando equivalente ao ```fundrawtransaction```, ficaremos satisfeitos em saber que existe: Ele é o ```walletcreatefundedpsbt```. Podemos usá-lo da mesma forma que ```createpsbt```: +#### Função na PSBT: Criador e Atualizador + +Se esperamos que haja um comando equivalente ao ```fundrawtransaction```, ficaremos satisfeitos em saber que existe: ele é o ```walletcreatefundedpsbt```. Podemos usá-lo da mesma forma que ```createpsbt```: ``` $ bitcoin-cli -named walletcreatefundedpsbt inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.0000065 }''' { @@ -438,7 +443,7 @@ $ bitcoin-cli decodepsbt $psbt_new "fee": 0.00028800 } ``` -Como podemos ver, criamos o PSBT e depois o atualizamos com todas as informações que encontramos localmente. +Como podemos ver, criamos a PSBT e depois a atualizamos com todas as informações que encontramos localmente. A partir daí, precisamos usar o ```walletprocesspsbt``` para finalizar, como de costume: ``` @@ -466,12 +471,13 @@ $ bitcoin-cli analyzepsbt $psbt_new_f "next": "extractor" } ``` -Agora, realmente iremos querer usar o ```walletcreatefundedpsbt``` se estivermos criando um programa com o ```bitcoin-cli```? Provavelmente não. Mas é a mesma análise que fazemos com o ```fundrawtransaction```. Deixamos o Bitcoin Core fazer a análise, o cálculo e as decisões, ou nós mesmos fazemos? +Agora, realmente gostaríamos de usar o ```walletcreatefundedpsbt``` se estivermos criando um programa com o ```bitcoin-cli```? Provavelmente não. Mas é a mesma análise que fazemos com o ```fundrawtransaction```. Deixamos o Bitcoin Core fazer a análise, o cálculo e as decisões, ou nós mesmos fazemos? -## Enviando um PSBT -#### Função do PSBT: Extrator +## Enviando uma PSBT -Para finalizar o PSBT, usamos o ```finalizepsbt```, que irá transformar o PSBT novamente em um modelo hexadecimal. (Ele também assumirá a função de Finalizador, caso ainda não tenha acontecido). +#### Função na PSBT: Extrator + +Para finalizar a PSBT, usamos o ```finalizepsbt```, que irá transformar a PSBT novamente em hexadecimal. (Também assumirá a função de Finalizador, caso ainda não tenha acontecido). ``` $ bitcoin-cli finalizepsbt $psbt_f { @@ -485,9 +491,9 @@ $ psbt_hex=$(bitcoin-cli finalizepsbt $psbt_f | jq -r '.hex') $ bitcoin-cli -named sendrawtransaction hexstring=$psbt_hex ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3 ``` -## Revisando o fluxo de trabalho +## Revisando o Fluxo de Trabalho -Ao criar o software ```bitcoin-cli```, é mais provável que iremos cumprir as cinco funções principais dos PSBTs usando os comandos ```createpsbt```, ```walletprocesspsbt``` e ```finalizepsbt```. Esta é a aparência desse fluxo: +Ao criar software ```bitcoin-cli```, é mais provável que iremos cumprir as cinco funções principais dos PSBTs usando os comandos ```createpsbt```, ```walletprocesspsbt``` e ```finalizepsbt```. Esta é a aparência desse fluxo: ![](images/psbt-roles-for-cli-1.png) @@ -495,15 +501,14 @@ Se escolhermos usar o atalho de ```walletcreatefundedpsbt```, teremos um fluxo m ![](images/psbt-roles-for-cli-2.png) -Finally, if you instead need more control and choose to use `utxoupdatepsbt` (which is largely undocumented here), you instead have this workflow: Finalmente, se precisarmos de mais controle e optarmos por usar o comando ```utxoupdatepsbt``` (que não está documentado aqui), teremos um fluxo de trabalho assim: ![](images/psbt-roles-for-cli-3.png) ## Resumo: Criando uma Transação Bitcoin Parcialmente Assinada -A criação de um PSBT envolve um fluxo de trabalho um tanto complexo de criação, atualização, assinatura, finalização e extração de um PSBT, após o qual ele se converte novamente em uma transação bruta. Por que teríamos tanto trabalho? Porque deseja colaborar entre vários usuários ou vários programas. Agora que entendemos esse fluxo de trabalho, a próxima seção irá apresentar alguns exemplos reais de como fazer isso. +A criação de uma PSBT envolve um fluxo de trabalho um tanto complexo de criação, atualização, assinatura, finalização e extração da PSBT, após o qual ela se converte novamente em uma transação bruta. Por que teríamos tanto trabalho? Porque desejamos colaborar entre vários usuários ou vários programas. Agora que entendemos esse fluxo de trabalho, a próxima seção irá apresentar alguns exemplos reais de como fazer isso. ## O Que Vem Depois? -Vamos continuar "Expandindo as Transações de Bitcoin com PSBTs" na seção [§7.2: Usando uma transação Bitcoin parcialmente assinada](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md). +Vamos continuar "Expandindo Transações no Bitcoin com PSBTs" na seção [§7.2: Usando uma Transação Bitcoin Parcialmente Assinada](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md). From e00f732d534ab6c497ec16a5fa6afbea3aa8df17 Mon Sep 17 00:00:00 2001 From: namcios Date: Fri, 23 Jul 2021 12:00:53 -0300 Subject: [PATCH 038/155] Review 07_2 --- ..._a_Partially_Signed_Bitcoin_Transaction.md | 63 +++++++++---------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md b/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md index 9da3b3a..4686c87 100644 --- a/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md +++ b/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md @@ -1,14 +1,14 @@ -# 7.2: Usando uma transação Bitcoin parcialmente assinada +# 7.2: Usando uma Transação Bitcoin Parcialmente Assinada > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Agora que aprendemos o fluxo de trabalho básico para gerar um PSBT, provavelmente desejamos fazer algo com ele. O que os PSBTs podem fazer que os multisigs (e as transações brutas normais) não podem? Para começar, temos a facilidade de usar um formato padronizado, o que significa que podemos usar nossas transações do ```bitcoin-cli``` e combiná-las com transações geradas por pessoas (ou programas) em outras plataformas. Além disso, podemos fazer algumas coisas que simplesmente não eram fáceis usando outros mecanismos. +Agora que aprendemos o fluxo de trabalho básico para gerar uma PSBT, provavelmente desejamos fazer algo com ela. O que as PSBTs podem fazer que os multisigs (e as transações brutas normais) não podem? Para começar, temos a facilidade de usar um formato padronizado, o que significa que podemos usar nossas transações do ```bitcoin-cli``` e combiná-las com transações geradas por pessoas (ou programas) em outras plataformas. Além disso, podemos fazer algumas coisas que simplesmente não eram fáceis usando outros mecanismos. -A seguir estão três exemplos do uso dos PSBTs para: Multisigs, financiamentos e CoinJoins. +A seguir estão três exemplos do uso das PSBTs para: multisigs, financiamentos e CoinJoins. -> :aviso: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.17.0. As versões anteriores do Bitcoin Core não funcionarão com o PSBT enquanto ele estiver em andamento (embora ainda consigam reconhecer a transação final). +> :aviso: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.17.0. As versões anteriores do Bitcoin Core não funcionarão com a PSBT enquanto estiver em andamento (embora ainda consigam reconhecer a transação final). -## Usando um PSBT para gastar fundos MultiSig +## Usando uma PSBT para Gastar Fundos MultiSig Suponha que tenhamos criado um endereço multisig, assim como fizemos na seção [§6.3](06_3_Sending_an_Automated_Multisig.md). ``` @@ -48,16 +48,16 @@ $ bitcoin-cli listunspent } ] ``` -Nós _poderíamos_ gastá-las usando os mecanismos no [Capítulo 6](06_0_Expanding_Bitcoin_Transactions_Multisigs.md), onde assinamos serialmente uma transação, mas ao invés disso, vamos mostrar a vantagem do PSBTs para o uso das multisigs. Podemos gerar um único PSBT, permitir que todos o assinem em paralelo e depois podemos combinar todos resultados! Não há mais como passar o arquivo hexadecimal em constante expansão de pessoa para pessoa, o que acelera as coisas e reduz as chances de erros. +Nós _poderíamos_ gastá-las usando os mecanismos do [Capítulo 6](06_0_Expanding_Bitcoin_Transactions_Multisigs.md), onde assinamos serialmente uma transação, mas ao invés disso, vamos mostrar a vantagem das PSBTs para o uso dos multisigs. Podemos gerar uma única PSBT, permitir que todos a assinem em paralelo e depois podemos combinar todos resultados! Não há mais a necessidade de passar o arquivo hexadecimal em constante expansão de pessoa para pessoa, o que acelera as coisas e reduz as chances de erros. -Para demonstrar essa metodologia, vamos extrair aquele BTC 0,02 do multisig e dividi-lo entre os dois assinantes, cada um deles gerando um novo endereço com esse propósito: +Para demonstrar essa metodologia, vamos extrair aquele 0,02 BTC do multisig e dividi-lo entre os dois assinantes, cada um deles gerando um novo endereço com esse propósito: ``` machine1$ bitcoin-cli getnewaddress tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma machine2$ bitcoin-cli getnewaddress tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp ``` -A primeira coisa que fazemos é criar um PSBT em uma máquina. Não importa onde. Precisamos usar o ```createpsbt``` da seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) para isso, não iremos usar o método mais simples que é o comando ```walletcreatefundedpsbt```, porque precisamos do controle extra de selecionar o dinheiro protegido pelo multisig. Esse será o caso para todos os três exemplos nesta seção, o que demonstra porque geralmente precisemos usar o ```createpsbt``` para coisas mais complexas. +A primeira coisa que fazemos é criar uma PSBT em uma máquina. (Não importa qual). Precisamos usar o ```createpsbt``` da seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) para isso, e não o comando mais simples ```walletcreatefundedpsbt```, porque precisamos do controle extra de selecionar o dinheiro protegido pelo multisig. (Este será o caso para todos os três exemplos nesta seção, o que demonstra por quê geralmente precisamos usar o ```createpsbt``` para coisas mais complexas. ``` machine1$ utxo_txid=53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5 machine1$ utxo_vout=0 @@ -65,14 +65,14 @@ machine1$ split1=tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma machine1$ split2=tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp machine1$ psbt=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$split1'": 0.009998,"'$split2'": 0.009998 }''') ``` -Em seguida, precisamos enviar esse $psbt a todas as partes do multisig para que assinem: +Em seguida, precisamos enviar essa $psbt a todo mundo para que assinem: ``` machine1$ echo $psbt cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAAAAAA= ``` Mas você só precisa enviar uma vez! E você faz isso simultaneamente. -Aqui está o resultado da primeira máquina, onde geramos o PSBT: +Aqui está o resultado da primeira máquina, onde geramos a PSBT: ``` machine1$ psbt_p1=$(bitcoin-cli walletprocesspsbt $psbt | jq -r '.psbt') machine1$ bitcoin-cli decodepsbt $psbt_p1 @@ -280,9 +280,9 @@ machine2$ psbt_p2=$(bitcoin-cli walletprocesspsbt $psbt | jq -r '.psbt') machine3$ echo $psbt_p2 cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAABASu4gx4AAAAAACIAICJMtQOn94NXmbnCLuDDx9k9CQNW4w5wAVw+u/pRWjB0IgIDeJ9UNCNnDhaWZ/9+Hy2iqX3xsJEicuFC1YJFGs69BjZHMEQCIDJ71isvR2We6ym1QByLV5SQ+XEJD0SAP76fe1JU5PZ/AiB3V7ejl2H+9LLS6ubqYr/bSKfRfEqrp2FCMISjrWGZ6QEBBUdSIQONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDiEDeJ9UNCNnDhaWZ/9+Hy2iqX3xsJEicuFC1YJFGs69BjZSriIGA3ifVDQjZw4Wlmf/fh8toql98bCRInLhQtWCRRrOvQY2ENPtiCUAAACAAAAAgAYAAIAiBgONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDgRZu4lPAAAiAgNJzEMyT3rZS7QHqb8SvFCv2ee0MKRyVy8bY8tVUDT1KhDT7YglAAAAgAAAAIADAACAAA== ``` -Observe novamente que gerenciamos a assinatura deste multisig gerando um PSBT totalmente sem assinatura com o UTXO correto, permitindo que cada um dos usuários processe esse PSBT por conta própria, adicionando entradas e assinaturas. Como resultado, temos dois PSBTs, cada um contendo apenas uma assinatura. Isso não funcionaria no cenário multisig clássico, porque todas as assinaturas devem ser serializadas. Porém, podemos assinar em paralelo neste momento, e em seguida, usar a função Combinador para juntá-los. +Observe novamente que gerenciamos a assinatura deste multisig gerando uma PSBT totalmente sem assinatura com o UTXO correto, permitindo que cada um dos usuários processe essa PSBT por conta própria, adicionando entradas e assinaturas. Como resultado, temos duas PSBTs, cada uma contendo apenas uma assinatura. Isso não funcionaria no cenário multisig clássico, porque todas as assinaturas devem ser serializadas. Porém, podemos assinar em paralelo neste momento, e em seguida, usar a função Combinador para juntá-las. -Vamos novamente em qualquer máquina e vamos nos certificar de que temos os dois PSBTs nas variáveis e, em seguida, vamos combiná-los: +Vamos novamente a qualquer uma das máquinas e vamos nos certificar de que temos as duas PSBTs nas variáveis e, em seguida, vamos combiná-las: ``` machine1$ psbt_p2="cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAABAIcCAAAAAtu5pTheUzdsTaMCEPj3XKboMAyYzABmIIeOWMhbhTYlAAAAAAD//////uSTLbibcqSd/Z9ieSBWJ2psv+9qvoGrzWEa60rCx9cAAAAAAP////8BuIMeAAAAAAAiACAiTLUDp/eDV5m5wi7gw8fZPQkDVuMOcAFcPrv6UVowdAAAAAAAACICA0nMQzJPetlLtAepvxK8UK/Z57QwpHJXLxtjy1VQNPUqENPtiCUAAACAAAAAgAMAAIAA" machine2$ psbt_c=$(bitcoin-cli combinepsbt '''["'$psbt_p1'", "'$psbt_p2'"]''') @@ -415,21 +415,21 @@ machine2$ psbt_c_hex=$(bitcoin-cli finalizepsbt $psbt_c | jq -r '.hex') standup@btctest2:~$ bitcoin-cli -named sendrawtransaction hexstring=$psbt_c_hex ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16 ``` -Obviamente, não houve uma grande melhoria no uso deste método em relação à assinatura em série de uma transação para um multisig 2 de 2 quando todos estavam usando o ```bitcoin-cli```: Poderíamos ter passado uma transação bruta com assinaturas parciais de um usuário para o outro tão facilmente quanto enviar o PSBT. Mas, este foi o caso mais simples. À medida que nos aprofundamos em multisigs mais complexas, essa metodologia se torna cada vez melhor, mas já podemos destacar alguns pontos importantes: +Obviamente, não houve uma grande melhoria no uso deste método em relação à assinatura em série de uma transação para um multisig 2-de-2 quando todos estavam usando o ```bitcoin-cli```: poderíamos ter passado uma transação bruta com assinaturas parciais de um usuário para o outro tão facilmente quanto enviar a PSBT. Mas, este foi o caso mais simples. À medida que nos aprofundamos em multisigs mais complexos, essa metodologia se torna cada vez melhor, mas já podemos destacar alguns pontos importantes: Em primeiro lugar, é independente de plataforma. Enquanto todos estiverem usando um serviço compatível com o Bitcoin Core 0.17, todos poderão assinar essa transação, o que não é verdade quando os multisigs clássicos estão sendo repassados ​​entre diferentes plataformas. -Em segundo lugar, é muito mais escalável. Considere um multisig 3 de 5. De acordo com a metodologia antiga, isso teria que ser transmitido de pessoa para pessoa, aumentando enormemente os problemas se alguém o corrompesse. Aqui, outros usuários precisam apenas enviar os PSBTs de volta ao Criador e, assim que tiver a quantidade suficiente, poderá gerar a transação final. +Em segundo lugar, é muito mais escalável. Considere um multisig 3-de-5. De acordo com a metodologia antiga, isso teria que ser transmitido de pessoa para pessoa, aumentando enormemente os problemas se alguém o corrompesse. Aqui, outros usuários precisam apenas enviar as PSBTs de volta ao Criador e, assim que tiver a quantidade suficiente, poderá gerar a transação final. -## Usando um PSBT para financiamentos +## Usando uma PSBT Para Financiamentos -Os Multisigs como o usado no exemplo anterior são frequentemente usados ​​para receber pagamentos por trabalho colaborativo, seja royalties de um livro ou pagamentos feitos a uma empresa. Nessa situação, o exemplo acima funciona muito bem: Os dois participantes recebem seu dinheiro, que depois é dividido. Mas e quanto ao caso inverso, em que dois (ou mais) participantes desejam criar uma joint venture e precisam dividir o dinheiro? +Os Multisigs como o usado no exemplo anterior são frequentemente usados ​​para receber pagamentos por trabalho colaborativo, seja royalties de um livro ou pagamentos feitos a uma empresa. Nessa situação, o exemplo acima funciona muito bem: os dois participantes recebem seu dinheiro, que depois é dividido. Mas e quanto ao caso inverso, em que dois (ou mais) participantes desejam criar uma _joint venture_ e precisam dividir o dinheiro? -A resposta tradicional é criar um multisig e depois fazer com que os participantes enviem individualmente os fundos para lá. O problema é que o primeiro pagador depende da boa fé do segundo, e isso não é a base do Bitcoin, que diz que _não devemos confiar_. Felizmente, com o advento dos PSBTs, agora podemos fazer pagamentos sem confiança para podemos enviar fundos. +A resposta tradicional é criar um multisig e depois fazer com que os participantes enviem individualmente os fundos para lá. O problema é que o primeiro pagador depende da boa fé do segundo, e isso não é a base do Bitcoin, que diz que _não devemos confiar_. Felizmente, com o advento das PSBTs, agora podemos fazer pagamentos sem confiança para podemos enviar fundos. -> :book: ***O que significa a ideia de não podermos confiar?*** Quando dizemos, não devemos confiar, significa que nenhum participante precisa confiar em nenhum outro participante. Ao invés disso, eles esperam que os protocolos de software garantam que tudo seja executado de maneira justa, de maneira esperada. O Bitcoin é um protocolo que não depende de confiança porque não precisamos de ninguém para agir de boa fé. O sistema faz o gerenciamento. Da mesma forma, os PSBTs permitem a criação de transações que agrupam ou dividem fundos sem a necessidade de nenhuma parte confiar na outra. +> :book: ***O que significa a ideia de não podermos confiar?*** Quando dizemos que não devemos confiar, significa que nenhum participante precisa confiar em nenhum outro participante. Ao invés disso, eles esperam que os protocolos de software garantam que tudo seja executado de maneira justa e esperada. O Bitcoin é um protocolo que não depende de confiança porque não precisamos que ninguém mais aja de boa fé. O sistema faz o gerenciamento. Da mesma forma, as PSBTs permitem a criação de transações que agrupam ou dividem fundos sem a necessidade de nenhuma parte confiar na outra. -O exemplo a seguir mostra dois usuários que possuem 0,010 BTC e que desejam agrupar no endereço multisig `tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0`, criado acima. +O exemplo a seguir mostra dois usuários que possuem 0,010 BTC e que desejam agrupar no endereço multisig `tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0` criado acima. ``` machine1$ bitcoin-cli listunspent [ @@ -473,7 +473,7 @@ machine1$ utxo_vout_2=0 machine1$ multisig=tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0 ``` -E criam um PSBT: +E criam uma PSBT: ``` machine1$ psbt=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$multisig'": 0.019998 }''') ``` @@ -539,9 +539,9 @@ machine1$ bitcoin-cli decodepsbt $psbt ] } ``` -Não importa se as transações sejam de propriedade de duas pessoas diferentes ou que as informações completas apareçam em duas máquinas diferentes. Este PSBT de financiamento funcionará exatamente da mesma forma que o PSBT multisig. Uma vez que todos os controladores tenham assinado, a transação pode ser finalizada. +Não importa se as transações sejam de propriedade de duas pessoas diferentes ou que as informações completas apareçam em duas máquinas diferentes. Esta PSBT de financiamento funcionará exatamente da mesma forma que a PSBT multisig. Uma vez que todos os controladores tenham assinado, a transação pode ser finalizada. -Aqui está o processo, desta vez passando o PSBT parcialmente assinado de um usuário para outro, ao invés de ter que combinar as coisas no final. +Aqui está o processo, desta vez passando a PSBT parcialmente assinada de um usuário para outro, ao invés de ter que combinar as coisas no final. ``` machine1$ bitcoin-cli walletprocesspsbt $psbt { @@ -574,11 +574,11 @@ machine2$ psbt_hex=$(bitcoin-cli finalizepsbt $psbt_f | jq -r '.hex') machine2$ bitcoin-cli -named sendrawtransaction hexstring=$psbt_hex 53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5 ``` -Usamos um PSBT para reunir o dinheiro usando um multisig sem precisar de confiança! +Usamos uma PSBT para reunir o dinheiro usando um multisig sem precisar de confiança! -## Useando um PSBT para CoinJoin +## Usando uma PSBT para CoinJoin -O CoinJoin é outro aplicativo Bitcoin que não requer confiança. Aqui, temos uma variedade de entes que não se conhecem juntando dinheiro e recebendo de volta. +O CoinJoin é outra aplicação no Bitcoin que não requer confiança. Aqui, temos uma variedade de entes que não se conhecem juntando dinheiro e recebendo de volta. A metodologia para gerenciá-lo com PSBTs é exatamente a mesma que vimos nos exemplos acima, como o seguinte pseudocódigo demonstra: ``` @@ -586,17 +586,16 @@ $ psbt=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid_1'", " ``` Cada usuário coloca o próprio UTXO e cada um recebe uma saída correspondente. -A melhor maneira de gerenciar um CoinJoin é enviar o PSBT básico para todas as partes (que podem ser inúmeras) e, em seguida, fazer com que cada uma assine o PSBT e envie de volta para uma única parte que irá combinar, finalizar e enviar. +A melhor maneira de gerenciar um CoinJoin é enviar a PSBT básica para todas as partes (que podem ser inúmeras) e, em seguida, fazer com que cada uma assine a PSBT e envie de volta para uma única parte que irá combinar, finalizar e enviar. -## Resumo: Usando uma transação Bitcoin parcialmente assinada +## Resumo: Usando uma Transação Bitcoin Parcialmente Assinada -Agora vimos o processo PSBT que aprendemos na seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) em uso em três exemplos da vida real: Criando um multisig, um financiamento e fazendo o CoinJoin. Tudo isso era teoricamente possível no Bitcoin por ter várias pessoas assinando transações cuidadosamente construídas, mas os PSBTs tornam isso padronizado e simples. +Agora vimos o processo PSBT que aprendemos na seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) em uso em três exemplos da vida real: criando um multisig, um financiamento e fazendo CoinJoin. Tudo isso era teoricamente possível no Bitcoin com várias pessoas assinando transações cuidadosamente construídas, mas as PSBTs tornam isso padronizado e simples. -> :fire: ***Qual é o poder de um PSBT?*** Um PSBT permite a criação de transações sem necessidade de confiança entre várias partes e várias máquinas. Se mais de uma parte precisar financiar uma transação, se mais de uma parte precisar assinar uma transação, ou se uma transação precisar ser criada em uma máquina e assinada em outra, um PSBT torna isso simples, sem depender do mecanismos de assinatura parcial não padronizados que existiam antes do PSBT. +> :fire: ***Qual é o poder de uma PSBT?*** Uma PSBT permite a criação de transações sem necessidade de confiança entre várias partes e várias máquinas. Se mais de uma parte precisar financiar uma transação, se mais de uma parte precisar assinar uma transação, ou se uma transação precisar ser criada em uma máquina e assinada em outra, uma PSBT torna isso simples, sem depender do mecanismos de assinatura parcial não padronizados que existiam antes da PSBT. -Esse último ponto, ao criar uma transação em uma máquina e assinar em outra, é um elemento dos PSBTs que ainda não chegamos. Ele está no centro das carteiras de hardware, onde geralmente desejamos criar uma transação em um full node e, em seguida, passá-la para uma hardware wallet quando uma assinatura for necessária. Esse é o tópico da nossa última seção (e do nosso quarto exemplo da vida real) deste capítulo sobre PSBTs. +Esse último ponto, sobre criar uma transação em uma máquina e assinar em outra, é um elemento das PSBTs ao qual ainda não chegamos. Ele está no centro das carteiras de hardware, onde geralmente desejamos criar uma transação em um full node e, em seguida, passá-la para uma hardware wallet quando uma assinatura for necessária. Esse é o tópico da nossa última seção (e do nosso quarto exemplo da vida real) deste capítulo sobre PSBTs. ## O Que Vem Depois? -Continue "Expanding Bitcoin Transactions with PSBTs" with [§7.3: Inegrating with Hardware Wallets](07_3_Integrating_with_Hardware_Wallets.md). -Vamos continuar "Expandindo as Transações de Bitcoin com PSBTs" na seção [§7.3: Integração com hardware wallets](07_3_Integrating_with_Hardware_Wallets.md). \ No newline at end of file +Vamos continuar "Expandindo Transações no Bitcoin com PSBTs" na seção [§7.3: Integrando com Hardware Wallets](07_3_Integrating_with_Hardware_Wallets.md). \ No newline at end of file From ad06362641bbcbfb5933749e5b1c1123796515c5 Mon Sep 17 00:00:00 2001 From: namcios Date: Fri, 23 Jul 2021 12:33:07 -0300 Subject: [PATCH 039/155] Review 07_3 --- pt/07_3_Integrating_with_Hardware_Wallets.md | 103 +++++++++---------- 1 file changed, 51 insertions(+), 52 deletions(-) diff --git a/pt/07_3_Integrating_with_Hardware_Wallets.md b/pt/07_3_Integrating_with_Hardware_Wallets.md index f15f506..4ae6f45 100644 --- a/pt/07_3_Integrating_with_Hardware_Wallets.md +++ b/pt/07_3_Integrating_with_Hardware_Wallets.md @@ -1,26 +1,26 @@ -# 7.3: Integração com hardware wallets +# 7.3: Integrando com Hardware Wallets > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Leitor de advertência. -Uma das principais vantagens dos PSBTs é a capacidade de transferir transações para hardware wallets. Esta será uma ótima ferramenta de desenvolvimento para nós continuarmos a programar usando o Bitcoin. No entanto, não podemos testá-la agora se estivermos usando uma das configurações que sugerimos para este curso, uma VM no Linode de acordo com a seção [§2.1](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) ou uma opção mais expansiva ainda como um AWS de acordo com a seção [§2.2](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_2_Setting_Up_Bitcoin_Core_Other.md), isso porque obviamente não teremos como conectar uma hardware wallet à nossa máquina virtual remota. +Uma das principais vantagens das PSBTs é a capacidade de transferir transações para hardware wallets. Esta será uma ótima ferramenta de desenvolvimento para nós continuarmos a programar com Bitcoin. No entanto, não podemos testá-la agora se estivermos usando uma das configurações que sugerimos para este curso, uma VM no Linode de acordo com a seção [§2.1](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) ou uma opção mais expansiva ainda como um AWS de acordo com a seção [§2.2](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_2_Setting_Up_Bitcoin_Core_Other.md), isso porque obviamente não teremos como conectar uma hardware wallet à nossa máquina virtual remota. -> :book: ***O que é uma hardware wallet?*** Uma hardware wallet é um dispositivo eletrônico que melhora a segurança da criptomoeda mantendo todas as chaves privadas no dispositivo, ao invés de colocá-las em um computador conectado diretamente a internet. As carteiras de hardware têm protocolos específicos para fornecer interações online, geralmente gerenciadas por um programa que se comunica com o dispositivo por meio de uma porta USB. Neste capítulo, gerenciaremos uma carteira de hardware com o ```bitcoin-cli``` e o programa ```hwy.py```. +> :book: ***O que é uma hardware wallet?*** Uma hardware wallet é um dispositivo eletrônico que melhora a segurança da criptomoeda mantendo todas as chaves privadas no dispositivo, ao invés de colocá-las em um computador conectado diretamente a internet. As hardware wallets têm protocolos específicos para fornecer interações online, geralmente gerenciadas por um programa que se comunica com o dispositivo por meio de uma porta USB. Neste capítulo, gerenciaremos uma hardware wallet com o ```bitcoin-cli``` e o programa ```hwy.py```. -Existem três opções de como passar por este capítulo: (1) Ler sem testar o código; (2) Instalar o Bitcoin em uma máquina local para testar todos esses comandos ou; (3) Pular direto para o [Capítulo 8: Expandindo as transações de Bitcoin usando outras maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md). Sugerimos a primeira opção, mas se quisermos colocar a mão na massa, iremos dar o suporte necessário para a segunda opção falando sobre o uso de um Macintosh (uma plataforma hardware que o [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup) dá suporte) para teste. +Existem três opções de como passar por este capítulo: (1) ler sem testar o código; (2) instalar o Bitcoin em uma máquina local para testar todos esses comandos ou; (3) pular direto para o [Capítulo 8: Expandindo Transações no Bitcoin de Outras Maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md). Sugerimos a primeira opção, mas se quisermos colocar a mão na massa, iremos dar o suporte necessário para a segunda opção falando sobre o uso de um Macintosh (uma plataforma hardware que o [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup) dá suporte) para teste. -> :warning: **AVISO DE VERSÃO:** Os PSBTs são uma inovação do Bitcoin Core v0.17.0. As versões anteriores do Bitcoin Core não funcionarão com o PSBT enquanto ele estiver em andamento (embora ainda consigam reconhecer a transação final). A interface HWI apareceu no Bitcoin Core v 0.18.0, mas, desde que estejamos usando nossa configuração sugerida com o Bitcoin Standup, ela deve funcionar. +> :warning: **AVISO DE VERSÃO:** As PSBTs são uma inovação do Bitcoin Core v0.17.0. As versões anteriores do Bitcoin Core não funcionarão com o PSBT enquanto ele estiver em andamento (embora ainda consigam reconhecer a transação final). A interface HWI apareceu no Bitcoin Core v 0.18.0, mas, desde que estejamos usando nossa configuração sugerida com o Bitcoin Standup, ela deve funcionar. -A metodologia descrita neste capítulo para integração com uma hardware wallet depende do [Bitcoin Hardware Wallet Interface](https://github.com/bitcoin-core/HWI) lançada através do Bitcoin Core e que se baseia na [instalação](https://github.com/bitcoin-core/HWI/blob/master/README.md) e [uso](https://hwi.readthedocs.io) das instruções contidas nele. +A metodologia descrita neste capítulo para integração com uma hardware wallet depende do [Bitcoin Hardware Wallet Interface](https://github.com/bitcoin-core/HWI) lançada através do Bitcoin Core e que se baseia nas instruções de [instalação](https://github.com/bitcoin-core/HWI/blob/master/README.md) e [uso](https://hwi.readthedocs.io) contidas nele. -> :warning: **AVISO DE NOVIDADE:** A interface HWI é muito nova e precisa de alguns ajustes ainda, mesmo depois usando a v0.20.0 do Bitcoin Core. Pode ser difícil instalá-la corretamente e pode conter erros não intuitivos. O que se segue é uma descrição de uma configuração de trabalho, mas foram necessárias várias tentativas para ter sucesso e sua configuração pode variar. +> :warning: **AVISO DE NOVIDADE:** A interface HWI é muito nova e precisa de alguns ajustes ainda, mesmo na v0.20.0 do Bitcoin Core. Pode ser difícil instalá-la corretamente e pode conter erros não intuitivos. O que segue é uma descrição de uma configuração que funciona, mas foram necessárias várias tentativas para ter sucesso e sua configuração pode variar. -## Instalando o Bitcoin Core em uma máquina local +## Instalando o Bitcoin Core em uma Máquina Local -_Se pretendemos apenas ler esta seção e não testar os comandos, podemos pular esta subseção, que basicamente explicará como criar uma instalação Bitcoin Core em uma máquina local, como um Mac ou Máquina Linux._ +_Se pretendemos apenas ler esta seção e não testar os comandos, podemos pular esta subseção, que basicamente explicará como criar uma instalação Bitcoin Core em uma máquina local, como uma máquina Mac ou Linux._ Existem versões alternativas do script Bitcoin Standup que usamos para criar nossa VM que será instalada em um MacOS ou em uma máquina Linux que não seja o Linode. -Se tivermos um MacOS, podemos instalar o [Bitcoin Standup MacOS](https://github.com/BlockchainCommons/Bitcoin-Standup-MacOS/blob/master/README.md). +Se tivermos MacOS, podemos instalar o [Bitcoin Standup MacOS](https://github.com/BlockchainCommons/Bitcoin-Standup-MacOS/blob/master/README.md). Se tivermos uma máquina Linux local, podemos instalar o [Bitcoin Standup Linux Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-MacOS/blob/master/README.md). @@ -28,9 +28,9 @@ Depois de colocar o Bitcoin Standup em execução em nossa máquina local, vamos Estaremos usando um Macintosh e um Testnet para os exemplos desta seção. -### Criando um alias para o Bitcoin-CLI +### Criando um Alias para o Bitcoin-CLI -Criando um alias que execute o ```bitcoin-cli``` no diretório correto com quaisquer flags apropriadas. +Crie um alias que execute o ```bitcoin-cli``` no diretório correto com quaisquer flags apropriadas. Aqui está um exemplo de um alias de um Mac: ``` @@ -38,13 +38,13 @@ $ alias bitcoin-cli="~/StandUp/BitcoinCore/bitcoin-0.20.0/bin/bitcoin-cli -testn ``` Podemos notar que ele nos dá não apenas o caminho completo, mas também garante que permaneçamos na Testnet. -## Instalando o HWI em uma máquina local +## Instalando o HWI em uma Máquina Local _As instruções a seguir novamente presumem um Mac e podemos pular novamente esta subseção se estivermos apenas lendo o capítulo._ O HWI é um programa do Bitcoin Core disponível em python que podemos usar para interagir com as hardware wallets. -### Instalando o Python +### Instalando Python Como o HWI é escrito em ```python```, precisaremos instalá-lo, bem como alguns programas auxiliares. @@ -84,46 +84,46 @@ Depois, precisaremos instalar o pacote e as dependências: $ cd HWI HWI$ python3 setup.py install ``` -### Criando um alias para o HWI +### Criando um Alias para o HWI Iremos querer criar um alias aqui também, variando de acordo com o local de instalação real: ``` $ alias hwi="~/Standup/HWI/hwi.py --testnet" ``` -Novamente, incluímos uma referência a testnet ao alias. +Novamente, incluímos uma referência a testnet no alias. ## Preparando nossa Ledger -_Precisamos escolher uma plataforma de hardware wallet para a demonstração de HWI. Nossa escolha foi a Ledger, que há muito tempo é onde fazemos os testes nestes casos. Podemos consultar as [informações de suporte do dispositivo do HWI](https://github.com/bitcoin-core/HWI/blob/master/README.md#device-support) para obter uma lista de outros dispositivos compatíveis. Se usarmos um dispositivo diferente de uma Ledger, precisaremos avaliar as nossas soluções para prepará-la para uso na Testnet, mas caso contrário, devemos ser capazes de continuar com o curso conforme escrito aqui._ +_Tivemos que escolher uma plataforma de hardware wallet para a demonstração de HWI. Nossa escolha foi a Ledger, que há muito tempo é onde fazemos os testes nestes casos. Podemos consultar as [informações de suporte do dispositivo do HWI](https://github.com/bitcoin-core/HWI/blob/master/README.md#device-support) para obter uma lista de outros dispositivos compatíveis. Se usarmos um dispositivo diferente de uma Ledger, precisaremos avaliar as nossas soluções para prepará-la para uso na Testnet, mas caso contrário, devemos ser capazes de continuar com o curso conforme escrito aqui._ -Se estiver trabalhando com Bitcoins usando a Ledger, provavelmente precisaremos fazer nada. (Mas não sugerimos isso neste curso). +Se estiver trabalhando com Bitcoins usando a Ledger, provavelmente não precisaremos fazer nada. (Mas não sugerimos isso neste curso). -Para trabalhar com moedas usando a Testnet, conforme sugerido aqui, precisaremos fazer algumas atualizações: +Para trabalhar com moedas da Testnet, conforme sugerido aqui, precisaremos fazer algumas atualizações: 1. Vamos em Configurações em nosso aplicativo Ledger Live (clicando na engrenagem), depois na guia "Recursos Experimentais" e vamos ativar o "Modo de Desenvolvedor"; 2. Vamos no "Gerenciar" para instalar o "Bitcoin Test". A versão atual requer que tenhamos o "Bitcoin" e o "Ethereum" instalados primeiro; -3. Vamos no "Gerenciar", para instalar o nosso novo "Bitcoin Test" e "Adicionar uma conta". +3. Vamos ao "Gerenciar", para instalar o nosso novo "Bitcoin Test" e "Adicionar uma conta". -## Acoplando na Ledger +## Acoplando a Ledger -Para que um Razão esteja acessível, devemos fazer o login com o nosso PIN e, em seguida, acessar o aplicativo que desejamos usar, que no caso é o aplicativo "Bitcoin Test". Pode ser necessário repetir isso algumas vezes quando nossa Ledger ficar em stand-by. +Para que uma Ledger esteja acessível, devemos fazer o login com o nosso PIN e, em seguida, acessar o aplicativo que desejamos usar, que no caso é o aplicativo "Bitcoin Test". Pode ser necessário repetir isso algumas vezes quando nossa Ledger ficar em stand-by. Depois, podemos solicitar que o HWI acesse a Ledger com o comando `enumerate`: ``` $ hwi enumerate [{"type": "ledger", "model": "ledger_nano_s", "path": "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/XHC1@14000000/HS05@14100000/Nano S@14100000/Nano S@0/IOUSBHostHIDDevice@14100000,0", "fingerprint": "9a1d520b", "needs_pin_sent": false, "needs_passphrase_sent": false}] ``` -Se recebermos algumas informações no nosso dispositivo, está tudo certo! Como podemos observar, ele verifica o tipo da hardware wallet, fornecendo outras informações de identificação e também informa como se comunicar com o dispositivo. A ```fingerprint``` (```9a1d520b```) é o que devemos prestar atenção especial, porque todas as interações com nossa hardware wallet irá exigir essa informação. +Se recebermos algumas informações no nosso dispositivo, está tudo certo! Como podemos observar, ele verifica o tipo da hardware wallet, fornecendo outras informações de identificação e também informa como se comunicar com o dispositivo. A ```fingerprint``` (```9a1d520b```) é o que devemos prestar atenção especial, porque todas as interações com nossa hardware wallet irão exigir essa informação. -Se, ao invés disso, obtivermos como resultado ```[]```, então (1) Não deixamos nosso dispositivo Ledger habilitado com o PIN correto e não escolhemos o aplicativo correto, ou (2) há algo errado com nossa configuração Python, provavelmente uma dependência esteja faltando: Devemos considerar usar o comando ```uninstall``` e tentar do zero novamente. +Se, ao invés disso, obtivermos como resultado ```[ ]```, então ou (1) não deixamos nosso dispositivo Ledger habilitado com o PIN correto e não escolhemos o aplicativo correto, ou (2) há algo de errado com nossa configuração Python, provavelmente uma dependência esteja faltando: devemos considerar usar o comando ```uninstall``` e tentar do zero novamente. -## Importando os endereços +## Importando Endereços -A interação com uma hardware wallet geralmente ocorre em duas partes: Observar os saldos e gastá-los. +A interação com uma hardware wallet geralmente ocorre em duas partes: observando os saldos e gastando-os. Podemos monitorar os fundos importando os endereços da nossa hardware wallet para o full node, usando o HWI e o ```bitcoin-cli```. -### Criando uma carteira +### Criando uma Carteira Para usar nossa hardware wallet com o ```bitcoin-cli```, precisaremos criar uma carteira com nome específico no Bitcoin Core, usando o RPC ```createwallet```, que é um comando que não discutimos anteriormente. ``` @@ -133,9 +133,9 @@ $ bitcoin-cli --named createwallet wallet_name="ledger" disable_private_keys="tr "warning": "" } ``` -Neste caso, estamos criando uma carteira chamada `ledger` sem chaves privadas (já que estas estarão no dispositivo da Ledger). +Neste caso, estamos criando uma carteira chamada `ledger` sem chaves privadas (já que estas estarão no dispositivo Ledger). -> :book: ***Por que nomear as carteiras?*** Até agora, este curso usou uma carteira padrão ("") no Bitcoin Core. Isso é bom para muitos propósitos, mas é inadequado se tivermos uma situação mais complexa, como quando estamos usando as chaves de uma hardware wallet. Aqui, queremos ser capazes de diferenciar as chaves de locais (que são mantidas na carteira "") e as chaves da Ledger (que são mantidas na carteira "ledger"). +> :book: ***Por que nomear as carteiras?*** Até agora, este curso usou uma carteira padrão ("") no Bitcoin Core. Isso é bom para muitos propósitos, mas é inadequado se tivermos uma situação mais complexa, como quando estamos usando as chaves de uma hardware wallet. Aqui, queremos ser capazes de diferenciar as chaves locais (que são mantidas na carteira "") e as chaves da Ledger (que são mantidas na carteira "ledger"). Agora podemos observar que a nova carteira está em nossa lista de carteiras: ``` @@ -145,20 +145,20 @@ $ bitcoin-cli listwallets "ledger" ] ``` -Como criamos uma segunda carteira, alguns comandos exigirão um sinalizador ```-rpcwallet =```, para especificar qual delas estamos utilizando. +Como criamos uma segunda carteira, alguns comandos exigirão um sinalizador ```-rpcwallet=```, para especificar qual delas estamos utilizando. -### Importando as chaves +### Importando as Chaves -Agora temos que importar uma lista de endereços de observação da hardware wallet. Isso é feito com o comando ```getkeypool``` do HWI: +Agora temos que importar uma lista de observação de endereços da hardware wallet. Isso é feito com o comando ```getkeypool``` do HWI: ``` $ hwi -f 9a1d520b getkeypool --wpkh 0 1000 [{"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/0/*)#qttxy592", "range": [0, 1000], "timestamp": "now", "internal": false, "keypool": true, "active": true, "watchonly": true}, {"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/1/*)#3lw8ep4j", "range": [0, 1000], "timestamp": "now", "internal": true, "keypool": true, "active": true, "watchonly": true}] ``` -Endereçamos o HWI com a ```fingerprint``` e solicitamos os primeiros 1000 endereços WPKH (Segwit nativo). Em troca, recebemos dois descritores para o conjunto de chaves: Um para receber endereços e outro para alterar endereços. +Endereçamos o HWI com a ```fingerprint``` e solicitamos os primeiros 1000 endereços WPKH (Segwit nativo). Em troca, recebemos dois descritores para o conjunto de chaves: um para receber endereços e outro para alterar endereços. > :book: ***O que é um conjunto de chaves?*** Um conjunto de chaves é um grupo de chaves pré-geradas. As hardware wallets modernas criam molhos de chaves usando novos endereços hierárquicos com base na seed original. A ideia destes molhos de chaves é facilitar os requisitos de backup das carteiras. Isso permitia que um usuário gerasse um conjunto de chaves e fizesse backup da carteira imediatamente, ao invés de exigir backups após a criação de cada novo endereço. O conceito também tem se mostrado muito útil na atualidade, pois permite a importação de todo um conjunto de endereços de um dispositivo para outro. -Os valores retornados pelo comando ```getkeypool``` são os mesmos tipos de descritores que aprendemos na seção [§3.5: Compreendendo o descritor](03_5_Understanding_the_Descriptor.md). Na época, dissemos que eram úteis para mover endereços entre máquinas diferentes. Aqui está o exemplo da vida real: Mover endereços de uma hardware wallet para o node do Bitcoin Core, de modo que nossa máquina conectada à rede possa vigiar as chaves pertencentes à carteira da hardware wallet. +Os valores retornados pelo comando ```getkeypool``` são os mesmos tipos de descritores que aprendemos na seção [§3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md). Na época, dissemos que eram úteis para mover endereços entre máquinas diferentes. Aqui está o exemplo da vida real: mover endereços de uma hardware wallet para o node do Bitcoin Core, de modo que nossa máquina conectada à rede possa vigiar as chaves pertencentes à carteira da hardware wallet. Assim como aprendemos na seção [§3.5](03_5_Understanding_the_Descriptor.md), podemos examinar esses descritores com o comando RPC ```getdescriptorinfo```: ``` @@ -171,7 +171,7 @@ $ bitcoin-cli getdescriptorinfo "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr "hasprivatekeys": false } ``` -Como seria de esperar, _não_ temos ```privatekeys```, porque as hardware wallets ficam com a posse. +Como era de se esperar, _não_ temos ```privatekeys```, porque as hardware wallets as mantém. Com os descritores em mãos, podemos importar as chaves para nossa nova carteira ```ledger``` usando o comando RPC ```importmulti``` que já usamos na seção [§3.5](03_5_Understanding_the_Descriptor.md). Nesse caso, basta colocar toda a resposta que recebemos do HWI entre ```'``` s. ``` @@ -187,7 +187,7 @@ $ bitcoin-cli -rpcwallet=ledger importmulti '[{"desc": "wpkh([9a1d520b/84h/1h/0h ``` (Observe que HWI aproveita o caminho de derivação com ```h```s para mostrar as derivações ao invés dos ```'```s, além de ter calculado a soma da verificação corretamente, para que não tenhamos que fazer citações massivas como fizemos na seção §3.5.) -Agora, _podemos_ listar todos os endereços apenas para observar que recebemos o valor, usando o comando ```getaddressesbylabel```. Todos os 1000 endereços de recebimento estão ali, na carteira ```ledger```! +Agora, _poderíamos_ listar todos os endereços apenas para observar que recebemos o valor, usando o comando ```getaddressesbylabel```. Todos os 1000 endereços de recebimento estão ali, na carteira ```ledger```! ``` $ bitcoin-cli -rpcwallet=ledger getaddressesbylabel "" | more { @@ -200,16 +200,16 @@ $ bitcoin-cli -rpcwallet=ledger getaddressesbylabel "" | more ... } ``` -## Recebendo uma transação +## Recebendo uma Transação -Obviamente, receber uma transação é bem simples. Usamos o ```getnewaddress``` para solicitar um desses endereços importados: +Obviamente, receber uma transação é bem simples. Usamos o ```getnewaddress``` para solicitar um daqueles endereços importados: ``` $ bitcoin-cli -rpcwallet=ledger getnewaddress tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y ``` Então enviamos o dinheiro para ele. -O poder do HWI é que podemos observar os pagamentos do nosso node Bitcoin Core, ao invés de ter que conectar nossa hardware wallet e consultá-la. +O poder do HWI é que podemos observar os pagamentos do nosso node Bitcoin Core, ao invés de termos que conectar nossa hardware wallet e consultá-la. ``` $ bitcoin-cli -rpcwallet=ledger listunspent [ @@ -241,11 +241,11 @@ $ bitcoin-cli -rpcwallet=ledger listunspent } ] ``` -## Criando uma transação com o PSBT +## Criando uma Transação com PSBT -Observar e receber os pagamentos é apenas metade da batalha. Também podemos fazer pagamentos usando contas mantidas em nossa hardware wallet. Este é o quarto exemplo da vida real usando os PSBTs, de acordo com o processo descrito na seção [§7.1: Criando uma Transação Bitcoin Parcialmente Assinada](7_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md). +Observar e receber pagamentos é apenas metade da batalha. Também podemos fazer pagamentos usando contas mantidas em nossa hardware wallet. Este é o quarto exemplo da vida real usando as PSBTs, de acordo com o processo descrito na seção [§7.1: Criando uma Transação Bitcoin Parcialmente Assinada](7_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md). -Os comandos funcionam exatamente da mesma forma. Nesse caso, usamos o ```walletcreatefundedpsbt``` para formar nosso PSBT porque estamos em uma situação em que não nos importamos com quais UTXOs são usados: +Os comandos funcionam exatamente da mesma forma. Nesse caso, usamos o ```walletcreatefundedpsbt``` para formar nossa PSBT porque estamos em uma situação em que não nos importamos com quais UTXOs são usados: ``` $ bitcoin-cli -named -rpcwallet=ledger walletcreatefundedpsbt inputs='''[]''' outputs='''[{"tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd":0.015}]''' { @@ -254,7 +254,7 @@ $ bitcoin-cli -named -rpcwallet=ledger walletcreatefundedpsbt inputs='''[]''' ou "changepos": 1 } ``` -Podemos observar os PSBT e verificar se ele parece correto: +Podemos observar a PSBT e verificar se ela parece correta: ``` $ psbt="cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giBgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxRiaHVILVAAAgAEAAIAAAACAAAAAADkCAAAAAQEfQEIPAAAAAAAWABQtTxOfqohTBNFWFqFm0tUVdK9KXSIGAqATz5xLX1aJ2SUwNqPkd8+YaJYm94FMlPCScm8Rt0GrGJodUgtUAACAAQAAgAAAAIAAAAAAAAAAAAAAIgID2UK1nupSfXC81nmB65XZ+pYlJp/W6wNk5FLt5ZCSx6kYmh1SC1QAAIABAACAAAAAgAEAAAABAAAAAA==" @@ -373,7 +373,6 @@ $ bitcoin-cli decodepsbt $psbt "fee": 0.00000209 } ``` -And as usual, `analyzepsbt` will show how far you've gotten: E, como de costume, `analisepsbt` mostrará o quão longe você chegou: ``` $ bitcoin-cli analyzepsbt $psbt @@ -408,17 +407,17 @@ $ bitcoin-cli analyzepsbt $psbt ``` Como importamos aquele conjunto de chaves, o ```bitcoin-cli``` tem todas as informações de que precisa para preencher as entradas, porém, ele não pode assinar porque as chaves privadas são mantidas na hardware wallet. -É aí que entra o HWI, com o comando ```signtx```. Basta que enviemos junto com o PSBT: +É aí que entra o HWI, com o comando ```signtx```. Basta que enviemos a PSBT junto: ``` $ hwi -f 9a1d520b signtx $psbt ``` -É provável que tenhamos de mexer em nossa hardware wallet neste momento. O dispositivo provavelmente pedirá a confirmação das entradas, as saídas e a taxa. Quando terminar, ele deve retornar um novo PSBT. +É provável que tenhamos de mexer em nossa hardware wallet neste momento. O dispositivo provavelmente pedirá a confirmação das entradas, as saídas e a taxa. Quando terminar, ele deve retornar uma nova PSBT. ``` {"psbt": "cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giAgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxUcwRAIgAxkQlk2fqEMxvP54WWyiFhlfSul9sd4GzKDhfGpmlewCIHYej3zXWWMgWI6rixxQw9yzGozDaFPqQNNIvcFPk+lfASIGAwFo2UguKwLXAn+0qJ7cVK2qGt9wkzT2R9ChsFM4KK7FGJodUgtUAACAAQAAgAAAAIAAAAAAOQIAAAABAR9AQg8AAAAAABYAFC1PE5+qiFME0VYWoWbS1RV0r0pdIgICoBPPnEtfVonZJTA2o+R3z5holib3gUyU8JJybxG3QatHMEQCIH5t6T2yufUP7glYZ8YH0/PhDFpotSmjgZUhvj6GbCFIAiBcgXzyYl7IjYuaF3pJ7AgW1rLYkjeCJJ2M9pVUrq5vFwEiBgKgE8+cS19WidklMDaj5HfPmGiWJveBTJTwknJvEbdBqxiaHVILVAAAgAEAAIAAAACAAAAAAAAAAAAAACICA9lCtZ7qUn1wvNZ5geuV2fqWJSaf1usDZORS7eWQksepGJodUgtUAACAAQAAgAAAAIABAAAAAQAAAAA="} $ psbt_f="cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giAgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxUcwRAIgAxkQlk2fqEMxvP54WWyiFhlfSul9sd4GzKDhfGpmlewCIHYej3zXWWMgWI6rixxQw9yzGozDaFPqQNNIvcFPk+lfASIGAwFo2UguKwLXAn+0qJ7cVK2qGt9wkzT2R9ChsFM4KK7FGJodUgtUAACAAQAAgAAAAIAAAAAAOQIAAAABAR9AQg8AAAAAABYAFC1PE5+qiFME0VYWoWbS1RV0r0pdIgICoBPPnEtfVonZJTA2o+R3z5holib3gUyU8JJybxG3QatHMEQCIH5t6T2yufUP7glYZ8YH0/PhDFpotSmjgZUhvj6GbCFIAiBcgXzyYl7IjYuaF3pJ7AgW1rLYkjeCJJ2M9pVUrq5vFwEiBgKgE8+cS19WidklMDaj5HfPmGiWJveBTJTwknJvEbdBqxiaHVILVAAAgAEAAIAAAACAAAAAAAAAAAAAACICA9lCtZ7qUn1wvNZ5geuV2fqWJSaf1usDZORS7eWQksepGJodUgtUAACAAQAAgAAAAIABAAAAAQAAAAA=" ``` -Ao analisá-lo, veremos que estamos prontos para finalizá-lo: +Ao analisá-la, veremos que estamos prontos para finalizá-la: ``` $ bitcoin-cli analyzepsbt $psbt_f { @@ -453,18 +452,18 @@ $ bitcoin-cli sendrawtransaction $hex ``` Pronto, enviamos um saldo com sucesso usando as chaves privadas de nossa hardware wallet! -## Aprendendo outros comandos HWI +## Aprendendo Outros Comandos HWI Existem vários outros comandos disponíveis para usar com o HWI. No momento em que este artigo foi escrito, são eles: ``` numerate,getmasterxpub,signtx,getxpub,signmessage,getkeypool,getdescriptors,displayaddress,setup,wipe,restore,backup,promptpin,togglepassphrase,sendpin ``` -## Resumo: Integração com hardware wallets +## Resumo: Integrando com Hardware Wallets -As hardware wallets podem oferecer melhor proteção, mantendo nossas chaves privadas offline, protegidas no hardware. Felizmente, ainda há uma maneira de interagir com elas usando o ```bitcoin-cli```. Basta instalar o HWI e ele permitirá (1) Importar as chaves públicas para observarmos e; (2) Assinar transações usando nossa hardware wallet. +As hardware wallets podem oferecer melhor proteção, mantendo nossas chaves privadas offline, protegidas no hardware. Felizmente, ainda há uma maneira de interagir com elas usando o ```bitcoin-cli```. Basta instalar o HWI e ele permitirá (1) importar as chaves públicas para observarmos; e (2) assinar transações usando nossa hardware wallet. -> :fire: ***Qual é o poder do HWI?*** O HWI permite que possamos interagir com hardware wallets usando todos os comandos de ```bitcoin-cli``` que aprendemos até agora. Podemos fazer as transações brutas de qualquer tipo e enviar PSBTs para hardware wallets para serem assinadas. Assim, temos todo o poder do Bitcoin Core, mas também temos a segurança de um dispositivo hardware. +> :fire: ***Qual é o poder do HWI?*** O HWI nos permite interagir com hardware wallets usando todos os comandos do ```bitcoin-cli``` que aprendemos até agora. Podemos fazer transações brutas de qualquer tipo e enviar PSBTs para hardware wallets para serem assinadas. Assim, temos todo o poder do Bitcoin Core, mas também temos a segurança de um dispositivo hardware. ## O Que Vem Depois? -Vamos expandir ainda mais as transações de Bitcoin com o [Capítulo Oito: Expandindo transações de Bitcoin de outras maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md). \ No newline at end of file +Vamos expandir ainda mais as transações de Bitcoin com o [Capítulo Oito: Expandindo Transações no Bitcoin de Outras Maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md). \ No newline at end of file From a16039f068c7d1b4ac2650802e5c824010cacfc6 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 27 Jul 2021 11:02:59 -0300 Subject: [PATCH 040/155] Review 09_0 --- pt/09_0_Introducing_Bitcoin_Scripts.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pt/09_0_Introducing_Bitcoin_Scripts.md b/pt/09_0_Introducing_Bitcoin_Scripts.md index 097fc65..9e4999f 100644 --- a/pt/09_0_Introducing_Bitcoin_Scripts.md +++ b/pt/09_0_Introducing_Bitcoin_Scripts.md @@ -1,27 +1,27 @@ -# Capítulo 9: Apresentando os Scripts no Bitcoin +# Capítulo 9: Apresentando Scripts no Bitcoin -Até o momento, estamos interagindo com o Bitcoin em um nível relativamente alto de abstração. O programa ```Bitcoin-cli``` oferece acesso a uma variedade de comandos RPC que suportam a criação e controle de transações brutas de Bitcoin que incluem saldos, dados, timelocks e multisigs. +Até o momento, temos interagido com o Bitcoin em um nível relativamente alto de abstração. O programa ```bitcoin-cli``` oferece acesso a uma variedade de comandos RPC que suportam a criação e controle de transações brutas de Bitcoin que incluem saldos, dados, timelocks e multisigs. -No entanto, o Bitcoin oferece muito mais complexidade do que isso. O software oferece uma linguagem de script simples que pode ser usada para criar condições de resgate ainda mais complexas. Se as multisigs e os timelocks fornecerem as bases para os contratos inteligentes, o script do Bitcoin constrói os alicerces. É o próximo passo para nos capacitar no mundo do bitcoin. +No entanto, o Bitcoin oferece muito mais complexidade do que isso. O software oferece uma linguagem de script simples que pode ser usada para criar condições de resgate ainda mais complexas. Se os multisigs e os timelocks fornecerem as bases para os contratos inteligentes, o script do Bitcoin constrói os alicerces. É o próximo passo para capacitar o Bitcoin. ## Objetivos deste capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - * Projetar um script do Bitcoin; - * Aplicar um script do Bitcoin. - + * Projetar um script no Bitcoin; + * Aplicar um script no Bitcoin. + Os objetivos secundários do capítulo incluem a capacidade de: - * Compreender o propósito dos scripts do Bitcoin; + * Compreender o propósito dos scripts no Bitcoin; * Entender os script P2PKH; * Entender como o P2WPKH funciona com os scripts; * Compreender as necessidades dos testes dos scripts do bitcoin. - + ## Tabela de Conteúdo -* [Seção 1: Entendendo o alicerce das transações](09_1_PriveStanding_the_foundation_of_transactions.md) -* [Seção 2: Executando um script do Bitcoin](09_2_running_a_bitcoin_script.md) -* [Seção 3: Testando um script do Bitcoin](09_3_testing_a_bitcoin_script.md) -* [Seção 4: Criando um script P2PKH](09_4_scripting_a_p2pkh.md) -* [Seção 5: Criando um script P2WPKH](09_5_scripting_a_p2wpkh.md) \ No newline at end of file +* [Seção Um: Compreendendo o Alicerce das Transações](09_1_PriveStanding_the_foundation_of_transactions.md) +* [Seção Dois: Executando um Script no Bitcoin](09_2_running_a_bitcoin_script.md) +* [Seção Três: Testando um Script no Bitcoin](09_3_testing_a_bitcoin_script.md) +* [Seção Quatro: Programando um P2PKH](09_4_scripting_a_p2pkh.md) +* [Seção Cinco: Programando um P2WPKH](09_5_scripting_a_p2wpkh.md) \ No newline at end of file From e35c5ae4fd31c271134ef693b972650bf5846fcd Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 27 Jul 2021 16:25:40 -0300 Subject: [PATCH 041/155] Review 09_1 --- ...standing_the_Foundation_of_Transactions.md | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/pt/09_1_Understanding_the_Foundation_of_Transactions.md b/pt/09_1_Understanding_the_Foundation_of_Transactions.md index c98291d..8ca5cdd 100644 --- a/pt/09_1_Understanding_the_Foundation_of_Transactions.md +++ b/pt/09_1_Understanding_the_Foundation_of_Transactions.md @@ -1,27 +1,27 @@ -# 9.1: Entendendo o alicerce das transações +# 9.1: Compreendendo a Base de Transações -Os alicerces do Bitcoin são as capacidades de proteger as transações, algo que é feito com uma linguagem de scripts simples. +A base do Bitcoin é a capacidade de proteger transações, algo que é feito com uma linguagem de programação simples. -## Conhecendo as partes do quebra-cabeça criptográfico +## Conhecendo as Partes do Quebra-Cabeça Criptográfico -Conforme descrito no [Capítulo 1](01_0_INTRODUCING_BITCOIN.MD), os saldos em cada transação Bitcoin estão travados com um quebra-cabeça criptográfico. Para sermos mais precisos, dissemos que o Bitcoin é composto de "uma sequência de transações atômicas". Observamos que: "Cada transação é autenticada por um remetente com a solução para um quebra-cabeça criptográfico anterior que foi armazenado como um script. A nova transação é bloqueada para o destinatário com um novo quebra-cabeça criptográfico que também é armazenado como um script". Esses scripts, que bloqueiam e desbloqueiam as transações, são escritos usando o script do bitcoin. +Conforme descrito no [Capítulo 1](01_0_INTRODUCING_BITCOIN.MD), os saldos em cada transação Bitcoin estão travados com um quebra-cabeça criptográfico. Para sermos mais precisos, dizemos que o Bitcoin é composto de "uma sequência de transações atômicas". Observamos que: "Cada transação é autenticada por um remetente com a solução para um quebra-cabeça criptográfico anterior que foi armazenado como um script. A nova transação é bloqueada para o destinatário com um novo quebra-cabeça criptográfico que também é armazenado como um script". Esses scripts, que bloqueiam e desbloqueiam as transações, são escritos usando o Bitcoin Script. -> :book: ***O que é o script do Bitcoin?*** O script do Bitcoin é uma linguagem baseada na linguagem de programação Forth que propositadamente evita loops, o que significa que ela não passa no processo de Turing. É composto de opcodes individuais. Cada transação única no Bitcoin é bloqueada com um script do Bitcoin. Quando a transação de bloqueio para um UTXO é executada com as entradas corretas, esse UTXO pode ser gasto. +> :book: ***O que é o Bitcoin Script?*** O Bitcoin Script é uma linguagem baseada em pilhas (ou _stacks_), similar à linguagem de programação Forth que propositadamente evita loops, o que significa que ela não é Turing-completa. É composta de opcodes individuais. Cada transação no Bitcoin é bloqueada com um script do Bitcoin. Quando a transação de bloqueio para um UTXO é executada com as entradas corretas, esse UTXO pode então ser gasto. O fato de que as transações estão bloqueadas com scripts significa que podem ser bloqueadas de várias maneiras diferentes, exigindo uma variedade de chaves diferentes. Na verdade, encontramos vários mecanismos de travamento diferentes até o momento, cada um dos quais usa diferentes opcodes: - * OP_CHECKSIG, que verifica uma chave pública contra uma assinatura, é a base do endereço P2PKH clássico, como será totalmente detalhado na seção [§9.3: Criando um script P2PKH](09_3_scripting_a_p2pkh.md); - * OP_CHECKMULTISIG, faz a mesma coisa com as multisigs, como será totalmente detalhado na seção [§10.4: Criando um script multisig](10_4_scripting_a_multisig.md); - * OP_CHECKLOCKTIMEVERIFY e OP_SEQUENCEVERIFY formam a base dos timelocks mais complexos, como será totalmente detalhado nas seções [§11.2: Usando CLTV nos scripts](11_2_using_cltv_in_scripts) e [§11.3: Usando o CSV nos scripts](11_3_using_csv_in_scripts.md). - * OP_RETURN é a marca de uma transação não gasta, e é por isso que é usado para transportar dados, como falamos na seção [§8.2: Enviando uma transação com dados](08_2_sending_a_transaction_with_data.md). + * OP_CHECKSIG, que verifica uma chave pública contra uma assinatura, é a base do endereço P2PKH clássico, como será totalmente detalhado na seção [§9.4: Programando um P2PKH](09_4_Scripting_a_P2PKH.md); + * OP_CHECKMULTISIG, faz a mesma coisa com os multisigs, como será totalmente detalhado na seção [§10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md); + * OP_CHECKLOCKTIMEVERIFY e OP_SEQUENCEVERIFY formam a base dos timelocks mais complexos, como será totalmente detalhado nas seções [§11.2: Usando CLTV em Scripts](11_2_Using_CLTV_in_Scripts) e [§11.3: Usando CSV em Scripts](11_3_Using_CSV_in_Scripts.md). + * OP_RETURN é a marca de uma transação não gasta, e é por isso que é usado para transportar dados, como falamos na seção [§8.2: Enviando uma Transação com Dados](08_2_sending_a_transaction_with_data.md). -## Accessando os scripts em nossas transações +## Accessando Scripts em Nossas Transações Podemos não perceber, mas já vimos esses scripts de bloqueio e desbloqueio como parte das transações brutas que fizemos. A melhor maneira de analisar esses scripts com mais profundidade é, portanto, criar uma transação bruta e examiná-la. -### Criando uma transação de teste +### Criando uma Transação de Teste -Para examinar os scripts reais de desbloqueio e bloqueio, vamos criar uma transação bruta rapidamente, pegando um UTXO legado não gasto e reenviando-o a um endereço de troco legado, deixando uma parte para as taxas de transação: +Para examinar scripts reais de desbloqueio e bloqueio, vamos criar uma transação bruta rapidamente, pegando um UTXO legado não gasto e reenviando-o a um endereço de troco legado, deixando uma parte para as taxas de transação: ``` $ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') $ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') @@ -31,11 +31,11 @@ $ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex ``` Não precisamos enviá-la. O objetivo é simplesmente produzir uma transação para que possamos examiná-la. ->**NOTA:** Por que usar endereços legados? Porque nossos scripts são mais significativos. No entanto, também ofereceremos um exemplo de um endereço nativo Segwit P2WPKH na seção [§9.5](09_5_scripting_a_p2wpkh.md). +>**NOTA:** Por que usar endereços legados? Porque seus scripts são mais significativos. No entanto, também ofereceremos um exemplo de um endereço nativo Segwit P2WPKH na seção [§9.5](09_5_Scripting_a_P2WPKH.md). -### Examinando nossa transação de teste +### Examinando Nossa Transação de Teste -Agora podemos examinar nossa transação com profundida necessária usando ```decodivawtransaction``` no ```$signedtx```: +Agora podemos examinar nossa transação profundamente usando ```decoderawtransaction``` no ```$signedtx```: ``` $ bitcoin-cli -named decoderawtransaction hexstring=$signedtx { @@ -81,29 +81,29 @@ O ```scriptSig``` está localizado no ```vin```. Este é o script de _desbloquei O ```scriptpubkey``` está localizado no ```vout```. Este é o script de _bloqueio_. É o que bloqueia a nova saída da transação. Haverá um ```scriptPubKey``` por cada saída em cada transação. -> :book: ***Como o scriptsig e o scriptpubkey interagem?*** O ```scriptSig``` de uma transação desbloqueia o UTXO anterior. A saída desta nova transação será bloqueada com um ```scriptPubKey```, que pode, por sua vez, ser desbloqueado pela ```scriptsig``` da transação que reutiliza esse UTXO. +> :book: ***Como o scriptSig e o scriptPubKey interagem?*** O ```scriptSig``` de uma transação desbloqueia o UTXO anterior. A saída desta nova transação será bloqueada com um ```scriptPubKey```, que pode, por sua vez, ser desbloqueado pelo ```scriptSig``` da transação que reutiliza aquele UTXO. -### Lendo os scripts da transação +### Lendo os Scripts na Transação -Se olharmos para os dois scripts e veremos que cada um possui duas representações diferentes: o ```hex``` é o que realmente é armazenado, mas a linguagem de montagem mais legível (```asm```) pode mostrar o que está acontecendo. +Se olharmos para os dois scripts veremos que cada um possui duas representações diferentes: o ```hex``` é o que realmente é armazenado, mas a linguagem assembly (```asm```) mais legível pode meio que mostrar o que está acontecendo. -Vamos dar uma olhada no ```asm``` do script de desbloqueio para podermos ver em primeira mão como o Script do Bitcoin se parece: +Vamos dar uma olhada na ```asm``` do script de desbloqueio para podermos ver em primeira mão como é programar no Bitcoin: ``` 04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b ``` -Como acontece, essa bagunça de números é uma assinatura privada, seguida pela chave pública associada. Ou pelo menos isso é o esperado, porque é isso que é necessário para desbloquear o P2PKH UTXO que esta transação está usando. +Como acontece, essa bagunça de números é uma assinatura de chave privada, seguida pela chave pública associada. Ou pelo menos isso é o esperado, porque é isso que é necessário para desbloquear o UTXO P2PKH que esta transação está usando. -Vamos ler o script de bloqueio e veremos que é algo muito mais óbvio: +Lendo o script de bloqueio vemos que é algo muito mais óbvio: ``` OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG ``` -Esse é o método padrão do script do Bitcoin para bloquear uma transação P2PKH. +Esse é o método padrão em Bitcoin Script para bloquear uma transação P2PKH. -Na seção [§9.4](09_4_scripting_a_p2pkh.md) será explicado como esses dois scripts andam juntos, mas primeiro precisamos saber como os scripts do Bitcoin são avaliados. +A seção [§9.4](09_4_Scripting_a_P2PKH.md) explicará como esses dois scripts andam juntos, mas primeiro precisamos saber como os scripts são avaliados no Bitcoin. -## Examinando um tipo diferente de transação +## Examinando um Tipo Diferente de Transação -Antes de sairmos do alicerce, vamos olhar para um tipo diferente de script de bloqueio. Aqui está o ```scriptPubKey``` da transação multisig que criamos na seção [§6.1: Enviando uma Transação com Multisig](06_1_sending_a_transaction_to_a_multisig.md). +Antes de deixarmos esta base para trás, vamos olhar para um tipo diferente de script de bloqueio. Aqui está o ```scriptPubKey``` da transação multisig que criamos na seção [§6.1: Enviando uma Transação com Multisig](06_1_sending_a_transaction_to_a_multisig.md). ``` "scriptPubKey": { "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", @@ -129,14 +129,14 @@ Vamos comparar isso com o ```ScriptPubkey``` da nossa nova transação P2PKH: } ``` -Essas duas transações são _definitivamente_ trancadas de maneiras diferentes. O Bitcoin reconhece o primeiro como sendo ```scripthash``` (P2SH) e o segundo como sendo ```pubkeyhash``` (P2PKH), mas também devemos ser capazes de ver a diferença nos diferentes códigos ```asm```:```OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL``` quando comparado com o ```OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 Op_equalverify op_checksig```. Este é o poder do script. Podemos simplesmente produzir alguns dos tipos drasticamente diferentes de transações que aprendemos nos capítulos anteriores. +Essas duas transações são _definitivamente_ trancadas de maneiras diferentes. O Bitcoin reconhece a primeira como sendo ```scripthash``` (P2SH) e a segunda como sendo ```pubkeyhash``` (P2PKH), mas também devemos ser capazes de ver a diferença nos diferentes códigos ```asm```: ```OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL``` versus ```OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 Op_equalverify op_checksig```. Este é o poder da programação: conseguimos, de maneira bem simples, produzir alguns dos tipos drasticamente diferentes de transações que aprendemos nos capítulos anteriores. -## Resumo: Entendendo o alicerce das transações +## Resumo: Compreendendo a Base de Transações -Cada transação do bitcoin inclui pelo menos um script de desbloqueio (```scriptSig```), que resolve um quebra-cabeça criptográfico anterior, e pelo menos um script de bloqueio (```scriptPubKey```), que cria um novo quebra-cabeça criptográfico. Há um ```scriptSig``` para cada entrada e um ```scriptPubKey``` para cada saída. Cada um desses scripts é escrito usando o script do Bitcoin, uma linguagem semelhante a linguagem de programação Forth que fortalece ainda mais o Bitcoin. +Cada transação do bitcoin inclui pelo menos um script de desbloqueio (```scriptSig```), que resolve um quebra-cabeça criptográfico anterior, e pelo menos um script de bloqueio (```scriptPubKey```), que cria um novo quebra-cabeça criptográfico. Há um ```scriptSig``` para cada entrada e um ```scriptPubKey``` para cada saída. Cada um desses scripts é escrito usando o Bitcoin Script, uma linguagem semelhante à linguagem de programação Forth que fortalece ainda mais o Bitcoin. -> :fire: ***Qual é o poder dos scripts?*** Os scripts de desbloqueio são todo o poder dos contratos inteligentes. Com os opcodes apropriados, podemos tomar decisões muito precisas sobre quem pode resgatar os fundos, quando podem ser resgatados e como podem resgatá-los. Regras mais complexas para saldos corporativos, endereços de parceria, gastos com proxy e outras metodologias também podem ser codificados dentro de um script. Os scripts também conseguem capacitar serviços bitcoin mais complexos, como a lightning e as sidechains. +> :fire: ***Qual é o poder dos scripts?*** Os scripts desbloqueiam todo o poder dos contratos inteligentes. Com os opcodes apropriados, podemos tomar decisões muito precisas sobre quem pode resgatar os fundos, quando podem ser resgatados e como eles podem resgatá-los. Regras mais complexas para saldos corporativos, endereços de parceria, gastos com proxy e outras metodologias também podem ser codificados dentro de um script. Os scripts também conseguem capacitar serviços mais complexos no Bitcoin, como a Lightning e sidechains. -## O que vem depois? +## O Que Vem Depois? -Vamos continuar "Apresentando os Scripts no Bitcoin" na seção [§9.2: Executando um script do Bitcoin](09_2_running_a_bitcoin_script.md). +Vamos continuar "Apresentando os Scripts no Bitcoin" na seção [§9.2: Executando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md). From 4330d0f779af0e7afa558452f6546dab3731d3ab Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 27 Jul 2021 16:57:35 -0300 Subject: [PATCH 042/155] Review 09_2 --- pt/09_2_Running_a_Bitcoin_Script.md | 52 ++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/pt/09_2_Running_a_Bitcoin_Script.md b/pt/09_2_Running_a_Bitcoin_Script.md index 54ddd21..1ced01a 100644 --- a/pt/09_2_Running_a_Bitcoin_Script.md +++ b/pt/09_2_Running_a_Bitcoin_Script.md @@ -1,24 +1,24 @@ -# 9.2: Executando um script do Bitcoin +# 9.2: Executando um Script no Bitcoin -Os scripts de Bitcoin podem não parecer tão intuitivos no começo, mas sua execução é bastante simples usando a notação polonesa reversa e uma pilha. +Os scripts de Bitcoin podem não parecer tão intuitivos no começo, mas sua execução é bastante simples usando a notação polonesa reversa e uma pilha (_stack_). -## Compreendendo a linguagem do script +## Compreendendo a Linguagem de Programação -Um script Bitcoin possui três partes: Uma linha de entrada; uma pilha para o armazenamento e; comandos específicos para execução. +Um script Bitcoin possui três partes: uma linha de entrada; uma pilha para o armazenamento; e comandos específicos para execução. -### Compreendendo o pedido +### Compreendendo a Ordem -Os scripts do Bitcoin são executados da esquerda para a direita. Para nós é fácil, porque é a mesma na qual lemos. No entanto, podemos ser o elemento mais não intuitivo do script do Bitcoin, porque significa que as funções não têm a aparência que nós esperávamos. Ao invés disso, _os operandos vêm antes do operador._ +Os scripts do Bitcoin são executados da esquerda para a direita. Para nós é fácil, porque é a mesma ordem na qual lemos. No entanto, pode na verdade ser o elemento menos intuitivo do Bitcoin Script, porque significa que as funções não têm a aparência que esperaríamos. Ao invés disso, _os operandos vêm antes do operador._ Por exemplo, se estivéssemos somando "1" e "2", nosso script do Bitcoin ficaria ```1 2 OP_ADD```, e _não_"1 + 2". Como sabemos que o operador OP_ADD recebe duas entradas, sabemos que as duas entradas anteriores são os operandos. -> :warning: **ATENÇÃO:** Tecnicamente, tudo no script do Bitcoin é um opcode, portanto, seria mais apropriado registrar o exemplo acima como ```OP_1 OP_2 OP_ADD```. Em nossos exemplos, não nos preocupamos sobre como as constantes serão avaliadas, pois esse é um tópico de tradução, como é explicado no capítulo [§10.2: Construindo a estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md). Alguns escritores preferem também não usar o prefixo "OP" nos operadores, mas optamos por não fazê-lo. +> :warning: **ATENÇÃO:** Tecnicamente, tudo em Bitcoin Script é um opcode, portanto, seria mais apropriado registrar o exemplo acima como ```OP_1 OP_2 OP_ADD```. Em nossos exemplos, não nos preocupamos sobre como as constantes serão avaliadas, pois esse é um tópico de tradução, como é explicado em [§10.2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md). Alguns escritores preferem também retirar o prefixo "OP" de todos os operadores, mas nós optamos por não fazê-lo. -### Compreendendo a pilha +### Compreendendo a Pilha Na verdade, não é correto dizer que um operador se aplica às entradas anteriores. Na verdade, um operador se aplica às entradas principais na pilha do Bitcoin. -> :book: ***O que é uma pilha?*** Uma pilha é uma estrutura de dados LIFO (last in, first out, ou no português, primeiro a entrar, último a sair). Possui duas funções de acesso: Push e Pop. Empurrar (Push) coloca um novo objeto no topo da pilha, empurrando para baixo tudo que está abaixo dele. Retirar (Pop) remove o objeto superior da pilha. +> :book: ***O que é uma pilha?*** Uma pilha é uma estrutura de dados LIFO (last in, first out, ou no português, primeiro a entrar, último a sair). Possui duas funções de acesso: push e pop. Empurrar (push) coloca um novo objeto no topo da pilha, empurrando para baixo tudo que está abaixo dele. Retirar (pop) remove o objeto superior da pilha. Sempre que o script do Bitcoin encontrar uma constante, ele a coloca na pilha. Portanto, o exemplo acima de ```1 2 OP_ADD``` seria realmente parecido com o que foi processado: ``` @@ -31,13 +31,13 @@ Stack: [ 1 ] Script: OP_ADD Stack: [ 1 2 ] ``` -_ Observe que, neste e nos exemplos seguintes, o topo da pilha está à direita e a parte inferior à esquerda._ - +_Observe que, neste e nos exemplos seguintes, o topo da pilha está à direita e a parte inferior à esquerda._ + ### Compreendendo os Opcodes Quando um script do Bitcoin encontra um operador, ele o avalia. Cada operador retira zero ou mais elementos da pilha como entradas, geralmente um ou dois. Em seguida, ele os processa de uma maneira específica antes de colocar zero ou mais elementos de volta na pilha, geralmente um ou dois. -> :book: ***O que é um Opcode?*** O Opcode significa "código de operação". É normalmente associado ao código de linguagem de máquina e é uma função simples (ou "operador"). +> :book: ***O que é um Opcode?*** O Opcode significa "código de operação" (no inglês, "_operation code_"). É normalmente associado a código de linguagem de máquina e é uma função simples (ou "operador"). OP_ADD retira dois itens da pilha (no nosso caso: 2 depois 1), adiciona-os e coloca o resultado de volta na pilha (no exemplo: 3). ``` @@ -46,7 +46,7 @@ Running: 1 2 OP_ADD Stack: [ 3 ] ``` -## Colocando mais complexidade +## Construindo Complexidade Scripts mais complexos são criados executando mais comandos em ordem. Eles precisam ser avaliados cuidadosamente da esquerda para a direita, para que possamos entender o estado da pilha conforme cada novo comando é executado. Ele mudará constantemente, como resultado de operadores anteriores: ``` @@ -71,15 +71,15 @@ Running: 5 4 OP_SUB Stack: [ 1 ] ``` -## Compreendendo o uso do script do Bitcoin +## Compreendendo o Uso do Bitcoin Script -Acima, você viu basicamente, o que é o script do Bitcoin... Além de algumas complexidades de como essa, a linguagem script interage com o próprio Bitcoin. +É basicamente programar no Bitcoin ... além de algumas complexidades de como essa linguagem de programação interage com o próprio Bitcoin. -### Compreendendo o scriptSig e scriptPubKey +### Compreendendo scriptSig e scriptPubKey -Como vimos anteriormente, cada entrada da transação de Bitcoin contém um ```scriptSig``` que é usado para desbloquear o ```scriptPubKey``` para o UTXO associado. Eles são _efetivamente_ concatenados, o que significa que o ```scriptSig``` e o ```scriptPubKey``` são executados juntos, nessa ordem. +Como vimos anteriormente, cada entrada de uma transação no Bitcoin contém um ```scriptSig``` que é usado para desbloquear o ```scriptPubKey``` para o UTXO associado. Eles são _efetivamente_ concatenados, o que significa que o ```scriptSig``` e o ```scriptPubKey``` são executados juntos, nessa ordem. -Então, podemos presumir que um UTXO foi bloqueado com um ```scriptPubKey``` que lê ```OP_ADD 99 OP_EQUAL```, exigindo como entrada dois números que somam noventa e nove, e podemos presumir que o ```scriptSig``` de ```1 98``` foi executado para desbloquear. Os dois scripts seriam efetivamente executados em ordem como ```1 98 OP_ADD 99 OP_EQUAL```. +Então, presuma que um UTXO foi bloqueado com um ```scriptPubKey``` que leia ```OP_ADD 99 OP_EQUAL```, exigindo como entrada dois números que somam noventa e nove, e presuma que o ```scriptSig``` de ```1 98``` foi executado para desbloqueá-lo. Os dois scripts seriam efetivamente executados em ordem como ```1 98 OP_ADD 99 OP_EQUAL```. Avaliando o resultado: ``` @@ -103,23 +103,23 @@ Script: Running: 99 99 OP_EQUAL Stack: [ True ] ``` -Esta abstração não é muito precisa, já que, por razões de segurança, o ```scriptSig``` é executado, então o conteúdo da pilha é transferido para o ```scriptPubKey``` para ser executado, mas é preciso o suficiente para entender como a chave do ```scriptSig``` se encaixa o bloqueio de ```scriptPubKey```. +Esta abstração não é muito precisa: por razões de segurança, o ```scriptSig``` é executado, então o conteúdo da pilha é transferido para o ```scriptPubKey``` para ser executado, mas é precisa o suficiente para entender como a chave do ```scriptSig``` se encaixa no cadeado de ```scriptPubKey```. -> :warning: **AVISO:** O exemplo acima é um tipo de transação incomum. Na verdade, não seria aceito por nós que executamos o Bitcoin Core com as configurações padrões. Na seção [§10.1: Construindo um script do Bitcoin com P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) iremos discutir como realmente _podemos_ executar um Script Bitcoin como este, usando o poder do P2SH. +> :warning: **AVISO:** O exemplo acima é um tipo de transação não-padrão. Na verdade, não seria aceito por nós que executamos o Bitcoin Core com as configurações padrões. Na seção [§10.1: Compreendendo a Base do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) iremos discutir como realmente _poderíamos_ executar um Script Bitcoin como este, usando o poder do P2SH. -### Obtendo os resultados +### Obtendo os Resultados O Bitcoin irá verificar uma transação e permitir que o UTXO possa ser gasto novamente se dois critérios forem atendidos ao executar o ```scriptSig``` e o ```scriptPubKey```: 1. A execução não foi marcada como inválida em nenhum ponto, por exemplo, com um OP_VERIFY com falha ou com o uso de um opcode desativado; 2. O item no topo da pilha no final da execução é verdadeiro (diferente de zero). - + No exemplo acima, a transação seria bem-sucedida porque a pilha tem um ```True``` no final. Mas, seria igualmente permitido terminar com uma pilha completa e o número ```42``` no topo (os leitores do Guia do Mochileiro das Galáxias pegaram a referência). -## Resumo: Executando um script do Bitcoin +## Resumo: Executando um Script no Bitcoin -Para processar um script do Bitcoin, um ```scriptSig``` é executado seguido pelo ```scriptPubKey``` que está desbloqueando. Esses comandos são executados em ordem, da esquerda para a direita, com constantes sendo colocadas em uma pilha e os operadores retirando elementos dessa pilha e, em seguida, enviando os resultados de volta para ela. Se o Script não parar no meio e se o item no topo da pilha no final for diferente de zero, o UTXO será desbloqueado. +Para processar um script no Bitcoin, um ```scriptSig``` é executado seguido pelo ```scriptPubKey``` que ele está desbloqueando. Esses comandos são executados em ordem, da esquerda para a direita, com constantes sendo colocadas em uma pilha e os operadores retirando elementos dessa pilha e, em seguida, enviando os resultados de volta para ela. Se o script não parar no meio e se o item no topo da pilha no final for diferente de zero, então o UTXO será desbloqueado. -## O que vem depois? +## O Que Vem Depois? -Vamos continuar "Apresentando os Scripts no Bitcoin" na seção [§9.3: Testando o Script do Bitcoin](09_3_Testing_a_Bitcoin_Script.md). \ No newline at end of file +Vamos continuar "Apresentando Scripts no Bitcoin" na seção [§9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md). \ No newline at end of file From 5c5642dd6e434c1a0aeb3c1bfa4af1510aabad22 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 27 Jul 2021 17:35:28 -0300 Subject: [PATCH 043/155] Review 09_3 --- pt/09_3_Testing_a_Bitcoin_Script.md | 38 ++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/pt/09_3_Testing_a_Bitcoin_Script.md b/pt/09_3_Testing_a_Bitcoin_Script.md index e00e531..b79a2a4 100644 --- a/pt/09_3_Testing_a_Bitcoin_Script.md +++ b/pt/09_3_Testing_a_Bitcoin_Script.md @@ -1,12 +1,12 @@ -# 9.3: Testando um script do Bitcoin +# 9.3: Testando um Script no Bitcoin -O script do Bitcoin permite um controle adicional considerável sobre as transações do bitcoin, mas também é um tanto quanto perigoso. Como descreveremos na seção [§10.1](10_1_Understanding_the_Foundation_of_P2SH.md), os scripts reais são um tanto isolados da rede Bitcoin, o que significa que é possível escrever um script e a rede aceitá-lo, mesmo que seja impossível resgatar o script! Portanto, precisamos testar exaustivamente nossos scripts antes de colocarmos nosso saldo neles. +Programar no Bitcoin nos permite um controle adicional considerável sobre as transações no Bitcoin, mas também é um tanto quanto perigoso. Como descreveremos na seção [§10.1](10_1_Understanding_the_Foundation_of_P2SH.md), os scripts reais são um tanto isolados da rede Bitcoin, o que significa que é possível escrever um script e a rede aceitá-lo, mesmo que seja impossível resgatar daquele script! Portanto, precisamos testar exaustivamente nossos scripts antes de colocarmos nosso dinheiro neles. Este capítulo, portanto, descreve um método primário para testar os scripts do Bitcoin, que também usaremos para os exemplos ocasionais que ocorrerem durante esta seção. ## Instalando o btcdeb -O Bitcoin Script Debugger (```btcdeb```) criado por @kallewoof é um dos métodos mais confiáveis ​​que encontramos para depurar os scripts do Bitcoin. No entanto, ele requer a configuração do C++ e algumas coisas mais em nossa máquina, portanto, também ofereceremos algumas outras opções no final do capítulo. +O Bitcoin Script Debugger (```btcdeb```) criado por @kallewoof é um dos métodos mais confiáveis ​​que encontramos para depurar os scripts no Bitcoin. No entanto, ele requer a configuração de C++ e algumas coisas a mais em nossa máquina, portanto, também ofereceremos algumas outras opções no final do capítulo. Primeiro, precisamos clonar o repositório do ```btcdeb``` do GitHub, que também exigirá a instalação do ```git``` caso ainda não o tenhamos em nossa máquina. ``` @@ -44,9 +44,9 @@ $ which btcdeb O ```btcdeb``` funciona como um depurador padrão. Ele pega um script (bem como qualquer número de entradas da pilha) como um argumento de inicialização. Em seguida, podemos percorrer o script usando o ```step```. -Se ao invés disso nós querermos inicializá-lo sem argumentos, iremos obter simplesmente um interpretador onde podemos emitir comandos ```exec [opcode]``` para realizar ações diretas. +Se ao invés disso nós quisermos inicializá-lo sem argumentos, iremos obter simplesmente um interpretador onde podemos emitir comandos ```exec [opcode]``` para realizar ações diretas. -### Usando o btcdeb para um exemplo de adição +### Usando o btcdeb para um Exemplo de Adição O exemplo a seguir mostra o uso do ```btcdeb``` usando como exemplo a adição da seção anterior, ```1 2 OP_ADD``` ``` @@ -98,11 +98,11 @@ script | stack ``` E é aí que nosso script termina, sem mais nada para executar e com um ```03``` no topo da pilha como resultado do script. -> **NOTA:** O ```btcdeb``` permite que possamos repetir o comando anterior pressionando apenas a tecla enter. Faremos isso em exemplos subsequentes, então não fiquemos assustados com os prompts ```btcdeb>``` se não houver nenhum comando. Isso significa que apenas repetimos o comando anterior (geralmente usando o ```step```). +> **NOTA:** O ```btcdeb``` nos permite repetir o comando anterior pressionando apenas a tecla enter. Faremos isso em exemplos subsequentes, então não fique assustado com os prompts ```btcdeb>``` se não houver nenhum comando. Isto está apenas repetindo o comando anterior (geralmente o ```step```). -### Usando o btcdeb com um exemplo de subtração +### Usando o btcdeb com um Exemplo de Subtração -A seção anterior também incluiu um exemplo de subtração um pouco mais complexa na criação do script: ```3 2 OP_ADD 4 OP_SUB```. Isso é o resultado: +A seção anterior também incluiu um exemplo de subtração um pouco mais complexo na criação do script: ```3 2 OP_ADD 4 OP_SUB```. Isso é o resultado: ``` $ btcdeb '[3 2 OP_ADD 4 OP_SUB]' @@ -164,7 +164,7 @@ script | stack ``` Voltaremos ao ```btcdeb``` de tempos em tempos, e ele continuará sendo uma excelente ferramenta para testarmos nossos scripts. -### Usando todo o poder do btcdeb +### Usando o Poder do btcdeb O ```btcdeb``` também tem algumas funções mais poderosas, como ```print``` e ```stack```, que mostram o script e a pilha a qualquer momento da execução. @@ -180,30 +180,30 @@ btcdeb> stack <01> 02 (top) <02> 03 ``` -Usar esses comandos tornará mais fácil observarmos o que está acontecendo e onde estamos no processo. +Usar esses comandos pode tornar mais fácil observarmos o que está acontecendo e onde estamos no processo. -## Testando um script online +## Testando um Script Online -Existem também alguns simuladores web que podemos usar para testar os scripts online. Eles podem ser superiores a uma ferramenta de linha de comando, oferecendo uma saída gráfica melhor, mas também descobrimos que eles tendem a ter certas deficiências. +Existem também alguns simuladores na web que podemos usar para testar os scripts online. Eles podem ser superiores a uma ferramenta de linha de comando, oferecendo uma saída gráfica melhor, mas também descobrimos que eles tendem a ter certas deficiências. No passado, tentamos fornecer diretrizes abrangentes sobre o uso de sites como o [Script Playground](http://www.crmarsh.com/script-playground/) ou o [Bitcoin Online Script Debugger](https: // bitcoin-script-debugger.visvirial.com/), mas eles estão desatualizados e/ou sumiram e não podemos mais acompanhá-los. O que podemos garantir é que esses depuradores possuem a vantagem de mostrar coisas visualmente e explicitamente informando se um script foi bem-sucedido (desbloqueado) ou que houve falha (permanece bloqueado). Porém eles possuem algumas desvantagens relacionadas as assinaturas, onde muitos deles sempre retornam ```true``` para testes de assinatura ou então possuem mecanismos muito complicados para incorporá-las. -## Testando um script com Bitcoin +## Testando um Script com Bitcoin -Mesmo com uma ótima ferramenta como o ```btcdeb``` ou recursos transitórios como os diversos testadores de script online, não estamos trabalhando com a coisa real. Não podemos garantir que elas sigam as regras de consenso do Bitcoin, o que significa que não podemos garantir os resultados. Por exemplo, o Script Playground diz explicitamente que ignora um bug que está implícito quando usando o multisig do Bitcoin. Isso significa que qualquer código multisig que testarmos com sucesso no Script Playground irá dar erro no mundo real. +Mesmo com uma ótima ferramenta como o ```btcdeb``` ou recursos transitórios como os diversos testadores de script online, não estamos trabalhando com a coisa real. Não podemos garantir que elas seguem as regras de consenso do Bitcoin, o que significa que não podemos garantir os resultados. Por exemplo, o Script Playground diz explicitamente que ignora um bug que está implícito quando usando o multisig no Bitcoin. Isso significa que qualquer código multisig que testarmos com sucesso no Script Playground dará erro no mundo real. Portanto, a única maneira de _realmente_ testar os scripts do Bitcoin é testá-los usando a Testnet. -E como podemos faz isso? Acontece que esse é o tópico do [capítulo 10](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md), que examina a introdução desses scripts abstratos no mundo real do Bitcoin incorporando-os em transações P2SH. (Mas, mesmo assim, provavelmente, precisaremos de uma API para enviar nossa transação P2SH para a rede Bitcoin, então os testes que avaliam o processo completo ainda serão produzidos no futuro). +E como podemos faz isso? Acontece que esse é o tópico do [capítulo 10](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md), que examina a introdução desses scripts abstratos no mundo real do Bitcoin incorporando-os em transações P2SH. (Mas, mesmo assim, provavelmente precisaremos de uma API para enviar nossa transação P2SH para a rede Bitcoin, então os testes completos ainda serão produzidos no futuro). -_ Quaisquer que sejam_ os outros métodos de teste que usamos, testar um script na Testnet deve ser nosso teste final _antes_ de colocar nosso script em Mainnet. Não podemos confiar que nosso código está correto. Não podemos fazer isso apenas olhando para ele. Nem mesmo podemos confiar em quaisquer simuladores ou depuradores que estivermos utilizando. Fazer isso é outra ótima maneira de perder seu saldo no Bitcoin. +_Quaisquer que sejam_ os outros métodos de teste que usamos, testar um script na Testnet deve ser nosso teste final _antes_ de colocar nosso script em Mainnet. Não podemos confiar que nosso código está correto. Não podemos fazer isso apenas olhando para ele. Nem mesmo podemos confiar em quaisquer simuladores ou depuradores que estivermos utilizando. Fazer isso é outra ótima maneira de perder seu saldo no Bitcoin. -## Resumo: Testando um script do Bitcoin +## Resumo: Testando um Script no Bitcoin Você deve instalar o ```btcdeb``` como uma ferramenta de linha de comando para testar os scripts do Bitcoin. No momento em que este livro foi escrito, produzimos resultados precisos que podem percorrer todo o processo do script. Também podemos procurar em alguns sites online uma representação mais visual. Quando estivermos com tudo pronto, vamos precisar usar a testnet para ter certeza de que as coisas estão funcionando com precisão, antes de implantarmos na Mainnet. -## O que vem depois? +## O Que Vem Depois? -Vamos continuar "Apresentando os Scripts no Bitcoin" com nosso primeiro exemplo real na seção [§9.4: Criando um script P2PKH](09_4_Scripting_a_P2PKH.md). \ No newline at end of file +Vamos continuar "Apresentando Scripts no Bitcoin" com nosso primeiro exemplo real na seção [§9.4: Programando um P2PKH](09_4_Scripting_a_P2PKH.md). \ No newline at end of file From 53818e633740ab616abcb2ab0adac2d100cc43b4 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 27 Jul 2021 17:55:23 -0300 Subject: [PATCH 044/155] Review 09_4 --- pt/09_4_Scripting_a_P2PKH.md | 57 ++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/pt/09_4_Scripting_a_P2PKH.md b/pt/09_4_Scripting_a_P2PKH.md index 8d94e4f..96cf863 100644 --- a/pt/09_4_Scripting_a_P2PKH.md +++ b/pt/09_4_Scripting_a_P2PKH.md @@ -1,10 +1,10 @@ -# 9.4: Criando um script P2PKH +# 9.4: Programando um P2PKH Os endereços P2PKH estão desaparecendo rapidamente devido ao advento do Segwit, porém, são importantes para entender o Bitcoin, e especialmente para entender os scripts do Bitcoin. Vamos dar uma olhada rápida como os scripts nativos do Segwit (P2WPKH) funcionam na próxima seção. -## Entendendo o script de desbloqueio +## Entendendo o Script de Desbloqueio -Dissemos que quando os fundos são enviados para um endereço de bitcoin, eles estão bloqueados juntamente com a chave privada associada a esse endereço. Isso é gerenciado através do ```scriptpubkey``` de uma transação P2PKH, que é projetado de forma que requer que o destinatário tenha a chave privada associada ao endereço bitcoin do tipo P2PKH. Para ser preciso, o destinatário deve fornecer tanto a chave pública ligada à chave privada quanto uma assinatura gerada pela chave privada. +Dissemos que quando os fundos são enviados para um endereço de bitcoin, eles estão bloqueados juntamente com a chave privada associada a esse endereço. Isso é gerenciado através do ```scriptPubKey``` de uma transação P2PKH, que é projetado de forma que requer que o destinatário tenha a chave privada associada ao endereço bitcoin do tipo P2PKH. Para ser preciso, o destinatário deve fornecer tanto a chave pública ligada à chave privada quanto uma assinatura gerada pela chave privada. Vamos dar uma olhada novamente na transação que criamos na seção [§9.1](09_1_Understanding_the_Foundation_of_Transactions.md): ``` @@ -45,13 +45,13 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$signedtx ] } ``` -Podemos ver que o script de desbloqueio do ```scriptSig``` tem dois valores, uma `````` (e um ```[ALL]```) e um ``````: +Podemos ver que o script de desbloqueio do ```scriptSig``` tem dois valores, uma `````` (e um ```[ALL]```) e uma ``````: ``` 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b ``` Isso é tudo que um script de desbloqueio é! (No caso de um endereço P2PKH). -## Entendendo o script de bloqueio +## Entendendo o Script de Bloqueio Lembre-se de que cada script de desbloqueio desbloqueia um UTXO anterior. No exemplo acima, o ```vin``` revela que é realmente desbloqueado o vout ```0``` da txid ```bb4362dec15e67d366088f5493c789f22fbb4a6049f22fb4a604e767dae1f6a631687E2784aa```. @@ -83,8 +83,8 @@ $ bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6 "hex": "020000000001011efcc3bf9950ac2ea08c53b43a0f8cc21e4b5564e205f996f7cadb7d13bb79470000000017160014c4ea10874ae77d957e170bd43f2ee828a8e3bc71feffffff0218730100000000001976a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac713b10000000000017a914b780fc2e945bea71b9ee2d8d2901f00914a25fbd8702473044022025ee4fd38e6865125f7c315406c0b3a8139d482e3be333727d38868baa656d3d02204b35d9b5812cb85894541da611d5cec14c374ae7a7b8ba14bb44495747b571530121033cae26cb3fa063c95e2c55a94bd04ab9cf173104555efe448b1bfc3a68c8f873342c1b00" } ``` -Mas como podemos observar, não recebemos o ```scriptPubKey``` com o ```gettransaction```. Precisamos ter um passo adicional para recuperar essa informação, examinando as informações da transação bruta (que é o ```hex```) com o ```DecoderAwTransaction```: -``` +Mas como podemos observar, não recebemos o ```scriptPubKey``` com o ```gettransaction```. Precisamos dar um passo adicional para recuperar essa informação, examinando as informações da transação bruta (que é o ```hex```) com o ```Decoderawtransaction```: +```bash $ hex=$(bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa" | jq -r '.hex') $ bitcoin-cli decoderawtransaction $hex { @@ -142,11 +142,11 @@ $ bitcoin-cli decoderawtransaction $hex ``` Podemos olhar agora para o ```vout``` ```0``` e ver que ele foi bloqueado com o ```scriptPubKey``` no ```OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG```. Essa é a metodologia de bloqueio padrão usada para um endereço P2PKH mais antigo com o `` preso no meio. -Executando vamos demonstrar seu funcionamento. +Executando-o demonstrará seu funcionamento. -## Executando um script P2PKH +## Executando um Script P2PKH -Quando desbloqueamos um UTXO do tipo P2PKH, efetivamente concatenamos os scripts de desbloqueio e de bloqueio. Para um endereço P2PKH, como o exemplo que usamos neste capítulo, que produz o seguinte: +Quando desbloqueamos um UTXO do tipo P2PKH, efetivamente concatenamos os scripts de desbloqueio e de bloqueio. Para um endereço P2PKH, como o exemplo que usamos neste capítulo, isso produz o seguinte: ``` Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ``` @@ -169,7 +169,7 @@ Stack: [ ] ``` Por que duplicar? Porque é necessário verificar os dois elementos de desbloqueio, a chave pública e a assinatura. -Em seguida, o ```OP_HASH160``` retira o `````` fora da pilha, cria um hash e coloca o resultado de volta na nela. +Em seguida, o ```OP_HASH160``` retira o `````` fora da pilha, cria um hash e coloca o resultado de volta nela. ``` Script: OP_EQUALVERIFY OP_CHECKSIG Running: OP_HASH160 @@ -180,27 +180,28 @@ Então, colocamos o `````` que estava no script de bloqueio na pilha Script: OP_EQUALVERIFY OP_CHECKSIG Stack: [ ] ``` -O ```OP_EQUALVERIFY``` é efetivamente dois opcodes: O ```OP_EQUAL```, que retira dois itens da pilha e coloca `True` ou `False` baseado na comparação de ambos elementos; e o ```OP_VERIFY``` que retira o resultado e imediatamente marca a transação como inválida se for ```False```. No capítulo 12 falaremos mais sobre o uso de ```OP_VERIFY``` como condicional. +O ```OP_EQUALVERIFY``` é efetivamente dois opcodes: ```OP_EQUAL```, que retira dois itens da pilha e coloca `True` ou `False` de volta baseado na comparação de ambos elementos; e o ```OP_VERIFY``` que retira o resultado e imediatamente marca a transação como inválida se for ```False```. (No capítulo 12 falaremos mais sobre o uso de ```OP_VERIFY``` como condicional.) -Assumindo que os dois `````` estão iguais, teremos o seguinte resultado: +Assumindo que os dois `````` são iguais, teremos o seguinte resultado: ``` Script: OP_CHECKSIG Running: OP_EQUALVERIFY Stack: [ ] ``` -Neste momento, provamos os `````` fornecido nos hashes ```scriptSig``` para o endereço Bitcoin em questão, para que saibamos que o dono conhecia a chave pública. Mas, eles também precisam provar o conhecimento da chave privada, o que é feito com os ```OP_CHECKSIG```, que confirma que a assinatura do script de desbloqueio corresponde a essa chave pública. +Neste momento, provamos que a `` fornecida no `scriptSig` leva ao endereço Bitcoin em questão, então sabemos que o redentor conhecia a chave púbica. Mas, ele também precisa provar o conhecimento da chave privada, o que é feito com os ```OP_CHECKSIG```, que confirmam que a assinatura do script de desbloqueio corresponde a essa chave pública. + ``` Script: Running: OP_CHECKSIG Stack: [ True ] ``` -O script agora termina e se foi bem sucedido, a transação é permitida para gastar novamente o UTXO em questão. +O script agora termina e, se foi bem sucedido, a transação é permitida para gastar o UTXO em questão novamente. -### Usando o btcdeb em um exemplo P2PKH +### Usando o btcdeb em um Exemplo P2PKH -Testando transações de bitcoin reais com o ```btcdeb``` é um pouco mais complicado, porque precisamos conhecer a chave pública e uma assinatura para fazer todo o trabalho, e gerar o último é um pouco difícil. No entanto, uma maneira de testar as coisas é, deixar o Bitcoin fazer o trabalho para nós, gerando uma transação que _possa_ desbloquear um UTXO. Isso é o que fizemos acima, geramos a transação para gastar o UTXO criado pelo ```bitcoin-cli``` para calcular a `````` e o ``````. Podemos analisar as informações da transação bruta do UTXO para conhecer o script de bloqueio, incluindo o ``````. +Testando transações de bitcoin reais com o ```btcdeb``` é um pouco mais complicado, porque precisamos conhecer a chave pública e uma assinatura para fazer todo o trabalho, e gerar o último é um pouco difícil. No entanto, uma maneira de testar as coisas é deixar o Bitcoin fazer o trabalho para nós, gerando uma transação que _possa_ desbloquear um UTXO. Isso é o que fizemos acima, geramos a transação para gastar o UTXO criado pelo ```bitcoin-cli``` para calcular a `````` e a ``````. Podemos analisar as informações da transação bruta do UTXO para conhecer o script de bloqueio, incluindo o ``````. -Podemos montar o script de bloqueio, a assinatura e o pubkey usando o `btcdeb`, mostrando como pode ser simples um script P2PKH . +Podemos montar o script de bloqueio, a assinatura e a pubkey usando o `btcdeb`, mostrando como pode ser simples um script P2PKH . ``` $ btcdeb '[304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG]' btcdeb 0.2.19 -- type `btcdeb -h` for start up options @@ -220,7 +221,7 @@ OP_CHECKSIG | | #0000 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c ``` -Colocamos a `````` e o `````` dentro da pilha: +Colocamos a `````` e a `````` dentro da pilha: ``` btcdeb> step <> PUSH stack 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c @@ -347,12 +348,12 @@ error: Signature is found in scriptCode ``` Infelizmente, esta verificação pode ou não estar funcionando no momento do teste devido a caprichos do Bitcoin Core e do `btcdeb`. -Como mostramos, um P2PKH é bastante simples. Nossa proteção vem através da força da criptografia. +Como mostramos, um P2PKH é bastante simples. Nossa proteção vem através da força de sua criptografia. -### Como procurar uma Pub Key e uma Signature manualmente +### Como Procurar uma Pub Key e uma Assinatura Manualmente + +E se quiséssemos gerar a `````` e a ``````, informações necessárias para desbloquear um UTXO, sem usar o ```bitcoin-cli``` para criar uma transação? -E se quiséssemos gerar a `````` e o ``````, informações necessárias para desbloquear um UTXO, sem usar o ```bitcoin-cli``` para criar uma transação? - Acontece que é muito fácil obtermos uma ````````. Nós precisamos usar o ```getaddressinfo``` para examinar o endereço onde o UTXO está: ``` $ bitcoin-cli getaddressinfo mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9 @@ -377,12 +378,12 @@ $ bitcoin-cli getaddressinfo mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9 ] } ``` -Descobrir essa assinatura, no entanto, requer que entendamos os meandros de como as transações do Bitcoin são criadas. Portanto, vamos deixar isso como sendo um estudo avançado para você leitor: criando uma transação de ```bitcoin-cli``` para "resolver" a UTXO é a melhor solução neste momento para conseguir essa informação. +Descobrir essa assinatura, no entanto, requer que entendamos os meandros de como as transações do Bitcoin são criadas. Portanto, vamos deixar isso como sendo um estudo avançado para você leitor: criando uma transação de ```bitcoin-cli``` para "resolver" o UTXO é a melhor solução para isso neste momento. -## Resumo: Criando um script P2PKH +## Resumo: Programando um P2PKH -O envio para um endereço P2PKH foi relativamente fácil quando estávamos usando o ````bitcoin-cli````. Examinando o script do Bitcoin, pudemos ver que ele estabelece as funções criptográficas que estavam implícitas no financiamento da transação, ou seja, como o UTXO é desbloqueado com uma assinatura e uma chave pública. +Enviar para um endereço P2PKH foi relativamente fácil quando estávamos usando o ````bitcoin-cli````. Examinando o script do Bitcoin subjacente nos revela as funções criptográficas que estavam implícitas no financiamento da transação: como o UTXO foi desbloqueado com uma assinatura e uma chave pública. -## O que vem depois? +## O Que Vem Depois? -Vamos continuar "Apresentando os Scripts no Bitcoin" na seção [§9.4: Criando um script P2WPKH](09_4_Scripting_a_P2PKH.md). \ No newline at end of file +Vamos continuar "Apresentando Scripts no Bitcoin" na seção [§9.4: Programando um P2WPKH](09_4_Scripting_a_P2WPKH.md). \ No newline at end of file From 26a6fb1a7f974e8aa1d1b8759a566794dc9a92bc Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 27 Jul 2021 18:10:24 -0300 Subject: [PATCH 045/155] Review 09_5 --- pt/09_5_Scripting_a_P2WPKH.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pt/09_5_Scripting_a_P2WPKH.md b/pt/09_5_Scripting_a_P2WPKH.md index df9f164..e83fa6c 100644 --- a/pt/09_5_Scripting_a_P2WPKH.md +++ b/pt/09_5_Scripting_a_P2WPKH.md @@ -1,10 +1,10 @@ # 9.5: Criando um script P2WPKH -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Cautela, leitor. -Os P2PKHs são bons para explicar a maneira fundamental como os scripts de Bitcoin funcionam, mas por que os scripts SegWit P2WPKH nativos estão se tornando cada vez mais a maioria das transações de Bitcoin? Acontece que os endereços P2WPKH não usam Scripts de Bitcoin como os endereços de Bitcoin tradicionais fazem e, portanto, esta seção é realmente uma digressão do script deste capítulo, mas ela é importante, porque descreve a _outra_ maneira principal pela qual os Bitcoins podem ser transacionados. +Os P2PKHs são bons para explicar a maneira fundamental de como os scripts de Bitcoin funcionam, mas por que os scripts SegWit P2WPKH nativos estão se tornando cada vez mais a maioria das transações no Bitcoin? Acontece que os endereços P2WPKH não usam Scripts de Bitcoin como os endereços de Bitcoin tradicionais fazem e, portanto, esta seção é realmente uma digressão do script deste capítulo, mas ela é importante, porque descreve a _outra_ maneira principal pela qual bitcoins podem ser transacionados. -## Observando um script P2WPKH +## Observando um Script P2WPKH É fácil ver a aparência de um script P2WPKH. A transação bruta abaixo foi criada gastando um UTXO P2WPKH e, em seguida, enviando o dinheiro para um endereço de troco P2WPKH, assim como fizemos com um endereço legado na seção [§9.1](09_1_Understanding_the_Foundation_of_Transactions.md). ``` @@ -51,13 +51,13 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$signedtx ``` Provavelmente existem duas coisas surpreendentes aqui: (1) Não há ```scriptSig``` para desbloquear a transação anterior e; (2) o ```scriptPubKey``` para bloquear a nova transação é apenas ```0 92a0db923b3a13eb576a40c4b35515aa30206cb```. -Isso é assim porque o P2WPKH funciona de forma totalmente diferente! +Isso é assim porque o P2WPKH funciona de forma diferente! -## Compreendendo uma transação P2WPKH +## Compreendendo uma Transação P2WPKH -Uma transação P2WPKH contém todas as mesmas informações que uma transação P2PKH clássica, mas a coloca em lugares diferentes, não dentro de um script Bitcoin tradicional, e essa é a cereja do bolo das transações SegWit, pois coloca as informações nas "witness" (testemunhas), que é onde as chaves públicas e as assinaturas vão, ficando fora da transação, dando suporte para diminuir o tamanho da transação e aumentando a quantidade sem aumentar o tamanho bloco. +Uma transação P2WPKH contém todas as mesmas informações que uma transação P2PKH clássica, mas a coloca em lugares diferentes, não dentro de um script Bitcoin tradicional, e essa é a cereja do bolo das transações SegWit, pois retira as informações "witness" (testemunhas), que são as chaves públicas e as assinaturas, para fora da transação, dando suporte a uma mudança de tamanho do bloco. -Mas, se olharmos com cuidado, veremos que o ```scriptSig``` vazio foi substituído por duas entradas em uma nova seção chamada ```txinwitness```. Se examinarmos os tamanhos e formatações, eles devem parecer familiares, afinal, elas são uma assinatura e uma chave pública. Da mesma forma, se olharmos o `scriptPubKey`, veremos que é feito de um ```0``` (Na verdade, de um ```OP_0```, que é o número da versão do SegWit) e outro número longo, que é o hash de chave pública. +Mas, se olharmos com cuidado, veremos que o ```scriptSig``` vazio foi substituído por duas entradas em uma nova seção chamada ```txinwitness```. Se examinarmos os tamanhos e formatações, eles devem parecer familiares, afinal, elas são uma assinatura e uma chave pública. Da mesma forma, se olharmos o `scriptPubKey`, veremos que é feito de um ```0``` (na verdade, de um ```OP_0```, que é o número da versão do SegWit) e outro número longo, que é o hash de chave pública. Aqui está uma comparação dos nossos dois exemplos: | Tipo | PubKeyHash | PubKey | Signature | @@ -65,9 +65,9 @@ Aqui está uma comparação dos nossos dois exemplos: | SegWit | 92a0db923b3a13eb576a40c4b35515aa30206cba | 03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903 | 3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001 | | SegWit | 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | 04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c | -Então, como isso tudo funciona? Depende da interpretação do código antigo como uma transação válida e do conhecimento do novo código para verificar as novas informações da "witness". +Então, como isso tudo funciona? Depende da interpretação do código antigo como uma transação válida e do conhecimento do novo código para verificar as novas informações "testemunhas". -### Lendo um script SegWit em uma máquina antiga +### Lendo um Script SegWit em uma Máquina Antiga Se um node não foi atualizado para suportar SegWit, então ele faz o seu truque usual de concatenar o ```scriptSig``` e o ```scriptPubKey```. Isso produz o seguinte: ```0 92a0db923b3a13eb576a40c4b35515aa30206cba``` (porque há apenas um ```scriptPubKey```). Ao executar isso, iremos produzir uma pilha com tudo na ordem inversa: ``` @@ -94,13 +94,13 @@ script | sta | 92a0db923b3a13eb576a40c4b35515aa30206cba | 0x ``` -Os scripts do Bitcoin são considerados bem-sucedidos se houver algo na pilha e ele for diferente de zero, portanto, os scripts SegWit são automaticamente bem-sucedidos nos nós antigos, desde que o ```scriptPubKey``` seja criado corretamente com um hash de uma pub-key diferente de zero. Isso é chamado de transação _"anyone-can-spend"_, ou no português, _"qualquer-um-pode-gastar"_, porque os nodes antigos os verificaram como corretos sem a necessidade de assinaturas. +Os scripts do Bitcoin são considerados bem-sucedidos se houver algo na pilha e ele for diferente de zero, portanto, os scripts SegWit são automaticamente bem-sucedidos nos nodes antigos, desde que o ```scriptPubKey``` seja criado corretamente com um hash de uma pub-key diferente de zero. Isso é chamado de transação _"anyone-can-spend"_, ou no português, _"qualquer-um-pode-gastar"_, porque os nodes antigos os verificaram como corretos sem a necessidade de assinaturas. -> :book: ***Os nodes antigos não podem roubar os UTXOs do SegWit?*** O SegWit foi habilitado na rede Bitcoin quando 95% dos mineradores sinalizaram que estavam prontos para começar a utilizá-lo. Isso significa que apenas 5% dos nodes naquele momento podem ter registrado transações SegWit que _qualquer-um-pode-gastar_ como sendo válidas, sem passar pelo trabalho adequado de verificação dos ```txinwitness```. Se incorporassem incorretamente um UTXO inválido que _qualquer-um-pode-gastar_ em um bloco, os outros 95% dos nodes se recusariam a validar esse bloco, e assim ele ficaria rapidamente órfão ao invés de ser adicionado a blockchain "principal". (Certamente, 51% dos nodes poderiam escolher parar de interpretar as transações SegWit corretamente, mas 51% dos nodes podem fazer qualquer coisa em uma rede de consenso, como uma blockchain). +> :book: ***Os nodes antigos não podem roubar os UTXOs do SegWit?*** O SegWit foi habilitado na rede Bitcoin quando 95% dos mineradores sinalizaram que estavam prontos para começar a utilizá-lo. Isso significa que apenas 5% dos nodes naquele momento podem ter registrado transações SegWit que _qualquer-um-pode-gastar_ como sendo válidas, sem passar pelo trabalho adequado de verificação dos ```txinwitness```. Se incorporassem incorretamente um UTXO inválido que _qualquer-um-pode-gastar_ em um bloco, os outros 95% dos nodes se recusariam a validar esse bloco, e assim ele ficaria rapidamente órfão ao invés de ser adicionado à blockchain "principal". (Certamente, 51% dos nodes poderiam escolher parar de interpretar as transações SegWit corretamente, mas 51% dos nodes podem fazer qualquer coisa em uma rede de consenso, como uma blockchain). Como os nodes antigos sempre acham que os scripts SegWit estão corretos, eles sempre os verificam, mesmo sem entender seu conteúdo. -### Lendo um script SegWit em uma máquina nova +### Lendo um Script SegWit em uma Máquina Nova Uma máquina que entende como o SegWit funciona faz exatamente as mesmas coisas que faria com um script P2PKH antigo, mas não usa o script por si só. Ela apenas sabe que precisa fazer o hash da chave pública no ```txinwitness```, verificando-a usando a chave hash após o número da versão no ```scriptPubKey``` e, em seguida, executando o ```OP_CHECKSIG``` na assinatura e na chave pública do ```txinwitness```. @@ -108,12 +108,12 @@ Portanto, é outra maneira de fazer a mesma coisa, mas sem ter os scripts embuti ## Resumo: Criando um script P2WPKH -Em grande parte, _não_ fazemos um script de um P2WPKH. Ao invés disso, o Bitcoin Core cria a transação de uma maneira diferente, colocando as informações da testemunha em um lugar diferente ao invés de um ```scriptSig``` tradicional. Isso significa que os P2WPKHs são uma digressão dos scripts de Bitcoin desta parte do livro, porque são uma expansão do Bitcoin que se distancia dos scripts tradicionais. +Em grande parte, _não_ programamos um P2WPKH. Ao invés disso, o Bitcoin Core cria a transação de uma maneira diferente, colocando as informações da testemunha em um lugar diferente ao invés de um ```scriptSig``` tradicional. Isso significa que os P2WPKHs são uma digressão dos scripts de Bitcoin desta parte do livro, porque são uma expansão do Bitcoin que se distancia dos scripts tradicionais. No entanto, o SegWit também usa os scripts do Bitcoin de maneira inteligente. Sabendo que haveria nodes que não seriam atualizados e que precisariam permanecer compatíveis com versões anteriores, os desenvolvedores criaram o formato P2WPKH de forma que gerasse um script que sempre seria validado nos nodes antigos (embora ainda tivesse aquele script fornecendo informações para os nodes novos em uma forma de um número de versão e uma chave pública com hash). Quando estamos programando usando a linha de comando, fundamentalmente não precisamos nos preocupar com isso, a não ser com saber que não encontraremos os scripts tradicionais em transações brutas do tipo SegWit (o que, novamente, era o ponto desta seção). -## O que vem depois? +## O Que Vem Depois? -Vamos continuar "Criando scripts no Bitcoin" no [Capítulo 10: Incorporando scripts do bitcoin em transações P2SH](09_4_Scripting_a_P2PKH.md). \ No newline at end of file +Vamos continuar "Programando no Bitcoin" no [Capítulo 10: Incorporando Scripts em Transações P2SH no Bitcoin](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md). \ No newline at end of file From b630588e1ddc581c680c5f615d00d4fb4c0ce48e Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Fri, 30 Jul 2021 14:14:06 -0300 Subject: [PATCH 046/155] Chapter 10 full translated --- ...ng_Bitcoin_Scripts_in_P2SH_Transactions.md | 26 +++ ..._1_Understanding_the_Foundation_of_P2SH.md | 100 ++++++++++ pt/10_2_Building_the_Structure_of_P2SH.md | 182 ++++++++++++++++++ pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md | 99 ++++++++++ pt/10_4_Scripting_a_Multisig.md | 149 ++++++++++++++ pt/10_5_Scripting_a_Segwit_Script.md | 127 ++++++++++++ pt/10_6_Spending_a_P2SH_Transaction.md | 42 ++++ 7 files changed, 725 insertions(+) create mode 100644 pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md create mode 100644 pt/10_1_Understanding_the_Foundation_of_P2SH.md create mode 100644 pt/10_2_Building_the_Structure_of_P2SH.md create mode 100644 pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md create mode 100644 pt/10_4_Scripting_a_Multisig.md create mode 100644 pt/10_5_Scripting_a_Segwit_Script.md create mode 100644 pt/10_6_Spending_a_P2SH_Transaction.md diff --git a/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md b/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md new file mode 100644 index 0000000..24b4992 --- /dev/null +++ b/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md @@ -0,0 +1,26 @@ +# Capítulo 10: Incorporando Scripts em Transações P2SH no Bitcoin + +O Script do Bitcoin desce vários níveis de abstração, permitindo que controlemos minuciosamente as condições de resgate dos fundos. Mas, como realmente incorporamos esses scripts do Bitcoin nas transações que construímos até agora? A resposta é um novo tipo de transação de Bitcoin, o P2SH. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Projetar uma transação P2SH; + * Aplicar um script P2SH Bitcoin. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Compreender o script P2SH; + * Compreender o Script Multisig; + * Compreender as várias variações dos scripts Segwit; + * Entender como gastar fundos enviados a um P2SH. + +## Tabela de conteúdo + +* [Seção 1: Entendendo a Fundação do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) +* [Seção 2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md) +* [Seção 3: Executando um script Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) +* [Seção 4: Criando scripts multisig](10_4_Scripting_a_Multisig.md) +* [Seção 5: Criando um script Segwit](10_5_Scripting_a_Segwit_Script.md) +* [Seção 6: Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md) \ No newline at end of file diff --git a/pt/10_1_Understanding_the_Foundation_of_P2SH.md b/pt/10_1_Understanding_the_Foundation_of_P2SH.md new file mode 100644 index 0000000..be5a000 --- /dev/null +++ b/pt/10_1_Understanding_the_Foundation_of_P2SH.md @@ -0,0 +1,100 @@ +# 10.1: Entendendo a Fundação do P2SH + +Sabemos que os scripts do Bitcoin podem ser usados para controlar o resgate dos UTXOs. A próxima etapa é criar os nossos próprios scripts... Mas isso requer uma técnica muito específica. + +## Conhecendo os Padrões do Bitcoin + +Aqui está a pegadinha sobre como usar scripts do Bitcoin: Por razões de segurança, a maioria dos nós do Bitcoin aceitará apenas seis tipos de transações de Bitcoin, ditas como "padrão". + +* __Pay to Public Key (P2PK)__ - O tipo de transação mais antiga e obsoleta (``` OP_CHECKSIG```) que foi substituída por uma mais segura, a P2PKH. +* __Pay to Public Key Hash (P2PKH)__ - Uma transação padrão (```OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG```) que paga para o hash de uma chave pública. +* __Pay to Witness Public Key Hash (P2WPKH)__ - O tipo mais novo de transação de chave pública. Usa apenas (```OP_0 ```) porque depende do consenso do minerador para funcionar, conforme descrito na seção [§9.5](09_5_Scripting_a_P2WPKH.md). +* __Multisig__ - Uma transação para um grupo de chaves, conforme explicado mais detalhadamente na seção [§8.4](08_4_Scripting_a_Multisig.md). +* __Null Data__ - Uma transação que não pode ser gasta (`OP_RETURN Data`). +* __Pay to Script Hash (P2SH)__ - Uma transação que paga a um script específico, conforme explicado mais detalhadamente neste capítulo. + +Então, como podemos descrever um script mais complexo do Bitcoin? A resposta está nesse último tipo de transação padrão, o P2SH. Podemos colocar qualquer tipo de script mais longo e complexo em uma transação P2SH e, contanto que sigamos as regras padrões para incorporar nosso script e resgatar os fundos, obteremos todos os benefícios do Script do Bitcoin. + +> :warning: **AVISO DE VERSÃO:** Os Scripts P2SH somente se tornaram padrão à partir do Bitcoin Core 0.10.0. Antes disso, apenas os scripts do tipo P2SH Multisigs eram permitidos. + +## Compreendendo o script P2SH + +Você já viu uma transação P2SH quando criou uma multisig na seção [§6.1: Enviando uma Transação com Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md). Embora o multisig seja um dos tipos de transação padrão, o ```bitcoin-cli``` simplifica o uso dos multisigs, incorporando-os às transações P2SH, conforme descrito mais detalhadamente na seção [§10.4: Scripting a Multisig](10_4_Scripting_a_Multisig.md). + +Então, vamos olhar mais uma vez para o ```scriptPubKey``` daquela transação multisig P2SH: +``` + "scriptPubKey": { + "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", + "hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + ] + } +``` + +O script de bloqueio tem uma aparência bastante simples: ```OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL```. Como de costume, há um grande bloco de dados no meio. Este é um hash de outro script de bloqueio que está oculto (```redeemScript```) que só será revelado quando os fundos forem resgatados. Em outras palavras, o script de bloqueio padrão para um endereço P2SH é: ```OP_HASH160 OP_EQUAL```. + +> :book: *** O que é um redemScript? *** Cada transação P2SH carrega a impressão digital de um script de bloqueio que fica oculto como um hash de 20 bytes. Quando uma transação P2SH é resgatada, o ```redeemScript``` completo (sem o hash) é incluído como parte do ```scriptSig```. O Bitcoin garantirá que o ```redeemScript``` corresponda ao hash. Então, ele realmente executa o ```redeemScript``` para ver se os fundos podem ser gastos (ou não). + +Um dos elementos interessantes das transações P2SH é que nem o remetente nem o Blockchain sabem realmente o que é o ```redemScript```! Um remetente simplesmente envia para um endereço P2SH padronizado que é marcado com um prefixo "2" e, não se preocupa com a forma como o destinatário irá recuperar os fundos. + +> :link: **TESTNET vs MAINNET:** Na testnet, o prefixo para endereços P2SH é ```2```, enquanto na mainnet, é ```3```. + +## Entendendo como construir um script P2SH + +Como o script de bloqueio está visível para uma transação P2SH e é bem simples, criar uma transação desse tipo também é um tanto quanto fácil. Em teoria. Tudo o que precisamos fazer é criar uma transação cujo script de bloqueio inclua um hash de 20 bytes do ```redeemScript```. Esse hash é feito com o padrão ```OP_HASH160``` do Bitcoin. + +> :book: ***O que é OP_HASH160?*** Uma operação padrão do hash para o Bitcoin executar um hash SHA-256 e, em seguida, um hash RIPEMD-160. + +No geral, quatro etapas são necessárias: + +1. Criar um script de bloqueio arbitrário com o script do Bitcoin; +2. Criar uma versão serializada desse script de bloqueio; +3. Executar um hash SHA-256 nesses bytes serializados; +4. Executar um hash RIPEMD-160 nos resultados desse hash SHA-256. + +Cada uma dessas etapas exige algum trabalho e, algumas delas podem ser bastante complexas. A boa notícia é que realmente não precisamos se preocupar com elas, porque são complexas o suficiente para que tenhamos uma API que faz o serviço para nós, normalmente. + +Por enquanto, forneceremos apenas uma visão geral, para que entendamos o contexto da metodologia. Na seção [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md), forneceremos uma visão mais aprofundada da criação do script, caso queiramos entender a essência desse processo. + +## Entendendo como enviar uma transação do tipo P2SH + +Então, como enviamos nossa transação P2SH? Novamente, a teoria é muito simples: + +1. Incorporamos o hash em um script ```OP_HASH160 OP_EQUAL```; +2. Traduzimos isso para um código hexadecimal; +3. Usamos esse hex como nosso ```scriptPubKey```; +4. Criamos o resto da transação. + +Infelizmente, este é lugar momento em que precisaremos usar às APIs, em grande parte porque o ```bitcoin-cli``` não fornece nenhum suporte para a criação de transações P2SH. Mas, podemos resgatá-las sem problema. + +## Entendendo como desbloquear uma transação do tipo P2SH + +O truque para resgatar uma transação P2SH é que o destinatário deve ter salvo o script secreto de bloqueio serializado que foi codificado para criar o endereço P2SH. Isso se chama ```redeemScript``` porque é o que o destinatário precisa para resgatar os fundos. + +Um ```scriptSig``` de desbloqueio para uma transação P2SH tem o seguinte formato:``` ... dados ... ```. Os ```dados``` devem ser _somente_ dados que são colocados na pilha, não operadores. O [BIP 16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki) os chama de assinaturas, mas isso não é um requisito real. + +> :warning: **AVISO:** Embora assinaturas não sejam um requisito, um script P2SH na verdade não é muito seguro se não exigir pelo menos uma assinatura nas entradas. As razões para isso estão descritas na seção [§13.1: Escrevendo scripts de quebra-cabeças](13_1_Writing_Puzzle_Scripts.md). + +Quando um UTXO é resgatado, ele é executado em duas rodadas de verificação: + +1. Primeiro, o ```redeemScript``` no ```scriptSig``` está em hash e é comparado ao hash do script no ```scriptPubKey```; +2. Se eles corresponderem, uma segunda rodada de verificação será iniciada; +3. Em segundo lugar, o ```redeemScript``` é executado usando os dados anteriores que foram colocados na pilha; +4. Se a segunda rodada de verificação _também_ for bem-sucedida, o UTXO é desbloqueado. + +Considerando que não podemos criar facilmente uma transação P2SH sem uma API, devemos ser capazes de resgatar facilmente uma transação P2SH com o ```bitcoin-cli```. Na verdade, já fizemos isso na seção [§6.2: Gastando uma Transação com Multsig] (06_2_Spending_a_Transaction_to_a_Multisig.md). O processo exato é descrito na seção [§10.6: Gastando uma transação P2SH](10_6_Spending_a_P2SH_Transaction.md), após terminarmos com todas as complexidades da criação de uma transação P2SH. + +> :warning: **AVISO:** Podemos criar uma transação perfeitamente válida com um redemScript com o hash correto, mas se o redemScript não funcionar, ou não funcionar corretamente, os fundos serão perdidos para sempre. É por isso que é importantíssimo testar os Scripts, conforme discutido na seção [§9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md). + +## Resumo: Entendendo a Fundação do P2SH + +Os scripts arbitrários do Bitcoin não são o padrão neste sistema. No entanto, podemos incorporá-los em transações padrão usando o tipo de endereço P2SH. Precisamos apenas fazer um hash do nosso script como parte do script de bloqueio, então o revelamos e executamos como parte do script de desbloqueio. Contanto que também possamos satisfazer o ```redeemScript```, o UTXO poderá ser gasto. + +> :fire: ***Qual é o poder do P2SH?*** Já sabemos o poder do script do Bitcoin, que nos permite criar Contratos Inteligentes mais complexos de todos os tipos. O P2SH é o que realmente libera esse poder, nos permitindo que incluamos o Script arbitrário do Bitcoin em transações padrão. + +## O que vem depois? + +Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md). \ No newline at end of file diff --git a/pt/10_2_Building_the_Structure_of_P2SH.md b/pt/10_2_Building_the_Structure_of_P2SH.md new file mode 100644 index 0000000..ebdb344 --- /dev/null +++ b/pt/10_2_Building_the_Structure_of_P2SH.md @@ -0,0 +1,182 @@ +# 10.2: Construindo a Estrutura de P2SH + +Na seção anterior, apresentamos uma visão geral da teoria de como criar as transações P2SH para armazenar os scripts de Bitcoin. Na prática, fazer isso é _muito mais difícil_, mas por uma questão de integridade, vamos examinar minuciosamente todos os pontos. Provavelmente, isso não é algo que faríamos sem uma API, então, se ficar muito complicado, esteja ciente de que retornaremos aos scripts originais de alto nível mais pra frente. + +## Criando um Script de Bloqueio + +Qualquer transação P2SH começa com um script de bloqueio. Esse é o assunto dos capítulos 9, 11 e 12. Podemos usar qualquer um dos métodos de script do Bitcoin descritos nestes capítulos para criar qualquer tipo de script de bloqueio, desde que o ```redeemScript``` serializado resultante tenha 520 bytes ou menos. + +> :book: ***Por que os scripts P2SH são limitados a 520 bytes?*** Como muitas coisas no Bitcoin, a resposta é a compatibilidade com as versões anteriores: Novas funcionalidades devem ser constantemente criadas dentro das antigas restrições do sistema. Nesse caso, 520 bytes é o máximo que pode ser colocado na pilha de uma vez. Como todo o redemScript é colocado na pilha como parte do processo de resgate, ele está limitado a essa quantidade. + +## Serializando um script de bloqueio da maneira mais difícil + +Depois de criar um script de bloqueio, precisamos serializá-lo antes que possamos ser inseridos no Bitcoin. Este é um processo de duas partes. Primeiro, devemos transformá-lo em um hexcode, para então transformar esse hex em binário. + +### Criando o código hexadecimal + +Criar o hexcode necessário para serializar um script é uma simples tradução, mas ao mesmo tempo, algo complexo o suficiente para ir além de qualquer script shell que provavelmente escreveremos. Esta etapa é um dos principais motivos pelos quais precisamos de uma API para criar as transações P2SH. + +Podemos criar um hexcode percorrendo nosso script de bloqueio e transformando cada elemento em um comando hexadecimal de um byte, possivelmente seguido por dados adicionais. De acordo com o guia da [página Bitcoin Wiki Script](https://en.bitcoin.it/wiki/ Roteiro): + +* Os operadores são traduzidos para o byte correspondente para esse opcode; +* As constantes 1-16 são convertidas para opcodes 0x51 a 0x61 (OP_1 a OP_16); +* A constante -1 é traduzida para opcode 0x4f (OP_1NEGATE); +* Outras constantes são precedidas por opcodes 0x01 a 0x4e (OP_PUSHDATA, com o número especificando de quantos bytes adicionar); + * Os inteiros são traduzidos em hexadecimal usando a notação de magnitude com sinal _little-endian_. + +### Traduzindo os tipos inteiros + +Os inteiros são a parte mais problemática de uma tradução de script de bloqueio. + +Primeiro, devemos verificar se o nosso número está entre -2147483647 e 2147483647, o intervalo de inteiros de quatro bytes quando o byte mais significativo é usado para assinatura. + +Em segundo lugar, precisamos traduzir o valor decimal em hexadecimal e preenchê-lo com um número par de dígitos. Isso pode ser feito com o comando ```printf```: +``` +$ integer=1546288031 +$ hex=$(printf '%08x\n' $integer | sed 's/^\(00\)*//') +$ echo $hex +5c2a7b9f +``` +Terceiro, precisamos adicionar um byte inicial adicional de ```00``` se o dígito superior for "8" ou maior, para que o número não seja interpretado como negativo. +``` +$ hexfirst=$(echo $hex | cut -c1) +$ [[ 0x$hexfirst -gt 0x7 ]] && hex="00"$hex +``` +Quarto, precisamos traduzir o hexa em _big-endian_ (byte menos significativo por último) para _little-endian_ (byte menos significativo primeiro). Podemos fazer isso com o comando ```tac```: +``` +$ lehex=$(echo $hex | tac -rs .. | echo "$(tr -d '\n')") +$ echo $lehex +9f7b2a5c +``` +Além disso, sempre precisaremos saber o tamanho dos dados que colocamos na pilha, para que possa precedê-los com o opcode adequado. Podemos apenas lembrar que cada dois caracteres hexadecimais é um byte. Ou podemos usar o comando ```echo -n``` com o pipe para ```wc -c``` e dividi-lo ao meio: +``` +$ echo -n $lehex | wc -c | awk '{print $1/2}' +4 +``` +Com todo esse trabalho, iríamos saber que poderíamos traduzir o número inteiro 1546288031 em um opcode ```04``` (para colocar quatro bytes na pilha) seguido por ```9f7b2a5c``` (a representação hexadecimal do tipo _little-endian_ de 1546288031). + +Se, ao invés disso, tivéssemos um número negativo, precisaríamos (1) fazer os cálculos no valor absoluto do número e, em seguida, (2) bit a bit - ou colocar 0x80 para nosso resultado _little-endian_ final. Por exemplo, ```9f7b2a5c```, que é 1546288031, se tornaria ```9f7b2adc```, que é -1546288031: +``` +$ neglehex=$(printf '%x\n' $((0x$lehex | 0x80))) +$ echo $neglehex +9f7b2adc +``` + +### Transformando o Hex em Binário + +Para completar nossa serialização, traduzimos o código hexadecimal em binário. Na linha de comando, isso requer apenas uma invocação simples do ```xxd -r -p```. No entanto, provavelmente desejamos fazer isso tudo junto, para também fazer o hash do script... + +## Executando o script de conversão de tipos inteiros + +Um script completo para alterar um número inteiro entre -2147483647 e 2147483647 para uma representação de magnitude assinada do tipo _little-endian_ em hexadecimal pode ser encontrado no [diretório de código src](src/10_2_integer2lehex.sh). Podemos baixar o ```integeer2lehex.sh```. + +> :warning: **AVISO:** Este script não foi verificado de forma consistente. Se formos utilizá-lo para criar scripts de bloqueio reais, precisamos nos certificar de verificar e testar os resultados. + +Precisamos nos certificar de que as permissões no script estão corretas: +``` +$ chmod 755 integer2lehex.sh +``` +Podemos então executar o script da seguinte maneira: +``` +$ ./integer2lehex.sh 1546288031 +Integer: 1546288031 +LE Hex: 9f7b2a5c +Length: 4 bytes +Hexcode: 049f7b2a5c + +$ ./integer2lehex.sh -1546288031 +Integer: -1546288031 +LE Hex: 9f7b2adc +Length: 4 bytes +Hexcode: 049f7b2adc +``` + +## Analisando um P2SH Multisig + +Para entender melhor o processo, faremos a engenharia reversa do multisig P2SH que criamos na seção [§6.1: Enviando uma Transação com Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md). Dê uma olhada no ```redeemScript``` que usamos, que agora sabemos que é a versão hexadecimal do script de bloqueio: +``` +522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae +``` +Podemos traduzir isso de volta para o script manualmente usando a [página do Bitcoin Wiki Script](https://en.bitcoin.it/wiki/Script) como uma referência. Basta olhar para um byte (dois caracteres hexadecimais) de dados por vez, a menos que nos seja dito para olhar pra mais bytes usando OP_PUSHDATA (um opcode no intervalo de 0x01 a 0x4e). + +Todo o Script será dividido da seguinte forma: +``` +52 / 21 / 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 / 21 / 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 / 52 / ae +``` +Aqui está o que as partes individuais significam: + +* 0x52 = OP_2 +* 0x21 = OP_PUSHDATA 33 bytes (hex: 0x21) +* 0x02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 = os próximos 33 bytes (hash de chave pública) +* 0x21 = OP_PUSHDATA 33 bytes (hex: 0x21) +* 0x02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 = os próximos 33 bytes (hash de chave pública) +* 0x52 = OP_2 +* 0xae = OP_CHECKMULTISIG + +Em outras palavras, esse ```redeemScript``` era uma tradução de ```2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG``` Voltaremos a este script na seção [§10.4: Criando scripts multisig](10_4_Scripting_a_Multisig.md) quando detalharmos exatamente como os multisigs funcionam dentro do paradigma P2SH. + +Se gostarmos de fazer o trabalho manual com esse tipo de tradução no futuro, podemos usar o ```decodescript bitcoin-cli```: +``` +$ bitcoin-cli -named decodescript hexstring=522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae +{ + "asm": "2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG", + "reqSigs": 2, + "type": "multisig", + "addresses": [ + "mmC2x2FoYwBnVHMPRUAzPYg6WDA31F1ot2", + "mhwZFJUnWqTqy4Y7pXVum88qFtUnVG1keM" + ], + "p2sh": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr", + "segwit": { + "asm": "0 6fe9f451ccedb8e4090b822dcad973d0388a37b4c89fd1aed485110adecab2a9", + "hex": "00206fe9f451ccedb8e4090b822dcad973d0388a37b4c89fd1aed485110adecab2a9", + "reqSigs": 1, + "type": "witness_v0_scripthash", + "addresses": [ + "tb1qdl5lg5wvakuwgzgtsgku4ktn6qug5da5ez0artk5s5gs4hk2k25szvjky9" + ], + "p2sh-segwit": "2NByn92W1vH5oQC1daY69F5sU7PEStKKQBR" + } +} +``` +É especialmente útil para verificar nosso trabalho durante a serialização. + +## Serializando um script de bloqueio da maneira mais fácil + +Quando instalamos o ```btcdeb``` na seção [§9.3](09_3_Testing_a_Bitcoin_Script.md) também instalamos o ```btcc``` que pode ser usado para serializar scripts do Bitcoin: +``` +$ btcc 2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG +warning: ambiguous input 2 is interpreted as a numeric value; use OP_2 to force into opcode +warning: ambiguous input 2 is interpreted as a numeric value; use OP_2 to force into opcode +522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae +``` +Isso é muito mais fácil do que fazer tudo na mão! + +Considere também o compilador em Python, [Transaction Script Compiler](https://github.com/Kefkius/txsc), que traduz de trás pra frente também. + +## Fazendo o hash de um script serializado + +Depois de criar um script de bloqueio e serializá-lo, a terceira etapa na criação de uma transação P2SH é fazer o hash do script de bloqueio. Conforme observado anteriormente, um hash OP_HASH160 de 20 bytes é criado por meio de uma combinação de um hash SHA-256 e um hash RIPEMD-160. O hash de um script serializado, portanto, requer dois comandos: ```openssl dgst -sha256 -binary``` que faz o hash SHA-256 e produz um binário a ser enviado no pipe, então o ```openssl dgst -rmd160``` pega o fluxo do binário, faz um RIPEMD- 160 hash e, finalmente, gera um código hexadecimal legível. + +Aqui está todo o processo, incluindo a transformação anterior do script hexadecimal em binário: +``` +$ redeemScript="522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae" +$ echo -n $redeemScript | xxd -r -p | openssl dgst -sha256 -binary | openssl dgst -rmd160 +(stdin)= a5d106eb8ee51b23cf60d8bd98bc285695f233f3 +``` + +## Criando uma transação P2SH + +Criar o hash de 20 bytes apenas fornece o hash no centro de um script de bloqueio P2SH. Ainda precisamos colocá-lo junto com os outros opcodes que criam uma transação P2SH padrão: ```OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL```. + +Dependendo de nossa API, podemos inserir isso como um ```scriptPubKey``` no estilo ```asm``` para nossa transação, ou podemos ter que traduzi-lo para o código ```hex``` também. Se tivermos que traduzir, podemos usar os mesmos métodos descritos acima para "Criar o código hexadecimal" (ou usar o ```btcc```), resultando em ```a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387```. + +Podemos observar que o ```hex scriptPubKey``` para a transação P2SH Script irá _sempre_ começar com um ```a914```, que é o ```OP_HASH160``` seguido por um ```OP_PUSHDATA``` de 20 bytes (hex: ```0x14```); e _sempre_ terminará com um ```87```, que é um ```OP_EQUAL```. Portanto, tudo o que precisamos fazer é colocar o script de resgate em hash entre esses números. + +## Resumo: Construindo a Estrutura de P2SH + +Na verdade, a criação do script de bloqueio P2SH entra ainda mais nas entranhas do Bitcoin. Embora seja útil saber como tudo isso funciona em um nível muito baixo, é mais provável que tenhamos uma API cuidando de todo o trabalho pesado para nós. Nossa tarefa será simplesmente criar o Script Bitcoin para fazer o bloqueio... Que é o tópico principal dos capítulos 9, 11 e 12. + +## O que vem depois? + +Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.3: Executando um script Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md). \ No newline at end of file diff --git a/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md b/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md new file mode 100644 index 0000000..c45b98b --- /dev/null +++ b/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md @@ -0,0 +1,99 @@ +# 10.3: Executando um script Bitcoin com P2SH + +Agora que conhecemos a teoria e a prática por trás dos endereços P2SH, estamos prontos para transformar um script de Bitcoin não padrão em uma transação real. Vamos utilizar o script de bloqueio simples da seção [§9.2: Executando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md), `OP_ADD 99 OP_EQUAL`. + +## Criando uma transação P2SH + +Para bloquear uma transação com este script, precisamos fazer o seguinte: + +1. Serializar o `OP_ADD 99 OP_EQUAL`: + 1. OP_ADD = 0x93 - uma tradução simples do opcode; + 2. 99 = 0x01, 0x63 - este opcode coloca um byte na pilha, 99 (hex: 0x63); + * Não se preocupe com a conversão porque é apenas um byte. + 3. OP_EQUAL = 0x87 - uma tradução simples do opcode; + 4. `````` = "93016387". + +``` +$ btcc OP_ADD 99 OP_EQUAL +93016387 +``` +2. Vamos salvar o `````` para referência futura como ```redeemScript```; + 1. `` = "93016387". +3. SHA-256 e RIPEMD-160 do hash do script serializado; + 1. `````` = "3f58b4f7b14847a9083694b9b3b52a4cea2569ed". +4. Produzir um script de bloqueio P2SH que inclua o ``````; + 1. ```scriptPubKey``` ="a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87". + +Podemos então criar uma transação usando o ```scriptPubKey```, provavelmente através de uma API. + +## Desbloqueando a transação P2SH + +Para desbloquear essa transação, é necessário que o destinatário produza um ```scriptSig``` que acrescente duas constantes, totalizando noventa e nove, ao script serializado:```1 98 ```. + +### Executando a primeira rodada de validação + +O processo de desbloqueio da transação P2SH começa com uma primeira rodada de validação, que nada mais é que a verificação se o script de resgate corresponde ao valor hash no script de bloqueio. + +Vamos concatenar o ```scriptSig``` e o ```scriptPubKey``` e executá-los, normalmente: +``` +Script: 1 98 OP_HASH160 OP_EQUAL +Stack: [] + +Script: 98 OP_HASH160 OP_EQUAL +Stack: [ 1 ] + +Script: OP_HASH160 OP_EQUAL +Stack: [ 1 98 ] + +Script: OP_HASH160 OP_EQUAL +Stack: [ 1 98 ] + +Script: OP_EQUAL +Running: OP_HASH160 +Stack: [ 1 98 ] + +Script: OP_EQUAL +Stack: [ 1 98 ] + +Script: +Running: OP_EQUAL +Stack: [ 1 98 True ] +``` +O script termina com um ```True``` no topo da pilha e, portanto, foi bem-sucedido... Embora haja outro fragmento abaixo dele. + +Porém, por se tratar de um script P2SH, a execução não está concluída. + +### Executando a segunda rodada de validação + +Para a segunda rodada de validação, vamos verificar se os valores no script de desbloqueio satisfazem o ```redeemScript```: Desserializando o ```redeemScript``` ("93016387" = "OP_ADD 99 OP_EQUAL") e executando-o usando os itens no ```scriptSig``` anterior para o script serializado: + +``` +Script: 1 98 OP_ADD 99 OP_EQUAL +Stack: [ ] + +Script: 98 OP_ADD 99 OP_EQUAL +Stack: [ 1 ] + +Script: OP_ADD 99 OP_EQUAL +Stack: [ 1 98 ] + +Script: 99 OP_EQUAL +Running: 1 98 OP_ADD +Stack: [ 99 ] + +Script: OP_EQUAL +Stack: [ 99 99 ] + +Script: +Running: 99 99 OP_EQUAL +Stack: [ True ] +``` +Com essa segunda validação _também_ verdadeira, o UTXO agora pode ser gasto! + +## Resumo: Executando um script Bitcoin com P2SH + +Depois de conhecer a técnica de construção dos P2SH, qualquer script pode ser embutido em uma transação Bitcoin, e depois de entender a técnica de validação do P2SH, é fácil executar os scripts em duas fases. + +## O que vem depois? + +Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.4: Criando scripts multisig](10_4_Scripting_a_Multisig.md). \ No newline at end of file diff --git a/pt/10_4_Scripting_a_Multisig.md b/pt/10_4_Scripting_a_Multisig.md new file mode 100644 index 0000000..f254bc7 --- /dev/null +++ b/pt/10_4_Scripting_a_Multisig.md @@ -0,0 +1,149 @@ +# 10.4: Criando scripts multisig + +Antes de encerrarmos esta introdução ao script P2SH, vale a pena examinar um exemplo mais realista. Desde a seção [§6.1](06_1_Sending_a_Transaction_to_a_Multisig.md), dissemos casualmente que a interface ```bitcoin-cli``` envolve nossa transação multisig em uma transação P2SH. Na verdade, esta é a metodologia padrão para a criação dos multisigs na Blockchain do Bitcoin. Veja como isso funciona, com mais detalhes. + +## Compreendendo o Código Multisig + +As transações multisig são criadas no Bitcoin usando o código ```OP_CHECKMULTISIG```. O ```OP_CHECKMULTISIG``` espera uma longa sequência de argumentos que se parece com isto: ```0 ... sigs ... ... endereços ... OP_CHECKMULTISIG```. Quando o ```OP_CHECKMULTISIG``` é executado, ele faz o seguinte: + +1. Retira o primeiro valor da pilha (``````); +2. Retira os valores "n" da pilha como endereços Bitcoin (chaves públicas com hash); +3. Retira o próximo valor da pilha (``````); +4. Retira os valores "m" da pilha como assinaturas potenciais; +5. Retire um `0` da pilha devido a um erro na codificação original; +6. Compara as assinaturas com os endereços de Bitcoin; +7. Coloca ```True``` ou ```False``` dependendo do resultado. + +Os operandos do ```OP_MULTISIG``` são tipicamente divididos, com o ```0``` e as assinaturas vindo do script de desbloqueio e o "m", "n" e endereços sendo detalhados pelo script de bloqueio. + +O requisito para que o ```0``` seja o primeiro operando para o ```OP_CHECKMULTISIG``` é uma regra de consenso. Como a versão original do ```OP_CHECKMULTISIG``` acidentalmente retirou um item extra da pilha, o Bitcoin deve seguir esse padrão para sempre, para que os scripts de resgate complexos daquele período de tempo não sejam acidentalmente quebrados, tornando fundos antigos irrecuperáveis. + +> :book: ***O que é uma regra de consenso?*** Estas são as regras que os nodes do Bitcoin seguem para trabalharem juntos. Em grande parte, eles são definidos pelo código do Bitcoin Core. Essas regras incluem muitas regras óbvias, como o limite de quantos Bitcoins são criados para cada bloco e as regras de como as transações podem ser respondidas. No entanto, eles também incluem correções para bugs que apareceram ao longo dos anos, porque uma vez que um bug foi introduzido na base de código do Bitcoin, ele deve ser continuamente suportado, para que os antigos Bitcoins não se tornem impossíveis de serem gastos. + +## Criando uma Transação Multisig Bruta + +Conforme discutido na seção [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md), os multisigs são um dos tipos de transação padrão do Bitcoin. Uma transação pode ser criada com um script de bloqueio que usa o comando ```OP_CHECKMULTISIG``` bruto e será aceito em um bloco. Esta é a metodologia clássica para usar multisigs no Bitcoin. + +Como exemplo, iremos revisitar o multisig criado na seção [§8.1](08_1_Sending_a_Transaction_with_a_Locktime.md) uma última vez e construir um novo script de bloqueio para ele usando esta metodologia. Como devemos nos lembrar, essa transação era uma multisig 2 de 2 construída a partir do ```$address1``` e ```$address2```. + +Como o script de bloqueio ```OP_CHECKMULTISIG``` requer o "m"(```2```), os endereços, e o "n"(```2```), poderíamos escrever o seguinte ```scriptPubKey```: +``` +2 $address1 $address2 2 OP_CHECKMULTISIG +``` +Se isso parece familiar, é porque é o multisig que desserializamos no [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md). +``` +2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG +``` +> **AVISO:** Para assinaturas `OP_CHECKMULTISIG` clássicas, o "n"deve ser ≤ 3 para que a transação seja padrão. + +## Desbloqueando uma Transação Multisig Bruta + +O ```scriptSig``` para um endereço multisig padrão deve então enviar os operandos ausentes para o ```OP_CHECKMULTISIG```: Um ```0``` seguido por assinaturas "m". Por exemplo: +``` +0 $signature1 $signature2 +``` + +### Executando um Script Multisig Bruto + +Para gastar um UTXO multisig, executamos o ```scriptSig``` e o ```scriptPubKey``` da seguinte maneira: +``` +Script: 0 $signature1 $signature2 2 $address1 $address2 2 OP_CHECKMULTISIG +Stack: [ ] +``` +Primeiro, colocamos todas as constantes na pilha: +``` +Script: OP_CHECKMULTISIG +Stack: [ 0 $signature1 $signature2 2 $address1 $address2 2 ] +``` +Então, o ```OP_CHECKMULTISIG``` começa a rodar. Primeiro, o "2" é retirado: +``` +Running: OP_CHECKMULTISIG +Stack: [ 0 $signature1 $signature2 2 $address1 $address2 ] +``` +Então, o "2" diz ao ```OP_CHECKMULTISIG``` para retirar dois endereços: +``` +Running: OP_CHECKMULTISIG +Stack: [ 0 $signature1 $signature2 2 ] +``` +Então, o próximo "2" é retirado: +``` +Running: OP_CHECKMULTISIG +Stack: [ 0 $signature1 $signature2 ] +``` +Então, o "2" diz ao ```OP_CHECKMULTISIG``` para retirar duas assinaturas: +``` +Running: OP_CHECKMULTISIG +Stack: [ 0 ] +``` +Então, mais um item é retirado por engano: +``` +Running: OP_CHECKMULTISIG +Stack: [ ] +``` +Depois, o ```OP_CHECKMULTISIG``` completa a operação comparando as assinaturas "m" aos endereços "n": +``` +Script: +Stack: [ True ] +``` +## Compreendendo as limitações de scripts multisig brutos + +Infelizmente, a técnica de incorporar um multisig bruto em uma transação tem algumas desvantagens notáveis: + +1. Como não há formato de endereço padrão para as multisigs, cada remetente deve: inserir um script multisig longo e complicado; ter um software que permite fazer isso e; ser confiável para não bagunçar nada. +2. Como os multisigs podem ser muito mais longos do que os scripts padrão de bloqueio, isso significa mais custos. Isso requer taxas de transação mais altas para o remetente e cria mais incômodo para cada node. + +Geralmente eram problemas com qualquer tipo de script complexo do Bitcoin, mas rapidamente se tornaram problemas muito reais quando aplicados as multisigs, que foram alguns dos primeiros scripts complexos a serem amplamente usados ​​na rede Bitcoin. As transações P2SH foram criadas para resolver esses problemas, começando em 2012. + +> :book: ***O que é um multisig P2SH?*** As Multisigs P2SH foram a primeira implementação de transações P2SH. Elas simplesmente empacotam uma transação multisig padrão em uma transação P2SH padrão. Isso permite a padronização de endereços, reduz o armazenamento de dados e, aumenta as contagens "m" e "n". + +## Criando um P2SH Multisig + +As Multisigs P2SH são a metodologia moderna para a criação de multisigs na Blockchain. Elas podem ser criadas de forma muito simples, usando o mesmo processo visto nas seções anteriores. + +### Criando a Bloqueio para o P2SH Multisig + +Para criar uma multisig P2SH, siga as etapas padrão para criar um script de bloqueio P2SH: + +1. Serializar ```2 $ address1 $ address2 2 OP_CHECKMULTISIG```; + 1. `````` = "522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98dfaed8d287f76c570e98dfaed8d287f76c570123582e38ed8287fab56c570123582e38ed8287fab56. +2. Salvar o `````` para referência futura como o redemScript; + 1. `````` = "522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae". +3. Fazer o hash SHA-256 e RIPEMD-160 do script serializado; + 1. `` = "a5d106eb8ee51b23cf60d8bd98bc285695f233f3". +4. Produzir um script de bloqueio P2SH Multisig que inclua o hash do script (```OP_HASH160 OP_EQUAL```). + 1. ```scriptPubKey``` =" a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387 ". + +Você pode criar uma transação usando o ```scriptPubKey```. + +## Desbloqueando o P2SH Multisig + +Para desbloquear essa transação multisig, é necessário que o destinatário produza um scriptSig que inclua as duas assinaturas e o ```redeemScript```. + +### Executando a primeira rodada de validação do P2SH + +Para desbloquear o multisig P2SH, primeiro vamos confirmar o script: + +1. Produzir um script de desbloqueio de ```0 $ signature1 $ signature2 ```; +2. Concatenar isso com o script de bloqueio ```OP_HASH160 OP_EQUAL```; +3. Validar o ```0 $ assinatura1 $ assinatura2 OP_HASH160 OP_EQUAL```; +4. Teremos êxito se o `````` corresponder ao ``````. + +### Executando a segunda rodada de validação do P2SH + +Em seguida, vamos executar o script multisig: + + +1. Desserializar o `````` para ```2 $ address1 $ address2 2 OP_CHECKMULTISIG```; +2. Concatenar isso com os operandos anteriores no script de desbloqueio, ```0 $ assinatura1 $ assinatura2```; +3. Validar o ```0 $ assinatura1 $ assinatura2 2 $ endereço1 $ endereço2 2 OP_CHECKMULTISIG```; +4. Teremos sucesso se os operandos cumprirem o ```redemScript``` desserializado. + +Agora sabemos como a transação multisig da seção [§6.1](06_1_Sending_a_Transaction_to_a_Multisig.md) foi realmente criada, como foi validada para ser gasta e o motivo pelo qual o ```redeemScript``` foi tão importante. + +## Resumo: Criando scripts multisig + +As multisigs são um tipo de transação padrão, mas são um pouco complicadas de serem usadas. Então, eles são regularmente incorporadas em transações P2SH, como foi o caso na seção [§6.1](06_1_Sending_a_Transaction_to_a_Multisig.md) quando criamos nossas primeiras multisigs. O resultado é mais limpo, menor e mais padronizado, porém, o mais importante, é um ótimo exemplo do mundo real de como os scripts P2SH realmente funcionam. + +## O que vem depois? + +Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.5: Crigando um script Segwit](10_5_Scripting_a_Segwit_Script.md). \ No newline at end of file diff --git a/pt/10_5_Scripting_a_Segwit_Script.md b/pt/10_5_Scripting_a_Segwit_Script.md new file mode 100644 index 0000000..04d2868 --- /dev/null +++ b/pt/10_5_Scripting_a_Segwit_Script.md @@ -0,0 +1,127 @@ +# 10.5: Criando um script Segwit +> :information_source: * NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +O segwit introduziu uma série de novas opções para tipos de endereço e também de scripts. Na seção [§9.5: Scripting a P2WPKH](09_5_Scripting_a_P2WPKH.md) explicamos como o novo tipo de endereço Bech32 variou os scripts padrão encontrados na maioria das transações tradicionais. Este capítulo examina os três outros tipos de scripts introduzidos pela atualização do Segwit: O P2SH-Segwit (que era o endereço "Segwit aninhado" de transição, quando o Segwit passou a ser usado), o P2WSH (que é o Segwit equivalente ao endereço P2SH , assim como P2WPKH é o Segwit equivalente ao endereço P2PKH) e o endereço P2WSH aninhado. + +Esta é outra situação onde realmente não teremos que nos preocupar com os nuances ao trabalhar com o ```bitcoin-cli```, mas é útil saber como tudo funciona. + +## Compreendendo um script P2SH-Segwit + +O endereço P2SH-Segwit é uma tipo em extinção. Foi basicamente uma medida paliativa enquanto o Bitcoin fazia a transição para o Segwit que permitia a um usuário criar um endereço Segwit e, em seguida, alguém como uma exchange que ainda não habilitou o Segwit ou carteira antiga financiasse esse endereço. + +Se precisarmos usar um, há uma opção para criar um endereço P2SH-Segwit usando ```getnewaddress```: +``` +$ bitcoin-cli getnewaddress -addresstype p2sh-segwit +2NEzBvokxh4ME4ahdT18NuSSoYvvhS7EnMU +``` +O endereço começa com um ```2``` (ou ```3```) revelando-o como um script. + +> :book: ***Por que os nodes antigos não podem enviar para endereços Segwit nativos?*** Na seção [§10.1](10_1_Understanding_the_Foundation_of_P2SH.md) observamos que havia um número definido de transações padrão no Bitcoin. Na verdade, não podemos bloquear uma transação com um script que não seja um desses tipos padrão. O Segwit agora é reconhecido como um desses padrões, mas um node antigo não saberá disso e, portanto, se recusará a enviar tal transação para a proteção daquele que o está enviando. Encapsular um endereço Segwit dentro de um script padrão em hash resolve o problema. + +Quando você olha para um UTXO enviado para esse endereço, pode ver que o ```desc``` é diferente, revelando um endereço WPKH envolto em um script: +``` +$ bitcoin-cli listunspent + { + "txid": "ed752673bfd4338ccf0995983086da846ad652ae0f28280baf87f9fd44b3c45f", + "vout": 1, + "address": "2NEzBvokxh4ME4ahdT18NuSSoYvvhS7EnMU", + "redeemScript": "001443ab2a09a1a5f2feb6c799b5ab345069a96e1a0a", + "scriptPubKey": "a914ee7aceea0865a05a29a28d379cf438ac5b6cd9c687", + "amount": 0.00095000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "sh(wpkh([f004311c/0'/0'/3']03bb469e961e9a9cd4c23db8442d640d9b0b11702dc0126462ac9eb88b64a4dd48))#p29e839h", + "safe": true + } +``` +Mais importante ainda, é a presença de um ```redeemScript```, que decodifica para ```OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a```. Isso deve parecer familiar, porque é um ```OP_0``` seguido por um hexcode de 20 bytes de um hash de chave pública. Em outras palavras, um P2SH-SegWit é apenas um SegWit ```scriptPubKey``` preso em um script. Isso é tudo que há para fazer. Corresponde precisamente ao modo como os multisigs modernos são um multsig preso em um P2SH, conforme discutido na seção [§10.4: Criando scripts multisig](10_4_Scripting_a_Multisig.md). + +A transação bruta revela um pouco mais de detalhes quando olhamos para o ```vout``` ```1```: +``` +$ hex=$(bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa" | jq -r '.hex') +$ bitcoin-cli decoderawtransaction $hex +{ + "txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa", + "hash": "6866490b16a92d68179e1cf04380fd08f16ec80bf66469af8d5e78ae624ff202", + "version": 2, + "size": 249, + "vsize": 168, + "weight": 669, + "locktime": 1780788, + "vin": [ + { + "txid": "4779bb137ddbcaf796f905e264554b1ec28c0f3ab4538ca02eac5099bfc3fc1e", + "vout": 0, + "scriptSig": { + "asm": "0014c4ea10874ae77d957e170bd43f2ee828a8e3bc71", + "hex": "160014c4ea10874ae77d957e170bd43f2ee828a8e3bc71" + }, + "txinwitness": [ + "3044022025ee4fd38e6865125f7c315406c0b3a8139d482e3be333727d38868baa656d3d02204b35d9b5812cb85894541da611d5cec14c374ae7a7b8ba14bb44495747b5715301", + "033cae26cb3fa063c95e2c55a94bd04ab9cf173104555efe448b1bfc3a68c8f873" + ], + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.00095000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9" + ] + } + }, + { + "value": 0.01063793, + "n": 1, + "scriptPubKey": { + "asm": "OP_HASH160 b780fc2e945bea71b9ee2d8d2901f00914a25fbd OP_EQUAL", + "hex": "a914b780fc2e945bea71b9ee2d8d2901f00914a25fbd87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N9yWARt5E3TQsX2RjsauxSZaEZVhinAS4h" + ] + } + } + ] +} +``` +Isso confirma que este é apenas um P2SH normal, bloqueado por ```" OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG "```. É quando o script de resgate é executado que a mágica ocorre. Assim como com um P2WPKH, um node antigo verá ```OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a``` e verificará automaticamente, enquanto um novo node verá isso, saberá que é um P2WPKH e, assim, irá verificar o ```witness```. Podemos consultar isso na seção [§9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md). + +> :book: ***Quais são as desvantagens das transações Segwit aninhadas?*** Elas são maiores do que as transações Segwit nativas, então temos algumas das vantagens do Segwit, mas não todas. + +## Compreendendo um script P2WSH + +Ao contrário, as transações P2WSH devem ser cada vez mais utilizadas, uma vez que são a substituição do Segwit nativa para o P2SH, oferecendo todas as mesmas vantagens de tamanho de bloco que foram criadas com transações Segwit P2WPKH nativas. + +Este é um exemplo de endereço P2WSH: +[https://mempool.space/pt/testnet/address/tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7](https://blockstream.info/testnet/address/tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7). + +Os detalhes mostram que um UTXO enviado para este endereço está bloqueado com um ```scriptPubKey``` como este: +``` +OP_0 OP_PUSHDATA (32 bytes) 1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262 +``` + +O funcionamento é exatamente como um endereço P2WPKH, a única diferença é que ao invés de um hash de chave pública de 20 bytes, o UTXO inclui um hash de script de 32 bytes. Assim como com um P2WPKH, os nodes antigos apenas verificam isso, enquanto os novos nodes reconhecem que se trata de um P2WSH e verificam internamente o script conforme descrito nas seções anteriores, mas usando os dados da ```witness```, que agora incluem o script de resgate. + +Há também mais uma variante, um script P2WSH embutido em um script P2SH, que funciona muito como o P2SH-Segwit descrito acima, mas para scripts P2WSH aninhados. + +## Resumo: Criando um script Segwit + +Existem dois tipos de scripts P2SH relacionados ao Segwit. + +O endereço P2SH-Segwit é um endereço Segwit aninhado que incorpora o Segwit ```scriptPubkey``` simples dentro de um Script, assim como multisigs são incorporados nos scripts hoje em dia: A chave do tipo Segwit é desenrolada e então analisada normalmente em uma máquina que entende o Segwit . O objetivo é a compatibilidade com versões anteriores dos nodes antigos que, de outra forma, não seriam capazes de enviar saldos para endereços Segwit nativos. + +O endereço P2WSH é uma variante Segwit de P2SH, assim como P2WPKH é uma variante Segwit de P2WSH. Ele funciona com a mesma lógica e é identificado por ter um hash de 32 bytes em vez de um hash de 20 bytes. O objetivo é estender as vantagens do Segwit a outros tipos de scripts. + +## O que vem depois? + +Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.6:Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md). \ No newline at end of file diff --git a/pt/10_6_Spending_a_P2SH_Transaction.md b/pt/10_6_Spending_a_P2SH_Transaction.md new file mode 100644 index 0000000..6b85b33 --- /dev/null +++ b/pt/10_6_Spending_a_P2SH_Transaction.md @@ -0,0 +1,42 @@ +# 10.6: Gastando uma Transação P2SH + +Antes de encerrarmos esta visão geral das transações P2SH, vamos abordar como gastá-las. Esta seção é principalmente uma visão geral, referindo-se a uma seção anterior onde _já_ gastamos uma transação P2SH. + +## Usando o script de resgate + +Como vimos na seção [§6.2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md), gastar uma transação P2SH tem tudo a ver com ter aquela versão serializada do script de bloqueio, o chamado _redeemScript_. Portanto, o primeiro passo para poder gastar uma transação P2SH é ter certeza de salvar o _redeemScript_ antes de fornecer o endereço P2SH para todos. + +### Coletando as variáveis + +Como os endereços P2SH são diferentes dos endereços multisig especiais e Segwit aninhados não estão integrados no ```bitcoin-cli```, não haverá atalhos para gastarmos o P2SH como vimos na seção [§6.3: Enviando e Gastando um Multisig de Maneira Automatizada](6_3_Sending_an_Automated_Multisig.md) . Vamos precisar coletar todas as variáveis mais complexas por conta própria! + +Isso significa que precisaremos coletar: + + * O ```hex``` do ```scriptPubKey``` para a transação que estamos gastando; + * O ```redeemScript``` serializado; + * Quaisquer chaves privadas, já que assinaremos manualmente; + * Todos os ```txids```,```vouts``` e ```endereços``` regulares que precisarmos. + +## Criando a transação + +Como vimos na seção §6.2, a criação de uma transação é bem padrão: +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''') +$ echo $rawtxhex +020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b10000000000ffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 +``` +No entanto, a assinatura requer a inserção de informações extras para o (1) ```scriptPubKey```; (2) o ```redeemScript``` e; (3) quaisquer chaves privadas necessárias. + +Aqui está o exemplo de como fazer isso para aquele multisig P2SH integrado da seção §6.2: +``` +$ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR"]' +``` +Com qualquer outro tipo de P2SH, incluiremos um ```redeemscript``` diferente, mas, fora isso, a prática é exatamente a mesma. A única diferença é que depois de dois capítulos de trabalho com scripts agora entendemos o que é o ```scriptPubKey``` e o que é o ```redeemScript```, então, esperançosamente, o que eram elementos misteriosos a quatro capítulos atrás, agora não são tão misteriosos assim. + +## Resumo: Gastando uma Transação P2SH + +Já gastamos um P2SH no Capítulo 6, quando reenviamos uma transação multsig da maneira mais difícil, que exigia alinhar as informações do ```scriptPubKey``` e do ```redeemScript```. Agora sabemos que o ```scriptPubKey``` é um script de bloqueio P2SH padronizado, enquanto o ```redeemScript``` corresponde a um hash nesse script de bloqueio e que precisamos ser capazes de executá-lo com as variáveis ​​adequadas para receber um resultado ```True```. Mas além disso, não há nada de novo ao gastar uma transação P2SH, porque já fizemos isso! + +## O que vem depois? + +Vamos avançar com os "Script do Bitcoin" no [Capítulo 11: Aumentando o poder do timelock com scripts do Bitcoin](11_0_Empowering_Timelock_with_Bitcoin_Scripts.md). \ No newline at end of file From 05374400c03a56a04371142ad6e5579fe04b6603 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Wed, 4 Aug 2021 11:05:39 -0300 Subject: [PATCH 047/155] Translation Concluded in Chapter11 --- ...mpowering_Timelock_with_Bitcoin_Scripts.md | 23 +++ pt/11_1_Understanding_Timelock_Options.md | 49 ++++++ pt/11_2_Using_CLTV_in_Scripts.md | 154 ++++++++++++++++++ pt/11_3_Using_CSV_in_Scripts.md | 149 +++++++++++++++++ 4 files changed, 375 insertions(+) create mode 100644 pt/11_0_Empowering_Timelock_with_Bitcoin_Scripts.md create mode 100644 pt/11_1_Understanding_Timelock_Options.md create mode 100644 pt/11_2_Using_CLTV_in_Scripts.md create mode 100644 pt/11_3_Using_CSV_in_Scripts.md diff --git a/pt/11_0_Empowering_Timelock_with_Bitcoin_Scripts.md b/pt/11_0_Empowering_Timelock_with_Bitcoin_Scripts.md new file mode 100644 index 0000000..935a8d7 --- /dev/null +++ b/pt/11_0_Empowering_Timelock_with_Bitcoin_Scripts.md @@ -0,0 +1,23 @@ + +# Capítulo 11: Expandindo o timelock com scripts do Bitcoin + +O recurso ```nLockTime``` da seção [§8.1](08_1_Sending_a_Transaction_with_a_Locktime.md) foi apenas o começo dos Timelocks. Quando começamos a escrever scripts do Bitcoin, dois opcodes de timelocks ficam disponíveis. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Decidir qual Timelock usar; + * Criar scripts com CLTV; + * Criar scripts com CSV. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Compreender as diferenças entre os diferentes timelocks; + * Gerar tempos relativos. + +## Índice + +* [Seção 1: Compreendendo as Opções de Timelocks](11_1_Understanding_Timelock_Options.md) +* [Seção 2: Usando o CLTV nos Scripts](11_2_Using_CLTV_in_Scripts.md) +* [Seção 3: Usando o CSV nos Scripts](11_3_Using_CSV_in_Scripts.md) \ No newline at end of file diff --git a/pt/11_1_Understanding_Timelock_Options.md b/pt/11_1_Understanding_Timelock_Options.md new file mode 100644 index 0000000..5c4c109 --- /dev/null +++ b/pt/11_1_Understanding_Timelock_Options.md @@ -0,0 +1,49 @@ +# 11.1: Compreendendo as Opções de Timelocks + +Na seção [§8.1: Enviando uma transação com Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md), o ```nLocktime``` ofereceu uma ótima opção inicial para bloquear as transações para que não pudessem ser gastas até algum ponto no futuro, com base no tempo (data/hora) ou na altura do bloco. Mas, essa não é a única maneira de colocar um timelock em uma transação. + +## Compreendendo as limitações do nLockTime + +O ```nLockTime``` é uma maneira simples e poderosa de bloquear uma transação, mas possui algumas limitações: + +1. **Sem divisões.** O `nLocktime` bloqueia toda a transação; +2. **Sem rede.** A maioria dos nodes modernos não aceita um ```nLockTime``` na mempool até que esteja na hora ou próximo para ser finalizada; +3. **Sem Scripts.** O uso simples e original do ```nLockTime``` não permitia que fosse usado em Scripts; +4. **Sem proteção.** O ```nLockTime``` permite que os fundos sejam gastos com uma transação diferente e não bloqueada. + +O último item costumava ser o _dealbreaker_ para o ```nLockTime```. Isso evitou que uma transação fosse gasta, mas não impediu que os fundos fossem usados em uma transação diferente. Então, haviam certos usos, mas todos dependiam de confiança. + +## Compreendendo as possibilidades dos scripts de Timelock + +Nos últimos anos, o Bitcoin Core foi expandido para permitir a manipulação dos timelocks no nível do opcode com os _OP_CHECKLOCKTIMEVERIFY_ (CLTV) e _OP_CHECKSEQUENCEVERIFY_ (CSV). Ambos trabalham sob uma nova metodologia que fortalece ainda mais o Bitcoin. + +_Eles são opcodes._ Por serem opcodes, o CLTV e o CSV podem ser usados ​​como parte de condições de resgate mais complexas. Na maioria das vezes, eles estão vinculados às condicionais que ireimos descrever no próximo capítulo. + +_Eles bloqueiam as saídas._ Por serem opcodes incluídos nas transações como parte de uma ```sigPubKey```, eles apenas bloqueiam aquela saída única. Isso significa que as transações são aceitas na rede Bitcoin e que os UTXOs usados ​​para financiar essas transações são gastos. Não há como voltar atrás em uma transação bloqueada por tempo com o CLTV ou o CSV como acontece com um ```nLockTime``` vazio. Gastar novamente o UTXO resultante requer que as condições do timelock sejam atendidas. + +Aqui está um ponto importante sobre a utilização dos timelocks: _Eles são bloqueios de mão única._ Os bloqueios de tempo são projetados para desbloquear fundos em um determinado momento. Eles não podem bloquear novamente um fundo: Uma vez que um fundo bloqueado por tempo está disponível, ele ficará disponível para ser gasto. + +### Compreendendo as possibilidades do CLTV + +O _OP_CHECKLOCKTIMEVERIFY_ ou CLTV é uma combinação para o recurso clássicos usando o ```nLockTime```, mas no novo paradigma baseado em opcode. Ele permite que um UTXO se torne acessível em um determinado momento ou em uma determinada altura de bloco. + +O CLTV foi detalhado pela primeira vez no [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki). + +### Compreendendo as possibilidades do CSV + +O _OP_CHECKSEQUENCEVERIFY_ ou CSV depende de um novo tipo de "locktime relativo", que é definido no campo _nSequence_ da transação. Como de costume, ele pode ser definido como uma data/hora ou uma altura de bloco. Se for definido como um tempo "n", então uma transação bloqueada em um tempo relativo pode ser gasta "n x 512" segundos depois que o UTXO foi minerado, e se for definido como um bloco "n", então uma transação bloqueada em tempo relativo pode ser gasta em "n" blocos depois que o UTXO foi minerado. + +O uso do ```nSequence``` para um bloqueio de tempo relativo foi detalhado primeiramente no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki), e o opcode CSV foi adicionado no [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki). + +## Resumo: Compreendendo as Opções de Timelocks + +Agora possuímos quatro opções de Timelocks: + +* ```nLockTime``` para manter uma transação fora do blockchain até um dado momento específico; +* ```nSequence``` para manter uma transação fora do blockchain até um dado momento relativo; +* CLTV para tornar um UTXO impossível de ser gasto até uma data/hora específica; +* CSV para tornar um UTXO impossível de ser gasto até uma data/hora ou altura do bloco relativa. + +## O Que Vem Depois? + +Vamos continuar "Aumentando o poder do timelock com scripts do Bitcoin" na seção [§11.2: Usando o CLTV nos Scripts](11_2_Using_CLTV_in_Scripts.md). \ No newline at end of file diff --git a/pt/11_2_Using_CLTV_in_Scripts.md b/pt/11_2_Using_CLTV_in_Scripts.md new file mode 100644 index 0000000..d8ee5cd --- /dev/null +++ b/pt/11_2_Using_CLTV_in_Scripts.md @@ -0,0 +1,154 @@ +# 11.2: Usando o CLTV nos Scripts + +O ```OP_CHECKLOCKTIMEVERIFY``` (ou CLTV) é o complemento natural para o ```nLockTime```. Ele muda a ideia de bloquear transações por um tempo absoluto ou altura de bloco para o reino dos opcodes, permitindo o bloqueio de UTXOs individuais. + +> :warning: **AVISO DE VERSÃO:** O CLTV ficou disponível no Bitcoin Core 0.11.2, mas deve ser amplamente implementado neste momento. + +## Lembrando do nLockTime + +Antes de nos aprofundarmos no CLTV, devemos primeiro lembrar do funcionamento do ```nLockTime```. + +Conforme detalhado na seção [§8.1:Enviando uma transação com Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md), o locktime é habilitado pela configuração de duas variáveis, o ```nLockTime``` e o ```nSequence```. O ```nSequence``` deve ser definido para ser menor do que 0xffffffff (geralmente: 0xffffffff-1), então o ```nLockTime``` será interpretado da seguinte forma: + +* Se o ```nLockTime``` for inferior a 500 milhões, será interpretado como uma altura de bloco; +* Se o ```nLockTime``` for 500 milhões ou mais, será interpretado como um carimbo de data/hora UNIX. + +Uma transação com ```nLockTime``` definida não pode ser gasta (ou mesmo colocada na blockchain) até que a altura do bloco ou a data/hora sejam alcançados. Nesse ínterim, a transação pode ser cancelada gastando-se qualquer um dos UTXOs que constituem a transação. + +## Compreendendo o Opcode CLTV + +O ```OP_CHECKLOCKTIMEVERIFY``` funciona dentro do mesmo paradigma de altura de blocos ou tempos UNIX, ambos absolutos, mas é executado como parte de um Script do Bitcoin. Ele lê um argumento, que pode ser os dois já mencionados. Por meio de uma metodologia um tanto complicada, ele compara esse argumento ao tempo atual. Se for muito cedo, o script irá falhar, porém, se a condição de tempo for atendida, o script continua. + +Como o CLTV é apenas parte de um script (e presumivelmente parte de uma transação P2SH), uma transação CLTV não é mantida fora da mempool como uma transação ```nLockTime```. Logo, assim que for verificado, ele vai para a blockchain e os fundos são considerados gastos. O truque é que todas as saídas que foram bloqueadas com o CLTV não estão disponíveis para _serem gastas_ até que o CLTV permita. + +### Compreendendo um CLTV de tempo absoluto + +É assim que o ```OP_CHECKLOCKTIMEVERIFY``` seria utilizado para verificar o locktime de 24 de maio de 2017: +``` +1495652013 OP_CHECKLOCKTIMEVERIFY +``` +Mas geralmente vamos descrever isso em uma abstração: +``` + OP_CHECKLOCKTIMEVERIFY +``` +Ou assim: +``` + OP_CHECKLOCKTIMEVERIFY +``` + +### Compreendendo um CLTV de altura de bloco absoluta + +É assim que o ```OPCHECKLOCKTIMEVERIFY``` compararia a uma altura de bloqueio alcançada no dia 24 de maio de 2017: +``` +467951 OP_CHECKLOCKTIMEVERIFY +``` +Mas geralmente vamos abstrair assim: +``` + OP_CHECKLOCKTIMEVERIFY +``` + +### Entendendo como o CLTV realmente funciona + +A explicação acima é suficiente para usar e entender o CLTV. No entanto, o [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) apresenta todos os seguintes detalhes. + +Um script de bloqueio só permitirá que uma transação reenvie um UTXO bloqueado com um CLTV se o ```OP_CHECKLOCKTIMEVALUE``` verificar todas as seguintes condições: + +* O campo ```nSequence``` deve ser definido como sendo menor do que 0xffffffff, geralmente 0xffffffff-1 para evitar conflitos com os timelocks relativos; +* CLTV deve retirar um operando da pilha e deve ser 0 ou maior. +* Tanto o operando da pilha quanto o ```nLockTime``` devem estar acima ou abaixo de 500 milhões, para representar o mesmo tipo de locktime absoluto; +* O valor ```nLockTime``` deve ser maior ou igual ao operando da pilha. + +Portanto, a primeira coisa a se notar aqui é que o ```nLockTime``` ainda é utilizado com o CLTV. Para ser mais preciso, ele é necessário na transação que tenta _gastar novamente_ um UTXO com o temporizador CLTV. Isso significa que não faz parte dos requisitos do script. É apenas o cronômetro que é usado para liberar os fundos, _como definido no script_. + +Isso é gerenciado por meio de um entendimento inteligente de como o ```nLockTime``` funciona: Um valor para o ```nLockTime``` deve sempre ser escolhido sendo menor ou igual ao tempo presente (ou altura do bloco), de modo que a transação de gasto possa ser colocada na blockchain. Porém, devido aos requisitos do CLTV, também deve ser escolhido um valor maior ou igual ao operando do CLTV. A união desses dois conjuntos é ```NULL``` até que o tempo presente corresponda ao operando CLTV. Posteriormente, qualquer valor pode ser escolhido entre o operando do CLTV e o tempo atual. Normalmente, apenas iríamos configurar para a hora atual (ou para o bloco atual). + +## Escrevendo um Script CLTV + +O ```OP_CHECKLOCKTIMEVERIFY``` inclui um ```OP_VERIFY```, o que significa que ele irá parar imediatamente o script se nossa verificação não for bem-sucedida. Ele tem uma outra peculiaridade: Ao contrário da maioria dos comandos de "verificação", ele deixa o que está sendo testado na pilha (apenas no caso de querermos fazer qualquer outra verificação no tempo). Isso significa que um ```OP_CHECKLOCKTIMEVERIFY``` geralmente é seguido por um ```OP_DROP``` para limpar a pilha. + +O seguinte script de bloqueio simples pode ser usado para transformar uma saída P2PKH em uma transação P2PKH bloqueada por tempo: +``` + OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +``` + +### Codificando um script CLTV + +Obviamente, como acontece com quaisquer scripts Bitcoin complexos, este script CLTV seria realmente codificado em um script P2SH, conforme explicado na seção [§10.1: Entendendo a Fundação do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) e na [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md). + +Supondo que o `````` fosse o número inteiro "1546288031" (little-endian hex: 0x9f7b2a5c) e o `````` fosse "371c20fb2e9899338ce5e99908e64fd30b789313", este ```redeemScript``` seria construído assim: +``` +OP_PUSHDATA (4 bytes) 0x9f7b2a5c OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_PUSHDATA (20 bytes) 0x371c20fb2e9899338ce5e99908e64fd30b789313 OP_EQUALVERIFY OP_CHECKSIG +``` +O que se traduz em hexadecimal como sendo: +``` +04 9f7b2a5c b1 75 76 a9 14 371c20fb2e9899338ce5e99908e64fd30b789313 88 ac +``` +Ou se preferir: +``` +$ btcc 0x9f7b2a5c OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 0x371c20fb2e9899338ce5e99908e64fd30b789313 OP_EQUALVERIFY OP_CHECKSIG +049f7b2a5cb17576a914371c20fb2e9899338ce5e99908e64fd30b78931388ac +``` +O RPC ```decodescript``` pode verificar se acertamos a decodificação: +``` +{ + "asm": "1546288031 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 371c20fb2e9899338ce5e99908e64fd30b789313 OP_EQUALVERIFY OP_CHECKSIG", + "type": "nonstandard", + "p2sh": "2MxANZMPo1b2jGaeKTv9rwcBEiXcXYCc3x9", + "segwit": { + "asm": "0 07e55bf1eaedf43ec52af57b77ad7330506c209a70d17fa2e1853304aa8e4e5b", + "hex": "002007e55bf1eaedf43ec52af57b77ad7330506c209a70d17fa2e1853304aa8e4e5b", + "reqSigs": 1, + "type": "witness_v0_scripthash", + "addresses": [ + "tb1qqlj4hu02ah6ra3f274ah0ttnxpgxcgy6wrghlghps5esf25wfedse4yw4w" + ], + "p2sh-segwit": "2N4HTwMjVdm38bdaQ5h3X3VktLY74D2qBoK" + } +} +``` + +Não vamos mostrar continuamente como todos os Scripts do Bitcoin são codificados em transações P2SH, ao invés disso, ofereceremos estes atalhos: Quando descrevemos um script, ele será um ```redeemScript```, que normalmente seria serializado e codificado em um script de bloqueio e serializado no script de desbloqueio. Quando mostramos um procedimento de desbloqueio, será a segunda rodada de validação, seguindo a confirmação do hash do script de bloqueio. + +## Gastando um UTXO do CLTV + +In the case of the above example, the following unlocking script would suffice, provided that `nLockTime` was set to somewhere in advance of the `` date, and provided it was indeed at least ``: +No caso do exemplo acima, o script de desbloqueio abaixo seria suficiente, desde que o ```nLockTime``` fosse definido em algum lugar antes da data ``````, e desde que o momento atual fosse, de fato, pelo menos ``````: +``` + +``` + +### Executando um script CLTV + +Para executar o Script, primeiro devemos concatenar os scripts de desbloqueio e bloqueio: +``` +Script: OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] +``` +As três constantes seriam colocadas na pilha: +``` +Script: OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] +``` +Então, o ```OP_CHECKLOCKTIMEVERIFY``` é executado. Ele encontra algo na pilha e verifica se o ```nSequence``` não é 0xffffffff. Finalmente, ele compara o `````` com o ```nLockTime```. Se ambos são o mesmo tipo de representação e se ```nLockTime ≥ ```, então ele é processado com sucesso (caso contrário, termina o script): +``` +Script: OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: OP_CHECKLOCKTIMEVERIFY +Stack: [ ] +``` +Então, o ```OP_DROP``` se livra daquele `````` restante: +``` +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: OP_DROP +Stack: [ ] +``` +Finalmente, o restante do script é executado, que é uma verificação normal de uma assinatura e chave pública. + +## Resumo: Usando o CLTV nos Scripts + +O ```OP-CHECKLOCKTIMEVERIFY``` é um opcode simples que olha para um único argumento, o interpreta como uma altura de bloco ou timestamp UNIX, e só permite que o UTXO seja desbloqueado se aquela altura de bloco ou timestamp UNIX estiver no passado. Definir o ```nLockTime``` na transação de gastos é o que permite ao Bitcoin fazer este cálculo. + +> :fire: ***Qual é o poder do CLTV?*** Já vimos que os tempos de bloqueio simples eram uma das bases dos Contratos Inteligentes. O CLTV dá o próximo passo. Agora podemos garantir que um UTXO não pode ser gasto antes de um certo tempo _e_ podemos garantir que ele também não será gasto. Em sua forma mais simples, isso poderia ser usado para criar um fundo que alguém só poderia ter acesso aos 18 anos ou um fundo de aposentadoria que só poderia ser acessado quando fizesse 50 anos. No entanto, o verdadeiro poder vem quando combinado com condicionais, onde apenas o CLTV apenas é ativado em certas situações. + +## O Que Vem Depois? + +Vamos continuar "Aumentando o poder do timelock com scripts do Bitcoin" na seção [§11.3: Usando o CSV nos Scripts](11_3_Using_CSV_in_Scripts.md). \ No newline at end of file diff --git a/pt/11_3_Using_CSV_in_Scripts.md b/pt/11_3_Using_CSV_in_Scripts.md new file mode 100644 index 0000000..1efbdd7 --- /dev/null +++ b/pt/11_3_Using_CSV_in_Scripts.md @@ -0,0 +1,149 @@ +# 11.3: Usando o CSV nos Scripts + +O ```nLockTime``` e o ```OP_CHECKLOCKTIMEVERIFY``` (ou CLTV) são apenas um lado da equação do timelock. Do outro lado estão o ```nSequence``` e o ```OP_CHECKSEQUENCEVERIFY```, que podem ser usados ​​para verificar tempos relativos ao invés de tempos absolutos. + +> :warning: **AVISO DE VERSÃO:** O CSV está disponível no Bitcoin Core 0.12.1. + +## Compreendendo o nSequence + +Cada entrada em uma transação tem um valor ```nSequence``` (ou se preferirmos ```sequence```). Tem sido uma ferramenta principal para melhorias do Bitcoin, conforme discutido anteriormente na seção [§5.2: Reenviando uma transação com o RBF](05_2_Resending_a_Transaction_with_RBF.md) e na [§8.1 Enviando uma transação com Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md), onde o usamos para sinalizar o RBF e o ```nLockTime```, respectivamente. No entanto, há mais um uso para o ```nSequence```, descrito no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Podemos usá-lo para criar um timelock relativo em uma transação. + +Um timelock relativo é um bloqueio colocado em uma entrada específica de uma transação e que é calculado em relação à data de mineração do UTXO que está sendo usado na entrada. Por exemplo, se um UTXO foi minerado no bloco #468260 e uma transação foi criada onde a entrada para aquele UTXO foi uma ```nSequence``` de 100, então a nova transação não poderia ser minerada até o bloco #468360. + +Simples assim! + +> :information_source: **NOTA - SEQUÊNCIA:** Este é o terceiro uso do ```nSequence``` no Bitcoin. Qualquer valor no ```nSequence``` sem o conjunto de 32 bits (1 << 31), ou seja, do 0x00000001 a 0x7ffffffff, será interpretado como um bloqueio de tempo relativo se a ```nVersion ≥ 2``` (que é o padrão do Bitcoin Core depois da versão 0.14.0). Devemos ter cuidado para garantir que os timelocks relativos não entrem em conflito com os outros dois usos de ```nSequence```, que é para sinalizar o ```nTimeLock``` e o RBF. O ```nTimeLock``` geralmente define um valor como sendo 0xffffffff-1, onde um timelock relativo não é permitido e, o RBF geralmente define um valor de "1", onde um bloqueio de tempo relativo é irrelevante, porque define um timelock de 1 bloco. + +> De maneira geral, podemos lembrar do seguinte: Com um valor ```nVersion``` de 2, um valor ```nSequence``` que vai de 0x00000001 a 0x7fffffff permite um timelock relativo, o RBF e o ```nTimeLock```. Um valor ```nSequence``` de 0x7fffffff a 0xffffffff-2 permite o RBF e o ```nTimeLock```. Um valor ```nSequence``` de 0xffffffff-1 permite apenas o ```nTimeLock```. Um valor ```nSequence``` de 0xffffffff não permite nenhum dos três. Um ```nVersion``` pode ser definido como 1 para não permitir bloqueios de tempo relativos para qualquer valor do ```nSequence```. Ufa! + +### Criando um CSV de Tempo de Bloco Relativo + +O formato para usar o ```nSequence``` para representar bloqueios de tempo relativos é definido no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) e é um pouco mais complexo do que apenas inserir um número qualquer, como fizemos no ```nTimeLock```. Ao invés disso, as especificações BIP dividem o número de quatro bytes em três partes: + +* Os primeiros dois bytes são usados ​​para especificar um timelock relativo; +* O 23º bit é usado para sinalizar positivamente se o bloqueio se refere a um tempo ou a uma altura de bloco; +* O 32º bit é usado para sinalizar positivamente se os timelocks relativos estão desativados. + +Com isso dito, a construção de um timelock relativo baseado em bloco é bem fácil, porque os dois bits sinalizados são definidos como ```0```, então apenas precisamos definir o ```nSequence``` para um valor entre 1 e 0xffff (65535). A nova transação pode ser extraída naquele número de blocos depois que o UTXO associado foi extraído. + +### Criando um CSV de Tempo Relativo + +Podemos definir o ```nSequence``` como um tempo relativo, onde o bloqueio dura 512 segundos vezes o valor do ```nSequence```. + +A fim de fazer isso, precisamos: + +1. Decidir o quanto no futuro definiremos o nosso bloqueio de tempo relativo; +2. Converter isso para segundos; +3. Dividir por 512; +4. Arredondar esse valor para cima ou para baixo e definí-lo como ```nSequence```; +5. Definir o 23º bit como verdadeiro. + +Para definir um período de 6 meses no futuro, devemos primeiro calcular da seguinte forma: +``` +$ seconds=$((6*30*24*60*60)) +$ nvalue=$(($seconds/512)) +``` +Em seguida, transformar isso em hexadecimal: +``` +$ hexvalue=$(printf '%x\n' $nvalue) +``` +Finalmente, definimos o 23º bit do valor hexadecimal que criamos: +``` +$ relativevalue=$(printf '%x\n' $((0x$hexvalue | 0x400000))) +$ echo $relativevalue +4224679 +``` +Se convertermos de volta, teremos o valor de 4224679 = 10000000111011010100111. O 23º dígito é definido como "1", enquanto os primeiros 2 bytes, 0111011010100111, são convertidos em 76A7 em hexadecimal ou 30375 em decimal. Multiplicando isso por 512, teremos 15,55 milhões de segundos, o que de fato é 180 dias. + +## Criando uma transação com um timelock relativo + +Então desejamos criar uma transação simples com um timelock relativo? Tudo que precisamos fazer é emitir uma transação onde o ```nSequence``` de uma entrada é definido como mostramos acima: Com o ```nSequence``` para essa entrada definido de forma que os primeiros dois bytes definam o timelock, o 23º bit define o tipo do timelock, e o 32º bit é definido como sendo falso. + +Vamos enviar a transação e veremos que ela não pode ser legalmente minerada até que blocos ou tempo suficientes tenham passado além do tempo que o UTXO foi minerado. + +Exceto que praticamente ninguém faz isso. As definições do [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) para ```nSequence``` foram incorporadas ao Bitcoin Core ao mesmo tempo que o [BIP 112](https: //github.com/bitcoin/bips/blob/master/bip-0112.mediawiki), que descreve o opcode CSV e o ```nSequence``` equivalente ao opcode CLTV. Assim como o CLTV, o CSV oferece recursos aprimorados. Portanto, quase todo o uso dos timelocks relativos foi com o opcode CSV, não com o valor ```nSequence``` bruto por si só. + +| | Absolute Timelock | Relative Timelock | +|:--------------------:|-------------------|-------------------| +| **Transaction Bloqueada** | nTimeLock | nSequence | +| **Saída do Bloqueio** | OP_CHECKLOCKTIMEVERIFY| OP_CHECKSEQUENCEVERIFY | + +## Compreendendo o Opcode CSV + +O ```OP_SEQUENCEVERIFY``` nos Scripts do Bitcoin funciona quase como o ```OP_LOCKTIMEVERIFY```. + +Podemos exigir que um UTXO seja mantido por cem blocos após sua mineração: +``` +100 OP_CHECKSEQUENCEVERIFY +``` +Ou podemos fazer um cálculo mais complexo para exigir que um UTXO seja retido daqui seis meses, neste caso acabaremos com um número mais complexo: +``` +4224679 OP_CHECKSEQUENCEVERIFY +``` +Neste caso, usaremos uma abreviatura: +``` +<+6Months> OP_CHECKSEQUENCEVERIFY +``` + +> :warning: **ATENÇÃO:** Lembre-se de que um timelock relativo é um intervalo de tempo desde a mineração do UTXO usado como uma entrada. _Não_ é um intervalo de tempo após a criação da transação. Se usarmos um UTXO que já foi confirmado cem vezes, e colocarmos um timelock relativo de 100 blocos nele, ele será elegível para mineração imediatamente. Os timelocks relativos têm alguns usos muito específicos, mas provavelmente não se aplicam se nosso único objetivo for determinar algum tempo definido no futuro. + +### Entendendo como o CSV realmente funciona + +O CSV tem muitas das mesmas sutilezas de uso que CLTV: + +* O campo ```nVersion``` deve ser definido como 2 ou mais; +* O campo ```nSequence``` deve ser definido como sendo menor do que 0x80000000; +* Quando CSV é executado, deve haver um operando na pilha que esteja entre 0 e 0xf0000000-1; +* Tanto o operando da pilha quanto o ```nSequence``` devem ter o mesmo valor no 23º bit; +* O ```nSequence``` deve ser maior ou igual ao operando da pilha. + +Assim como no CLTV, quando estamos repensando um UTXO com um CSV em condições de bloqueio, devemos definir o ```nSequence``` para habilitar a transação. Normalmente, o configuraremos com o valor exato no script de bloqueio. + +## Escrevendo um script CSV + +Assim como o ```OP_CHECKLOCKTIMEVERIFY```, o ```OP_CHECKSEQUENCEVERIFY``` inclui um ```OP_VERIFY``` implícito e deixa os argumentos na pilha, exigindo um ```OP_DROP``` quando finalizar tudo. + +Um script que bloquearia fundos por até seis meses após a mineração e que exigiria uma assinatura no estilo P2PKH padrão teria a seguinte aparência: +``` +<+6Months> OP_CHECKSEQUENCEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +``` + +### Codificando um script CSV + +Ao codificar um script CSV, precisamos tomar cuidado ao codificar o valor inteiro para o timelock relativo. Deve ser passado como um número inteiro de 3 bytes, o que significa que iremos ignorar o maior byte, o que pode desativar o timelock relativo. Como é um número inteiro, precisamos nos certificar de convertê-lo para little-endian. + +Isso pode ser feito com o script de shell ```integer2lehex.sh``` do capítulo anterior. + +Para um tempo relativo de 100 blocos: +``` +$ ./integer2lehex.sh 100 +Integer: 100 +LE Hex: 64 +Length: 1 bytes +Hexcode: 0164 +``` +Embora deva ser preenchido como ```000064```, exigindo um código de ```03000064```. + +Por um período relativo de 6 meses: +``` +$ ./integer2lehex.sh 4224679 +Integer: 4224679 +LE Hex: a77640 +Length: 3 bytes +Hexcode: 03a77640 +``` + +## Gastando um UTXO do CSV + +Para gastar um UTXO bloqueado com um script CSV, devemos definir o ```nSequence``` dessa entrada para um valor maior que o requerido no script, mas menor que o tempo entre o UTXO e o bloco atual. Isso mesmo, isso significa que precisamos saber o requisito exato no script de bloqueio. Mas temos uma cópia do ```redeemScript```, então se não conhecermos os requisitos, podemos desserializá-lo e, em seguida, definir o ```nSequence``` como sendo o número que é mostrado lá. + +## Resumo: Usando o CSV nos Scripts + +O ```nSequence``` e o CSV oferecem uma alternativa para o ```nLockTime``` e o CLTV onde bloqueamos uma transação com base em um tempo relativo desde que a entrada foi extraída, ao invés de basear o bloqueio em um tempo definido no futuro. Eles funcionam quase de forma idêntica, exceto pelo fato de que o valor do ```nSequence``` é codificado de forma ligeiramente diferente do valor do ```nLockTime```, com bits específicos significando coisas específicas. + +> :fire: ***What is the power of CSV?*** CSV isn't just a lazy way to lock, when you don't want to calculate a time in the future. Instead, it's a totally different paradigm, a lock that you would use if it was important to create a specific minimum duration between when a transaction is mined and when its funds can be respent. The most obvious usage is (once more) for an escrow, when you want a precise time between the input of funds and their output. However, it has much more powerful possibilities in off-chain transactions, including payment channels. These applications are by definition built on transactions that are not actually put onto the blockchain, which means that if they are later put on the blockchain an enforced time-lapse can be very helpful. [Hashed Timelock Contracts](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) have been one such implementation, empowering the Lightning payment network. They're discussed in [§13.3: Empowering Bitcoin with Scripts](13_3_Empowering_Bitcoin_with_Scripts.md). +> :fire: ***Qual é o poder do CSV?*** O CSV não é apenas uma maneira preguiçosa de bloquear uma transação, quando não queremos calcular um tempo no futuro. Ele é um paradigma totalmente diferente, um bloqueio que usaríamos se fosse importante criar uma duração mínima específica entre o momento em que uma transação é minerada e o momento em que os fundos podem ser gastos. O uso mais óbvio é (mais uma vez) para um depósito, quando desejamos um tempo preciso entre a entrada dos fundos e a saída. No entanto, ele tem possibilidades muito mais poderosas em transações fora da rede, incluindo canais de pagamento. Esses aplicativos são, por definição, construídos em transações que não são realmente colocadas na blockchain, o que significa que, se forem posteriormente colocados em um bloco, um período de tempo pode ser muito útil. Os [Hashed Timelock Contracts](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) foram uma dessas implementações, dando a base para a rede de pagamento Lightning. Eles serão discutidos na seção [§13.3: Expandindo os Scripts do Bitcoin](13_3_Empowering_Bitcoin_with_Scripts.md). + +## O Que Vem Depois? + +Vamos avançar "Criando Scripts do Bitcoin" no capítulo [12: Expandindo os Scripts do Bitcoin](12_0_Expanding_Bitcoin_Scripts.md). \ No newline at end of file From 267f1aa16fcdf99f65fcddaed7a2f2316b27d9bd Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Wed, 4 Aug 2021 19:09:40 -0300 Subject: [PATCH 048/155] Chapter 12 translated. --- pt/12_0_Expanding_Bitcoin_Scripts.md | 20 +++ pt/12_1_Using_Script_Conditionals.md | 199 +++++++++++++++++++++++++ pt/12_2_Using_Other_Script_Commands.md | 85 +++++++++++ 3 files changed, 304 insertions(+) create mode 100644 pt/12_0_Expanding_Bitcoin_Scripts.md create mode 100644 pt/12_1_Using_Script_Conditionals.md create mode 100644 pt/12_2_Using_Other_Script_Commands.md diff --git a/pt/12_0_Expanding_Bitcoin_Scripts.md b/pt/12_0_Expanding_Bitcoin_Scripts.md new file mode 100644 index 0000000..2354278 --- /dev/null +++ b/pt/12_0_Expanding_Bitcoin_Scripts.md @@ -0,0 +1,20 @@ +# Capítulo 12: Expandindo os Scripts do Bitcoin + +Ainda há um pouco mais sobre os Scripts do Bitcoin que precisamos saber. As condicionais fornecem acesso total ao controle de fluxo, enquanto uma variedade de outros opcodes podem expandir nossas possibilidades. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Decidir como usar os condicionais no script; + * Decidir como usar outros opcodes no script. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Compreender toda a gama de possibilidades do script; + * Identificar como aprender mais sobre os opcodes. + +## Tabela de conteúdo + +* [Seção 1: Usando condicionais no script](12_1_Using_Script_Conditionals.md) +* [Seção 2: Usando outros comandos no script](12_2_Using_Other_Script_Commands.md) \ No newline at end of file diff --git a/pt/12_1_Using_Script_Conditionals.md b/pt/12_1_Using_Script_Conditionals.md new file mode 100644 index 0000000..aab7ad9 --- /dev/null +++ b/pt/12_1_Using_Script_Conditionals.md @@ -0,0 +1,199 @@ +# 12.1: Usando condicionais no script + +Há um aspecto importante na criação de Script de Bitcoin que é crucial para expandir o seu verdadeiro poder. Os condicionais permitem que criemos vários caminhos de execução. + +## Entendendo as Verificações + +Já vimos um condicional dentro do script, o ```op_verify``` (0x69). Ele retira o item superior na pilha e verifica se é verdade. Se não for _ele termina a execução do script_. + +A verificação é geralmente incorporada em outros opcodes. Já vimos o ```OP_EQUALVERIFY``` (0xad), o ```OP_CHECKLOCKTIMEVERIFY``` (0xb1) e o ```OP_CHECKSEQUENCEVERIFY``` (0xb2). Cada um desses opcodes faz nossa ação central (equal, checklocktime ou checkscence) e então faz uma verificação posteriormente. Os outros opcodes de verificação que ainda não vimos são: ```OP_NUMEQUALVERIFY``` (0x9d), ```OP_CHECKSIGVERIFY``` (0xad), e ```OP_CHECKMULTISIGVERIFY``` (0xaf). + +Então, como o ```OP_VERIFY``` é um condicional? É o tipo mais poderoso de condicional. Usando o ```OP_VERIFY```, _SE_ uma condição é verdadeira, o script continua executando, _SENÃO_ o script para a execução. É assim que verificamos as condições que são absolutamente necessárias para que um script tenha sucesso. Por exemplo, o script P2PKH (```OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG```) tem duas condições necessárias: (1) a chave pública fornecida precisa corresponder ao hash da chave pública e; (2) a assinatura fornecida precisa corresponder a essa chave pública. Um ```OP_EQUALVERIFY``` é usado para a comparação do hash da chave pública e a chave pública do hash porque é uma condição absolutamente necessária. Não _QUEREMOS_ que o script continue caso venha a falhar. + +Podemos notar que não há ```OP_VERIFY``` no final deste (ou da maioria dos demais) script, apesar da condição final também ser necessária. Isso porque o Bitcoin efetivamente faz um ```OP_VERIFY``` no final de cada roteiro, para garantir que o resultado final da pilha seja verdadeiro. Não podemos fazer um ```OP_VERIFY``` antes do final do script, porque precisamos deixar algo na pilha para ser testado! + +## Entendendo o If/Then (Se/Então) + +O outro condicional principal no script do Bitcoin é o clássico ```OP_IF``` (0x63) / ```OP_ELSE``` (0x67) / ```OP_ENDIF``` (0x68). Este é o controle típico do fluxo: Se o ```OP_IF``` detectar uma afirmação verdadeira, executa o bloco abaixo dele, caso contrário, se houver um ```OP_ELSE```, executa-o e; o ```OP_ENDIF``` marca o final do bloco. + +> :warning: **AVISO:** Estes condicionais tecnicamente são opcodes também, mas como são pequenos números, vamos deixar o prefixo do ```OP_``` desligado para manter a brevidade e a clareza. Assim, vamos escrever ```IF```, ```ELSE```, e ```ENDIF``` ao invés de ```OP_IF```, ```OP_ELSE```, e ```OP_ENDIF```. + +### Entendendo a Ordem do If/Then + +Existem duas grandes sacadas nos condicionais. Eles dificultam a leitura e determinam os scripts se não tivermos cuidado. + +Primeiro, o ```IF``` condicional verifica a verdade do que é _antes dele_ (em outras palavras, o que está na pilha), não o que está depois dele. + +Segundo, o ```IF``` condicional tende a estar no script de bloqueio e o que é verificado tende a estar no script de desbloqueio. + +Claro, podemos dizer, é assim que funciona o Script do Bitcoin. Condicionais usam notação polonesa reversa e adotam o paradigma padrão de desbloqueio/bloqueio, assim como todos os scripts do bitcoin. Isso é tudo verdade, mas também vai ao contrário da maneira padrão que lemos IF/ELSE condicionais em outras linguagens de programação. Assim, é fácil lermos inconscientemente errado os condicionais do Bitcoin. + +Vamos observar o seguinte código: `IF OP_DUP OP_HASH160 ELSE OP_DUP OP_HASH160 ENDIF OP_EQUALVERIFY OP_CHECKSIG`. + +Olhando para os condicionais na notação do prefixo podemos ler isso da seguinte maneira: +``` +IF (OP_DUP) THEN + OP_HASH160 + OP_PUSHDATA +ELSE + OP_DUP + OP_HASH160 + OP_PUSHDATA +ENDIF + OP_EQUALVERIFY + OP_CHECKSIG +``` +Então, podemos pensar, se o ```OP_DUP``` é verdadeiro, então nós vamos fazer o primeiro bloco, senão, o segundo. Mas isso não faz sentido! Por que o ```OP_DUP``` não daria verdadeiro?! + +E, de fato, não faz nenhum sentido, porque acidentalmente lemos a declaração usando a notação errada. A leitura correta é: +``` +IF + OP_DUP + OP_HASH160 + OP_PUSHDATA +ELSE + OP_DUP + OP_HASH160 + OP_PUSHDATA +ENDIF + OP_EQUALVERIFY + OP_CHECKSIG +``` +A declaração que avaliará para é ```True``` ou ```False``` é colocada na pilha _antes_ de executar o ```IF```, então o bloco correto do código será executado com base nesse resultado. + +Este exemplo específico de código é destinado a uma simples multisig 1-de-2. O proprietário da `````` colocaria ``` TRUE``` no script de desbloqueio, enquanto o proprietário da `````` colocaria ``` FALSE``` no script de desbloqueio. Aquele que for rastreado como ```TRUE``` ou ```FALSE``` é o que é verificado pela instrução ```IF```/```ELSE```. Ele conta ao script qual o hash da chave pública é para verificar, então o ```OP_EQUALVERIFY``` e o ```OP_CHECKSIG``` no final fazem o verdadeiro trabalho. + +### Executando um If/Then com Multisig + +Com uma compreensão central dos condicionais do Bitcoin, estamos prontos para executar scripts utilizando-os. Nós vamos começar, criando uma ligeira variante da multisig 1-de-2 do exemplo, onde nossos usuários não precisam lembrar se eles são ```TRUE``` ou ```FALSE```. Ao invés disso, se necessário, o script verifica os hashes de chave pública, apenas exigindo um único sucesso: +``` +OP_DUP OP_HASH160 OP_EQUAL +IF + OP_CHECKSIG +ELSE + OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +ENDIF +``` +Precisamos lembrar da notação polonesa reversa! Aquela instrução ```IF``` está referindo-se ao ```OP_EQUAL``` antes dela, não ao `OP_CHECKSIG` posterior! + +#### Executando a Parte Verdadeira + +Veja como é executado se desbloquearmos com ``` ```: +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Primeiro, colocamos as constantes na pilha: +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Em seguida, nós executamos os primeiros, comandos óbvios, ```OP_DUP``` e ```OP_HASH160``` e colocamos outra constante: +``` +Script: OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_DUP +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Em seguida, executamos o ```OP_EQUAL```, que é o que vai alimentar o ```IF```: +``` +Script: IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_EQUAL +Stack: [ True ] +``` +Agora, o ```IF``` executa, e desde que seja um ```TRUE```, ele só executa o primeiro bloco, eliminando todo o resto: +``` +Script: OP_CHECKSIG +Running: True IF +Stack: [ ] +``` +E o ```OP_CHECKSIG``` acabará sendo ```TRUE``` também: +``` +Script: +Running: OP_CHECKSIG +Stack: [ True ] +``` + +#### Executando a Parte Falsa + +Veja como ele iria executar se fossemos desbloquear com ``` ```: +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Primeiro, colocamos as constantes na pilha: +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Em seguida, executamos os primeiros, comandos óbvios, ```OP_DUP``` e ```OP_HASH160``` e adicionamos outra constante: +``` +Script: OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_DUP +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Em seguida, executamos o ```OP_EQUAL```, que é o que vai alimentar o ```IF```: +``` +Script: IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_EQUAL +Stack: [ False ] +``` +Uhul! O resultado foi ```FALSE``` porque o `````` não é igual ao ``````. Agora, quando o ```IF``` for executado, ele vai pular para a instrução ```ELSE```: +``` +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: False IF +Stack: [ ] +``` +Depois, passamos por todo o imbróglio, começando com outro ```OP_DUP```, mas eventualmente o testando usando outro ```pubKeyHash```: +``` +Script: OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: OP_DUP +Stack: [ ] + +Script: OP_EQUALVERIFY OP_CHECKSIG +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] + +Script:OP_CHECKSIG +Running: OP_EQUALVERIFY +Stack: [ ] + +Script: +Running: OP_CHECKSIG +Stack: [ True ] +``` +Isso provavelmente não é tão eficiente quanto um verdadeiro multisig do Bitcoin, mas é um bom exemplo de como os resultados adicionados a pilha devido a testes anteriores podem ser usados para alimentar futuros condicionais. Neste caso, é o fracasso da primeira assinatura que diz a condicional que deve ir verificar a segunda. + +## Entendendo os Demais Condicionais + +Existem alguns outros condicionais para ser analisados. O maior deles é o ```OP_NOTIF``` (0x64), que é o oposto de ```OP_IF```. Ele executa o próximo bloco se o item superior for ```FALSE```. Um ```ELSE``` pode ser colocado junto, que como usual é executado se o primeiro bloco não for executado. Podemos ainda terminar com o ```OP_ENDIF```. + +Há também um ```OP_IFDUP``` (0x73), que duplica o item de pilha superior somente se o resultado não for 0. + +Essas opções são usadas com muito menos frequência do que a construção usando ```IF```/```ELSE```/```ENDIF```. + +## Resumo: Usando condicionais no script + +Os condicionais no script do Bitcoin permitem deter o script (usando o ```OP_VERIFY```) ou para escolher diferentes ramos de execução (usando ```OP_IF```). No entanto, a ler o ```OP_IF``` pode ser um pouco complicado. Precisamos lembrar de que é o item adicionado a pilha _antes_ do operador ```OP_IF``` ser executado que controla a sua execução. Esse item normalmente fará parte do script de desbloqueio (ou será um resultado direto de itens do script de desbloqueio). + +> :fire: ***Qual é o poder dos condicionais?*** Os condicionais do script são o principal bloco de construção no script do Bitcoin. Eles transformam os scripts simples e estáticos do Bitcoin em scripts de bitcoin complexos e dinâmicos que podem avaliar de maneira diferente com base em diferentes momentos, diferentes circunstâncias ou diferentes entradas de usuário. Em outras palavras, eles são o último pilar dos contratos inteligentes. + +## O Que Vem Depois? + +Vamos continuar "Expandindo os Scripts do Bitcoin" na seção [§12.2: Usando outros comandos no script](12_2_using_other_script_commands.md). \ No newline at end of file diff --git a/pt/12_2_Using_Other_Script_Commands.md b/pt/12_2_Using_Other_Script_Commands.md new file mode 100644 index 0000000..d44c1fb --- /dev/null +++ b/pt/12_2_Using_Other_Script_Commands.md @@ -0,0 +1,85 @@ +# 12.2: Usando outros comandos no script + +Já temos em mãos a maioria dos opcodes do script do Bitcoin que iremos usar na maioria dos nossos scripts. No entanto, o script do Bitcoin oferece muito mais opções, o que pode vir a ser exatamente o que precisamos para criar o nosso instrumento financeiro dos nossos sonhos. + +Devemos consultar a [página do script do Bitcoin](https://en.bitcoin.it/wiki/script) para termos uma lista mais completa de todos esses e muitos outros comandos. Esta seção destaca apenas os opcodes mais notáveis. + +## Entendendo os Opcodes Aritméticos + +Os opcodes aritméticos manipulam ou testam números. + +Manipulam um número: + +* OP_1ADD (0x8b) - Adiciona uma unidade; +* OP_1SUB (0x8C) - Subtrai uma unidade; +* OP_NEGATE (0x8f) - Inverte o sinal do número; +* OP_ABS (0x90) - O número fica positivo; +* OP_NOT (0x91) - Troca 1 por 0, senão 0. + +É legal saber sobre o ```OP_0NOTEQUAL``` (0x92). + +Manipulam dois números matematicamente: + +* OP_ADD (0x93) - Adiciona dois números; +* OP_SUB (0x94) - Subtrai dois números; +* OP_MIN (0xA3) - Retorna o menor entre dois números; +* OP_MAX (0xA4) - Retorna o maior entre dois números. + +Manipulam dois números logicamente: + +* OP_BOOLAND (0x9a) - 1 se ambos os números não são 0, senão 0; +* OP_BOOLOR (0x9B) - 1 se qualquer número não é 0, senão 0. + +Testa dois números: + +* OP_NUMEQUAL (0x9C) - 1 se ambos os números forem iguais, senão 0; +* OP_LESSTHAN (0x9f) - 1 se o primeiro número for menor que o segundo, senão 0; +* OP_GREATERTHAN (0xA0) - 1 se o primeiro número for maior que o segundo, senão 0; +* OP_LESSTHANOREQUAL (0xA1) - 1 se o primeiro número for menor ou igual ao segundo, senão 0; +* OP_GREATERTHANOREQUAL (0xA2) - 1 se o primeiro número for maior ou igual a segundo, senão 0. + +É legal saber também: O ```OP_NUMEQUALVERIFY``` (0x9d) e o ```OP_NUMNOTEQUAL``` (0x9e) + +Testa três números: + +* OP_WITHIN (0xA5) - 1 se um número estiver no intervalo de dois outros números. + +## Entendendo a Opcodes de Pilha + +Há um número chocante de opcodes de pilha, mas além de ```OP_DROP```, ```OP_DUP```, e às vezes, ```OP_SWAP``` geralmente não serão necessários se tivermos cuidado com a ordem da pilha. No entanto, aqui estão alguns dos mais interessantes: + +* OP_DEPTH (0x74) - Aumenta o tamanho da pilha; +* OP_DROP (0x75) - Retira o item superior da pilha; +* OP_DUP (0x76) - Duplica o item superior da pilha; +* OP_PICK (0x79) - Duplica o enésimo item da pilha começando pelo topo; +* OP_ROLL (0x7a) - Move o enésimo item para o topo da pilha; +* OP_SWAP(0x7C) - Troca os dois principais itens da pilha. + +É legal saber também: O `OP_TOALTSTACK` (0x6b), `OP_FROMALTSTACK` (0x6c), `OP_2DROP` (0x6d), `OP_2DUP` (0x6e), `OP_3DUP` (0x6f), `OP_2OVER` (0x70), `OP_2ROT` (0x71), `OP_2SWAP` (0x72), `OP_IFDUP` (0x73), `OP_NIP` (0x77), `OP_OVER` (0x78), `OP_ROT` (0x7b), e o `OP_TUCK` (0x7d). + +## Entendendo os Opcodes Criptográficos + +Finalmente, uma variedade de opcodes para dar suporte ao hashing e a verificação da assinatura: + +Hash: + +* OP_RIPEMD160 (0xa6) — RIPEMD-160; +* OP_SHA1 (0xa7) — SHA-1; +* OP_SHA256 (0xa8) - SHA-256; +* OP_HASH160 (0xa9) — SHA-256 + RIPEMD-160; +* OP_HASH256 (0xaa) — SHA-256 + SHA-256. + +Verifica as assinaturas: + +* Op_checksig (0xac) - Verifica uma assinatura; +* Op_checkmultisig (0xae) - Verifica uma multisig M-DE-N. + +É legal saber também: O `OP_CODESEPARATOR` (0xab), `OP_CHECKSIGVERIFY` (0xad), e o `OP_CHECKMULTISIGVERIFY` (0xaf). + +## Resumo: Usando outros comandos no script + +O script do Bitcoin inclui uma ampla gama de opcodes aritméticos, de pilha e criptográficos. A maioria desses opcodes adicionais provavelmente não serão tão comuns quanto os discutidos nas seções anteriores, mas, no entanto, estão disponíveis, para sabermos que existem caso precisemos utilizá-los para escrever nosso script! + +## O Que Vem Depois? + +Vamos avançar do "Expandindo os Scripts do Bitcoin" para o [Capítulo 13: Projetando Scripts Reais no Bitcoin](13_0_Designing_real_bitcoin_scripts.md). \ No newline at end of file From ddc5dae330f28848928e9abf611fb88cfeb2a0ec Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 5 Aug 2021 00:31:10 -0300 Subject: [PATCH 049/155] Chapter 13 translation finished --- pt/13_0_Designing_Real_Bitcoin_Scripts.md | 21 + pt/13_1_Writing_Puzzle_Scripts.md | 512 ++++++++++++++++++++ pt/13_2_Writing_Complex_Multisig_Scripts.md | 151 ++++++ pt/13_3_Empowering_Bitcoin_with_Scripts.md | 276 +++++++++++ 4 files changed, 960 insertions(+) create mode 100644 pt/13_0_Designing_Real_Bitcoin_Scripts.md create mode 100644 pt/13_1_Writing_Puzzle_Scripts.md create mode 100644 pt/13_2_Writing_Complex_Multisig_Scripts.md create mode 100644 pt/13_3_Empowering_Bitcoin_with_Scripts.md diff --git a/pt/13_0_Designing_Real_Bitcoin_Scripts.md b/pt/13_0_Designing_Real_Bitcoin_Scripts.md new file mode 100644 index 0000000..a602de6 --- /dev/null +++ b/pt/13_0_Designing_Real_Bitcoin_Scripts.md @@ -0,0 +1,21 @@ +# Capítulo 13: Projetando Scripts Reais no Bitcoin + +Nossos scripts do Bitcoin até agora têm sido exemplos teóricos, porque ainda estamos montando as peças do quebra-cabeça. Agora, com o repertório completo do Script do Bitcoin em mãos, estamos prontos para nos aprofundar em vários scripts do mundo real e ver como eles funcionam. + +## Objetivos deste Capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Avaliar os scripts do Bitcoin do mundo real; + * Criar scripts do Bitcoin no mundo real. + +Os objetivos secundários incluem a capacidade de: + + * Entender os scripts do Bitcoin existentes; + * Compreender a importância das assinaturas. + +## Tabela de Conteúdo + + * [Seção 1: Escrevendo Puzzles com Scripts](13_1_Writing_Puzzle_Scripts.md) + * [Seção 2: Escrevendo Scripts Multisig Complexos](13_2_Writing_Complex_Multisig_Scripts.md) + * [Seção 3: Expandindo o Bitcoin com os Scripts](13_3_Empowering_Bitcoin_with_Scripts.md) \ No newline at end of file diff --git a/pt/13_1_Writing_Puzzle_Scripts.md b/pt/13_1_Writing_Puzzle_Scripts.md new file mode 100644 index 0000000..961a253 --- /dev/null +++ b/pt/13_1_Writing_Puzzle_Scripts.md @@ -0,0 +1,512 @@ +# 13.1: Escrevendo Puzzles com Scripts + +Os scripts de Bitcoin realmente _não_ precisam depender do conhecimento de uma chave secreta. Ao invés disso, podemos criar puzzles de qualquer tipo. + +## Escrevendo Scripts de Álgebra Simples + +Nosso primeiro script real, da seção [§9.2: Executando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md) foi um puzzle simples. Esse script Bitcoin, ```OP_ADD 99 OP_EQUAL```, poderia ter sido descrito da seguinte forma: ```x + y = 99```. + +Esse tipo de script não tem muita aplicabilidade no mundo real, pois é muito fácil reivindicar os fundos. Mas, um quebra-cabeça que distribui pequenos valores em Bitcoin pode ser um entretenimento divertido. + +Mais notavelmente, a criação de puzzles algébricos fornece uma boa compreensão de como funcionam as funções aritméticas no script do Bitcoin. + +### Escrevendo um script multiplicador + +O Script do Bitcoin possui vários opcodes que foram desativados para manter a segurança do sistema. Um deles é o ```OP_MUL```, que teria permitido a multiplicação, mas, está desabilitado. + +Então, como escreveríamos uma função algébrica como ```3x + 7 = 13```? + +A resposta mais óbvia é usando o ```OP_DUP``` o número inserido no script de bloqueio duas vezes. Então podemos colocar o ```7``` e continuar adicionando até obter o total. O script de bloqueio completo ficaria assim: ```OP_DUP OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL```. + +Veja como seria executado o script de desbloqueio correto do ```2```: +``` +Script: 2 OP_DUP OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL +Stack: [ ] + +Script: OP_DUP OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL +Stack: [ 2 ] + +Script: OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL +Running: 2 OP_DUP +Stack: [ 2 2 ] + +Script: 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL +Running: 2 OP_DUP +Stack: [ 2 2 2 ] + +Script: OP_ADD OP_ADD OP_ADD 13 OP_EQUAL +Stack: [ 2 2 2 7 ] + +Script: OP_ADD OP_ADD 13 OP_EQUAL +Running: 2 7 OP_ADD +Stack: [ 2 2 9 ] + +Script: OP_ADD 13 OP_EQUAL +Running: 2 9 OP_ADD +Stack: [ 2 11 ] + +Script: 13 OP_EQUAL +Running: 2 11 OP_ADD +Stack: [ 13 ] + +Script: OP_EQUAL +Stack: [ 13 13 ] + +Script: +Running: 13 13 OP_EQUAL +Stack: [ True ] +``` +Ou se você preferir usar o `btcdeb`: +``` +$ btcdeb '[2 OP_DUP OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +valid script +9 op script loaded. type `help` for usage information +script | stack +---------+-------- +2 | +OP_DUP | +OP_DUP | +7 | +OP_ADD | +OP_ADD | +OP_ADD | +13 | +OP_EQUAL | + +#0000 2 +btcdeb> step + <> PUSH stack 02 +script | stack +---------+-------- +OP_DUP | 02 +OP_DUP | +7 | +OP_ADD | +OP_ADD | +OP_ADD | +13 | +OP_EQUAL | + +#0001 OP_DUP +btcdeb> step + <> PUSH stack 02 +script | stack +---------+-------- +OP_DUP | 02 +7 | 02 +OP_ADD | +OP_ADD | +OP_ADD | +13 | +OP_EQUAL | + +#0002 OP_DUP +btcdeb> step + <> PUSH stack 02 +script | stack +---------+-------- +7 | 02 +OP_ADD | 02 +OP_ADD | 02 +OP_ADD | +13 | +OP_EQUAL | + +#0003 7 +btcdeb> step + <> PUSH stack 07 +script | stack +---------+-------- +OP_ADD | 07 +OP_ADD | 02 +OP_ADD | 02 +13 | 02 +OP_EQUAL | + +#0004 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 09 +script | stack +---------+-------- +OP_ADD | 09 +OP_ADD | 02 +13 | 02 +OP_EQUAL | + +#0005 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 0b +script | stack +---------+-------- +OP_ADD | 0b +13 | 02 +OP_EQUAL | + +#0006 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 0d +script | stack +---------+-------- +13 | 0d +OP_EQUAL | +#0007 13 +btcdeb> step + <> PUSH stack 0d +script | stack +---------+-------- +OP_EQUAL | 0d + | 0d + +#0008 OP_EQUAL +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 01 +script | stack +---------+-------- + | 01 +``` +### Escrevendo um Sistema de Equações + +E se quiséssemos escrever um sistema de equações, como ```x + y = 3```,```y + z = 5``` e ```x + z = 4```? A álgebra diz que as respostas resultariam em ```x = 1```,```y = 2``` e ```z = 3```. Mas, como faríamos este script? + +Obviamente, depois que o remetente inserir os três números, precisaremos de duas cópias de cada número, uma vez que cada número entra em duas equações diferentes. O ```OP_3DUP``` cuida disso e resulta em```x y z x y z``` estando na pilha. Tirar dois itens de cada vez resultará em ```y z```,```z x``` e ```x y```. Pronto! Essas são as três equações, então só precisamos adicioná-las e testá-las na ordem correta! Aqui está o script completo: ```OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL```. + +Veja como funciona com o script de desbloqueio correto de ```1 2 3```: +``` +Script: 1 2 3 OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Stack: [ ] + +Script: OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Stack: [ 1 2 3 ] + +Script: OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Running: 1 2 3 OP_3DUP +Stack: [ 1 2 3 1 2 3 ] + +Script: 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Running: 2 3 OP_ADD +Stack: [ 1 2 3 1 5 ] + +Script: OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Stack: [ 1 2 3 1 5 5 ] + +Script: OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Running: 5 5 OP_EQUALVERIFY +Stack: [ 1 2 3 1 ] — Does Not Exit + +Script: 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Running: 3 1 OP_ADD +Stack: [ 1 2 4 ] + +Script: OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Stack: [ 1 2 4 4 ] + +Script: OP_ADD 3 OP_EQUAL +Running: 4 4 OP_EQUALVERIFY +Stack: [ 1 2 ] — Does Not Exit + +Script: 3 OP_EQUAL +Running: 1 2 OP_ADD +Stack: [ 3 ] + +Script: OP_EQUAL +Stack: [ 3 3 ] + +Script: +Running: 3 3 OP_EQUAL +Stack: [ True ] +``` +Aqui está usando o `btcdeb`: +``` +$ btcdeb '[1 2 3 OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +valid script +13 op script loaded. type `help` for usage information +script | stack +---------------+-------- +1 | +2 | +3 | +OP_3DUP | +OP_ADD | +5 | +OP_EQUALVERIFY | +OP_ADD | +4 | +OP_EQUALVERIFY | +OP_ADD | +3 | +OP_EQUAL | + +#0000 1 +btcdeb> step + <> PUSH stack 01 +script | stack +---------------+-------- +2 | 01 +3 | +OP_3DUP | +OP_ADD | +5 | +OP_EQUALVERIFY | +OP_ADD | +4 | +OP_EQUALVERIFY | +OP_ADD | +3 | +OP_EQUAL | + +#0001 2 +btcdeb> step + <> PUSH stack 02 +script | stack +---------------+-------- +3 | 02 +OP_3DUP | 01 +OP_ADD | +5 | +OP_EQUALVERIFY | +OP_ADD | +4 | +OP_EQUALVERIFY | +OP_ADD | +3 | +OP_EQUAL | + +#0002 3 +btcdeb> step + <> PUSH stack 03 +script | stack +---------------+-------- +OP_3DUP | 03 +OP_ADD | 02 +5 | 01 +OP_EQUALVERIFY | +OP_ADD | +4 | +OP_EQUALVERIFY | +OP_ADD | +3 | +OP_EQUAL | + +#0003 OP_3DUP +btcdeb> step + <> PUSH stack 01 + <> PUSH stack 02 + <> PUSH stack 03 +script | stack +---------------+-------- +OP_ADD | 03 +5 | 02 +OP_EQUALVERIFY | 01 +OP_ADD | 03 +4 | 02 +OP_EQUALVERIFY | 01 +OP_ADD | +3 | +OP_EQUAL | + +#0004 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 05 +script | stack +---------------+-------- +5 | 05 +OP_EQUALVERIFY | 01 +OP_ADD | 03 +4 | 02 +OP_EQUALVERIFY | 01 +OP_ADD | +3 | +OP_EQUAL | + +#0005 5 +btcdeb> step + <> PUSH stack 05 +script | stack +---------------+-------- +OP_EQUALVERIFY | 05 +OP_ADD | 05 +4 | 01 +OP_EQUALVERIFY | 03 +OP_ADD | 02 +3 | 01 +OP_EQUAL | + +#0006 OP_EQUALVERIFY +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 01 + <> POP stack +script | stack +---------------+-------- +OP_ADD | 01 +4 | 03 +OP_EQUALVERIFY | 02 +OP_ADD | 01 +3 | +OP_EQUAL | + +#0007 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 04 +script | stack +---------------+-------- +4 | 04 +OP_EQUALVERIFY | 02 +OP_ADD | 01 +3 | +OP_EQUAL | + +#0008 4 +btcdeb> step + <> PUSH stack 04 +script | stack +---------------+-------- +OP_EQUALVERIFY | 04 +OP_ADD | 04 +3 | 02 +OP_EQUAL | 01 + +#0009 OP_EQUALVERIFY +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 01 + <> POP stack +script | stack +---------------+-------- +OP_ADD | 02 +3 | 01 +OP_EQUAL | + +#0010 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 03 +script | stack +---------------+-------- +3 | 03 +OP_EQUAL | + +#0011 3 +btcdeb> step + <> PUSH stack 03 +script | stack +---------------+-------- +OP_EQUAL | 03 + | 03 + +#0012 OP_EQUAL +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 01 +script | stack +---------------+-------- + | 01 +``` + +> :warning: **ATENÇÃO** O ```btcdeb``` não é útil apenas para fornecer a visualização desses scripts, mas também para verificar os resultados. Com certeza, erramos na primeira vez, testando as equações na ordem errada. É tão fácil cometer um erro financeiramente fatal em um script Bitcoin, e é por isso que todo script deve ser testado exaustivamente. + +## Escrevendo Scripts Computacionais Simples + +Embora os scripts de puzzle sejam triviais, podem realmente ter utilidade no mundo real se quisermos terceirizar uma computação. Podemos simplesmente criar um script que requer a resposta do cálculo e enviar fundos para o endereço P2SH como recompensa. Assim, a recompensa ficará lá até que alguém dê a resposta. + +Por exemplo, Peter Todd [ofereceu recompensas](https://bitcointalk.org/index.php?topic=293382.0) por resolver equações que demonstram colisões para algoritmos criptográficos padrão. Aqui estava o script para confirmar uma colisão SHA1: ```OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL```. Requer duas entradas, que serão os dois números que colidem. + +Veja como funciona com as respostas corretas. + +Primeiro, preenchemos nossa pilha: +``` +Script: OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Stack: [ ] + +Script: OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Stack: [ ] + +Script: OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Running: OP_2DUP +Stack: [ ] +``` +Then, we make sure the two numbers aren't equal, exiting if they are: +Em seguida, certificamo-nos de que os dois números não são iguais, saindo se forem: +``` +Script: OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Running: OP_EQUAL +Stack: [ False ] + +Script: OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Running: False OP_NOT +Stack: [ True ] + +Script: OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Running: True OP_VERIFY +Stack: [ ] — Does Not Exit +``` +We now create two SHAs: +Agora criamos dois SHAs: +``` +Script: OP_SWAP OP_SHA1 OP_EQUAL +Running: OP_SHA1 +Stack: [ ] + +Script: OP_SHA1 OP_EQUAL +Running: OP_SWAP +Stack: [ ] + +Script: OP_EQUAL +Running: OP_SHA1 +Stack: [ ] +``` +Finally, we see if they match. +Finalmente, vemos se eles combinam. +``` +Script: +Running: OP_EQUAL +Stack: [ True ] +``` +Este é um bom script porque mostra o uso cuidadoso da lógica (com o ```OP_NOT``` e o ```OP_VERIFY```) e bom uso das funções de pilha (com o ```OP_SWAP```). Trata-se de um ótimo exemplo de função do mundo real. E isso é muito real. Quando o [SHA-1 foi quebrado](https://shattered.io/), 2,48 BTC foram rapidamente liberados do endereço, com um valor total de cerca de $3.000 na época. + +O ```btcdeb``` pode ser executado para provar a colisão (e o script): +``` +btcdeb $ btcdeb '[255044462d312e330a25e2e3cfd30a0a0a312030206f626a0a3c3c2f57696474682032203020522f4865696768742033203020522f547970652034203020522f537562747970652035203020522f46696c7465722036203020522f436f6c6f7253706163652037203020522f4c656e6774682038203020522f42697473506572436f6d706f6e656e7420383e3e0a73747265616d0affd8fffe00245348412d3120697320646561642121212121852fec092339759c39b1a1c63c4c97e1fffe017f46dc93a6b67e013b029aaa1db2560b45ca67d688c7f84b8c4c791fe02b3df614f86db1690901c56b45c1530afedfb76038e972722fe7ad728f0e4904e046c230570fe9d41398abe12ef5bc942be33542a4802d98b5d70f2a332ec37fac3514e74ddc0f2cc1a874cd0c78305a21566461309789606bd0bf3f98cda8044629a1 255044462d312e330a25e2e3cfd30a0a0a312030206f626a0a3c3c2f57696474682032203020522f4865696768742033203020522f547970652034203020522f537562747970652035203020522f46696c7465722036203020522f436f6c6f7253706163652037203020522f4c656e6774682038203020522f42697473506572436f6d706f6e656e7420383e3e0a73747265616d0affd8fffe00245348412d3120697320646561642121212121852fec092339759c39b1a1c63c4c97e1fffe017346dc9166b67e118f029ab621b2560ff9ca67cca8c7f85ba84c79030c2b3de218f86db3a90901d5df45c14f26fedfb3dc38e96ac22fe7bd728f0e45bce046d23c570feb141398bb552ef5a0a82be331fea48037b8b5d71f0e332edf93ac3500eb4ddc0decc1a864790c782c76215660dd309791d06bd0af3f98cda4bc4629b1 OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL'] +``` + +As outras [recompensas](https://bitcointalk.org/index.php?topic=293382.0) de Peter Todd permanecem intocadas, pelo menos até o momento da redação deste artigo. Elas são todas escritos da mesma maneira que o exemplo SHA-1 acima. + +## Compreendendo as Limitações dos Scripts de Puzzle + +Os scripts de puzzle são ótimos para examinar mais detalhadamente os scripts do Bitcoin, mas só os veremos em uso no mundo real se estiverem mantendo pequenas quantias de fundos ou se forem destinados ao resgate por usuários muito habilidosos. Há uma razão para isso: Eles não são seguros. + +É aqui que a segurança cai: + +Primeiro, qualquer um pode resgatá-los sem saber muito sobre um segredo. Eles precisam ter o ```redeemScript```, que oferece alguma proteção, mas uma vez que consigam, esse é provavelmente o único segredo necessário, a menos que nosso puzzle seja _realmente_ difícil, como um quebra-cabeça computacional. + +Em segundo lugar, o resgate real não é seguro. Normalmente, uma transação de Bitcoin é protegida pela assinatura. Como a assinatura cobre a transação, ninguém na rede pode reescrever essa transação para enviar para o endereço sem invalidar a assinatura (e, portanto, a transação). Isso não é verdade com transações cujas entradas são apenas números. Qualquer um poderia pegar a transação e reescrevê-la para permitir o roubo dos fundos. Se eles conseguirem colocar a transação em um bloco antes da nossa transação, eles ganham e nós não receberemos o dinheiro do puzzle. Existem soluções para isso, mas elas envolvem a mineração do bloco por conta própria ou um pool confiável para minerá-lo, e nenhuma dessas opções é racional para um usuário comum do Bitcoin. + +Ainda assim, as recompensas criptográficas de Peter Todd provam que os scripts de quebra-cabeça têm alguma aplicação no mundo real. + +## Resumo: Escrevendo Puzzles com Scripts + +Os scripts de puzzles são uma ótima introdução aos scripts do Bitcoin mais realistas e complexos. Eles demonstram o poder das funções matemáticas e de pilha no script do Bitcoin e como podem ser cuidadosamente combinadas para criar perguntas que requerem respostas muito específicas. No entanto, o uso no mundo real também é limitado pelos problemas de segurança inerentes às transações Bitcoin não assinadas. + +> :fire: ***Qual é o poder do script de puzzles?*** Apesar das limitações, os scripts de puzzles têm sido usados ​​no mundo real como prêmios para recompensas computacionais. Qualquer pessoa que consiga descobrir um quebra-cabeça complexo, cuja solução provavelmente tenha algum impacto no mundo real, pode ganhar a recompensa. Se vão conseguir sacar para seus endereços, é outra questão. + +## O Que Vem Depois? + +Vamos continuar "Projetando Scripts Reais no Bitcoin" na seção [§13.2: Escrevendo Scripts Multisig Complexos](13_2_Writing_Complex_Multisig_Scripts.md). \ No newline at end of file diff --git a/pt/13_2_Writing_Complex_Multisig_Scripts.md b/pt/13_2_Writing_Complex_Multisig_Scripts.md new file mode 100644 index 0000000..d10286f --- /dev/null +++ b/pt/13_2_Writing_Complex_Multisig_Scripts.md @@ -0,0 +1,151 @@ +# 13.2: Escrevendo Scripts Multisig Complexos + +Até o momento, os multisigs descritos nesses documentos têm sido inteiramente simples, na forma m-de-n ou n-de-n. No entanto, podemos desejar multisigs mais complexos, onde as pessoas que assinam as transações variam ou onde diferentes opções podem se tornar disponíveis ao longo do tempo. + +## Escrevendo uma Multisig Variável + +Uma multisig variável requer diferentes números de pessoas para assinar, dependendo de quem está assinando. + +### Escrevendo uma Multisig com um único assinante ou com vários assinantes + +Imagine uma empresa em que o presidente ou dois em cada três vice-presidentes concordem com o uso dos fundos. + +Podemos escrever isso criando uma instrução ```IF```/```ELSE```/```ENDIF``` que tem dois blocos, um para o presidente e sua assinatura um-de-um e um para os vice-presidentes e suas dois-de-três assinaturas. Podemos então, determinar qual bloco usar com base em quantas assinaturas estão no script de desbloqueio. Se usarmos ```OP_DEPTH 1 OP_EQUAL``` estaremos dizendo que há um item na pilha, e iremos partir daí. + +O script de bloqueio completo seria ```OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF```. + +Se executado pelo presidente, seria assim: +``` +Script: OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ ] + +Script: OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ ] + +Script: 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Running: OP_DEPTH +Stack: [ 1 ] + +Script: OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ 1 1 ] + +Script: IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Running: 1 1 OP_EQUAL +Stack: [ True ] +``` +Como o resultado é `True`, o script agora se reduz para a instrução ```IF```: +``` +Script: OP_CHECKSIGNATURE +Running: True IF +Stack: [ ] + +Script: OP_CHECKSIGNATURE +Stack: [ ] + +Script: +Running: OP_CHECKSIGNATURE +Stack: [ True ] +``` +Se administrado por dois vice-presidentes, ficaria assim: +``` +Script: 0 OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ ] + +Script: OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ 0 ] + +Script: 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Running: 0 OP_DEPTH +Stack: [ 0 3 ] + +Script: OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ 0 3 1 ] + +Script: IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Running: 3 1 OP_EQUAL +Stack: [ 0 False ] +``` +Como o resultado é `False`, o script agora se reduz à instrução ```ELSE```: +``` +Script: 2 3 OP_CHECKMULTISIG +Running: False IF +Stack: [ 0 ] + +Script: OP_CHECKMULTISIG +Stack: [ 0 2 3 ] + +Script: +Running: 0 2 3 OP_CHECKMULTISIG +Stack: [ ] +``` +Podemos notar que a assinatura do presidente usa apenas um simples ```OP_CHECKSIGNATURE``` ao invés do código mais complexo normalmente exigido para um P2PKH. Podemos nos safar incluindo a chave pública no script de bloqueio, evitando um trabalhão padrão, porque é o hash e não será revelado (por meio do ```redeemScript```) até que a transação seja desbloqueada. Isso também permite que todos os possíveis assinantes assinem usando a mesma metodologia. + +O único problema é se o presidente estiver distraído e acidentalmente assinar uma transação com um dos vice-presidentes, porque ele se lembra de ser um multisig 2 de 3. Uma opção é decidir que essa é uma condição de falha aceitável, porque o presidente está usando o multsig incorretamente. Outra opção é transformar o multisig 2 de 3 em um multisig 2 de 4, caso o presidente não tolere falhas: ```OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 < pubKeyVPC> 4 OP_CHECKMULTISIG ENDIF```. Isso permitiria ao presidente assinar por engano com qualquer vice-presidente, mas não afetaria as coisas se dois vice-presidentes quisessem assinar (corretamente). + +### Escrevendo um Multisig com um assinante obrigatório + +Outra possibilidade de multisig envolve ter um multisig m-of-n onde um dos assinantes é necessário. Isso geralmente pode ser gerenciado dividindo o multisig em vários m de n-1 multisigs. Por exemplo, um multisig 2 de 3 em que um dos signatários é necessário seria, na verdade, dois multisig 2 de 2, cada um incluindo o signatário necessário. + +Esta é uma maneira simples de criar um script para isso: +``` +OP_3DUP +2 2 OP_CHECKMULTISIG +NOTIF + 2 2 OP_CHECKMULTISIG +ENDIF +``` +O script de desbloqueio seria ```0 ``` ou ```0 ```. + +Primeiro, o script verifica as assinaturas no ``` ```. Se falhar, será verificado no ``` ```. + +O resultado do ```OP_CHECKMULTISIG``` final que foi executado será deixado no topo da pilha (embora haja um resto abaixo dele se o primeiro for bem-sucedido). + +## Escrevendo um Escrow Multisig + +Falamos muito sobre escrows. Os multisigs complexos combinados com timelocks oferecem uma maneira automatizada de criá-los de maneira robusta. + +Imagine a compradora de imóveis Alice e o vendedor de imóveis Bob que estão trabalhando com um agente de garantia. A maneira fácil de fazer o script seria como um multisig onde qualquer uma das três partes poderia liberar o dinheiro: Ou o vendedor e o comprador concordam ou o agente de garantia assume o controle e concorda com uma das partes: ```2 3 OP_CHECKMULTISG```. + +No entanto, isso enfraquece o poder do agente de garantia e permite que o vendedor e o comprador acidentalmente tomem uma decisão errada entre eles. O que é uma das coisas que um sistema de garantia deve evitar. Portanto, pode ser que o que realmente desejamos seja o sistema que acabamos de criar, onde o agente de custódia é uma parte necessária no multisig 2 de 3: ```OP_3DUP 2 2 OP_CHECKMULTISIG NOTIF 2 2 OP_CHECKMULTISIG ENDIF```. + +No entanto, isso não passa no teste de entrar na frente de um ônibus. Se o agente de custódia morre ou foge para as Bahamas durante o processo, o comprador e o vendedor ficam sem o dinheiro. É aqui que entra um bloqueio de tempo. Podemos criar um teste adicional que só será executado se tivermos passado o final do nosso período de garantia. Nessa situação, permitimos que o comprador e o vendedor assinem juntos: +``` +OP_3DUP +2 2 OP_CHECKMULTISIG +NOTIF + OP_3DUP + 2 2 OP_CHECKMULTISIG + NOTIF + <+30Days> OP_CHECKSEQUENCEVERIFY OP_DROP + 2 2 OP_CHECKMULTISIG + ENDIF +ENDIF +``` +Primeiro, testamos uma assinatura para o comprador e o agente de garantia e, em seguida, uma assinatura para o vendedor e o agente de garantia. Se ambos falharem e 30 dias se passaram, também permitimos uma assinatura para o comprador e o vendedor. + +### Escrevendo um Multisig de Compromisso Centrado no Comprador + +O [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki#Escrow_with_Timeout) oferece um exemplo diferente deste tipo de garantia que não tem proteções extras para evitar o agente de garantia, mas que dá a Alice controle total se a garantia falhar. +``` +IF + 2 3 OP_CHECKMULTISIG +ELSE + <+30Days> OP_CHECKSEQUENCEVERIFY OP_DROP + OP_CHECKSIGNATURE +ENDIF +``` +Aqui, qualquer um dos três assinantes pode liberar o dinheiro a qualquer momento, mas depois de 30 dias, Alice pode recuperar o dinheiro por conta própria. + +Observe que este script requer que um ```True``` ou ```False``` seja passado para identificar qual caminho será utilizado. Esta é uma maneira mais simples e menos computacionalmente intensiva de oferecer suporte aos caminhos usando o script de Bitcoin. É algo bem comum. + +No início, o seguinte ```sigScript``` seria permitido: ```0 True```. Após 30 dias, Alice poderia produzir um ```sigScript``` como este: ``` False```. + +## Resumo: Escrevendo Scripts Multisig Complexos + +Os multisigs mais complexos podem ser normalmente criados combinando assinaturas ou multi assinaturas com condicionais e testes. Os multisigs resultantes podem ser variáveis, exigindo diferentes números de assinantes com base em quem são e quando estão assinando. + +> :fire: ***Qual é o poder dos scripts complexos com multisigs?*** Mais do que qualquer coisa que vimos até agora, os scripts multisig complexos são contratos realmente inteligentes. Eles podem ser muito precisos sobre quem tem permissão para assinar e quando. Empresas com vários níveis, parcerias e escrows podem utilizar soluções semelhantes. O uso de outros recursos poderosos como os timelocks pode proteger ainda mais esses fundos, permitindo que sejam liberados ou mesmo devolvidos em determinados momentos. + +## O Que Vem Depois? + +Vamos continuar "Projetando Scripts Reais no Bitcoin" na seção [§13.3: Expandindo o Bitcoin com os Scripts] (13_3_Empowering_Bitcoin_with_Scripts.md). \ No newline at end of file diff --git a/pt/13_3_Empowering_Bitcoin_with_Scripts.md b/pt/13_3_Empowering_Bitcoin_with_Scripts.md new file mode 100644 index 0000000..d9970e7 --- /dev/null +++ b/pt/13_3_Empowering_Bitcoin_with_Scripts.md @@ -0,0 +1,276 @@ +# 13.3: Expandindo o Bitcoin com os Scripts + +Os scripts de Bitcoin podem ir muito além dos instrumentos financeiros relativamente simples detalhados até o momento. Eles também são a base dos usos mais complexos da rede Bitcoin, conforme demonstrado por esses exemplos do mundo real de funcionalidade fora da cadeia (offchain), extraídos dos exemplos da Lightning Network no [BIP 112](https://github.com/bitcoin /bips/blob/master/bip-0112.mediawiki). + +## Bloqueio para a Lightning Network + +A [Lightning Network](https://rusty.ozlabs.org/?p=450) é um canal de pagamento que permite aos usuários retirar fundos offchain e se envolver em várias micro-transações antes de finalizar o canal de pagamento e trazer os fundos de volta para Bitcoin. Os benefícios incluem taxas mais baixas e velocidades de transação mais rápidas. Iremos discutir com riqueza maior de detalhes, com exemplos de como utilizá-la usando a linha de comando, começando no [Capítulo 18](18_0_Understanding_Your_Lightning_Setup.md). + +O [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) contém alguns exemplos de como essas transações offchain podem ser geradas, usando scripts de bloqueio do Bitcoin. + +### Bloqueio com transações de compromisso revogáveis + +O truque do Lightning é o fato de ele estar fora da blockchain. Para usar a Lightning, os participantes bloqueiam fundos em conjunto na blockchain do Bitcoin com uma transação multisig n-de-n. Em seguida, eles se envolvem em uma série de transações entre si. Cada nova "transação de compromisso" (commitment transaction) divide esses fundos de uma maneira diferente. Essas transações são parcialmente assinadas, mas _não são colocadas na blockchain_. + +Se temos uma massa de transações não publicadas, qualquer uma delas _pode_ ser colocada na Blockchain, portanto, como evitamos que um dos participantes volte a uma transação antiga que é mais benéfica para eles? A resposta é _revogação_. Um exemplo simplificado no BIP 112, que oferece um dos trampolins para o Lightning, mostra o processo. Nós damos ao participante que seria prejudicado pela reversão de uma transação revogada a capacidade de retirar os fundos ele mesmo se o outro participante tentar usar ilegitimamente a transação revogada. + +Por exemplo, suponha que Alice e Bob atualizem a transação de compromisso para dar mais fundos a Bob (Ou seja, Alice enviou fundos a Bob por meio da rede Lightning). Eles assinam parcialmente novas transações, mas cada um também oferece seu próprio ```revokeCode``` para as transações anteriores. Isso efetivamente garante que nenhum deles irão publicar as transações anteriores, porque isso permitiria que a contraparte reivindicasse os fundos anteriores. + +Então, como se parece a transação antiga? Foi uma transação de compromisso mostrando fundos destinados a Alice, antes que ela os desse a Bob. Ele tinha um script de bloqueio da seguinte maneira: +``` +OP_HASH160 + +OP_EQUAL +IF + +ELSE + <+24Hours> + OP_CHECKSEQUENCEVERIFY + OP_DROP + +ENDIF +OP_CHECKSIG +``` +O bloco ```ELSE``` é onde Alice conseguiu os fundos, após um atraso de 24 horas. No entanto, agora foi substituído. Afinal, esse é o ponto principal de um canal de pagamento na Lightning. Nesta situação, esta transação nunca deve ser publicada. Bob não tem incentivo para isso porque ele tem uma transação mais recente, que o beneficia mais porque ele recebeu parte dos fundos de Alice. Alice também não tem incentivo, porque ela perde o dinheiro se tentar retirar mais do que deve, por conta do ```revokeCode```. Assim, ninguém coloca a transação na blockchain e as transações offchain continuam. + +Vale a pena explorar como esse script funcionaria em uma variedade de situações, a maioria das quais envolve Alice tentando trapacear, revertendo para a transação mais antiga, que descreve os fundos _antes_ da Alice enviar os satoshis para Bob. + +#### Executando o script de bloqueio para enganar Alice, com código de revogação + +Alice poderia tentar usar o código de revogação que ela deu a Bob para reivindicar imediatamente os fundos. Ela escreve um script de bloqueio de ``` ```: +``` +Script: OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: OP_EQUAL +Stack: [ True ] +``` +O ```OP_EQUAL``` alimenta a instrução ```IF```. Como Alice usa o ```revokeCode```, ela entra no caminho que permite gatar os fundos imediatamente, reduzindo o resto do script para `````` (dentro da condicional) e com o ```OP_CHECKSIG``` (depois). +``` +Script: OP_CHECKSIG +Running: True IF +Stack: [ ] +``` +Maldição! Apenas Bob pode assinar imediatamente usando o ```redeemCode```! +``` +Script: OP_CHECKSIG +Stack: [ ] + +Script: +Running: OP_CHECKSIG +Stack: [ False ] +``` +#### Executando o script de bloqueio para enganar Alice, sem código de revogação + +E daí se Alice tentar usar sua própria assinatura, sem o ```revokeCode```? Ela usa o seguinte script de desbloqueio ``` ```. +``` +Script: 0 OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ 0 ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: 0 OP_HASH160 +Stack: [ <0Hash> ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ <0Hash> ] + +Script: IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: <0Hash> OP_EQUAL +Stack: [ False ] +``` +Agora reduzimos para a instrução ```ELSE``` e o que vem depois da condicional: +``` +Script: <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKSIG +Running: False IF +Stack: [ ] + +Script: OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKSIG +Stack: [ <+24Hours> ] +``` +E então Alice é frustrada de novo porque 24 horas não se passaram! +``` +Script: OP_DROP OP_CHECKSIG +Running: <+24Hours> OP_CHECKSEQUENCEVERIFY +Stack: [ <+24Hours> ] — Script EXITS +``` +#### Executando o script de bloqueio para a vitima, o Bob + +O que isso significa é que Bob tem 24 horas para recuperar os fundos se Alice tentar trapacear, usando o `````` e a assinatura como script de desbloqueio: +``` +Script: OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: OP_EQUAL +Stack: [ True ] + +Script: OP_CHECKSIG +Running: True IF +Stack: [ ] + +Script: OP_CHECKSIG +Stack: [ ] + +Script: +Running: OP_CHECKSIG +Stack: [ True ] +``` +#### Executando o Script de Bloqueio para a Virtuosa Alice + +Todas as transações de confirmação de Alice são bloqueadas com este mesmo script de bloqueio, quer tenham sido revogadas ou não. Isso significa que a transação de confirmação mais recente, que é a válida atualmente, também está bloqueada com ela. Alice nunca enviou uma transação mais recente para Bob e, portanto, nunca enviou a ele o ```revokeCode``` anterior. + +Nessa situação, ela poderia publicar virtuosamente a transação, fechando o canal. Ela coloca a transação na cadeia e espera 24 horas. Bob não pode fazer nada a respeito porque não possui o código de recuperação. Então, após a espera, Alice recupera os fundos. Bob pode fazer a mesma coisa com sua própria transação final. + +### Bloqueando com Contratos de Bloqueio de Tempo com Hash + +As Transações de Compromisso Revogável foram apenas um trampolim para a Lightning. A Lightning Network real usa um mecanismo mais complexo chamado [Contrato de Bloqueio de Tempo com Hash (ou no inglês, Hashed TimeLock Contract)](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) ou mais conhecido como HTLC. + +O principal objetivo dos HTLCs é criar uma rede abrangente de participantes. As transações não são mais apenas entre um par de participantes que entraram na rede juntos, mas agora podem ser várias pessoas que não estão associadas diretamente. Quando os fundos são enviados, uma string de transações é criada, cada uma delas bloqueada com um ```secretHash```. Quando o ```secretCode``` correspondente é revelado, toda a sequência de transações pode ser gasta. Isso é o que permite que transações singulares realmente se tornem uma rede. + +Também há um pouco mais de complexidade nos scripts de bloqueio da Lightning Network. Existem bloqueios separados para o remetente e o destinatário de cada transação que são mais amplamente divergentes do que as diferentes transações de compromisso mencionadas na seção anterior. Vamos mostrar os dois, para demonstrar o poder desses scripts de bloqueio, mas não vamos explicar como eles interagem entre si. + +#### Bloqueando a transação do destinatário + +Mais uma vez, vamos começar a olhar para a transação de compromisso da Alice, que mostra os fundos que ela recebeu: +``` +OP_HASH160 +OP_DUP + +OP_EQUAL +IF + <+24Hours> + OP_CHECKSEQUENCEVERIFY + OP_2DROP + +ELSE + + OP_EQUAL + OP_NOTIF + + OP_CHECKLOCKTIMEVERIFY + OP_DROP + ENDIF + +ENDIF +OP_CHECKSIG +``` +A chave para esses novos HTLCs é o ```secretHash```, que dissemos que é o que permite que uma transação se estenda pela rede. Quando a transação vai do remetente ao destinatário pretendido, o ```secretCode``` é revelado, o que permite que todos os participantes criem um ```secretHash``` e desbloqueiem toda a rede de pagamentos. + +Após o ```secretCode``` ter sido revelado, o caminho do ```IF``` é utilizado. Alice pode reivindicar os fundos 24 horas após a transação ser colocada na rede Bitcoin. + +No entanto, também há a oportunidade de Bob recuperar os fundos, que aparecem no caminho do ```ELSE```. Ele pode fazer isso se a transação foi revogada, mas Alice a coloca na blockchain de qualquer maneira, _ou se_ um tempo limite absoluto ocorrer. + +#### Bloqueando a transação do remetente + +Este é o script de bloqueio de transação de confirmação alternativo usado pelo remetente: +``` +OP_HASH160 +OP_DUP + +OP_EQUAL +OP_SWAP + +OP_EQUAL +OP_ADD +IF + +ELSE + + OP_CHECKLOCKTIMEVERIFY + <+24Hours> + OP_CHECKSEQUENCEVERIFY + OP_2DROP + +ENDIF +OP_CHECKSIG +``` +A parte inicial do script é bastante inteligente e vale a pena executá-la: +``` +Initial Script: OP_HASH160 OP_DUP OP_EQUAL OP_SWAP OP_EQUAL OP_ADD +Stack: [ ] + +Initial Script: OP_HASH160 OP_DUP OP_EQUAL OP_SWAP OP_EQUAL OP_ADD +Stack: [ ] + +Initial Script: OP_DUP OP_EQUAL OP_SWAP OP_EQUAL OP_ADD +Running: OP_HASH160 +Stack: [ ] + +Initial Script: OP_EQUAL OP_SWAP OP_EQUAL OP_ADD +Running: OP_DUP +Stack: [ ] + +Initial Script: OP_EQUAL OP_SWAP OP_EQUAL OP_ADD +Stack: [ ] + +Initial Script: OP_SWAP OP_EQUAL OP_ADD +Running: OP_EQUAL +Stack: [ ] + +Initial Script: OP_EQUAL OP_ADD +Running: OP_SWAP +Stack: [ ] + +Initial Script: OP_EQUAL OP_ADD +Stack: [ ] + +Initial Script: OP_ADD +Running: OP_EQUAL +Stack: [ ] + +Initial Script: +Running: OP_ADD +Stack: [ ] +``` +A execução do script revela que as verificações iniciais, acima do ```IF```/```ELSE```/```ENDIF```, determinam se o hash era _tanto_ o ```secretCode``` _ou_ o ```revokeCode```. Nesse caso, Alice pode pegar os fundos no primeiro bloco. Do contrário, Bob pode pegar os fundos, mas somente depois que Alice tiver sua chance e depois que o tempo limite de 24 horas e o tempo limite absoluto tiverem passado. + +#### Compreendendo os HTLCs + +Os HTLCs são bastante complexos e esta seção não tenta explicar todas as suas complexidades. A [visão geral](https://rusty.ozlabs.org/?p=462) escrita por Rusty Russell explica bem mais, e há ainda mais detalhes no seu artigo [Deployable-lightning](https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf). Mas não se preocupe se algumas das complexidades ainda ficarem meio nebulosas para nós, especialmente sobre o funcionamento das inter-relações dos dois scripts. + +Para os fins deste tutorial, existem duas lições importantes em relação aos HTLCs: + + * Entender que uma estrutura muito complexa como um HTLC pode ser criada usando o Script do Bitcoin; + * Analisar como executar cada um dos scripts HTLC. + +Vale a pena executar cada um dos dois scripts HTLC em cada uma de permutações, um item da pilha de cada vez. + +## Resumo: Expandindo o Bitcoin com os Scripts + +Estamos encerrando o exame dos scripts do bitcoin com uma visão de como eles podem ser realmente poderosos. Com 20 opcodes ou menos, um script Bitcoin pode formar a base de todo um canal de pagamento fora da blockchain. Da mesma forma, sidechains com conexões bidirecionais são o produto de menos de vinte opcodes, como também observado brevemente em [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki). + +Se já vimos a funcionalidade complexa do Bitcoin ou os sistemas adjacentes ao Bitcoin, eles provavelmente foram construídos em scripts Bitcoin. E agora temos todas as ferramentas para fazer o mesmo. + +## O Que Vem Depois? + +Vamos ficar "Usando o Tor" no [Capítulo 14: Usando o Tor](14_0_Using_Tor.md). + +Ou, se preferir, existem dois caminhos alternativos: + +Se quiser manter o foco no Bitcoin, vá para o "Programando com o RPC" no [Capítulo Quinze: Conversando com Bitcoind usando C](15_0_Talking_to_Bitcoind.md). + +Ou, se quisermos manter o foco na linha de comando porque não somos programadores, podemos pular para o [Capítulo Dezoito: Entendendo Nossa Configuração da Lightning](18_0_Understanding_Your_Lightning_Setup.md) para continuar nossa aula usando a linha de comando com a Lightning Network. \ No newline at end of file From fd345a450f3239ff6fe2316c200a709716f22389 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 5 Aug 2021 10:33:44 -0300 Subject: [PATCH 050/155] Review 10_0 --- ...ng_Bitcoin_Scripts_in_P2SH_Transactions.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md b/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md index 24b4992..81de75a 100644 --- a/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md +++ b/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md @@ -1,26 +1,26 @@ # Capítulo 10: Incorporando Scripts em Transações P2SH no Bitcoin -O Script do Bitcoin desce vários níveis de abstração, permitindo que controlemos minuciosamente as condições de resgate dos fundos. Mas, como realmente incorporamos esses scripts do Bitcoin nas transações que construímos até agora? A resposta é um novo tipo de transação de Bitcoin, o P2SH. +O Bitcoin Script desce vários níveis de abstração, permitindo que controlemos minuciosamente as condições de resgate dos fundos. Mas, como realmente incorporamos esses scripts do Bitcoin nas transações que construímos até agora? A resposta é um novo tipo de transação de Bitcoin, o P2SH. -## Objetivos deste capítulo +## Objetivos deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: * Projetar uma transação P2SH; * Aplicar um script P2SH Bitcoin. - + Os objetivos secundários do capítulo incluem a capacidade de: * Compreender o script P2SH; - * Compreender o Script Multisig; + * Compreender o script Multisig; * Compreender as várias variações dos scripts Segwit; * Entender como gastar fundos enviados a um P2SH. - + ## Tabela de conteúdo -* [Seção 1: Entendendo a Fundação do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) -* [Seção 2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md) -* [Seção 3: Executando um script Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) -* [Seção 4: Criando scripts multisig](10_4_Scripting_a_Multisig.md) -* [Seção 5: Criando um script Segwit](10_5_Scripting_a_Segwit_Script.md) +* [Seção 1: Compreendendo a Base do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) +* [Seção 2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md) +* [Seção 3: Executando um Script Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) +* [Seção 4: Programando um Multisig](10_4_Scripting_a_Multisig.md) +* [Seção 5: Programando um Script Segwit](10_5_Scripting_a_Segwit_Script.md) * [Seção 6: Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md) \ No newline at end of file From 161ad35fb50fb985065150904ba962a274748de4 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 5 Aug 2021 10:47:20 -0300 Subject: [PATCH 051/155] Review 10_1 --- ..._1_Understanding_the_Foundation_of_P2SH.md | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/pt/10_1_Understanding_the_Foundation_of_P2SH.md b/pt/10_1_Understanding_the_Foundation_of_P2SH.md index be5a000..557daee 100644 --- a/pt/10_1_Understanding_the_Foundation_of_P2SH.md +++ b/pt/10_1_Understanding_the_Foundation_of_P2SH.md @@ -1,10 +1,10 @@ -# 10.1: Entendendo a Fundação do P2SH +# 10.1: Compreendendo a Fundação do P2SH -Sabemos que os scripts do Bitcoin podem ser usados para controlar o resgate dos UTXOs. A próxima etapa é criar os nossos próprios scripts... Mas isso requer uma técnica muito específica. +Sabemos que os scripts do Bitcoin podem ser usados para controlar o resgate dos UTXOs. A próxima etapa é criar os nossos próprios scripts... mas isso requer uma técnica muito específica. ## Conhecendo os Padrões do Bitcoin -Aqui está a pegadinha sobre como usar scripts do Bitcoin: Por razões de segurança, a maioria dos nós do Bitcoin aceitará apenas seis tipos de transações de Bitcoin, ditas como "padrão". +Aqui está a pegadinha sobre como usar scripts do Bitcoin: Por razões de segurança, a maioria dos nodes do Bitcoin aceitará apenas seis tipos de transações de Bitcoin, ditas como "padrão". * __Pay to Public Key (P2PK)__ - O tipo de transação mais antiga e obsoleta (``` OP_CHECKSIG```) que foi substituída por uma mais segura, a P2PKH. * __Pay to Public Key Hash (P2PKH)__ - Uma transação padrão (```OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG```) que paga para o hash de uma chave pública. @@ -17,9 +17,9 @@ Então, como podemos descrever um script mais complexo do Bitcoin? A resposta es > :warning: **AVISO DE VERSÃO:** Os Scripts P2SH somente se tornaram padrão à partir do Bitcoin Core 0.10.0. Antes disso, apenas os scripts do tipo P2SH Multisigs eram permitidos. -## Compreendendo o script P2SH +## Compreendendo o Script P2SH -Você já viu uma transação P2SH quando criou uma multisig na seção [§6.1: Enviando uma Transação com Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md). Embora o multisig seja um dos tipos de transação padrão, o ```bitcoin-cli``` simplifica o uso dos multisigs, incorporando-os às transações P2SH, conforme descrito mais detalhadamente na seção [§10.4: Scripting a Multisig](10_4_Scripting_a_Multisig.md). +Você já viu uma transação P2SH quando criou um multisig na seção [§6.1: Enviando uma Transação com Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md). Embora o multisig seja um dos tipos de transação padrão, o ```bitcoin-cli``` simplifica o uso dos multisigs, incorporando-os às transações P2SH, conforme descrito mais detalhadamente na seção [§10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md). Então, vamos olhar mais uma vez para o ```scriptPubKey``` daquela transação multisig P2SH: ``` @@ -36,13 +36,13 @@ Então, vamos olhar mais uma vez para o ```scriptPubKey``` daquela transação m O script de bloqueio tem uma aparência bastante simples: ```OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL```. Como de costume, há um grande bloco de dados no meio. Este é um hash de outro script de bloqueio que está oculto (```redeemScript```) que só será revelado quando os fundos forem resgatados. Em outras palavras, o script de bloqueio padrão para um endereço P2SH é: ```OP_HASH160 OP_EQUAL```. -> :book: *** O que é um redemScript? *** Cada transação P2SH carrega a impressão digital de um script de bloqueio que fica oculto como um hash de 20 bytes. Quando uma transação P2SH é resgatada, o ```redeemScript``` completo (sem o hash) é incluído como parte do ```scriptSig```. O Bitcoin garantirá que o ```redeemScript``` corresponda ao hash. Então, ele realmente executa o ```redeemScript``` para ver se os fundos podem ser gastos (ou não). +> :book: ***O que é um redeemScript?*** Cada transação P2SH carrega a impressão digital de um script de bloqueio que fica oculto como um hash de 20 bytes. Quando uma transação P2SH é resgatada, o ```redeemScript``` completo (sem o hash) é incluído como parte do ```scriptSig```. O Bitcoin garantirá que o ```redeemScript``` corresponda ao hash. Então, ele realmente executa o ```redeemScript``` para ver se os fundos podem ser gastos (ou não). -Um dos elementos interessantes das transações P2SH é que nem o remetente nem o Blockchain sabem realmente o que é o ```redemScript```! Um remetente simplesmente envia para um endereço P2SH padronizado que é marcado com um prefixo "2" e, não se preocupa com a forma como o destinatário irá recuperar os fundos. +Um dos elementos interessantes das transações P2SH é que nem o remetente nem o Blockchain sabem realmente o que é o ```redeemScript```! Um remetente simplesmente envia para um endereço P2SH padronizado que é marcado com um prefixo "2" e não se preocupa com a forma como o destinatário irá recuperar os fundos. > :link: **TESTNET vs MAINNET:** Na testnet, o prefixo para endereços P2SH é ```2```, enquanto na mainnet, é ```3```. -## Entendendo como construir um script P2SH +## Compreendendo Como Construir um Script P2SH Como o script de bloqueio está visível para uma transação P2SH e é bem simples, criar uma transação desse tipo também é um tanto quanto fácil. Em teoria. Tudo o que precisamos fazer é criar uma transação cujo script de bloqueio inclua um hash de 20 bytes do ```redeemScript```. Esse hash é feito com o padrão ```OP_HASH160``` do Bitcoin. @@ -50,16 +50,16 @@ Como o script de bloqueio está visível para uma transação P2SH e é bem simp No geral, quatro etapas são necessárias: -1. Criar um script de bloqueio arbitrário com o script do Bitcoin; +1. Criar um script de bloqueio arbitrário com Bitcoin Script; 2. Criar uma versão serializada desse script de bloqueio; 3. Executar um hash SHA-256 nesses bytes serializados; 4. Executar um hash RIPEMD-160 nos resultados desse hash SHA-256. -Cada uma dessas etapas exige algum trabalho e, algumas delas podem ser bastante complexas. A boa notícia é que realmente não precisamos se preocupar com elas, porque são complexas o suficiente para que tenhamos uma API que faz o serviço para nós, normalmente. +Cada uma dessas etapas exige algum trabalho e algumas delas podem ser bastante complexas. A boa notícia é que realmente não precisamos nos preocupar com elas, porque são complexas o suficiente para que tenhamos uma API que faz o serviço para nós, normalmente. -Por enquanto, forneceremos apenas uma visão geral, para que entendamos o contexto da metodologia. Na seção [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md), forneceremos uma visão mais aprofundada da criação do script, caso queiramos entender a essência desse processo. +Por enquanto, forneceremos apenas uma visão geral, para que entendamos o contexto da metodologia. Na seção [§10.2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md), forneceremos uma visão mais aprofundada da criação do script, caso queiramos entender a essência desse processo. -## Entendendo como enviar uma transação do tipo P2SH +## Compreendendo Como Enviar uma Transação P2SH Então, como enviamos nossa transação P2SH? Novamente, a teoria é muito simples: @@ -68,15 +68,15 @@ Então, como enviamos nossa transação P2SH? Novamente, a teoria é muito simpl 3. Usamos esse hex como nosso ```scriptPubKey```; 4. Criamos o resto da transação. -Infelizmente, este é lugar momento em que precisaremos usar às APIs, em grande parte porque o ```bitcoin-cli``` não fornece nenhum suporte para a criação de transações P2SH. Mas, podemos resgatá-las sem problema. +Infelizmente, este é outro momento em que precisaremos usar APIs, em grande parte porque o ```bitcoin-cli``` não fornece nenhum suporte para a criação de transações P2SH. Mas, podemos resgatá-las sem problema. + +## Compreendendo Como Desbloquear uma Transação P2SH -## Entendendo como desbloquear uma transação do tipo P2SH - O truque para resgatar uma transação P2SH é que o destinatário deve ter salvo o script secreto de bloqueio serializado que foi codificado para criar o endereço P2SH. Isso se chama ```redeemScript``` porque é o que o destinatário precisa para resgatar os fundos. -Um ```scriptSig``` de desbloqueio para uma transação P2SH tem o seguinte formato:``` ... dados ... ```. Os ```dados``` devem ser _somente_ dados que são colocados na pilha, não operadores. O [BIP 16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki) os chama de assinaturas, mas isso não é um requisito real. +Um ```scriptSig``` de desbloqueio para uma transação P2SH tem o seguinte formato: ``` ... dados ... ```. Os ```dados``` devem ser _somente_ dados que são colocados na pilha, não operadores. O [BIP 16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki) os chama de assinaturas, mas isso não é um requisito real. -> :warning: **AVISO:** Embora assinaturas não sejam um requisito, um script P2SH na verdade não é muito seguro se não exigir pelo menos uma assinatura nas entradas. As razões para isso estão descritas na seção [§13.1: Escrevendo scripts de quebra-cabeças](13_1_Writing_Puzzle_Scripts.md). +> :warning: **AVISO:** Embora assinaturas não sejam um requisito, um script P2SH na verdade não é muito seguro se não exigir pelo menos uma assinatura nas entradas. As razões para isso estão descritas na seção [§13.1: Escrevendo Scripts Quebra-Cabeças](13_1_Writing_Puzzle_Scripts.md). Quando um UTXO é resgatado, ele é executado em duas rodadas de verificação: @@ -85,16 +85,16 @@ Quando um UTXO é resgatado, ele é executado em duas rodadas de verificação: 3. Em segundo lugar, o ```redeemScript``` é executado usando os dados anteriores que foram colocados na pilha; 4. Se a segunda rodada de verificação _também_ for bem-sucedida, o UTXO é desbloqueado. -Considerando que não podemos criar facilmente uma transação P2SH sem uma API, devemos ser capazes de resgatar facilmente uma transação P2SH com o ```bitcoin-cli```. Na verdade, já fizemos isso na seção [§6.2: Gastando uma Transação com Multsig] (06_2_Spending_a_Transaction_to_a_Multisig.md). O processo exato é descrito na seção [§10.6: Gastando uma transação P2SH](10_6_Spending_a_P2SH_Transaction.md), após terminarmos com todas as complexidades da criação de uma transação P2SH. +Considerando que não podemos criar facilmente uma transação P2SH sem uma API, devemos ser capazes de resgatar facilmente uma transação P2SH com o ```bitcoin-cli```. Na verdade, já fizemos isso na seção [§6.2: Gastando uma Transação com Multisig](06_2_Spending_a_Transaction_to_a_Multisig.md). O processo exato é descrito na seção [§10.6: Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md), após terminarmos com todas as complexidades da criação de uma transação P2SH. -> :warning: **AVISO:** Podemos criar uma transação perfeitamente válida com um redemScript com o hash correto, mas se o redemScript não funcionar, ou não funcionar corretamente, os fundos serão perdidos para sempre. É por isso que é importantíssimo testar os Scripts, conforme discutido na seção [§9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md). +> :warning: **AVISO:** Podemos criar uma transação perfeitamente válida com um redeemScript com o hash correto, mas se o redeemScript não funcionar, ou não funcionar corretamente, os fundos serão perdidos para sempre. É por isso que é importantíssimo testar os scripts, conforme discutido na seção [§9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md). -## Resumo: Entendendo a Fundação do P2SH +## Resumo: Compreendendo a Fundação do P2SH -Os scripts arbitrários do Bitcoin não são o padrão neste sistema. No entanto, podemos incorporá-los em transações padrão usando o tipo de endereço P2SH. Precisamos apenas fazer um hash do nosso script como parte do script de bloqueio, então o revelamos e executamos como parte do script de desbloqueio. Contanto que também possamos satisfazer o ```redeemScript```, o UTXO poderá ser gasto. +Scripts arbitrários não são o padrão no Bitcoin. No entanto, podemos incorporá-los em transações padrão usando o tipo de endereço P2SH. Precisamos apenas fazer um hash do nosso script como parte do script de bloqueio, então o revelamos e executamos como parte do script de desbloqueio. Contanto que também possamos satisfazer o ```redeemScript```, o UTXO poderá ser gasto. -> :fire: ***Qual é o poder do P2SH?*** Já sabemos o poder do script do Bitcoin, que nos permite criar Contratos Inteligentes mais complexos de todos os tipos. O P2SH é o que realmente libera esse poder, nos permitindo que incluamos o Script arbitrário do Bitcoin em transações padrão. +> :fire: ***Qual é o poder do P2SH?*** Já sabemos o poder do Bitcoin Script, que nos permite criar Contratos Inteligentes mais complexos de todos os tipos. O P2SH é o que realmente libera esse poder, nos permitindo que incluamos o Script arbitrário do Bitcoin em transações padrão. -## O que vem depois? +## O Que Vem Depois? -Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md). \ No newline at end of file +Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md). \ No newline at end of file From 528a272d185662cc57a9e447905f387760b3d116 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 5 Aug 2021 11:06:15 -0300 Subject: [PATCH 052/155] Review 10_2 --- pt/10_2_Building_the_Structure_of_P2SH.md | 38 +++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/pt/10_2_Building_the_Structure_of_P2SH.md b/pt/10_2_Building_the_Structure_of_P2SH.md index ebdb344..4cfc3b9 100644 --- a/pt/10_2_Building_the_Structure_of_P2SH.md +++ b/pt/10_2_Building_the_Structure_of_P2SH.md @@ -1,4 +1,4 @@ -# 10.2: Construindo a Estrutura de P2SH +# 10.2: Construindo a Estrutura do P2SH Na seção anterior, apresentamos uma visão geral da teoria de como criar as transações P2SH para armazenar os scripts de Bitcoin. Na prática, fazer isso é _muito mais difícil_, mas por uma questão de integridade, vamos examinar minuciosamente todos os pontos. Provavelmente, isso não é algo que faríamos sem uma API, então, se ficar muito complicado, esteja ciente de que retornaremos aos scripts originais de alto nível mais pra frente. @@ -6,17 +6,17 @@ Na seção anterior, apresentamos uma visão geral da teoria de como criar as tr Qualquer transação P2SH começa com um script de bloqueio. Esse é o assunto dos capítulos 9, 11 e 12. Podemos usar qualquer um dos métodos de script do Bitcoin descritos nestes capítulos para criar qualquer tipo de script de bloqueio, desde que o ```redeemScript``` serializado resultante tenha 520 bytes ou menos. -> :book: ***Por que os scripts P2SH são limitados a 520 bytes?*** Como muitas coisas no Bitcoin, a resposta é a compatibilidade com as versões anteriores: Novas funcionalidades devem ser constantemente criadas dentro das antigas restrições do sistema. Nesse caso, 520 bytes é o máximo que pode ser colocado na pilha de uma vez. Como todo o redemScript é colocado na pilha como parte do processo de resgate, ele está limitado a essa quantidade. +> :book: ***Por que os scripts P2SH são limitados a 520 bytes?*** Como muitas coisas no Bitcoin, a resposta é a compatibilidade com as versões anteriores: novas funcionalidades devem ser constantemente criadas dentro das antigas restrições do sistema. Nesse caso, 520 bytes é o máximo que pode ser colocado na pilha de uma vez. Como todo o redeemScript é colocado na pilha como parte do processo de resgate, ele está limitado à essa quantidade. -## Serializando um script de bloqueio da maneira mais difícil +## Serializando um Script de Bloqueio da Maneira Difícil -Depois de criar um script de bloqueio, precisamos serializá-lo antes que possamos ser inseridos no Bitcoin. Este é um processo de duas partes. Primeiro, devemos transformá-lo em um hexcode, para então transformar esse hex em binário. +Depois de criar um script de bloqueio, precisamos serializá-lo antes que possam ser inseridos no Bitcoin. Este é um processo de duas partes. Primeiro, devemos transformá-lo em um hexcode, para então transformar esse hex em binário. -### Criando o código hexadecimal +### Criando o Código Hexadecimal Criar o hexcode necessário para serializar um script é uma simples tradução, mas ao mesmo tempo, algo complexo o suficiente para ir além de qualquer script shell que provavelmente escreveremos. Esta etapa é um dos principais motivos pelos quais precisamos de uma API para criar as transações P2SH. -Podemos criar um hexcode percorrendo nosso script de bloqueio e transformando cada elemento em um comando hexadecimal de um byte, possivelmente seguido por dados adicionais. De acordo com o guia da [página Bitcoin Wiki Script](https://en.bitcoin.it/wiki/ Roteiro): +Podemos criar um hexcode percorrendo nosso script de bloqueio e transformando cada elemento em um comando hexadecimal de um byte, possivelmente seguido por dados adicionais. De acordo com o guia da [página Wiki do Bitcoin Script](https://en.bitcoin.it/wiki/Script): * Os operadores são traduzidos para o byte correspondente para esse opcode; * As constantes 1-16 são convertidas para opcodes 0x51 a 0x61 (OP_1 a OP_16); @@ -24,7 +24,7 @@ Podemos criar um hexcode percorrendo nosso script de bloqueio e transformando ca * Outras constantes são precedidas por opcodes 0x01 a 0x4e (OP_PUSHDATA, com o número especificando de quantos bytes adicionar); * Os inteiros são traduzidos em hexadecimal usando a notação de magnitude com sinal _little-endian_. -### Traduzindo os tipos inteiros +### Traduzindo os Números Inteiros Os inteiros são a parte mais problemática de uma tradução de script de bloqueio. @@ -48,7 +48,7 @@ $ lehex=$(echo $hex | tac -rs .. | echo "$(tr -d '\n')") $ echo $lehex 9f7b2a5c ``` -Além disso, sempre precisaremos saber o tamanho dos dados que colocamos na pilha, para que possa precedê-los com o opcode adequado. Podemos apenas lembrar que cada dois caracteres hexadecimais é um byte. Ou podemos usar o comando ```echo -n``` com o pipe para ```wc -c``` e dividi-lo ao meio: +Além disso, sempre precisaremos saber o tamanho dos dados que colocamos na pilha, para que possamos precedê-los com o opcode adequado. Podemos apenas lembrar que cada dois caracteres hexadecimais é um byte. Ou podemos usar o comando ```echo -n``` com o pipe para ```wc -c``` e dividi-lo ao meio: ``` $ echo -n $lehex | wc -c | awk '{print $1/2}' 4 @@ -66,7 +66,7 @@ $ echo $neglehex Para completar nossa serialização, traduzimos o código hexadecimal em binário. Na linha de comando, isso requer apenas uma invocação simples do ```xxd -r -p```. No entanto, provavelmente desejamos fazer isso tudo junto, para também fazer o hash do script... -## Executando o script de conversão de tipos inteiros +## Executando o Script de Conversão de Inteiros Um script completo para alterar um número inteiro entre -2147483647 e 2147483647 para uma representação de magnitude assinada do tipo _little-endian_ em hexadecimal pode ser encontrado no [diretório de código src](src/10_2_integer2lehex.sh). Podemos baixar o ```integeer2lehex.sh```. @@ -91,19 +91,19 @@ Length: 4 bytes Hexcode: 049f7b2adc ``` -## Analisando um P2SH Multisig +## Analisando um Multisig P2SH Para entender melhor o processo, faremos a engenharia reversa do multisig P2SH que criamos na seção [§6.1: Enviando uma Transação com Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md). Dê uma olhada no ```redeemScript``` que usamos, que agora sabemos que é a versão hexadecimal do script de bloqueio: ``` 522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae ``` -Podemos traduzir isso de volta para o script manualmente usando a [página do Bitcoin Wiki Script](https://en.bitcoin.it/wiki/Script) como uma referência. Basta olhar para um byte (dois caracteres hexadecimais) de dados por vez, a menos que nos seja dito para olhar pra mais bytes usando OP_PUSHDATA (um opcode no intervalo de 0x01 a 0x4e). +Podemos traduzir isso de volta para o script manualmente usando a [página Wiki do Bitcoin Script](https://en.bitcoin.it/wiki/Script) como uma referência. Basta olhar para um byte (dois caracteres hexadecimais) de dados por vez, a menos que nos seja dito para olhar pra mais bytes usando OP_PUSHDATA (um opcode no intervalo de 0x01 a 0x4e). Todo o Script será dividido da seguinte forma: ``` 52 / 21 / 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 / 21 / 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 / 52 / ae ``` -Aqui está o que as partes individuais significam: +Aqui está o que cada parte individual significa: * 0x52 = OP_2 * 0x21 = OP_PUSHDATA 33 bytes (hex: 0x21) @@ -113,7 +113,7 @@ Aqui está o que as partes individuais significam: * 0x52 = OP_2 * 0xae = OP_CHECKMULTISIG -Em outras palavras, esse ```redeemScript``` era uma tradução de ```2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG``` Voltaremos a este script na seção [§10.4: Criando scripts multisig](10_4_Scripting_a_Multisig.md) quando detalharmos exatamente como os multisigs funcionam dentro do paradigma P2SH. +Em outras palavras, esse ```redeemScript``` era uma tradução de ```2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG```. Voltaremos a este script na seção [§10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md) quando detalharmos exatamente como os multisigs funcionam dentro do paradigma P2SH. Se gostarmos de fazer o trabalho manual com esse tipo de tradução no futuro, podemos usar o ```decodescript bitcoin-cli```: ``` @@ -141,7 +141,7 @@ $ bitcoin-cli -named decodescript hexstring=522102da2f10746e9778dd57bd0276a4f841 ``` É especialmente útil para verificar nosso trabalho durante a serialização. -## Serializando um script de bloqueio da maneira mais fácil +## Serializando um Script de Bloqueio da Maneira Fácil Quando instalamos o ```btcdeb``` na seção [§9.3](09_3_Testing_a_Bitcoin_Script.md) também instalamos o ```btcc``` que pode ser usado para serializar scripts do Bitcoin: ``` @@ -154,7 +154,7 @@ Isso é muito mais fácil do que fazer tudo na mão! Considere também o compilador em Python, [Transaction Script Compiler](https://github.com/Kefkius/txsc), que traduz de trás pra frente também. -## Fazendo o hash de um script serializado +## Fazendo o Hash de um Script Serializado Depois de criar um script de bloqueio e serializá-lo, a terceira etapa na criação de uma transação P2SH é fazer o hash do script de bloqueio. Conforme observado anteriormente, um hash OP_HASH160 de 20 bytes é criado por meio de uma combinação de um hash SHA-256 e um hash RIPEMD-160. O hash de um script serializado, portanto, requer dois comandos: ```openssl dgst -sha256 -binary``` que faz o hash SHA-256 e produz um binário a ser enviado no pipe, então o ```openssl dgst -rmd160``` pega o fluxo do binário, faz um RIPEMD- 160 hash e, finalmente, gera um código hexadecimal legível. @@ -165,7 +165,7 @@ $ echo -n $redeemScript | xxd -r -p | openssl dgst -sha256 -binary | openssl dgs (stdin)= a5d106eb8ee51b23cf60d8bd98bc285695f233f3 ``` -## Criando uma transação P2SH +## Criando uma Transação P2SH Criar o hash de 20 bytes apenas fornece o hash no centro de um script de bloqueio P2SH. Ainda precisamos colocá-lo junto com os outros opcodes que criam uma transação P2SH padrão: ```OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL```. @@ -175,8 +175,8 @@ Podemos observar que o ```hex scriptPubKey``` para a transação P2SH Script ir ## Resumo: Construindo a Estrutura de P2SH -Na verdade, a criação do script de bloqueio P2SH entra ainda mais nas entranhas do Bitcoin. Embora seja útil saber como tudo isso funciona em um nível muito baixo, é mais provável que tenhamos uma API cuidando de todo o trabalho pesado para nós. Nossa tarefa será simplesmente criar o Script Bitcoin para fazer o bloqueio... Que é o tópico principal dos capítulos 9, 11 e 12. +Na verdade, a criação do script de bloqueio P2SH entra ainda mais nas entranhas do Bitcoin. Embora seja útil saber como tudo isso funciona em um nível muito baixo, é mais provável que tenhamos uma API cuidando de todo o trabalho pesado para nós. Nossa tarefa será simplesmente criar o Script Bitcoin para fazer o bloqueio... que é o tópico principal dos capítulos 9, 11 e 12. -## O que vem depois? +## O Que Vem Depois? -Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.3: Executando um script Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md). \ No newline at end of file +Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.3: Executando um Script no Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md). \ No newline at end of file From b042cd480de33640e3cfd1d21ba61c52af68a52c Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 5 Aug 2021 11:11:42 -0300 Subject: [PATCH 053/155] Review 10_3 --- pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md b/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md index c45b98b..fb2bd48 100644 --- a/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md +++ b/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md @@ -1,6 +1,6 @@ -# 10.3: Executando um script Bitcoin com P2SH +# 10.3: Executando um Script no Bitcoin com P2SH -Agora que conhecemos a teoria e a prática por trás dos endereços P2SH, estamos prontos para transformar um script de Bitcoin não padrão em uma transação real. Vamos utilizar o script de bloqueio simples da seção [§9.2: Executando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md), `OP_ADD 99 OP_EQUAL`. +Agora que conhecemos a teoria e a prática por trás dos endereços P2SH, estamos prontos para transformar um script de Bitcoin não-padrão em uma transação real. Vamos utilizar o script de bloqueio simples da seção [§9.2: Executando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md), `OP_ADD 99 OP_EQUAL`. ## Criando uma transação P2SH @@ -12,7 +12,7 @@ Para bloquear uma transação com este script, precisamos fazer o seguinte: * Não se preocupe com a conversão porque é apenas um byte. 3. OP_EQUAL = 0x87 - uma tradução simples do opcode; 4. `````` = "93016387". - + ``` $ btcc OP_ADD 99 OP_EQUAL 93016387 @@ -26,11 +26,11 @@ $ btcc OP_ADD 99 OP_EQUAL Podemos então criar uma transação usando o ```scriptPubKey```, provavelmente através de uma API. -## Desbloqueando a transação P2SH +## Desbloqueando a Transação P2SH Para desbloquear essa transação, é necessário que o destinatário produza um ```scriptSig``` que acrescente duas constantes, totalizando noventa e nove, ao script serializado:```1 98 ```. -### Executando a primeira rodada de validação +### Executando a Primeira Rodada de Validação O processo de desbloqueio da transação P2SH começa com uma primeira rodada de validação, que nada mais é que a verificação se o script de resgate corresponde ao valor hash no script de bloqueio. @@ -59,13 +59,13 @@ Script: Running: OP_EQUAL Stack: [ 1 98 True ] ``` -O script termina com um ```True``` no topo da pilha e, portanto, foi bem-sucedido... Embora haja outro fragmento abaixo dele. +O script termina com um ```True``` no topo da pilha e, portanto, foi bem-sucedido... embora haja outro fragmento abaixo dele. Porém, por se tratar de um script P2SH, a execução não está concluída. -### Executando a segunda rodada de validação +### Executando a Segunda Rodada de Validação -Para a segunda rodada de validação, vamos verificar se os valores no script de desbloqueio satisfazem o ```redeemScript```: Desserializando o ```redeemScript``` ("93016387" = "OP_ADD 99 OP_EQUAL") e executando-o usando os itens no ```scriptSig``` anterior para o script serializado: +Para a segunda rodada de validação, vamos verificar se os valores no script de desbloqueio satisfazem o ```redeemScript```: desserializando o ```redeemScript``` ("93016387" = "OP_ADD 99 OP_EQUAL") e executando-o usando os itens no ```scriptSig``` anterior para o script serializado: ``` Script: 1 98 OP_ADD 99 OP_EQUAL @@ -90,10 +90,10 @@ Stack: [ True ] ``` Com essa segunda validação _também_ verdadeira, o UTXO agora pode ser gasto! -## Resumo: Executando um script Bitcoin com P2SH +## Resumo: Executando um Script no Bitcoin com P2SH Depois de conhecer a técnica de construção dos P2SH, qualquer script pode ser embutido em uma transação Bitcoin, e depois de entender a técnica de validação do P2SH, é fácil executar os scripts em duas fases. -## O que vem depois? +## O Que Vem Depois? -Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.4: Criando scripts multisig](10_4_Scripting_a_Multisig.md). \ No newline at end of file +Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md). \ No newline at end of file From 66cd73989bcf3280af279c664bca989d3f5f0684 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 5 Aug 2021 11:38:52 -0300 Subject: [PATCH 054/155] Review 10_4 --- pt/10_4_Scripting_a_Multisig.md | 61 +++++++++++++++++---------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/pt/10_4_Scripting_a_Multisig.md b/pt/10_4_Scripting_a_Multisig.md index f254bc7..980dd99 100644 --- a/pt/10_4_Scripting_a_Multisig.md +++ b/pt/10_4_Scripting_a_Multisig.md @@ -1,4 +1,4 @@ -# 10.4: Criando scripts multisig +# 10.4: Programando um Multisig Antes de encerrarmos esta introdução ao script P2SH, vale a pena examinar um exemplo mais realista. Desde a seção [§6.1](06_1_Sending_a_Transaction_to_a_Multisig.md), dissemos casualmente que a interface ```bitcoin-cli``` envolve nossa transação multisig em uma transação P2SH. Na verdade, esta é a metodologia padrão para a criação dos multisigs na Blockchain do Bitcoin. Veja como isso funciona, com mais detalhes. @@ -7,10 +7,10 @@ Antes de encerrarmos esta introdução ao script P2SH, vale a pena examinar um e As transações multisig são criadas no Bitcoin usando o código ```OP_CHECKMULTISIG```. O ```OP_CHECKMULTISIG``` espera uma longa sequência de argumentos que se parece com isto: ```0 ... sigs ... ... endereços ... OP_CHECKMULTISIG```. Quando o ```OP_CHECKMULTISIG``` é executado, ele faz o seguinte: 1. Retira o primeiro valor da pilha (``````); -2. Retira os valores "n" da pilha como endereços Bitcoin (chaves públicas com hash); +2. Retira "n" valores da pilha como endereços Bitcoin (hash de chaves públicas); 3. Retira o próximo valor da pilha (``````); -4. Retira os valores "m" da pilha como assinaturas potenciais; -5. Retire um `0` da pilha devido a um erro na codificação original; +4. Retira "m" valores da pilha como assinaturas potenciais; +5. Retira um `0` da pilha devido a um erro na codificação original; 6. Compara as assinaturas com os endereços de Bitcoin; 7. Coloca ```True``` ou ```False``` dependendo do resultado. @@ -18,27 +18,27 @@ Os operandos do ```OP_MULTISIG``` são tipicamente divididos, com o ```0``` e as O requisito para que o ```0``` seja o primeiro operando para o ```OP_CHECKMULTISIG``` é uma regra de consenso. Como a versão original do ```OP_CHECKMULTISIG``` acidentalmente retirou um item extra da pilha, o Bitcoin deve seguir esse padrão para sempre, para que os scripts de resgate complexos daquele período de tempo não sejam acidentalmente quebrados, tornando fundos antigos irrecuperáveis. -> :book: ***O que é uma regra de consenso?*** Estas são as regras que os nodes do Bitcoin seguem para trabalharem juntos. Em grande parte, eles são definidos pelo código do Bitcoin Core. Essas regras incluem muitas regras óbvias, como o limite de quantos Bitcoins são criados para cada bloco e as regras de como as transações podem ser respondidas. No entanto, eles também incluem correções para bugs que apareceram ao longo dos anos, porque uma vez que um bug foi introduzido na base de código do Bitcoin, ele deve ser continuamente suportado, para que os antigos Bitcoins não se tornem impossíveis de serem gastos. +> :book: ***O que é uma regra de consenso?*** Estas são as regras que os nodes do Bitcoin seguem para trabalharem juntos. Em grande parte, eles são definidos pelo código do Bitcoin Core. Essas regras incluem muitas regras óbvias, como o limite de quantos Bitcoins são criados para cada bloco e as regras de como as transações podem ser respondidas. No entanto, eles também incluem correções para bugs que apareceram ao longo dos anos, porque uma vez que um bug foi introduzido na base de código do Bitcoin, ele deve ser continuamente suportado, para que os antigos bitcoins não se tornem impossíveis de serem gastos. -## Criando uma Transação Multisig Bruta +## Criando um Multisig Bruto -Conforme discutido na seção [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md), os multisigs são um dos tipos de transação padrão do Bitcoin. Uma transação pode ser criada com um script de bloqueio que usa o comando ```OP_CHECKMULTISIG``` bruto e será aceito em um bloco. Esta é a metodologia clássica para usar multisigs no Bitcoin. +Conforme discutido na seção [§10.2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md), os multisigs são um dos tipos de transação padrão do Bitcoin. Uma transação pode ser criada com um script de bloqueio que usa o comando ```OP_CHECKMULTISIG``` bruto e será aceita em um bloco. Esta é a metodologia clássica para usar multisigs no Bitcoin. -Como exemplo, iremos revisitar o multisig criado na seção [§8.1](08_1_Sending_a_Transaction_with_a_Locktime.md) uma última vez e construir um novo script de bloqueio para ele usando esta metodologia. Como devemos nos lembrar, essa transação era uma multisig 2 de 2 construída a partir do ```$address1``` e ```$address2```. +Como exemplo, iremos revisitar o multisig criado na seção [§8.1](08_1_Sending_a_Transaction_with_a_Locktime.md) uma última vez e construir um novo script de bloqueio para ele usando esta metodologia. Como devemos nos lembrar, essa transação era uma multisig 2 de 2 construída a partir de ```$address1``` e ```$address2```. -Como o script de bloqueio ```OP_CHECKMULTISIG``` requer o "m"(```2```), os endereços, e o "n"(```2```), poderíamos escrever o seguinte ```scriptPubKey```: +Como o script de bloqueio ```OP_CHECKMULTISIG``` requer o "m" (```2```), os endereços, e o "n" (```2```), poderíamos escrever o seguinte ```scriptPubKey```: ``` 2 $address1 $address2 2 OP_CHECKMULTISIG ``` -Se isso parece familiar, é porque é o multisig que desserializamos no [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md). +Se isso parece familiar, é porque é o multisig que desserializamos no [§10.2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md). ``` 2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG ``` -> **AVISO:** Para assinaturas `OP_CHECKMULTISIG` clássicas, o "n"deve ser ≤ 3 para que a transação seja padrão. +> **AVISO:** Para assinaturas `OP_CHECKMULTISIG` clássicas, o "n" deve ser ≤ 3 para que a transação seja padrão. -## Desbloqueando uma Transação Multisig Bruta +## Desbloqueando um Multisig Bruto -O ```scriptSig``` para um endereço multisig padrão deve então enviar os operandos ausentes para o ```OP_CHECKMULTISIG```: Um ```0``` seguido por assinaturas "m". Por exemplo: +O ```scriptSig``` para um endereço multisig padrão deve então enviar os operandos ausentes para o ```OP_CHECKMULTISIG```: um ```0``` seguido por "m" assinaturas. Por exemplo: ``` 0 $signature1 $signature2 ``` @@ -80,29 +80,29 @@ Então, mais um item é retirado por engano: Running: OP_CHECKMULTISIG Stack: [ ] ``` -Depois, o ```OP_CHECKMULTISIG``` completa a operação comparando as assinaturas "m" aos endereços "n": +Depois, o ```OP_CHECKMULTISIG``` completa a operação comparando as "m" assinaturas aos "n" endereços: ``` Script: Stack: [ True ] ``` -## Compreendendo as limitações de scripts multisig brutos +## Compreendendo as Limitações dos Scripts Multisig Brutos Infelizmente, a técnica de incorporar um multisig bruto em uma transação tem algumas desvantagens notáveis: -1. Como não há formato de endereço padrão para as multisigs, cada remetente deve: inserir um script multisig longo e complicado; ter um software que permite fazer isso e; ser confiável para não bagunçar nada. -2. Como os multisigs podem ser muito mais longos do que os scripts padrão de bloqueio, isso significa mais custos. Isso requer taxas de transação mais altas para o remetente e cria mais incômodo para cada node. +1. Como não há formato de endereço padrão para os multisigs, cada remetente deve: inserir um script multisig longo e complicado; ter um software que permite fazer isso; e ser confiável para não bagunçar nada. +2. Como os multisigs podem ser muito mais longos do que os scripts padrão de bloqueio, a blockchain aumenta o custo. Isso requer taxas de transação mais altas para o remetente e cria mais incômodo para cada node. -Geralmente eram problemas com qualquer tipo de script complexo do Bitcoin, mas rapidamente se tornaram problemas muito reais quando aplicados as multisigs, que foram alguns dos primeiros scripts complexos a serem amplamente usados ​​na rede Bitcoin. As transações P2SH foram criadas para resolver esses problemas, começando em 2012. +Geralmente, esses eram problemas com qualquer tipo de script complexo do Bitcoin, mas rapidamente se tornaram problemas muito reais quando aplicados aos multisigs, que foram alguns dos primeiros scripts complexos a serem amplamente usados ​​na rede Bitcoin. As transações P2SH foram criadas para resolver esses problemas, começando em 2012. -> :book: ***O que é um multisig P2SH?*** As Multisigs P2SH foram a primeira implementação de transações P2SH. Elas simplesmente empacotam uma transação multisig padrão em uma transação P2SH padrão. Isso permite a padronização de endereços, reduz o armazenamento de dados e, aumenta as contagens "m" e "n". +> :book: ***O que é um multisig P2SH?*** Os Multisigs P2SH foram a primeira implementação de transações P2SH. Eles simplesmente empacotam uma transação multisig padrão em uma transação P2SH padrão. Isso permite a padronização de endereços, reduz o armazenamento de dados e, aumenta as contagens "m" e "n". -## Criando um P2SH Multisig +## Criando um Multisig P2SH -As Multisigs P2SH são a metodologia moderna para a criação de multisigs na Blockchain. Elas podem ser criadas de forma muito simples, usando o mesmo processo visto nas seções anteriores. +Os Multisigs P2SH são a metodologia moderna para a criação de multisigs na Blockchain. Elas podem ser criadas de forma muito simples, usando o mesmo processo visto nas seções anteriores. -### Criando a Bloqueio para o P2SH Multisig +### Criando o Bloqueio para o Multisig P2SH -Para criar uma multisig P2SH, siga as etapas padrão para criar um script de bloqueio P2SH: +Para criar um multisig P2SH, siga as etapas padrão para criar um script de bloqueio P2SH: 1. Serializar ```2 $ address1 $ address2 2 OP_CHECKMULTISIG```; 1. `````` = "522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98dfaed8d287f76c570e98dfaed8d287f76c570123582e38ed8287fab56c570123582e38ed8287fab56. @@ -113,13 +113,14 @@ Para criar uma multisig P2SH, siga as etapas padrão para criar um script de blo 4. Produzir um script de bloqueio P2SH Multisig que inclua o hash do script (```OP_HASH160 OP_EQUAL```). 1. ```scriptPubKey``` =" a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387 ". + Você pode criar uma transação usando o ```scriptPubKey```. -## Desbloqueando o P2SH Multisig +## Desbloqueando o Multisig P2SH Para desbloquear essa transação multisig, é necessário que o destinatário produza um scriptSig que inclua as duas assinaturas e o ```redeemScript```. -### Executando a primeira rodada de validação do P2SH +### Executando a Primeira Rodada de Validação do P2SH Para desbloquear o multisig P2SH, primeiro vamos confirmar o script: @@ -128,7 +129,7 @@ Para desbloquear o multisig P2SH, primeiro vamos confirmar o script: 3. Validar o ```0 $ assinatura1 $ assinatura2 OP_HASH160 OP_EQUAL```; 4. Teremos êxito se o `````` corresponder ao ``````. -### Executando a segunda rodada de validação do P2SH +### Executando a Segunda Rodada de Validação do P2SH Em seguida, vamos executar o script multisig: @@ -140,10 +141,10 @@ Em seguida, vamos executar o script multisig: Agora sabemos como a transação multisig da seção [§6.1](06_1_Sending_a_Transaction_to_a_Multisig.md) foi realmente criada, como foi validada para ser gasta e o motivo pelo qual o ```redeemScript``` foi tão importante. -## Resumo: Criando scripts multisig +## Resumo: Programando um Multisig -As multisigs são um tipo de transação padrão, mas são um pouco complicadas de serem usadas. Então, eles são regularmente incorporadas em transações P2SH, como foi o caso na seção [§6.1](06_1_Sending_a_Transaction_to_a_Multisig.md) quando criamos nossas primeiras multisigs. O resultado é mais limpo, menor e mais padronizado, porém, o mais importante, é um ótimo exemplo do mundo real de como os scripts P2SH realmente funcionam. +Os multisigs são um tipo de transação padrão, mas são um pouco complicados de serem usados. Então, eles são regularmente incorporados em transações P2SH, como foi o caso na seção [§6.1](06_1_Sending_a_Transaction_to_a_Multisig.md) quando criamos nossos primeiros multisigs. O resultado é mais limpo, menor e mais padronizado, porém, e mais importante, é um ótimo exemplo do mundo real de como os scripts P2SH realmente funcionam. -## O que vem depois? +## O Que Vem Depois? -Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.5: Crigando um script Segwit](10_5_Scripting_a_Segwit_Script.md). \ No newline at end of file +Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.5: Programando um Script Segwit](10_5_Scripting_a_Segwit_Script.md). \ No newline at end of file From 4f4b624b356deda07d22d0384b23d1ec885ff256 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 5 Aug 2021 11:56:55 -0300 Subject: [PATCH 055/155] Review 10_5 --- pt/10_5_Scripting_a_Segwit_Script.md | 30 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pt/10_5_Scripting_a_Segwit_Script.md b/pt/10_5_Scripting_a_Segwit_Script.md index 04d2868..b485f3f 100644 --- a/pt/10_5_Scripting_a_Segwit_Script.md +++ b/pt/10_5_Scripting_a_Segwit_Script.md @@ -1,13 +1,13 @@ -# 10.5: Criando um script Segwit -> :information_source: * NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. +# 10.5: Programando um Script Segwit +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -O segwit introduziu uma série de novas opções para tipos de endereço e também de scripts. Na seção [§9.5: Scripting a P2WPKH](09_5_Scripting_a_P2WPKH.md) explicamos como o novo tipo de endereço Bech32 variou os scripts padrão encontrados na maioria das transações tradicionais. Este capítulo examina os três outros tipos de scripts introduzidos pela atualização do Segwit: O P2SH-Segwit (que era o endereço "Segwit aninhado" de transição, quando o Segwit passou a ser usado), o P2WSH (que é o Segwit equivalente ao endereço P2SH , assim como P2WPKH é o Segwit equivalente ao endereço P2PKH) e o endereço P2WSH aninhado. +O Segwit introduziu uma série de novas opções para tipos de endereço e também de scripts. Na seção [§9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md) explicamos como o novo tipo de endereço Bech32 variou os scripts padrão encontrados na maioria das transações tradicionais. Este capítulo examina os três outros tipos de scripts introduzidos pela atualização do Segwit: o P2SH-Segwit (que era o endereço "nested Segwit" de transição, quando o Segwit passou a ser usado), o P2WSH (que é o Segwit equivalente ao endereço P2SH , assim como P2WPKH é o Segwit equivalente ao endereço P2PKH) e o endereço nested P2WSH. Esta é outra situação onde realmente não teremos que nos preocupar com os nuances ao trabalhar com o ```bitcoin-cli```, mas é útil saber como tudo funciona. -## Compreendendo um script P2SH-Segwit +## Compreendendo um Script P2SH-Segwit -O endereço P2SH-Segwit é uma tipo em extinção. Foi basicamente uma medida paliativa enquanto o Bitcoin fazia a transição para o Segwit que permitia a um usuário criar um endereço Segwit e, em seguida, alguém como uma exchange que ainda não habilitou o Segwit ou carteira antiga financiasse esse endereço. +O endereço P2SH-Segwit é um tipo em extinção. Foi basicamente uma medida paliativa enquanto o Bitcoin fazia a transição para o Segwit que permitia a um usuário criar um endereço Segwit e, em seguida, alguém como uma exchange que ainda não habilitou o Segwit ou carteira antiga financiasse esse endereço. Se precisarmos usar um, há uma opção para criar um endereço P2SH-Segwit usando ```getnewaddress```: ``` @@ -35,7 +35,7 @@ $ bitcoin-cli listunspent "safe": true } ``` -Mais importante ainda, é a presença de um ```redeemScript```, que decodifica para ```OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a```. Isso deve parecer familiar, porque é um ```OP_0``` seguido por um hexcode de 20 bytes de um hash de chave pública. Em outras palavras, um P2SH-SegWit é apenas um SegWit ```scriptPubKey``` preso em um script. Isso é tudo que há para fazer. Corresponde precisamente ao modo como os multisigs modernos são um multsig preso em um P2SH, conforme discutido na seção [§10.4: Criando scripts multisig](10_4_Scripting_a_Multisig.md). +Mais importante ainda, é a presença de um ```redeemScript```, que decodifica para ```OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a```. Isso deve parecer familiar, porque é um ```OP_0``` seguido por um hexcode de 20 bytes de um hash de chave pública. Em outras palavras, um P2SH-SegWit é apenas um SegWit ```scriptPubKey``` preso em um script. Isso é tudo que há para fazer. Corresponde precisamente ao modo como os multisigs modernos são um multsig preso em um P2SH, conforme discutido na seção [§10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md). A transação bruta revela um pouco mais de detalhes quando olhamos para o ```vout``` ```1```: ``` @@ -94,13 +94,13 @@ $ bitcoin-cli decoderawtransaction $hex ] } ``` -Isso confirma que este é apenas um P2SH normal, bloqueado por ```" OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG "```. É quando o script de resgate é executado que a mágica ocorre. Assim como com um P2WPKH, um node antigo verá ```OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a``` e verificará automaticamente, enquanto um novo node verá isso, saberá que é um P2WPKH e, assim, irá verificar o ```witness```. Podemos consultar isso na seção [§9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md). +Isso confirma que este é apenas um P2SH normal, bloqueado por ```"OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG"```. É quando o script de resgate é executado que a mágica ocorre. Assim como com um P2WPKH, um node antigo verá ```OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a``` e verificará automaticamente, enquanto um novo node verá isso, saberá que é um P2WPKH e, assim, irá verificar o ```witness```. Podemos consultar isso na seção [§9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md). -> :book: ***Quais são as desvantagens das transações Segwit aninhadas?*** Elas são maiores do que as transações Segwit nativas, então temos algumas das vantagens do Segwit, mas não todas. +> :book: ***Quais são as desvantagens das transações nested Segwit?*** Elas são maiores do que as transações Segwit nativas, então temos algumas das vantagens do Segwit, mas não todas. -## Compreendendo um script P2WSH +## Compreendendo um Script P2WSH -Ao contrário, as transações P2WSH devem ser cada vez mais utilizadas, uma vez que são a substituição do Segwit nativa para o P2SH, oferecendo todas as mesmas vantagens de tamanho de bloco que foram criadas com transações Segwit P2WPKH nativas. +Ao contrário, as transações P2WSH devem ser cada vez mais utilizadas, uma vez que são a substituição do Segwit nativo para o P2SH, oferecendo todas as mesmas vantagens de tamanho de bloco que foram criadas com transações Segwit P2WPKH nativas. Este é um exemplo de endereço P2WSH: [https://mempool.space/pt/testnet/address/tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7](https://blockstream.info/testnet/address/tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7). @@ -112,16 +112,16 @@ OP_0 OP_PUSHDATA (32 bytes) 1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6 O funcionamento é exatamente como um endereço P2WPKH, a única diferença é que ao invés de um hash de chave pública de 20 bytes, o UTXO inclui um hash de script de 32 bytes. Assim como com um P2WPKH, os nodes antigos apenas verificam isso, enquanto os novos nodes reconhecem que se trata de um P2WSH e verificam internamente o script conforme descrito nas seções anteriores, mas usando os dados da ```witness```, que agora incluem o script de resgate. -Há também mais uma variante, um script P2WSH embutido em um script P2SH, que funciona muito como o P2SH-Segwit descrito acima, mas para scripts P2WSH aninhados. +Há também mais uma variante, um script P2WSH embutido em um script P2SH, que funciona muito como o P2SH-Segwit descrito acima, mas para scripts P2WSH aninhados. (Ufa!) -## Resumo: Criando um script Segwit +## Resumo: Programando um Script Segwit Existem dois tipos de scripts P2SH relacionados ao Segwit. -O endereço P2SH-Segwit é um endereço Segwit aninhado que incorpora o Segwit ```scriptPubkey``` simples dentro de um Script, assim como multisigs são incorporados nos scripts hoje em dia: A chave do tipo Segwit é desenrolada e então analisada normalmente em uma máquina que entende o Segwit . O objetivo é a compatibilidade com versões anteriores dos nodes antigos que, de outra forma, não seriam capazes de enviar saldos para endereços Segwit nativos. +O endereço P2SH-Segwit é um endereço nested Segwit que incorpora o Segwit ```scriptPubkey``` simples dentro de um Script, assim como multisigs são incorporados nos scripts hoje em dia: a chave do tipo Segwit é desenrolada e então analisada normalmente em uma máquina que entende o Segwit . O objetivo é a compatibilidade com versões anteriores dos nodes antigos que, de outra forma, não seriam capazes de enviar saldos para endereços Segwit nativos. O endereço P2WSH é uma variante Segwit de P2SH, assim como P2WPKH é uma variante Segwit de P2WSH. Ele funciona com a mesma lógica e é identificado por ter um hash de 32 bytes em vez de um hash de 20 bytes. O objetivo é estender as vantagens do Segwit a outros tipos de scripts. -## O que vem depois? +## O Que Vem Depois? -Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.6:Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md). \ No newline at end of file +Vamos continuar "Incorporando Scripts em Transações P2SH no Bitcoin" na seção [§10.6: Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md). \ No newline at end of file From 11fb617d742e10c559506fdc57eb8e835d87f555 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 5 Aug 2021 12:11:21 -0300 Subject: [PATCH 056/155] Review 10_6 --- pt/10_6_Spending_a_P2SH_Transaction.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pt/10_6_Spending_a_P2SH_Transaction.md b/pt/10_6_Spending_a_P2SH_Transaction.md index 6b85b33..be2d4a3 100644 --- a/pt/10_6_Spending_a_P2SH_Transaction.md +++ b/pt/10_6_Spending_a_P2SH_Transaction.md @@ -2,22 +2,22 @@ Antes de encerrarmos esta visão geral das transações P2SH, vamos abordar como gastá-las. Esta seção é principalmente uma visão geral, referindo-se a uma seção anterior onde _já_ gastamos uma transação P2SH. -## Usando o script de resgate +## Usando o Script de Resgate Como vimos na seção [§6.2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md), gastar uma transação P2SH tem tudo a ver com ter aquela versão serializada do script de bloqueio, o chamado _redeemScript_. Portanto, o primeiro passo para poder gastar uma transação P2SH é ter certeza de salvar o _redeemScript_ antes de fornecer o endereço P2SH para todos. -### Coletando as variáveis +### Coletando as Variáveis -Como os endereços P2SH são diferentes dos endereços multisig especiais e Segwit aninhados não estão integrados no ```bitcoin-cli```, não haverá atalhos para gastarmos o P2SH como vimos na seção [§6.3: Enviando e Gastando um Multisig de Maneira Automatizada](6_3_Sending_an_Automated_Multisig.md) . Vamos precisar coletar todas as variáveis mais complexas por conta própria! +Como endereços P2SH além dos endereços especiais multisig e nested Segwit não estão integrados no ```bitcoin-cli```, não haverá atalhos para gastarmos o P2SH como vimos na seção [§6.3: Enviando e Gastando um Multisig de Maneira Automatizada](6_3_Sending_an_Automated_Multisig.md) . Vamos precisar coletar todas as variáveis mais complexas por conta própria! Isso significa que precisaremos coletar: * O ```hex``` do ```scriptPubKey``` para a transação que estamos gastando; * O ```redeemScript``` serializado; * Quaisquer chaves privadas, já que assinaremos manualmente; - * Todos os ```txids```,```vouts``` e ```endereços``` regulares que precisarmos. + * Todos os ```txids```,```vouts``` e ```addresses``` regulares que precisarmos. -## Criando a transação +## Criando a Transação Como vimos na seção §6.2, a criação de uma transação é bem padrão: ``` @@ -27,7 +27,7 @@ $ echo $rawtxhex ``` No entanto, a assinatura requer a inserção de informações extras para o (1) ```scriptPubKey```; (2) o ```redeemScript``` e; (3) quaisquer chaves privadas necessárias. -Aqui está o exemplo de como fazer isso para aquele multisig P2SH integrado da seção §6.2: +Aqui está o exemplo de como fazer isso para aquele multisig P2SH integrado na seção §6.2: ``` $ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR"]' ``` @@ -35,8 +35,8 @@ Com qualquer outro tipo de P2SH, incluiremos um ```redeemscript``` diferente, ma ## Resumo: Gastando uma Transação P2SH -Já gastamos um P2SH no Capítulo 6, quando reenviamos uma transação multsig da maneira mais difícil, que exigia alinhar as informações do ```scriptPubKey``` e do ```redeemScript```. Agora sabemos que o ```scriptPubKey``` é um script de bloqueio P2SH padronizado, enquanto o ```redeemScript``` corresponde a um hash nesse script de bloqueio e que precisamos ser capazes de executá-lo com as variáveis ​​adequadas para receber um resultado ```True```. Mas além disso, não há nada de novo ao gastar uma transação P2SH, porque já fizemos isso! +Já gastamos um P2SH no Capítulo 6, quando reenviamos uma transação multsig da maneira mais difícil, que exigia alinhar as informações do ```scriptPubKey``` e do ```redeemScript```. Agora sabemos que o ```scriptPubKey``` é um script de bloqueio P2SH padronizado, enquanto o ```redeemScript``` corresponde a um hash naquele script de bloqueio e que precisamos ser capazes de executá-lo com as variáveis ​​adequadas para receber um resultado ```True```. Mas além disso, não há nada de novo ao gastar uma transação P2SH, porque já fizemos isso! -## O que vem depois? +## O Que Vem Depois? -Vamos avançar com os "Script do Bitcoin" no [Capítulo 11: Aumentando o poder do timelock com scripts do Bitcoin](11_0_Empowering_Timelock_with_Bitcoin_Scripts.md). \ No newline at end of file +Vamos avançar com "Programando Bitcoin" no [Capítulo 11: Capacitando Timelock com Scripts no Bitcoin](11_0_Empowering_Timelock_with_Bitcoin_Scripts.md). \ No newline at end of file From dce2f7eefe1b1aadfd7cd60f3a5566822f867f76 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 5 Aug 2021 14:04:26 -0300 Subject: [PATCH 057/155] Chapter 14 transaltion completed --- pt/14_0_Using_Tor.md | 21 + pt/14_1_Verifying_Your_Tor_Setup.md | 365 ++++++++++++++++++ ...2_Changing_Your_Bitcoin_Hidden_Services.md | 74 ++++ pt/14_3_Adding_SSH_Hidden_Services.md | 59 +++ 4 files changed, 519 insertions(+) create mode 100644 pt/14_0_Using_Tor.md create mode 100644 pt/14_1_Verifying_Your_Tor_Setup.md create mode 100644 pt/14_2_Changing_Your_Bitcoin_Hidden_Services.md create mode 100644 pt/14_3_Adding_SSH_Hidden_Services.md diff --git a/pt/14_0_Using_Tor.md b/pt/14_0_Using_Tor.md new file mode 100644 index 0000000..b5b31df --- /dev/null +++ b/pt/14_0_Using_Tor.md @@ -0,0 +1,21 @@ +# Capítulo 14: Usando o Tor + +O Tor é um dos programas padrão instalados pelo [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Ele nos ajuda a manter nosso servidor seguro, o que é extremamente importante quando estamos lidando com Bitcoin. Este capítulo divaga um pouco do nosso objetivo para nos ajudar a entender essa infraestrutura de segurança. + +## Objetivos deste Capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Usar uma configuração Tor; + * Executar a manutenção do Tor. + +Os objetivos secundários incluem a capacidade de: + + * Compreender a rede Tor; + * Entender as várias portas do Bitcoin. + +## Tabela de Conteúdo + +* [Seção 1: Verificando a Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) +* [Seção 2: Mudando os Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) +* [Seção 3: Adicionando um Serviço SSH Oculto](14_3_Adding_SSH_Hidden_Services.md) \ No newline at end of file diff --git a/pt/14_1_Verifying_Your_Tor_Setup.md b/pt/14_1_Verifying_Your_Tor_Setup.md new file mode 100644 index 0000000..8da66c6 --- /dev/null +++ b/pt/14_1_Verifying_Your_Tor_Setup.md @@ -0,0 +1,365 @@ +# 14.1: Verificando a Configuração do Tor + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Se fizéssemos uma instalação padrão com o [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup), provavelmente já teríamos o Tor configurado como parte do nosso node de Bitcoin. O Tor está instalado e já foi criado os serviços ocultos para as Portas RPC do Bitcoin, enquanto um endereço Onion também foi criado para o ```bitcoind```. Esta seção iremos discutir tudo isso e o que fazer com essas informações e ferramentas. + +> :book: ***O que é o Tor?*** O Tor é uma rede de sobreposição e anonimato de baixa latência baseada no design de roteamento e construção de caminhos para permitir a comunicação anônima. É um software gratuito e open source com o nome derivado da sigla do nome do projeto de software original: "The Onion Router". + +> :book: ***Por que usar o Tor com o Bitcoin?*** A rede Bitcoin é uma rede de ponto a ponto que escuta as transações e as propaga usando um endereço IP público. Ao conectar-se à rede sem o Tor, iríamos compartilhar nosso endereço IP, o que poderia expor nossa localização, o tempo de atividade e outros detalhes a terceiros, o que é uma prática de privacidade indesejável. Para nos proteger virtualmente, devemos usar ferramentas como o Tor para ocultar os detalhes da nossa conexão. O Tor permite melhorar nossa privacidade online, pois os dados são codificados criptograficamente e passam por nodes diferentes, cada um decodificando uma única camada (por isso a metáfora da cebola). + +## Entendendo o Tor + +Então, como o Tor funciona? + +Quando um usuário deseja se conectar a um servidor na Internet, o Tor tenta construir um caminho formado por pelo menos três retransmissores de nodes do Tor, chamados de Guarda, Meio e Saída. Durante a construção desse caminho, as chaves de criptografia simétricas são negociadas. Quando uma mensagem se move ao longo do caminho, cada retransmissão remove sua camada de criptografia. Dessa forma, a mensagem chega ao destino final na forma original, e cada parte conhece apenas o salto anterior e o próximo e não pode determinar a origem ou o destino. + +Esta é a aparência de uma conexão sem o Tor: +``` +20:58:03.804787 IP bitcoin.36300 > lb-140-82-114-25-iad.github.com.443: Flags [P.], seq 1:30, ack 25, win 501, options [nop,nop,TS val 3087919981 ecr 802303366], length 29 +``` +Agora, com o Tor, muito menos informações sobre as máquinas reais são transmitidas: +``` +21:06:52.744602 IP bitcoin.58776 > 195-xxx-xxx-x.rev.pxxxxxm.eu.9999: Flags [P.], seq 264139:265189, ack 3519373, win 3410, options [nop,nop,TS val 209009853 ecr 3018177498], length 1050 +21:06:52.776968 IP 195-xxx-xxx-x.rev.pxxxxxm.eu.9999 > bitcoin.58776: Flags [.], ack 265189, win 501, options [nop,nop,TS val 3018177533 ecr 209009853], length 0 +``` +Resumindo: O Tor criptografa nossos dados de forma a ocultar nossa origem, destino e quais serviços estamos usando, enquanto um protocolo de criptografia padrão como TLS *apenas* protege o conteúdo dos nossos dados. + +### Compreendendo a Arquitetura de Rede Tor + +A arquitetura básica da rede Tor é composta pelos seguintes componentes: + +* **Cliente Tor (OP ou Onion Proxy).** Um cliente Tor instala o software local que atua como um proxy onion. Ele empacota os dados do aplicativo em células do mesmo tamanho (512 bytes), que então envia para a rede Tor. Uma célula é a unidade básica de transmissão do Tor. +* **Onion Node (OR ou Onion Router).** Um Onion Node transmite células provenientes do cliente Tor e de servidores online. Existem três tipos de Onion Nodes: Nós de entrada (Guarda), Nós intermediários (Meio) e Nós de saída (Saída). +* **Servidor de Diretório.** Um servidor de diretório armazena informações sobre roteadores e servidores onion (serviços ocultos), como as chaves públicas. +* **Onion Server (Servidor Oculto).** Um servidor onion oferece suporte a aplicativos TCP, como páginas da web ou IRC, como serviços. + +### Compreendendo as limitações do Tor + +O Tor não é uma ferramenta perfeita. Como as informações da rede Tor são descriptografadas nos nodes de saída antes de serem enviadas aos destinos finais, teoricamente um observador poderia coletar os metadados suficientes para comprometer o anonimato e potencialmente identificar os usuários. + +Também há estudos que sugerem que possíveis explorações da proteção anti-DoS do Bitcoin podem permitir que um invasor force outros usuários que usam o Tor a se conectar exclusivamente por meio dos nodes de saída do Tor ou dos seus pares Bitcoin, isolando o cliente do resto da rede Bitcoin e expondo-o a censura, correlação e demais ataques. + +Da mesma forma, os usuários do Bitcoin Tor podem ser atacados por impressão digital definindo um cookie de endereço nos nodes. Isso também permitiria a correlação e, portanto, acabando com o anonimato. + +Enquanto isso, mesmo no Tor, o Bitcoin é apenas um serviço pseudo-anônimo devido aos muitos perigos de correlação que se originam do próprio livro-razão permanente. Isso significa que o uso do Bitcoin sobre o Tor tem mais probabilidade de _perder o anonimato_ do que outros serviços (e pode levar ao anonimato de outras atividades). + +Com isso dito, o Tor é geralmente considerado mais seguro do que a alternativa, que é a navegação não anônima. + +## Verificando a configuração do Tor + +Então, como verificamos se o Tor está ativado? Se o instalamos com o Bitcoin Standup, podemos verificar se o Tor está sendo executado em nosso sistema: +``` +$ sudo -u debian-tor tor --verify-config +``` + +Se o Tor estiver instalado corretamente, devemos obter a seguinte resposta: +``` +Jun 26 21:52:09.230 [notice] Tor 0.4.3.5 running on Linux with Libevent 2.0.21-stable, OpenSSL 1.0.2n, Zlib 1.2.11, Liblzma 5.2.2, and Libzstd N/A. +Jun 26 21:52:09.230 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning +Jun 26 21:52:09.230 [notice] Read configuration file "/etc/tor/torrc". +Configuration was valid +``` +> :warning: **AVISO:** Isso significa apenas que o Tor está sendo executado, não que está sendo usado para todas (ou algumas) conexões. + +### Verificando nossa configuração Tor para o RPC + +O propósito mais importante do Tor, conforme instalado pelo Bitcoin Standup, é oferecer serviços ocultos para as portas RPC que são usadas para enviar comandos para o ```bitcoind```. + +> :book: ***O que é um serviço oculto do Tor?*** Um serviço oculto (também conhecido como "um onion service") é um serviço que pode ser acessado via Tor. A conexão feita a esse serviço _usando a Onion Network_ será anônima. + +O arquivo de configuração do Tor pode ser encontrado em ```/etc/tor/torrc```. Se olharmos para ele, veremos os seguintes serviços que protegem nossas portas do RPC: +``` +HiddenServiceDir /var/lib/tor/standup/ +HiddenServiceVersion 3 +HiddenServicePort 1309 127.0.0.1:18332 +HiddenServicePort 1309 127.0.0.1:18443 +HiddenServicePort 1309 127.0.0.1:8332 +``` +> :link: **TESTNET vs MAINNET:** Na Mainnet o RPC é executado na porta 8332, já na testnet, na porta 18332. + +> :information_source: **NOTA:** O ```HiddenServiceDir``` é onde todos os arquivos são mantidos para este serviço em particular. Se precisarmos pesquisar nosso endereço onion, chaves de acesso ou adicionar clientes autorizados, é aqui que iremos alterar! + +A maneira fácil de testar o nosso RPC Hidden Service é usar o [QuickConnect API](https://github.com/BlockchainCommons/Bitcoin-Standup/blob/master/Docs/Quick-Connect-API.md) integrado ao Bitcoin Standup . Basta baixar o código QR que encontramos em ```/qrcode.png``` e digitalizá-lo usando uma carteira ou node que suporte o QuickConnect, como [The Gordian Wallet](https://github.com/BlockchainCommons/FullyNoded-2). Ao escanear o QR, devemos ver a carteira sincronizada com o nosso node. Estaremos fazendo isso usando os serviços ocultos do RPC. + +A maneira mais difícil de testar nosso RPC Hidden Service é enviar um comando ```bitcoin-cli``` com o ```torify```, que permite traduzir um comando UNIX normal para um comando protegido por Tor. É algo difícil porque precisamos obter três informações. + +1. **Nossa porta de serviço oculta.** Isso pode ser obtido em ```/etc/tor/torrc/```. Por padrão, é a porta 1309. +2. **Nosso endereço Tor.** Essa informação encontra-se no arquivo ```hostname``` no diretório ```HiddenServiceDir``` definido em ```/etc/tor/torrc```. Por padrão, o arquivo pode ser encontrado em ```/var/lib/tor/standup/hostname```. Ele está protegido, então precisaremos usar o ```sudo``` para acessá-lo: +``` +$ sudo more /var/lib/tor/standup/hostname +mgcym6je63k44b3i5uachhsndayzx7xi4ldmwrm7in7yvc766rykz6yd.onion +``` +3. **Nossa senha do RPC.** Que está no arquivo ```~/.bitcoin/bitcoin.conf``` + +Quando tivermos todas essas informações, podemos emitir um comando ```bitcoin-cli``` usando o ```torify``` e especificando o ```-rpcconnect``` como nosso endereço onion, o ```-rpcport``` como nossa porta de serviço oculta, e o ```-rpcpassword``` como sendo nossa senha: +``` +$ torify bitcoin-cli -rpcconnect=mgcym6je63k44b3i5uachhsndayzx7xi4ldmwrm7in7yvc766rykz6yd.onion -rpcport=1309 -rpcuser=StandUp -rpcpassword=685316cc239c24ba71fd0969fa55634f getblockcount +``` + +### Verificando a configuração do Tor para o Bitcoind + +O Bitcoin Standup também garante que nosso ```bitcoind``` esteja configurado para se comunicar opcionalmente em um endereço onion. + +Podemos verificar a configuração inicial do Tor para o ```bitcoind``` executando grep usando "tor" no ```debug.log``` em nosso diretório de dados: +``` +$ grep "tor:" ~/.bitcoin/testnet3/debug.log +2021-06-09T14:07:04Z tor: ADD_ONION successful +2021-06-09T14:07:04Z tor: Got service ID vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd, advertising service vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion:18333 +2021-06-09T14:07:04Z tor: Cached service private key to /home/standup/.bitcoin/testnet3/onion_v3_private_key +``` +> :information_source: **NOTA:** O Bitcoin Core não suporta mais endereços v2. O suporte ao Tor v2 foi removido no Pull Request [#22050](https://github.com/bitcoin/bitcoin/pull/22050) + +> **TESTNET vs MAINNET:** Na Mainnet o ```bitcoind``` responde usando a porta 8333, na testnet, na porta 18333. + +Podemos verificar se um serviço oculto Tor foi criado para o Bitcoin usando o comando RPC ```getnetworkinfo```: + +``` +$ bitcoin-cli getnetworkinfo +... + "localaddresses": [ + { + "address": "173.255.245.83", + "port": 18333, + "score": 1 + }, + { + "address": "2600:3c01::f03c:92ff:fe86:f26", + "port": 18333, + "score": 1 + }, + { + "address": "vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion", + "port": 18333, + "score": 4 + } + ], +... +``` +Isso mostra três endereços para acessarmos nosso servidor Bitcoin, um endereço IPv4 (```173.255.245.83```), um endereço IPv6 (```2600:3c01::f03c:92ff:fe86:f26```), e um endereço Tor (```vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7htgtgaq2qudsc```). + +> :warning: **AVISO:** Obviamente, nunca podemos revelar seu endereço Tor de uma forma que esteja associada ao nosso nome ou outras PII! + +Podemos ver algumas informações semelhantes com o ```getnetworkinfo```. +``` + bitcoin-cli getnetworkinfo +{ + "version": 200000, + "subversion": "/Satoshi:0.20.0/", + "protocolversion": 70015, + "localservices": "0000000000000408", + "localservicesnames": [ + "WITNESS", + "NETWORK_LIMITED" + ], + "localrelay": true, + "timeoffset": 0, + "networkactive": true, + "connections": 10, + "networks": [ + { + "name": "ipv4", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "ipv6", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "onion", + "limited": false, + "reachable": true, + "proxy": "127.0.0.1:9050", + "proxy_randomize_credentials": true + } + ], + "relayfee": 0.00001000, + "incrementalfee": 0.00001000, + "localaddresses": [ + { + "address": "173.255.245.83", + "port": 18333, + "score": 1 + }, + { + "address": "2600:3c01::f03c:92ff:fe86:f26", + "port": 18333, + "score": 1 + }, + { + "address": "vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion", + "port": 18333, + "score": 4 + } + ], + "warnings": "" +} +``` +Este serviço oculto permitirá conexões anônimas com o nosso ```bitcoind``` através da rede Bitcoin. + +> :warning: **AVISO:** Executar o Tor e ter um serviço oculto do Tor não nos obriga a usar o Tor. + +### Verificando a configuração do Tor para os Peers + +Usando o comando RPC ```getpeerinfo```, podemos ver quais nodes estão conectados ao nosso node e verificar se eles estão conectados ao Tor. + +``` +$ bitcoin-cli getpeerinfo +``` +Alguns podem estar conectados via Tor: +``` +... +{ + "id": 9, + "addr": "nkv.......xxx.onion:8333", + "addrbind": "127.0.0.1:51716", + "services": "000000000000040d", + "servicesnames": [ + "NETWORK", + "BLOOM", + "WITNESS", + "NETWORK_LIMITED" + ], + "relaytxes": true, + "lastsend": 1593981053, + "lastrecv": 1593981057, + "bytessent": 1748, + "bytesrecv": 41376, + "conntime": 1593980917, + "timeoffset": -38, + "pingwait": 81.649295, + "version": 70015, + "subver": "/Satoshi:0.20.0/", + "inbound": false, + "addnode": false, + "startingheight": 637875, + "banscore": 0, + "synced_headers": -1, + "synced_blocks": -1, + "inflight": [ + ], + "whitelisted": false, + "permissions": [ + ], + "minfeefilter": 0.00000000, + "bytessent_per_msg": { + "addr": 55, + "feefilter": 32, + "getaddr": 24, + "getheaders": 1053, + "inv": 280, + "ping": 32, + "pong": 32, + "sendcmpct": 66, + "sendheaders": 24, + "verack": 24, + "version": 126 + }, + "bytesrecv_per_msg": { + "addr": 30082, + "feefilter": 32, + "getdata": 280, + "getheaders": 1053, + "headers": 106, + "inv": 9519, + "ping": 32, + "pong": 32, + "sendcmpct": 66, + "sendheaders": 24, + "verack": 24, + "version": 126 + } + } +... +``` +Alguns podem não estar, como esta conexão IPv6: +``` +... + { + "id": 17, + "addr": "[2001:638:a000:4140::ffff:191]:18333", + "addrlocal": "[2600:3c01::f03c:92ff:fe86:f26]:36344", + "addrbind": "[2600:3c01::f03c:92ff:fe86:f26]:36344", + "services": "0000000000000409", + "servicesnames": [ + "NETWORK", + "WITNESS", + "NETWORK_LIMITED" + ], + "relaytxes": true, + "lastsend": 1595447081, + "lastrecv": 1595447067, + "bytessent": 12250453, + "bytesrecv": 2298711417, + "conntime": 1594836414, + "timeoffset": -1, + "pingtime": 0.165518, + "minping": 0.156638, + "version": 70015, + "subver": "/Satoshi:0.20.0/", + "inbound": false, + "addnode": false, + "startingheight": 1780784, + "banscore": 0, + "synced_headers": 1781391, + "synced_blocks": 1781391, + "inflight": [ + ], + "whitelisted": false, + "permissions": [ + ], + "minfeefilter": 0.00001000, + "bytessent_per_msg": { + "addr": 4760, + "feefilter": 32, + "getaddr": 24, + "getdata": 8151183, + "getheaders": 1085, + "headers": 62858, + "inv": 3559475, + "ping": 162816, + "pong": 162816, + "sendcmpct": 132, + "sendheaders": 24, + "tx": 145098, + "verack": 24, + "version": 126 + }, + "bytesrecv_per_msg": { + "addr": 33877, + "block": 2291124374, + "feefilter": 32, + "getdata": 9430, + "getheaders": 1085, + "headers": 60950, + "inv": 2019175, + "ping": 162816, + "pong": 162816, + "sendcmpct": 66, + "sendheaders": 24, + "tx": 5136622, + "verack": 24, + "version": 126 + } + } +... +``` +Ter um endereço Tor para nosso ```bitcoind``` é provavelmente um pouco menos útil do que ter um endereço Tor para nossas conexões RPC. Isso é verdade porque não é recomendado tentar enviar todas as nossas conexões Bitcoin via Tor, e em parte porque proteger nossos comandos RPC é o que realmente importa. É muito mais provável que façamos isso remotamente, a partir de uma carteira de software como a The Gordian Wallet, enquanto o nosso próprio servidor tem mais probabilidade de estar no escritório, no porão ou em um bunker. + +No entanto, existem maneiras de fazer o ```bitcoind``` usar mais o Tor, conforme iremos discutir na próxima seção. + +## Resumo: Verificando a Configuração do Tor + +O Tor é um pacote de software instalado como parte do Bitcoin Standup que permite a troca de comunicações anonimamente. Ele protegerá nossas portas RPC (8332 ou 18332) e nossas portas do ```bitcoind``` (8333 ou 18333), porém, teremos que nos conectar ativamente ao endereço onion para utilizá-las! O Tor é um pilar fundamental da privacidade e segurança para a configuração do nosso Bitcoin, e podemos verificar se ele está disponível e vinculado ao Bitcoin com alguns comandos simples. + +> :fire: ***Qual é o poder do Tor?*** Muitos ataques a usuários de Bitcoins precisam saber quem é a vítima e se ela possui Bitcoins. O Tor pode nos proteger disso, escondendo onde estamos e o que estamos fazendo. É particularmente importante se desejamos nos conectar ao nosso próprio node remotamente por meio de uma carteira de software, e pode ser crucial se fizermos isso em algum país onde não vê com bons olhos quem usa Bitcoins. Se precisarmos acessar nossos serviços Bitcoin remotamente, precisamos nos certificar de que nossa carteira seja totalmente compatível com o Tor e envie todos os comandos RPC ao nosso servidor usando esse protocolo. + +## O Que Vem Depois? + +Vamos continuar "Usando o Tor" na seção [§14.2: Mudando os Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md). \ No newline at end of file diff --git a/pt/14_2_Changing_Your_Bitcoin_Hidden_Services.md b/pt/14_2_Changing_Your_Bitcoin_Hidden_Services.md new file mode 100644 index 0000000..5dad6a1 --- /dev/null +++ b/pt/14_2_Changing_Your_Bitcoin_Hidden_Services.md @@ -0,0 +1,74 @@ +# 14.2: Mudando os Serviços Ocultos do Bitcoin + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Temos um serviço Tor funcionando, mas com o tempo talvez queiramos reiniciá-lo ou ajustá-lo de outra forma. + +## Protejendo nossos serviços ocultos + +O Tor permite que limitemos quais clientes conversam com nossos serviços ocultos. Se ainda não autorizamos nosso cliente durante a configuração do servidor, na primeira oportunidade, devemos fazer o seguinte: + +1. Solicitar uma chave pública de autenticação Tor V3 do nosso cliente. (Na [GordianWallet](https://github.com/BlockchainCommons/GordianWallet-iOS), está disponível no menu de configurações). +2. Vamos para o subdiretório apropriado para nosso serviço oculto do Bitcoin. Se usamos o Bitcoin Standup é ```/var/lib/tor/standup/```. +3. Vamos para o subdiretório ```authorized_clients```. +4. Vamos adicionar um arquivo chamado ```[qualquer coisa].auth```. O ```[qualquer coisa]``` pode ser realmente qualquer coisa. +5. Colocamos a chave pública (e nada mais) no arquivo. + +Depois de adicionar um arquivo ```.auth``` ao subdiretório ```authorized_client```, somente os clientes autorizados serão capazes de se comunicar com esse serviço oculto. Podemos adicionar mais ou menos 330 chaves públicas diferentes para habilitar clientes diferentes. + +## Redefinindo nosso endereço Onion do ```bitcoind``` + +Se quisermos redefinir nosso endereço onion para o ```bitcoind```, podemos apenas remover o ```onion_private_key``` do nosso diretório de dados, no `~/.bitcoin/testnet`: +``` +$ cd ~/.bitcoin/testnet +$ rm onion_private_key +``` +Quando reiniciarmos, um novo endereço onion será gerado: +``` +2020-07-22T23:52:27Z tor: Got service ID pyrtqyiqbwb3rhe7, advertising service pyrtqyiqbwb3rhe7.onion:18333 +2020-07-22T23:52:27Z tor: Cached service private key to /home/standup/.bitcoin/testnet3/onion_private_key +``` + +## Redefinindo Nosso Endereço Onion do RPC + +Se quisermos redefinir nosso endereço onion para o acesso RPC, podemos excluir da mesma forma o ```HiddenServiceDirectory``` apropriado e reiniciar o Tor: +``` +$ sudo rm -rf /var/lib/tor/standup/ +$ sudo /etc/init.d/tor restart +``` + +> :warning: **AVISO:** Redefinir o endereço onion do RPC desconectará quaisquer carteiras mobile ou outros serviços que contamos usando a API Quicklink. Por isso, temos que tomar bastante cuidado. + +## Forçar o ```bitcoind``` a usar o Tor + +Finalmente, podemos forçar o ```bitcoind``` a usar o onion adicionando o seguinte ao nosso arquivo ```bitcoin.conf```: +``` +proxy=127.0.0.1:9050 +listen=1 +bind=127.0.0.1 +onlynet=onion +``` +Precisaremos adicionar seed nodes baseados no onion ou outros nodes à nossa configuração, mais uma vez editando o ```bitcoin.conf```: +``` +seednode=address.onion +seednode=address.onion +seednode=address.onion +seednode=address.onion +addnode=address.onion +addnode=address.onion +addnode=address.onion +addnode=address.onion +``` +Depois, basta reiniciar o ```tor``` e o ```bitcoind```. + +Agora devemos estar nos comunicando exclusivamente com o Tor. Mas, a menos que estejamos em um local hostil, esse nível de anonimato provavelmente não é necessário. Também não é particularmente recomendado, pois podemos diminuir muito o número potenciais peers, criando problemas de censura ou mesmo de correlação. Também podemos começar a sofrer com alta latência. E essa configuração pode nos dar uma falsa sensação de anonimato que realmente não existe na rede Bitcoin. + +> :warning: **AVISO:** Esta configuração não foi testada! Use por sua conta e risco! + +## Resumo: Mudando os Serviços Ocultos do Bitcoin + +Provavelmente nós não iremos precisará brincar com os nossos serviços onion depois de verificá-los, mas caso precisemos, veja como redefinir um endereço Tor que foi comprometido ou passar a usar exclusivamente o Tor com nosso ```bitcoind``` . + +## O Que Vem Depois? + +Vamos continuar "Usando o Tor" na seção [14.3: Adicionando SSH e Hidden Services](14_3_Adding_SSH_Hidden_Services.md). \ No newline at end of file diff --git a/pt/14_3_Adding_SSH_Hidden_Services.md b/pt/14_3_Adding_SSH_Hidden_Services.md new file mode 100644 index 0000000..ef9de32 --- /dev/null +++ b/pt/14_3_Adding_SSH_Hidden_Services.md @@ -0,0 +1,59 @@ +# 14.3: Adicionando um Serviço SSH Oculto + +>:information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Até agora, usamos o Tor com os nossos serviços Bitcoin, mas também podemos usá-lo para proteger outros serviços em nossa máquina, melhorando a segurança e a privacidade. Esta seção demonstra como fazer isso, introduzindo um serviço ```ssh``` oculto para fazer o login remotamente usando o Tor. + +## Criando serviços SSH ocultos + +Novos serviços são criados adicionando-os ao arquivo ```/etc/tor/torrc```: +``` +$ su +# cat >> /etc/tor/torrc << EOF +HiddenServiceDir /var/lib/tor/hidden-service-ssh/ +HiddenServicePort 22 127.0.0.1:22 +EOF +# exit +``` +Eis o que cada coisa significa: + +* HiddenServiceDir: Indica que temos um diretório de serviço oculto com a configuração necessária para este caminho. +* HiddenServicePort: Indica a porta Tor a ser usada, no caso do SSH, geralmente é a 22. + +Depois de adicionar as linhas apropriadas ao nosso arquivo ```torrc```, precisaremos reiniciar o Tor: +``` +$ sudo /etc/init.d/tor restart +``` + +Após a reinicialização, nosso ```HiddenServiceDir``` deve ter novos arquivos da seguinte forma: +``` +$ sudo ls -l /var/lib/tor/hidden-service-ssh +total 16 +drwx--S--- 2 debian-tor debian-tor 4096 Jul 22 14:55 authorized_clients +-rw------- 1 debian-tor debian-tor 63 Jul 22 14:56 hostname +-rw------- 1 debian-tor debian-tor 64 Jul 22 14:55 hs_ed25519_public_key +-rw------- 1 debian-tor debian-tor 96 Jul 22 14:55 hs_ed25519_secret_key +``` +O arquivo ```hostname``` neste diretório contém nosso novo ID onion: +``` +$ sudo cat /var/lib/tor/hidden-service-ssh/hostname +qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion +``` +Podemos nos conectar ao serviço oculto ```ssh``` usando o ```torify``` e esse endereço: +``` +$ torify ssh standup@qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion +The authenticity of host 'qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion (127.42.42.0)' can't be established. +ECDSA key fingerprint is SHA256:LQiWMtM8qD4Nv7eYT1XwBPDq8fztQafEJ5nfpNdDtCU. +Are you sure you want to continue connecting (yes/no)? yes +Warning: Permanently added 'qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion' (ECDSA) to the list of known hosts. +standup@qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion's password: +``` +## Resumo: Adicionando um Serviço SSH Oculto + +Agora que instalamos o Tor e sabemos como usá-lo, podemos adicionar outros serviços ao Tor. Apenas adicionamos as linhas ao nosso ```torrc``` (no nosso servidor) e o conectamos com o ```torify``` (no nosso cliente). + +> :fire: ***Qual é o poder de utilizar outros serviços ocultos?*** Cada vez que acessamos um serviço em nosso servidor remotamente, deixamos pegadas na rede. Mesmo que os dados sejam criptografados usando SSH (ou TLS), os vigias da rede podem ver de onde estamos nos conectando, para onde estamos conectando e qual serviço estamos usando. Isso realmente importa pra nós? Esta é a pergunta que devemos fazer. Mas se a resposta for "Sim", podemos proteger a conexão com um serviço oculto. + +Vamos seguir "Programando com o RPC" no [Capítulo Quinze: Conversando com Bitcoind usando C](15_0_Talking_to_Bitcoind.md). + +Ou, se não formos programadores, podemos pular para o [Capítulo Dezoito: Entendendo Nossa Configuração da Lightning](18_0_Understanding_Your_Lightning_Setup.md) para aumentar nosso conhecimento sobre a Lightning Network usando a linha de comando. \ No newline at end of file From 4fb508a05417a7ecdd72f648220f67e901444bf0 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Fri, 6 Aug 2021 11:18:29 -0300 Subject: [PATCH 058/155] Chapter 16 translation finished --- pt/16_0_Programming_with_Libwally.md | 29 ++ pt/16_1_Setting_Up_Libwally.md | 196 +++++++++ pt/16_2_Using_BIP39_in_Libwally.md | 106 +++++ pt/16_3_Using_BIP32_in_Libwally.md | 142 +++++++ pt/16_4_Using_PSBTs_in_Libwally.md | 378 ++++++++++++++++++ pt/16_5_Using_Scripts_in_Libwally.md | 179 +++++++++ pt/16_6_Using_Other_Functions_in_Libwally.md | 126 ++++++ ..._7_Integrating_Libwally_and_Bitcoin-CLI.md | 330 +++++++++++++++ 8 files changed, 1486 insertions(+) create mode 100644 pt/16_0_Programming_with_Libwally.md create mode 100644 pt/16_1_Setting_Up_Libwally.md create mode 100644 pt/16_2_Using_BIP39_in_Libwally.md create mode 100644 pt/16_3_Using_BIP32_in_Libwally.md create mode 100644 pt/16_4_Using_PSBTs_in_Libwally.md create mode 100644 pt/16_5_Using_Scripts_in_Libwally.md create mode 100644 pt/16_6_Using_Other_Functions_in_Libwally.md create mode 100644 pt/16_7_Integrating_Libwally_and_Bitcoin-CLI.md diff --git a/pt/16_0_Programming_with_Libwally.md b/pt/16_0_Programming_with_Libwally.md new file mode 100644 index 0000000..735b8ae --- /dev/null +++ b/pt/16_0_Programming_with_Libwally.md @@ -0,0 +1,29 @@ +# Capítulo 16: Programando com Libwally + +O capítulo anterior apresentou três bibliotecas C, para RPC, JSON e ZMQ, todas destinadas a interagir diretamente com o `bitcoind`, assim como você vem fazendo desde o início. Mas, às vezes você pode querer codificar sem acesso direto a um `bitcoind`. Isso pode ser devido a um cliente offline ou apenas porque você deseja manter algumas funcionalidades internas de seu programa C. Você também pode querer se aprofundar na funcionalidade da carteira, como criação de palavras mnemônicas ou derivação de endereços. É aí que entra Libwally: é uma biblioteca de carteira para C, C ++, Java, NodeJS ou Python, com wrappers também disponíveis para outras linguagens, como Swift. + +Este capítulo aborda a funcionalidade possível dentro do Libwally, a maioria das quais complementa o trabalho que você fez através do acesso RPC ao `bitcoind`, mas algumas das quais o replicam. Ele também mostra como integrar esse trabalho com os clientes RPC com os quais você está mais familiarizado. No entanto, observe que esta é apenas uma introdução básica ao Libwally. Vários de seus conjuntos de funções mais importantes são destacados, mas nunca fazemos mais do que enfiar os pés no chão. Se você acha suas funções úteis ou intrigantes, então você precisará se aprofundar muito mais profundamente do que este curso pode cobrir. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Usar as funções da carteira com o Libwally; + * Realizar manipulações de PSBTs e transações com o Libwally; + * Implementar designs que combinem o Libwally e o RPC. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Compreender palavras mnemônicas BIP39; + * Conhecer mais sobre as carteiras hierárquicas BIP32; + * Sintetizar a profundidade funcional do Libwally. + +## Tabela de Conteúdo + + * [Seção 1: Configurando o Libwally](16_1_Setting_Up_Libwally.md) + * [Seção 2: Usando o BIP39 no Libwally](16_2_Using_BIP39_in_Libwally.md) + * [Seção 3: Usando o BIP32 no Libwally](16_3_Using_BIP32_in_Libwally.md) + * [Seção 4: Usando o PSBTs no Libwally](16_4_Using_PSBTs_in_Libwally.md) + * [Seção 5: Usando Scripts no Libwally](16_5_Using_Scripts_in_Libwally.md) + * [Seção 6: Usando Outras Funções no Libwally](16_6_Using_Other_Functions_in_Libwally.md) + * [Seção 7: Integrando o Libwally ao Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md) \ No newline at end of file diff --git a/pt/16_1_Setting_Up_Libwally.md b/pt/16_1_Setting_Up_Libwally.md new file mode 100644 index 0000000..990b800 --- /dev/null +++ b/pt/16_1_Setting_Up_Libwally.md @@ -0,0 +1,196 @@ +# 16.1: Configurando a Libwally + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esta primeira seção explicará como fazer o download da Biblioteca Libwally C e como colocá-la em funcionamento. + +> :book: ***O que é a Libwally?*** A Libwally é uma biblioteca de primitivas útil para a criação de carteiras que é totalmente multiplataforma, de modo que as mesmas funções possam ser usadas em qualquer lugar. Existem [documentação online](https://wally.readthedocs.io/en/latest/), caso esteja interessado. A Libwally está disponível como parte do [Elements Project](https://github.com/ElementsProject) da Blockstream. + +## Instalando o Libwally + +Como de costume, precisaremos de alguns pacotes no nosso sistema: +``` +$ sudo apt-get install git +$ sudo apt-get install dh-autoreconf +``` +Podemos então fazer o download do Libwally com base no seu repositório Git: +``` +$ git clone https://github.com/ElementsProject/libwally-core +``` +Afterward, you can begin the configuration process: +Depois, podemos começar com o processo de configuração. +``` +$ ./tools/autogen.sh +``` +Como no ```libbitcoinrpc```, podemos querer instalar no caminho `/usr/include` e no `/usr/lib` para facilitar o uso. Basta modificar a linha apropriada no arquivo `configure` do programa: +``` +< ac_default_prefix=/usr +--- +> ac_default_prefix=/usr/local +``` +Depois, podemos terminar nossa preparação: +``` +$ ./configure +$ make +``` +Agora, podemos verificar se os testes estão funcionando: +``` +$ make check +Making check in src +make[1]: Entering directory '/home/standup/libwally-core/src' +Making check in secp256k1 +make[2]: Entering directory '/home/standup/libwally-core/src/secp256k1' +make check-TESTS +make[3]: Entering directory '/home/standup/libwally-core/src/secp256k1' +make[4]: Entering directory '/home/standup/libwally-core/src/secp256k1' +============================================================================ +Testsuite summary for libsecp256k1 0.1 +============================================================================ +# TOTAL: 0 +# PASS: 0 +# SKIP: 0 +# XFAIL: 0 +# FAIL: 0 +# XPASS: 0 +# ERROR: 0 +============================================================================ +make[4]: Leaving directory '/home/standup/libwally-core/src/secp256k1' +make[3]: Leaving directory '/home/standup/libwally-core/src/secp256k1' +make[2]: Leaving directory '/home/standup/libwally-core/src/secp256k1' +make[2]: Entering directory '/home/standup/libwally-core/src' +make check-TESTS check-local +make[3]: Entering directory '/home/standup/libwally-core/src' +make[4]: Entering directory '/home/standup/libwally-core/src' +PASS: test_bech32 +PASS: test_psbt +PASS: test_psbt_limits +PASS: test_tx +============================================================================ +Testsuite summary for libwallycore 0.7.8 +============================================================================ +# TOTAL: 4 +# PASS: 4 +# SKIP: 0 +# XFAIL: 0 +# FAIL: 0 +# XPASS: 0 +# ERROR: 0 +============================================================================ +make[4]: Leaving directory '/home/standup/libwally-core/src' +make[3]: Nothing to be done for 'check-local'. +make[3]: Leaving directory '/home/standup/libwally-core/src' +make[2]: Leaving directory '/home/standup/libwally-core/src' +make[1]: Leaving directory '/home/standup/libwally-core/src' +make[1]: Entering directory '/home/standup/libwally-core' +make[1]: Nothing to be done for 'check-am'. +make[1]: Leaving directory '/home/standup/libwally-core' +``` +Finalmente, podemos instalar: +``` +$ sudo make install +``` + +## Nos preparando para a Libwally + +Então, como usamos a Libwally em nosso programa que estamos construindo? Como de costume, precisaremos incluir os arquivos e vincular as bibliotecas apropriadas em nosso código. + +### Incluindo os arquivos + +Há um número considerável de arquivos que podemos incluir: + +``` +$ ls /usr/include/wally* +/usr/include/wally_address.h /usr/include/wally_bip39.h /usr/include/wally_elements.h /usr/include/wally_script.h +/usr/include/wally_bip32.h /usr/include/wally_core.h /usr/include/wally.hpp /usr/include/wally_symmetric.h +/usr/include/wally_bip38.h /usr/include/wally_crypto.h /usr/include/wally_psbt.h /usr/include/wally_transaction.h +``` +Felizmente, os nomes dos arquivos correspondem amplamente às seções da [documentação](https://wally.readthedocs.io/en/latest/), então devemos ser capazes de incluir os arquivos corretos com base no que estamos fazendo, depois de incluir o onipresente `wally_core.h`. + +### Vinculando as bibliotecas + +Também precisaremos vincular as bibliotecas apropriadas: +``` +$ ls /usr/lib/libsecp* /usr/lib/libwally* +/usr/lib/libsecp256k1.a /usr/lib/libwallycore.la /usr/lib/libwallycore.so.0 +/usr/lib/libsecp256k1.la /usr/lib/libwallycore.so /usr/lib/libwallycore.so.0.0.0 +``` +Usaremos principalmente a `libwallycore`. + +## Configurando um programa Libwally + +Comparado com algumas das bibliotecas anteriores, a Libwally é ridiculamente fácil de ser inicializada: +``` +lw_response = wally_init(0); +``` +E então, quando terminarmos, há uma função útil para limpar qualquer memória alocada: +``` +wally_cleanup(0); +``` +Em ambos os casos, o argumento é para flags, mas atualmente está definido como `0`. + +## Testando um programa de teste da Libwally + +O diretório src contém o arquivo [testwally.c](src / 16_1_testwally.c), que apenas mostra como funcionam as funções de inicialização e de limpeza. + +Podemos compilá-lo da seguinte maneira: +``` +$ cc testwally.c -lwallycore -o testwally +``` +Depois, podemos executá-lo: +``` +$ ./testwally +Startup: 0 +``` +O valor "Startup" é o retorno do comando `wally_init`. O valor `0` pode inicialmente parecer desanimador, mas é o que desejamos ver no momento: +``` +include/wally_core.h:#define WALLY_OK 0 /** Success */ +``` + +## Instalando o Libsodium + +Também precisamos instalar o Libsodium para obter acesso a um gerador de números aleatórios de alta qualidade para fins de teste. + +> :warning: **AVISO:** A geração de números aleatórios pode ser um dos maiores pontos de vulnerabilidade em qualquer software do Bitcoin. Se fizermos isso de maneira errada, podemos export nossos usuários a ataques porque eles acabam tendo chaves privadas do Bitcoin inseguras, e isso não é um [problema teórico](https://github.com/BlockchainCommons/SmartCustodyBook/blob/master/manuscript/ 03-adversaries.md # adversary-systemic-key-compromise). A BlockchainInfo gerou incorretamente 0,0002% das suas chaves, o que resultou na perda temporária de 250 Bitcoins. Resumindo: Precisamos nos certificar de estar totalmente confortável com a geração de números aleatórios. Podemos usar o Libsodium ou qualquer outro método TRNG ainda mais robusto. + +Podemos baixar um [Libsodium tarball](https://download.libsodium.org/libsodium/releases/) e seguir as instruções em [instalação do Libsodium](https://doc.libsodium.org/installation) para deixarmos tudo pronto em nosso computador. + +Primeiro, descompactamos: +``` +$ tar xzfv /tmp/libsodium-1.0.18-stable.tar.gz +``` +Então, ajustamos o arquivo `configure` exatamente como fizemos nas outras bibliotecas até o momento: +``` +< ac_default_prefix=/usr +--- +> ac_default_prefix=/usr/local +``` +Finalmente, usamos os comandos `make`,`check` e `install`: +``` +$ make +$ make check +... +============================================================================ +Testsuite summary for libsodium 1.0.18 +============================================================================ +# TOTAL: 77 +# PASS: 77 +# SKIP: 0 +# XFAIL: 0 +# FAIL: 0 +# XPASS: 0 +# ERROR: 0 +============================================================================ +... +$ sudo make install +``` +Este curso usará apenas `libsodium` para um pequeno (mas crucial!) bit de geração de entropia, mas precisamos prestar muita atenção na próxima seção. + +## Resumo: Configurando a Libwally + +Ao instalar os includes e as bibliotecas da Libwally (e do Libsodium), ganhamos acesso a uma série de funções criptográficas e de carteira, que podem complementar nossas bibliotecas RPC e ZMG (ou nossa linha de comando `bitcoin-cli`). + +Então, o que exatamente podemos fazer agora? É para dar essa resposta que temos todas as seções deste capítulo. + +## O Que Vem Depois? + +Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.2: Usando o BIP39 no Libwally](16_2_Using_BIP39_in_Libwally.md). \ No newline at end of file diff --git a/pt/16_2_Using_BIP39_in_Libwally.md b/pt/16_2_Using_BIP39_in_Libwally.md new file mode 100644 index 0000000..4669828 --- /dev/null +++ b/pt/16_2_Using_BIP39_in_Libwally.md @@ -0,0 +1,106 @@ +# 16.2: Usando o BIP39 no Libwally + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Um dos maiores poderes de Libwally é que ele pode revelar o trabalho oculto da geração de seeds, chaves privadas e, também, de endereços. Para começar, ele suporta o [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki), que é o BIP que define códigos mnemônicos para o Bitcoin, algo que é totalmente incompatível, na época, com o Bitcoin Core. + +> :book: ***O que é um código mnemônico?*** Os endereços de Bitcoin (e suas chaves privadas correspondentes e as suas seeds) são listas longas e ininteligíveis de caracteres e números, que não são apenas impossíveis de serem lembrados, mas também fáceis de serem digitados erroneamente. Os códigos mnemônicos são uma solução para isso que permitem aos usuários gravar 12 (ou 24) palavras em inglês, algo que é muito menos sujeito a erros. Esses códigos podem ser usados para restaurar totalmente uma seed BIP32 que é a base de uma carteira Determinística Hierárquica. + +> :book: ***O que é uma seed?*** Nós falamos brevemente das seeds na seção [§3.5: Compreendendo o descritor](03_5_Understanding_the_Descriptor.md). É o número aleatório usado para gerar uma sequência inteira de chaves privadas (e, portanto, endereços) em uma carteira Determinística Hierárquica. Voltaremos às seeds na próxima seção, onde falaremos sobre as carteiras Determinísticas Hierárquicas e a Libwally. Por enquanto, apenas é necessário saber que um código mnemônico BIP39 corresponde à seed para uma carteira determinística hierárquica do BIP32. + +## Criando Códigos Mnemônicos + +Todas as chaves Bitcoin começam com a entropia. Este primeiro uso de Libwally, e os mnemônicos BIP39, mostram como gerar entropia e obter um código mnemônico a partir disso. + +> :book: ***O que é entropia?*** Entropia é uma maneira sofisticada de dizer aleatoriedade, mas é uma aleatoriedade medida cuidadosamente que é usada como a base de um número aleatório gerado verdadeiramente (no inglês, true-random-number generated, TRG). É medido em "bits", com mais bits de entropia resultando em mais aleatoriedade (e, portanto, mais proteção para o que está sendo gerado). Para o Bitcoin, a entropia é a base de nossa seed, que em uma carteira Determinística Hierárquica que gera todos os seus endereços. + +Sempre começaremos a trabalhar com a Libwally inicializando a biblioteca e testando os resultados, conforme demonstrado pela primeira vez na seção [§16.1](16_1_Setting_Up_Libwally.md): +``` + int lw_response; + + lw_response = wally_init(0); + + if (lw_response) { + + printf("Error: Wally_init failed: %d\n",lw_response); + exit(-1); + + } +``` +Agora estamos prontos para a entropia. + +### Criando a Entropia + +Usando o `libsodium`, podemos criar a entropia com o comando `randombytes_buf`: +``` + unsigned char entropy[16]; + randombytes_buf(entropy, 16); +``` +Este exemplo, que será a única maneira de usarmos a biblioteca `libsodium`, cria 16 bytes de entropia. Geralmente, para criar um código mnemônico seguro, devemos usar entre 128 e 256 bits de entropia, que é 16 a 32 bytes. + +> :warning: **AVISO:** Mais uma vez, certifique-se de estar muito confortável com o método de geração de entropia antes de usá-lo em um programa do mundo real. + +### Traduzindo para um mnemônico + +16 bytes de entropia são suficientes para criar um código Mnemônico de 12 caracteres, que é feito com a função `bip39_mnemonic_from_bytes` da Libwally: +``` + char *mnem = NULL; + lw_response = bip39_mnemonic_from_bytes(NULL,entropy,16,&mnem); +``` +Observe que temos que passar o tamanho do byte, então se quiser aumentar o tamanho da entropia, para gerar uma frase mnemônica mais longa, também precisaria aumentar o valor nesta função. + +> **NOTA:** Existem listas de palavras mnemônicas para diferentes idiomas! O padrão é usar a lista do idioma inglês, que é a variável `NULL` nesses comandos mnemônicos da Libwally, mas podemos, alternativamente, solicitar um idioma diferente! + +É isso! Nós criamos uma frase mnemônica! + +> :book: ***Como a frase mnemônica é criada?*** Podemos aprender mais sobre isso no [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki), mas se preferir, Greg Walker tem um [excelente exemplo](https://learnmeabitcoin.com/technical/mnemonic): De maneira geral, adicionamos uma soma de verificação e convertemos cada conjunto de 11 bits em uma palavra da lista de palavras. Podemos fazer isso com os comandos `bip39_get_wordlist` e `bip39_get_word` se não confiarmos no comando `bip39_mnemonic_from_bytes`. + +### Traduzindo para uma seed + +Existem algumas funções, como o `bip32_key_from_seed` (que veremos na próxima seção) que requerem que tenhamos os bits ao invés do Mnemônico. As duas coisas são funcionalmente idênticas, se temos a seed, pode gerar o mnemônico e vice-versa. + +Se você precisarmos gerar a seed a partir do nosso mnemônico, basta usar o comando `bip39_mnemonic_to_seed`: +``` + unsigned char seed[BIP39_SEED_LEN_512]; + size_t seed_len; + + lw_response = bip39_mnemonic_to_seed(mnem,NULL,seed,BIP39_SEED_LEN_512,&seed_len); +``` +Observe que todas as seeds do BIP39 têm 512 bytes; no entanto, devemos definir o tamanho de nossa variável apropriadamente e passar o tamanho para o `bip39_mnemonic_to_seed`. + +### Mostrando na Tela a Nossa Seed + +Se quisermos ver como nossa semente se parece em hexadecimal, podemos usar a função `wally_hex_from_bytes` para transformar nossa seed em um código hexadecimal legível (mas isso não é muito bom para pessoas): +``` + char *seed_hex; + wally_hex_from_bytes(seed,sizeof(seed),&seed_hex); + printf("Seed: %s\n",seed_hex); +``` +Se dizermos tudo certo, devemos obter uma seed de 64 bytes. (Essa é a variável `BIP39_SEED_LEN_512` que estamos usando, que define um comprimento de seed padrão de 512 bits ou 64 bytes.) + +> :warning: **ATENÇÃO:** Definitivamente devemos testar se o comprimento da nossa seed é de 64 bytes de alguma forma, porque é fácil errar em alguma coisa, por exemplo, usando o tipo de variável errado quando executamos o `bip39_mnemonic_to_seed`. + +## Testando o Código Mnemônico + +O código completo para gerar entropia, gerar um mnemônico BIP39, validar o mnemônico e gerar uma seed pode ser encontrado no [diretório src/](src/16_2_genmnemonic.c). Podemos fazer o download e compilar: +``` +$ cc genmnemonic.c -lwallycore -lsodium -o genmnemonic +``` +Então podemos executar o teste: +``` +Mnemonic: parent wasp flight sweet miracle inject lemon matter label column canyon trend +Mnemonic validated! +Seed: 47b04cfb5d8fd43d371497f8555a27a25ca0a04aafeb6859dd4cbf37f6664b0600c4685c1efac29c082b1df29081f7a46f94a26f618fc6fd38d8bc7b6cd344c7 +``` + +## Resumo: Usando o BIP39 no Libwally + +O BIP39 permite que possamos gerar um conjunto de 12-24 palavras Mnemônicas a partir de uma seed e a biblioteca Libwally também permite que a validemos! + +> :fire: ***Qual é o poder do BIP39?*** Seeds de Bitcoin e chaves privadas estão sujeitas a todos os tipos de perda. Se digitarmos errado um único dígito, nosso dinheiro será perdido para sempre. Palavras mnemônicas são uma forma muito mais amigável de representar os mesmos dados, mas como são palavras no idioma de escolha do usuário, são menos sujeitas a erros. O poder do BIP39 é, portanto, melhorar a acessibilidade, usabilidade e segurança do Bitcoin. + +> :fire: ***Qual é o poder do BIP39 na Libwally?*** O Bitcoind atualmente não suporta palavras mnemônicas, então usar a Libwally pode permitir que geremos palavras mnemônicas em conjunto com endereços mantidos no `bitcoind`, embora como veremos na seção §16.7, é necessário um pouco de gambiarra para importar suas chaves para o Bitcoin Core. + +## O Que Vem Depois? + +Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.3: Usando o BIP32 no Libwally](16_3_Using_BIP32_in_Libwally.md). \ No newline at end of file diff --git a/pt/16_3_Using_BIP32_in_Libwally.md b/pt/16_3_Using_BIP32_in_Libwally.md new file mode 100644 index 0000000..040cae3 --- /dev/null +++ b/pt/16_3_Using_BIP32_in_Libwally.md @@ -0,0 +1,142 @@ +# 16.3: Usando o BIP32 no Libwally + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Na seção [§16.2](16_2_Using_BIP39_in_Libwally.md), fomos capazes de usar a entropia para gerar uma semente e nosso mnemônico relacionado. Como devemos nos lembrar da seção [§3.5: Compreendendo o descritor](03_5_Understanding_the_Descriptor.md), uma seed é a base de uma Carteira Determinística Hierárquica (no inglês Hierchical Deterministic, HD), onde aquela única seed pode ser usada para gerar muitos endereços. Então, como passamos da seed para os endereços reais? É aí que entra o [BIP32](https://en.bitcoin.it/wiki/BIP_0032). + +## Criando uma raiz HD + +Para criar um endereço HD, é necessário começar com uma seed e, em seguida, descer na hierarquia até o ponto em que criamos os endereços. + +Isso começa com bastante facilidade, conosco gerando uma seed, o que já fizemos na seção anterior: +``` + unsigned char entropy[16]; + randombytes_buf(entropy, 16); + + char *mnem = NULL; + lw_response = bip39_mnemonic_from_bytes(NULL,entropy,16,&mnem); + + unsigned char seed[BIP39_SEED_LEN_512]; + size_t seed_len; + lw_response = bip39_mnemonic_to_seed(mnem,NULL,seed,BIP39_SEED_LEN_512,&seed_len); +``` +### Gerando uma chave raiz + +Com uma seed em mãos, podemos gerar uma chave mestra estendida com a função `bip32_key_from_seed_alloc` (ou, alternativamente, com o comando `bip32_key_from_seed`, que não faz o `alloc`): +``` + struct ext_key *key_root; + lw_response = bip32_key_from_seed_alloc(seed,sizeof(seed),BIP32_VER_TEST_PRIVATE,0,&key_root); +``` +Como podemos ver, precisaremos dizer ao comando qual versão da chave retornar, neste caso `BIP32_VER_TEST_PRIVATE`, uma chave privada testnet. + +> :link: **TESTNET vs MAINNET:** Na mainnet, iríamos passar `BIP32_VER_MAIN_PRIVATE`. + +### Gerando a xpub e a xprv + +Sempre que tivermos uma chave em mãos, podemos transformá-la em chaves xpub ou xprv para distribuição com o comando `bip32_key_to_base58`. Basta dizer se desejamos uma chave `PRIVATE` (xprv) ou `PUBLIC` (xpub): +``` + char *xprv; + lw_response = bip32_key_to_base58(key_root, BIP32_FLAG_KEY_PRIVATE, &xprv); + + char *xpub; + lw_response = bip32_key_to_base58(key_root, BIP32_FLAG_KEY_PUBLIC, &xpub); +``` + +## Compreendendo a hierarquia + +Antes de prosseguir, precisamos entender como funciona a hierarquia de uma carteira HD. Conforme discutido na seção [§3.5](03_5_Understanding_the_Descriptor.md), um caminho de derivação descreve a árvore que seguimos para obter uma chave hierárquica, então `[0/1/0]` é o 0º filho do 1º filho do 0º filho de uma chave raiz. Às vezes, parte dessa derivação é marcada com `'` s ou `h`s para mostrar derivações endurecidas, que aumentam a segurança: `[0'/1'/0']`. + +No entanto, para carteiras HD, cada um desses níveis da hierarquia é usado de uma forma muito específica. Isso foi definido originalmente no [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) e foi atualizado posteriormente para o Segwit no [BIP84](https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki). + +Ao todo, um caminho de derivação BIP32 é definido para ter cinco níveis: + +1. **Objetivo.** Isso geralmente é definido como `44'` ou `84'`, dependendo do BIP que estamos seguindo; +2. **Moeda.** Para bitcoins Mainnet, é `0'`, para testnet é `1'`; +3. **Conta.** Uma carteira pode conter várias contas discretas, começando com `0'`; +4. **Troco.** Os endereços externos (para distribuição) são definidos como `0`, enquanto os endereços internos (para troco) são definidos como `1`; +5. **Índice.** O enésimo endereço da hierarquia, começando com `0`. + +Então, na testnet, o endereço zero para um endereço externo para a conta zero para moedas testnet usando os padrões BIP84 é `[m/84'/1'/0'/0/0]`. Esse é o endereço que criaremos neste momento. + +> :link: **TESTNET vs MAINNET:** Para a mainnet, seria `[m/84'/0'/0'/0/0]`. + +### Entendendo a Hierarquia no Bitcoin Core + +Estaremos usando a hierarquia acima para todas as chaves de HD na Libwally, mas observe que este padrão não é usado no `bitcoin-cli` do Bitcoin Core, que ao invés disso usa `[m/0'/0'/0']` para o enésimo endereço externo e `[m/0'/1'/0']` para o enésimo endereço de troco. + +## Gerando um endereço + +Para gerar um endereço, devemos explorar toda a hierarquia. + +### Gerando uma chave da conta + +Uma maneira de fazer isso é usar a função `bip32_key_from_parent_path_alloc` para descer vários níveis de uma hierarquia. Podemos incorporar os níveis em uma matriz: +``` + uint32_t path_account[] = {BIP32_INITIAL_HARDENED_CHILD+84, BIP32_INITIAL_HARDENED_CHILD+1, BIP32_INITIAL_HARDENED_CHILD}; +``` +Aqui, veremos a enésima filha endurecida (essa é a conta) ou a primeira filha endurecida (que são as moedas testnet) da 84ª filha endurecida (esse é o padrão BIP84): `[m/84'/1'/0']`. + +Podemos então usar esse caminho para gerar uma nova chave a partir da nossa antiga chave: +``` + struct ext_key *key_account; + lw_response = bip32_key_from_parent_path_alloc(key_root,path_account,sizeof(path_account),BIP32_FLAG_KEY_PRIVATE,&key_account); +``` +Sempre que tiviermos uma nova chave, poderemos usá-la para gerar novas chaves xprv e xpub, se desejarmos: +``` + lw_response = bip32_key_to_base58(key_account, BIP32_FLAG_KEY_PRIVATE, &a_xprv); + lw_response = bip32_key_to_base58(key_account, BIP32_FLAG_KEY_PUBLIC, &a_xpub); +``` + +### Gerando uma chave de endereço + +Alternativamente, podemos usar a função `bip32_key_from_parent_alloc`, que apenas desce um nível da hierarquia por vez. O exemplo a seguir desce para o enésimo filho da chave da conta (que é o endereço externo) e, em seguida, o enésimo filho dessa chave. Isso seria útil porque poderíamos continuar gerando o primeiro endereço, o segundo endereço e assim por diante a partir dessa chave externa: +``` + struct ext_key *key_external; + lw_response = bip32_key_from_parent_alloc(key_account,0,BIP32_FLAG_KEY_PRIVATE,&key_external); + + struct ext_key *key_address; + lw_response = bip32_key_from_parent_alloc(key_external,0,BIP32_FLAG_KEY_PRIVATE,&key_address); +``` +> :warning: **AVISO:** Em algum ponto desta hierarquia, podemos decidir gerar o `BIP32_FLAG_KEY_PUBLIC` ao invés do `BIP32_FLAG_KEY_PRIVATE`. Obviamente, essa decisão será baseada na nossa segurança e nas nossas necessidades, mas precisamos lembrar de que só precisamos de uma chave pública para gerar o endereço real. + +### Gerando um endereço + +Finalmente, estamos pronto para gerar um endereço a partir de sua chave final. Tudo que fazemos é executar `wally_bip32_to_addr_segwit` usando nossa chave final e uma descrição de que tipo de endereço é este. +``` + char *segwit; + lw_response = wally_bip32_key_to_addr_segwit(key_address,"tb",0,&segwit); + + printf("[m/84'/1'/0'/0/0]: %s\n",segwit); +``` + +> :link: **TESTNET vs MAINNET:** O argumento `tb` define um endereço Testnet. Para a Mainnet, usamos o `bc`. + +Há também uma função `wally_bip32_key_to_address`, que pode ser usada para gerar um endereço legado ou um endereço Segwit aninhado. + +## Testando o Código HD + +O código para esses exemplos de HD pode, como de costume, ser encontrado no [diretório src/](src / 16_3_genhd.c). + +Podemos compilá-lo e testá-lo: +``` +$ cc genhd.c -lwallycore -lsodium -o genhd +$ ./genhd +Mnemonic: behind mirror pond finish borrow wood park foam guess mail regular reflect +Root xprv key: tprv8ZgxMBicQKsPdLFXmZ6VegTxcmeieNpRUq8J2ahXxSaK2aF7CGqAc14ZADLjdHJdCr8oR2Zng9YH1x1A7EBaajQLVGNtxc4YpFejdE3wyj8 +Root xpub key: tpubD6NzVbkrYhZ4WoHKfCm64685BoAeoi1L48j5K6jqNiNhs4VspfeknVgRLLiQJ3RkXiA9VxguUjmEwobtmrXNbhXsPHfm9W5HJR9DKRGaGJ2 +Account xprv key: tprv8yZN7h6SPvJXrhAk56z6cwHQE6qZBRreB9fqqZJ1Xd1nLci3Rw8HTmqNkpFNgf3eZx8hYzhFWafUhHSt3HgF13aHvCE6kveS7gZAyfQwMDi +Account xpub key: tpubDWFQG78gYHzCkACXxkeh2LwWo8MVLm3YkTGd85LJwtpBB6xp4KwseGTEvxjeZNhnCNPdfZqRcgcZZAka4tD3xGS2J53WKHPMRhG357VKsqT +[m/84'/1'/0'/0/0]: tb1q0knqq26ek59pfl7nukzqr28m2zl5wn2f0ldvwu +``` + +## Resumo: Usando o BIP32 no Libwally + +Uma carteira HD permite gerar um grande número de chaves a partir de uma única seed. Agora sabemos como essas chaves são organizadas no BIP44, BIP84 e no Bitcoin Core e, como derivá-las, começando com uma seed ou palavras mnemônicas. + +> :fire: ***Qual é o poder do BIP32?*** As chaves são o elemento mais difícil (e mais perigoso) da maioria das operações criptográficas. Se as perdermos, perderemos tudo o que a chave protegeu. O BIP32 garante que só precisamos conhecer uma chave, a semente, ao invés de um grande número de chaves diferentes para endereços diferentes. + +> :fire: ***Qual é o poder do BIP32 na Libwally?*** O Bitcoind já faz a criação de endereços baseada em HD para nós, o que significa que normalmente não precisamos nos preocupar em derivar endereços dessa maneira. No entanto, usar as funções BIP32 da Libwally pode ser muito útil se estivermos uma máquina offline onde precisamos derivar endereços, possivelmente com base em uma semente passada do `bitcoind` para nosso dispositivo offline (ou vice-versa). + +## O Que Vem Depois? + +Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.4: Usando o PSBTs no Libwally](16_4_Using_PSBTs_in_Libwally.md). \ No newline at end of file diff --git a/pt/16_4_Using_PSBTs_in_Libwally.md b/pt/16_4_Using_PSBTs_in_Libwally.md new file mode 100644 index 0000000..efc9b3b --- /dev/null +++ b/pt/16_4_Using_PSBTs_in_Libwally.md @@ -0,0 +1,378 @@ +# 16.4: Usando o PSBTs na Libwally + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Nós aprendemos tudo sobre as transações do Bitcoin parcialmente assinadas (PSBTs) na seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) e na [§7.2](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md), e como vimos na [§7.3: Integrando com Hardware Wallets](/github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_3_Integrating_with_Hardware_Wallets.md), uma das nossas principais vantagens é a capacidade de integração com nodes offline, como Hardware Wallets. O HWI permitiu que passassemos comandos para uma carteira de hardware, mas o que a própria carteira usa para gerenciar os PSBTs? Por acaso, podemos usar algo na Libwally, como esta seção irá demonstrar. + +Basicamente, a Libwally tem todas as funcionalidades PSBT, então se há algo que podemos fazer com o `bitcoind`, também podemos fazer usando a Libwally, mesmo se nosso dispositivo estiver offline. O que se iremos fazer agora, é a introdução a um tópico bem complexo. + +## Convertendo um PSBT + +Converter um PSBT na estrutura interna da Libwally é incrivelmente fácil, basta executar `wally_psbt_from_base64` com um PSBT base64, que são as saídas produzidas pelo `bitcoin-cli`, como: + +`cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giBgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxRiaHVILVAAAgAEAAIAAAACAAAAAADkCAAAAAQEfQEIPAAAAAAAWABQtTxOfqohTBNFWFqFm0tUVdK9KXSIGAqATz5xLX1aJ2SUwNqPkd8+YaJYm94FMlPCScm8Rt0GrGJodUgtUAACAAQAAgAAAAIAAAAAAAAAAAAAAIgID2UK1nupSfXC81nmB65XZ+pYlJp/W6wNk5FLt5ZCSx6kYmh1SC1QAAIABAACAAAAAgAEAAAABAAAAAA==` + +No entanto, é um pouco mais difícil de lidar com o resultado, porque a Libwally o converte em uma estrutura `wally_psbt` muito complexa. + +Here's how it's defined in `/usr/include/wally_psbt.h`: +Veja como é definido no arquivo `/usr/include/wally_psbt.h`: +``` +struct wally_psbt { + unsigned char magic[5]; + struct wally_tx *tx; + struct wally_psbt_input *inputs; + size_t num_inputs; + size_t inputs_allocation_len; + struct wally_psbt_output *outputs; + size_t num_outputs; + size_t outputs_allocation_len; + struct wally_unknowns_map *unknowns; + uint32_t version; +}; + +struct wally_psbt_input { + struct wally_tx *non_witness_utxo; + struct wally_tx_output *witness_utxo; + unsigned char *redeem_script; + size_t redeem_script_len; + unsigned char *witness_script; + size_t witness_script_len; + unsigned char *final_script_sig; + size_t final_script_sig_len; + struct wally_tx_witness_stack *final_witness; + struct wally_keypath_map *keypaths; + struct wally_partial_sigs_map *partial_sigs; + struct wally_unknowns_map *unknowns; + uint32_t sighash_type; +}; + +struct wally_psbt_output { + unsigned char *redeem_script; + size_t redeem_script_len; + unsigned char *witness_script; + size_t witness_script_len; + struct wally_keypath_map *keypaths; + struct wally_unknowns_map *unknowns; +}; +``` +Estes, por sua vez, usam algumas estruturas de transação definidas em `/usr/include/wally_transaction.h`: +``` +struct wally_tx { + uint32_t version; + uint32_t locktime; + struct wally_tx_input *inputs; + size_t num_inputs; + size_t inputs_allocation_len; + struct wally_tx_output *outputs; + size_t num_outputs; + size_t outputs_allocation_len; +}; + +struct wally_tx_output { + uint64_t satoshi; + unsigned char *script; + size_t script_len; + uint8_t features; +}; +``` +Tem muita coisa aí! Embora muito disso deva ser familiar dos capítulos anteriores, é um pouco intimidador ver tudo disposto em estruturas C. + +## Lendo um PSBT convertido + +Obviamente, podemos ler qualquer coisa de uma estrutura PSBT chamando os elementos individuais das várias subestruturas. A seguir, uma breve visão geral que mostra como captar alguns dos elementos. + +Aqui está um exemplo de recuperação dos valores e os `scriptPubKeys` das entradas: +``` + int inputs = psbt->num_inputs; + printf("TOTAL INPUTS: %i\n",inputs); + + for (int i = 0 ; i < inputs ; i++) { + printf("\nINPUT #%i: %i satoshis\n",i, psbt->inputs[i].witness_utxo->satoshi); + + char *script_hex; + wally_hex_from_bytes(psbt->inputs[i].witness_utxo->script,psbt->inputs[i].witness_utxo->script_len,&script_hex); + printf("scriptPubKey: %s\n",script_hex); + wally_free_string(script_hex); + + } +``` +Este padrão de programação será usado em muitas partes do PSBT. Podemos olhar para o tamanho do array de entrada e depois o percorrer, recuperando o que desejamos observar (neste caso, satoshis e scripts). + +Aqui está um exemplo semelhante para as saídas: +``` + int outputs = psbt->num_outputs; + printf("\nTOTAL OUTPUTS: %i\n",outputs); + for (int i = 0 ; i < outputs ; i++) { + + char *pubkey_hex; + wally_hex_from_bytes(psbt->tx->outputs[i].script,psbt->tx->outputs[i].script_len,&pubkey_hex); + printf("\nINPUT #%i\n",i); + printf("scriptPubKey: %s\n",pubkey_hex); + wally_free_string(pubkey_hex); + } +``` +Obviamente, há muito mais coisas que poderemos observar nos PSBTs. Na verdade, olhar é o ponto principal de um PSBT: Podemos verificar entradas e saídas de um computador offline. + +> :warning: **AVISO:** Estas funções de leitura são _muito_ rudimentares e não funcionarão corretamente para situações extremamente normais como uma entrada ou saída que ainda está vazia ou que inclui um `non_witness_utxo`. Eles darão um segfault se não forem entregues um PSBT precisamente esperado. Um verdadeiro leitor precisaria ser consideravelmente mais robusto, para cobrir todas as situações possíveis, mas vamos deixar isso para o leitor. + +### Testando nosso leitor PSBT + +Novamente, o código para este leitor PSBT (extremamente rudimentar e específico) está no [diretório src/](src/16_4_examinepsbt.c). + +Podemos compilá-lo normalmente: +``` +$ cc examinepsbt.c -lwallycore -o examinepsbt +``` +O seguinte PSBT da seção [§7.3](07_3_Integrating_with_Hardware_Wallets.md) pode ser usado para o teste, pois atende aos critérios muito restritos exigidos por esta implementação limitada: +``` +psbt=cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giBgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxRiaHVILVAAAgAEAAIAAAACAAAAAADkCAAAAAQEfQEIPAAAAAAAWABQtTxOfqohTBNFWFqFm0tUVdK9KXSIGAqATz5xLX1aJ2SUwNqPkd8+YaJYm94FMlPCScm8Rt0GrGJodUgtUAACAAQAAgAAAAIAAAAAAAAAAAAAAIgID2UK1nupSfXC81nmB65XZ+pYlJp/W6wNk5FLt5ZCSx6kYmh1SC1QAAIABAACAAAAAgAEAAAABAAAAAA== +``` +Ao executar o comando `examinepsbt` com esse PSBT, deveremos ver os scripts nas entradas e saídas: +``` +$ ./examinepsbt $psbt +TOTAL INPUTS: 2 + +INPUT #0: 1000000 satoshis +scriptPubKey: 001400193c8bf25ef056f8d4571a1c3f65123e5fe788 + +INPUT #1: 1000000 satoshis +scriptPubKey: 00142d4f139faa885304d15616a166d2d51574af4a5d + +TOTAL OUTPUTS: 2 + +INPUT #0 +scriptPubKey: 0014c772d6f95542e11ef11e8efc7c7a69830ad38a05 + +INPUT #1 +scriptPubKey: 0014f4e8dde5db370898b57c84566e3f76098850817d +``` +And of course, you can check this with the `decodepsbt` RPC command for `bitcoin-cli`: +E, claro, você pode verificar isso com o comando RPC `decodepsbt` para` bitcoin-cli`: +``` +$ bitcoin-cli decodepsbt $psbt +{ + "tx": { + "txid": "45f996d4ff8c9e9ab162f611c5b6ad752479ede9780f9903bdc80cd96619676d", + "hash": "45f996d4ff8c9e9ab162f611c5b6ad752479ede9780f9903bdc80cd96619676d", + "version": 2, + "size": 154, + "vsize": 154, + "weight": 616, + "locktime": 0, + "vin": [ + { + "txid": "5b3c4aeb811f9a119fd633b12a6927415cc61b8654628df58e9141cab804bab8", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + }, + { + "txid": "c733533eb1c052242f9ed89cd8927aedb41852156e684634ee7c74028774e595", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01500000, + "n": 0, + "scriptPubKey": { + "asm": "0 c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "hex": "0014c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd" + ] + } + }, + { + "value": 0.00499791, + "n": 1, + "scriptPubKey": { + "asm": "0 f4e8dde5db370898b57c84566e3f76098850817d", + "hex": "0014f4e8dde5db370898b57c84566e3f76098850817d", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q7n5dmewmxuyf3dtus3txu0mkpxy9pqtacuprak" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.01000000, + "scriptPubKey": { + "asm": "0 00193c8bf25ef056f8d4571a1c3f65123e5fe788", + "hex": "001400193c8bf25ef056f8d4571a1c3f65123e5fe788", + "type": "witness_v0_keyhash", + "address": "tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y" + } + }, + "bip32_derivs": [ + { + "pubkey": "030168d9482e2b02d7027fb4a89edc54adaa1adf709334f647d0a1b0533828aec5", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/0/569" + } + ] + }, + { + "witness_utxo": { + "amount": 0.01000000, + "scriptPubKey": { + "asm": "0 2d4f139faa885304d15616a166d2d51574af4a5d", + "hex": "00142d4f139faa885304d15616a166d2d51574af4a5d", + "type": "witness_v0_keyhash", + "address": "tb1q948388a23pfsf52kz6skd5k4z4627jja2evztr" + } + }, + "bip32_derivs": [ + { + "pubkey": "02a013cf9c4b5f5689d9253036a3e477cf98689626f7814c94f092726f11b741ab", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/0/0" + } + ] + } + ], + "outputs": [ + { + }, + { + "bip32_derivs": [ + { + "pubkey": "03d942b59eea527d70bcd67981eb95d9fa9625269fd6eb0364e452ede59092c7a9", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/1/1" + } + ] + } + ], + "fee": 0.00000209 +} +``` +Podemos ver a entrada de satoshis e o `scriptPubKey` claramente listadas nos `inputs` e a nova `scriptPubKey` no `vout` do `tx`. + +Então, está tudo lá para utilizarmos! + +## Criando um PSBT + +Conforme observado no início desta seção, todas as funções necessárias para criar e processar os PSBTs estão disponíveis em Libwally. Na verdade, percorrer todo o processo para fazer isso é complexo o suficiente para estar além do escopo desta seção, mas aqui está um resumo rápido das funções necessárias. Observe que a [documentação](https://wally.readthedocs.io/en/latest/psbt/) está desatualizada para os PSBTs, portanto, precisaremos consultar o `/usr/include/wally_psbt.h` para obter as informações completas. + +Conforme discutido na seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md), existem várias funções envolvidas na criação dos PSBTs. + +### Assumindo o papel de criador + +A função de criador tem a tarefa de criar um PSBT com pelo menos uma entrada. + +Um PSBT é criado com um simples uso do comando `wally_psbt_init_alloc`, informando quantas entradas e saídas eventualmente adicionaremos: +``` + struct wally_psbt *psbt; + lw_response = wally_psbt_init_alloc(0,1,1,0,&psbt); +``` +Mas o que temos ainda não é um PSBT legal, por falta de entradas. Podemos criá-las criando uma transação e definindo-a como a transação global no PSBT, que atualiza todas as entradas e saídas: +``` + struct wally_tx *gtx; + lw_response = wally_tx_init_alloc(0,0,1,1,>x); + lw_response = wally_psbt_set_global_tx(psbt,gtx); +``` +### Testando nosso PSBT criado + +Neste ponto, devemos ter um PSBT vazio, mas funcionando, que pode ser visto compilando e executando [o programa](src/16_4_createemptypsbt.c). +``` +$ cc createemptypsbt.c -lwallycore -o createemptypsbt +$ ./createemptypsbt +cHNidP8BAAoAAAAAAAAAAAAAAA== +``` +Podemos até usar o `bitcoin-cli` para testar o resultado: +``` +$ psbt=$(./createpsbt) +$ bitcoin-cli decodepsbt $psbt +{ + "tx": { + "txid": "f702453dd03b0f055e5437d76128141803984fb10acb85fc3b2184fae2f3fa78", + "hash": "f702453dd03b0f055e5437d76128141803984fb10acb85fc3b2184fae2f3fa78", + "version": 0, + "size": 10, + "vsize": 10, + "weight": 40, + "locktime": 0, + "vin": [ + ], + "vout": [ + ] + }, + "unknown": { + }, + "inputs": [ + ], + "outputs": [ + ], + "fee": 0.00000000 +} +``` +## Assumindo as demais das funções + +Assim como na leitura de PSBT, estamos introduzindo o conceito de criação do PSBT e, em seguida, deixando o resto como um exercício para o leitor. + +A seguir está uma lista aproximada de funções para cada papel. Mais funções serão necessárias para criar alguns dos elementos que são adicionados aos PSBTs. + +**Criador:** + +* wally_psbt_init_alloc +* wally_psbt_set_global_tx + +**Atualizador:** + +* wally_psbt_input_set_non_witness_utxo +* wally_psbt_input_set_witness_utxo +* wally_psbt_input_set_redeem_script +* wally_psbt_input_set_witness_script +* wally_psbt_input_set_keypaths +* wally_psbt_input_set_unknowns +* wally_psbt_output_set_redeem_script +* wally_psbt_output_set_witness_script +* wally_psbt_output_set_keypaths +* wally_psbt_output_set_unknowns + +**Assinante:** + +* wally_psbt_input_set_partial_sigs +* wally_psbt_input_set_sighash_type +* wally_psbt_sign + +**Combinador:** + +* wally_psbt_combine + +**Finalizador:** +* wally_psbt_finalize +* wally_psbt_input_set_final_script_sig +* wally_psbt_input_set_final_witness + +**Extrator:** + +* wally_psbt_extract + +## Resumo: Usando o PSBTs na Libwally + +Esta seção poderia ser um capítulo inteiro, já que trabalhar com os PSBTs em um nível baixo é um trabalho muito intenso que requer uma manipulação muito mais intensiva de entradas e saídas como foi o caso do [Capítulo 7](07_0_Expanding_Bitcoin_Transactions_PSBTs.md). Ao invés disso, esta seção mostra o básico: como extrair informações de um PSBT e como começar a criar um. + +> :fire: ***Qual é o poder dos PSBTs na Libwally?*** Obviamente, já podemos fazer tudo isso nos `bitcoin-cli`, e é mais simples porque o Bitcoin Core gerencia muito do penoso trabalho. A vantagem de usar o Libwally é que ele pode ser executado offline, então pode ser a Libwally que está do outro lado de um dispositivo de hardware com o qual nosso `bitcoin-cli` está se comunicando com o HWI. Este é, de fato, um dos principais pontos dos PSBTs: ser capaz de manipular transações parcialmente assinadas sem a necessidade de um node completo. A Libwally permite isso. + +## O Que Vem Depois? + +Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.5: Usando Scripts no Libwally](16_5_Using_Scripts_in_Libwally.md). \ No newline at end of file diff --git a/pt/16_5_Using_Scripts_in_Libwally.md b/pt/16_5_Using_Scripts_in_Libwally.md new file mode 100644 index 0000000..5afb79e --- /dev/null +++ b/pt/16_5_Using_Scripts_in_Libwally.md @@ -0,0 +1,179 @@ +# 16.5: Usando Scripts na Libwally + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Na seção 3 deste capítulo, ao apresentar os scripts, dissemos que era provável que criássemos transações usando scripts com uma API e dissemos que este era um tópico para o futuro. Bem, o futuro já chegou. + +## Criando o Script + +Criar o script é a coisa mais _fácil_ de se fazer na Libwally. Veja o exemplo a seguir, um simples [Puzzle Script](13_1_Writing_Puzzle_Scripts.md) ao qual retornamos de vez em quando: +``` +OP_ADD 99 OP_EQUAL +``` +Usando o `btcc`, podemos serializar isso. +``` +$ btcc OP_ADD 99 OP_EQUAL +warning: ambiguous input 99 is interpreted as a numeric value; use 0x99 to force into hexadecimal interpretation +93016387 +``` +Anteriormente, construímos o script P2SH padrão manualmente, mas a Libwally pode fazer isso por nós. + +Primeiro, a Libwally precisa converter o hex em bytes, uma vez que os bytes são o que realmente funciona: +``` + int script_length = strlen(script)/2; + unsigned char bscript[script_length]; + + lw_response = wally_hex_to_bytes(script,bscript,script_length,&written); +``` +Então, executamos o comando `wally_scriptpubkey_p2sh_from_bytes` com os bytes, dizendo a Libwally para também fazer o `HASH160` para nós: +``` + unsigned char p2sh[WALLY_SCRIPTPUBKEY_P2SH_LEN]; + + lw_response = wally_scriptpubkey_p2sh_from_bytes(bscript,sizeof(bscript),WALLY_SCRIPT_HASH160,p2sh,WALLY_SCRIPTPUBKEY_P2SH_LEN,&written); +``` +Se olharmos os resultados do `p2sh`, veremos o seguinte: +``` +a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87 +``` +Que [devemos nos lembrar](10_2_Building_the_Structure_of_P2SH.md) de divide em: +``` +a9 / 14 / 3f58b4f7b14847a9083694b9b3b52a4cea2569ed / 87 +``` +Esse é nosso velho amigo `OP_HASH160 3f58b4f7b14847a9083694b9b3b52a4cea2569ed OP_EQUAL`. + +Basicamente, a Libwally pegou nosso script de resgate serializado, fez o hash para nós com SHA-256 e RIPEMD-160 e aplicou o enquadramento padrão para transformá-lo em um P2SH adequado. Fizemos um trabalho semelhante ao feito na seção [§10.2](10_2_Building_the_Structure_of_P2SH.md), mas com um excesso de comandos shell. + +Na verdade, podemos verificar novamente o nosso trabalho usando os mesmos comandos do §10.2: +``` +$ redeemScript="93016387" +$ echo -n $redeemScript | xxd -r -p | openssl dgst -sha256 -binary | openssl dgst -rmd160 +(stdin)= 3f58b4f7b14847a9083694b9b3b52a4cea2569ed +``` + +## Criando uma transação + +A fim de fazer uso do `pubScriptKey` que acabamos de criar, precisamos criar uma transação e incorporar o `pubScriptKey` dentro, e esta é a grande mudança para o `bitcoin-cli`. Podemos criar manualmente uma transação com um script P2SH. + +O processo de criação de uma transação na Libwally é muito intenso, assim como o processo de criação de um PSBT, portanto, vamos apenas esboçá-lo, pegando um atalho e, em seguida, deixando um método sem atalhos para investigação futura. + +Criar uma transação em si é fácil, só precisamos dizer ao comando `wally_tx_init_alloc` nosso número de versão, o tempo de bloqueio e o número de entradas e saídas: +``` + struct wally_tx *tx; + lw_response = wally_tx_init_alloc(2,0,1,1,&tx); +``` +Preencher essas entradas e saídas é onde as coisas ficam complicadas! + +### Criando uma saída na transação + +Para criar uma saída, dizemos a `wally_tx_output_init_alloc` quantos satoshis estamos gastando, além de entregar o script de bloqueio: +``` + struct wally_tx_output *tx_output; + lw_response = wally_tx_output_init_alloc(95000,p2sh,sizeof(p2sh),&tx_output); +``` +Essa parte não foi nem um pouco difícil e nos permitiu que finalmente incorporássemos um P2SH em um `vout`. + +Mais um comando o adiciona à nossa transação: +``` + lw_response = wally_tx_add_output(tx,tx_output); +``` + +### Criando uma entrada na transação + +Criar a entrada é muito mais difícil porque temos que empilhar informações nas rotinas de criação, nem todas as quais são intuitivamente acessíveis quando usamos a Libwally. Então, ao invés de ir mergulhar fundo nessa biblioteca, é neste momento que pegamos nosso atalho. Escrevemos o código de forma que seja passado o código hexadecimal para uma transação que já foi criada e, em seguida, apenas reutilizamos a entrada. + +A conversão do código hexadecimal é feita com `wally_tx_from_hex`: +``` + struct wally_tx *utxo; + lw_response = wally_tx_from_hex(utxo_hex,0,&utxo); +``` +Então podemos roubar as entradas de nosso código hexadecimal para criar uma entrada com a Libwally: +``` + struct wally_tx_input *tx_input; + lw_response = wally_tx_input_init_alloc(utxo->inputs[0].txhash,sizeof(utxo->inputs[0].txhash),utxo->inputs[0].index,0,utxo->inputs[0].script,utxo->inputs[0].script_len,utxo->inputs[0].witness,&tx_input); + assert(lw_response == WALLY_OK); +``` +Como seria de esperar, adicionamos essa entrada à nossa transação: +``` + lw_response = wally_tx_add_input(tx,tx_input); +``` + +> **NOTA:** Obviamente, iremos querer criar nossas próprias entradas se estivermos usando Libwally aplicativos reais, mas isso é uma primeira etapa. E, na verdade, pode ser útil para integração com o `bitcoin-cli`, como veremos na seção [§16.7](16_7_Integrating_Libwally_and_Bitcoin-CLI.md). + +### Mostrando na tela uma transação + +Teoricamente, poderíamos assinar e enviar esta transação para nosso programa C construído na Libwally, mas mantendo a ideia de que estamos apenas usando um programa C simples para substituir um P2SH, vamos imprimir o novo hex. Isso é feito com a ajuda de `wally_tx_to_hex`: +``` + char *tx_hex; + lw_response = wally_tx_to_hex(tx,0, &tx_hex); + + printf("%s\n",tx_hex); +``` +Mostraremos como fazer uso disso na seção §16.7. + +## Testando nosso script de substituição + +Podemos pegar o código de teste do [diretório src/](src/16_5_replacewithscript.c) e compilá-lo: +``` +$ cc replacewithscript.c -lwallycore -o replacewithscript +``` +Depois, preparamos uma transação hexadecimal e um script hexadecimal serializado: +``` +hex=020000000001019527cebb072524a7961b1ba1e58fc18dd7c6fc58cd6c1c45d7e1d8fc690b006e0000000017160014cc6e8522f0287b87b7d0a83629049c2f2b0e972dfeffffff026f8460000000000017a914ba421212a629a840492acb2324b497ab95da7d1e87306f0100000000001976a914a2a68c5f9b8e25fdd1213c38d952ab2be2e271be88ac02463043021f757054fa61cfb75b64b17230b041b6d73f25ff9c018457cf95c9490d173fb4022075970f786f24502290e8a5ed0f0a85a9a6776d3730287935fb23aa817791c01701210293fef93f52e6ce8be581db62229baf116714fcb24419042ffccc762acc958294e6921b00 + +script=93016387 +``` +Podemos então executar o programa de substituição: +``` +$ ./replacewithscript $hex $script +02000000019527cebb072524a7961b1ba1e58fc18dd7c6fc58cd6c1c45d7e1d8fc690b006e0000000017160014cc6e8522f0287b87b7d0a83629049c2f2b0e972d0000000001187301000000000017a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed8700000000 +``` +Podemos ver os resultados com o `bitcoin-cli`: +``` +$ bitcoin-cli decoderawtransaction $newhex +{ + "txid": "f4e7dbab45e759a7ac6e2fb0f10720cd29d047efad89fe1b569f5f4ba61fd8e6", + "hash": "f4e7dbab45e759a7ac6e2fb0f10720cd29d047efad89fe1b569f5f4ba61fd8e6", + "version": 2, + "size": 106, + "vsize": 106, + "weight": 424, + "locktime": 0, + "vin": [ + { + "txid": "6e000b69fcd8e1d7451c6ccd58fcc6d78dc18fe5a11b1b96a7242507bbce2795", + "vout": 0, + "scriptSig": { + "asm": "0014cc6e8522f0287b87b7d0a83629049c2f2b0e972d", + "hex": "160014cc6e8522f0287b87b7d0a83629049c2f2b0e972d" + }, + "sequence": 0 + } + ], + "vout": [ + { + "value": 0.00095000, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 3f58b4f7b14847a9083694b9b3b52a4cea2569ed OP_EQUAL", + "hex": "a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2My2ApqGcoNXYceZC4d7fipBu4GodkbefHD" + ] + } + } + ] +} +``` +O `vin` deve apenas corresponder à entrada que substituímos, mas é o `vout` que é empolgante. Criamos uma transação com um `scripthash`! + +## Resumo: Usando Scripts na Libwally + +A criação de transações na Libwally é outro tópico que pode ocupar um capítulo inteiro, mas o melhor é que, uma vez que demos esse salto, pode introduzir um P2SH `scriptPubKey`, e só essa parte é muito fácil. Embora a metodologia detalhada neste capítulo exija que já tenhamos um hex de transação em mãos (provavelmente criado com o `bitcoin-cli`) se nos aprofundarmos na Libwally, podemos fazer tudo sozinho. + +> :fire: ***Qual é o poder dos scripts no Libwally?*** De maneira bem simples, podemos fazer algo que não podíamos antes. Criar uma transação bloqueada com um P2SH arbitrário. + +## O Que Vem Depois? + +Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.6: Usando Outras Funções no Libwally](16_6_Using_Other_Functions_in_Libwally.md). \ No newline at end of file diff --git a/pt/16_6_Using_Other_Functions_in_Libwally.md b/pt/16_6_Using_Other_Functions_in_Libwally.md new file mode 100644 index 0000000..f198be2 --- /dev/null +++ b/pt/16_6_Using_Other_Functions_in_Libwally.md @@ -0,0 +1,126 @@ +# 16.6: Usando Outras Funções no Libwally + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +A Libwally é uma extensa biblioteca que fornece uma quantidade considerável de funcionalidades relacionadas à carteira, muitas delas não disponíveis por meio do `bitcoin-cli`. A seguir, está uma visão geral de algumas funcionalidades não abordadas anteriormente neste capítulo. + +## Usando funções criptográficas + +Diversas funções criptográficas podem ser acessadas diretamente na Libwally: + + * `wally_aes` - Usa criptografia ou descriptografia AES; + * `wally_aes_cbc` - Usa criptografia ou descriptografia AES no modo CBC; + * `wally_hash160` - Usa hash RIPEMD-160 (SHA-256); + * `wally_scrypt` - Usa derivação de chave Scrypt; + * `wally_sha256` - Usa hash SHA256; + * `wally_sha256_midstate` - Usa SHA256 para fazer hash apenas do primeiro bloco de dados; + * `wally_sha256d` - Conduza um hash duplo SHA256; + * `wally_sha512` - Usa hash SHA512. + +Existem também funções HMAC para os dois hashes SHA, que são usados ​​para gerar códigos de autenticação de mensagem com base nos hashes. Eles são usados no [BIP32](https://en.bitcoin.it/wiki/BIP_0032), entre outros lugares. + + * `wally_hmac_sha256` + * `wally_hmac_sha512` + +Funções adicionais cobrem derivação chave PBKDF2 e matemática de curva elíptica. + +## Usando funções de endereço + +A Libwally contém várias funções que podem ser usadas para importar, exportar e traduzir endereços de Bitcoin. + +Alguns convertem entre endereços e bytes `scriptPubKey`: + + * `wally_addr_segwit_from_bytes` - Converta um programa witness (em bytes) em um endereço Segwit; + * `wally_addr_segwit_to_bytes` - Converta um endereço Segwit em um `scriptPubKey` (em bytes); + * `wally_address_to_scriptpubkey` - Converta um endereço legado em um `scriptPubKey` (em bytes); + * `wally_scriptpubkey_to_address` - Converta um `scriptPubKey` (em bytes) em um endereço legado. + +Alguns estão relacionados ao formato de importação de carteira (WIF): + + * `wally_wif_from_bytes` - Converta uma chave privada (em bytes) para um WIF; + * `wally_wif_is_uncompressed` - Determina se um WIF está descompactado; + * `wally_wif_to_address` - Deriva um endereço P2PKH de um WIF; + * `wally_wif_to_bytes` - Converta um WIF em uma chave privada (em bytes); + * `wally_wif_to_public_key` - Deriva uma chave pública (em bytes) de um WIF. + +## Usando funções BIP32 + +Existem funções adicionais de carteira HD BIP32, além do que foi abordado na seção [§16.3: Usando o BIP32 no Libwally](16_3_Using_BIP32_in_Libwally.md). + + * `bip32_key_get_fingerprint` - Gera uma impressão digital BIP32 para uma chave estendida; + * `bip32_key_serialize` - Transforma uma chave estendida em bytes serializados; + * `bip32_key_strip_private_key` - Converte uma chave privada estendida em uma chave pública estendida; + * `bip32_key_unserialize` - Transforma bytes serializados em uma chave estendida. + +Existem também vários outros comandos, dependendo se desejamos alocar memória ou fazer com que a Libwally faça o `_alloc` para nós. + +## Usando funções BIP38 + +O [BIP38](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki) permite a criação de uma chave privada protegida por senha. Não ensinamos porque consideramos perigoso inserir esse tipo de fator humano no gerenciamento de chaves. Se duvida disso, consulte [#SmartCustody](https://www.smartcustody.com/index.html). + +As principais funções são: + + * `bip38_from_private_key` - Codifica uma chave privada usando BIP38; + * `bip38_to_private_key` - Decodifica uma chave privada usando BIP38. + +## Usando funções BIP39 + +Algumas funções de palavras mnemônicas do BIP39 foram resumidas recentemente na seção [§16.2: Usando o BIP39 no Libwally](16_2_Using_BIP39_in_Libwally.md): + + * `bip39_get_languages` - Veja a lista de idiomas suportados; + * `bit39_get_word` - Recupera uma palavra específica da lista de palavras de um idioma; + * `bip39_get_wordlist` - Veja uma lista de palavras para um idioma. + +## Usando funções PSBT + +As listas da maioria das funções PSBT podem ser encontradas na seção [16.4: Usando o PSBTs no Libwally](16_4_Using_PSBTs_in_Libwally.md). + +## Usando funções de script + +A seção [§16.5: Usando Scripts no Libwally](16_5_Using_Scripts_in_Libwally.md) apenas tocou nas funções de scripts da Libwally. + +Há outra função que permite determinar o tipo de script encontrado em uma transação: + + * `wally_scriptpubkey_get_type` — Determina a transaction's script type; + * `wally_scriptpubkey_get_type` - Determina o tipo de script de uma transação. + +Depois, há uma série de funções que criam `scriptPubKey` a partir de bytes, o `scriptSig` a partir de assinaturas e witness a partir de bytes ou assinaturas. + + * `wally_script_push_from_bytes` + * `wally_scriptpubkey_csv_2of2_then_1_from_bytes` + * `wally_scriptpubkey_csv_2of3_then_2_from_bytes` + * `wally_scriptpubkey_multisig_from_bytes` + * `wally_scriptpubkey_op_return_from_bytes` + * `wally_scriptpubkey_p2pkh_from_bytes` + * `wally_scriptpubkey_p2sh_from_bytes` + * `wally_scriptsig_multisig_from_bytes` + * `wally_scriptsig_p2pkh_from_der` + * `wally_scriptsig_p2pkh_from_sig` + * `wally_witness_multisig_from_bytes` + * `wally_witness_p2wpkh_from_der` + * `wally_witness_p2wpkh_from_sig` + * `wally_witness_program_from_bytes` + +## Usando Funções de Transação + +Também mal tocamos nas funções que podem ser usadas para criar e converter funções na seção [§16.5](16_5_Using_Scripts_in_Libwally.md). + +Existem inúmeras funções informativas, algumas das mais interessantes são: + + * `wally_tx_get_length` + * `wally_tx_get_total_output_satoshi` + * `wally_tx_get_weight` + +Também existem funções que afetam um `wally_tx`, um `wally_tx_input`, um `wally_tx_output`, ou um `wally_tx_witness_stack` e que criam assinaturas. + +## Usando funções de elementos + +A Libwally pode ser compilada para ser usada com os Elementos do Blockstream, que inclui acesso às funções dos ativos. + +## Resumo: Usando Outras Funções no Libwally + +Há muito mais coisas que podemos fazer com a Libwally, mais do que podemos abordar neste capítulo ou mesmo listar nesta seção. Notavelmente, podemos executar funções criptográficas, codificar chaves privadas, criar transações completas e usar elementos. A [documentação da Libwally](https://wally.readthedocs.io/en/latest/) é o lugar onde podemos obter mais informações, embora, no momento da criação deste livro, a documentação esteja limitada e desatualizada. Os arquivos de cabeçalho da Libwally são um backup se os documentos estiverem incompletos ou incorretos. + +## O Que Vem Depois? + +Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.7: Integrando o Libwally ao Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md). \ No newline at end of file diff --git a/pt/16_7_Integrating_Libwally_and_Bitcoin-CLI.md b/pt/16_7_Integrating_Libwally_and_Bitcoin-CLI.md new file mode 100644 index 0000000..b93d537 --- /dev/null +++ b/pt/16_7_Integrating_Libwally_and_Bitcoin-CLI.md @@ -0,0 +1,330 @@ +# 16.7: Integrando o Libwally ao Bitcoin-CLI + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +A Libwally é limitado. Trata-se de manipular seeds, chaves, endereços e outros elementos de carteiras, com algumas funções adicionais relacionadas a transações e PSBTs que podem ser úteis para serviços que não estão conectados a nodes completos na Internet. No final das contas, no entanto, precisaremos de serviços de nodes completos para aproveitar as vantagens da Libwally. + +Esta última seção oferecerá alguns exemplos de uso de programas Libwally para complementar um ambiente `bitcoin-cli`. Embora esses exemplos impliquem que esses serviços estão todos na mesma máquina, eles podem se tornar ainda mais poderosos se o serviço `bitcoin-cli` estiver diretamente conectado à internet e o serviço Libwally não. + +## Compartilhando uma transação + +Na seção [§16.5: Usando Scripts no Libwally](16_5_Using_Scripts_in_Libwally.md) detalhamos como a Libwally poderia ser usada para reescrever uma transação existente, para fazer algo que o `bitcoin-cli` não pode, ou seja, produzir uma transação que contém um P2SH único. Obviamente, este é um bloco de construção, se decidirmos nos aprofundar no Libwally, criaremos transações inteiras por conta própria. Mas, esta metodologia abreviada também tem seu próprio uso, mostrar como as transações podem ser passadas de um lado para outro entre `bitcoin-cli` e Libwally, demonstrando um primeiro exemplo de como usá-los de forma complementar. + +Para demonstrar totalmente essa metodologia, criaremos uma transação com o `bitcoin-cli`, usando este UTXO: +``` + { + "txid": "c0a110a7a84399b98052c6545018873b13ee3128fa74f7a697779174a36ea33a", + "vout": 1, + "address": "mvLyH7Rs45c16FG2dfV7uuTKV6pL92kWxo", + "label": "", + "scriptPubKey": "76a914a2a68c5f9b8e25fdd1213c38d952ab2be2e271be88ac", + "amount": 0.00094000, + "confirmations": 17375, + "spendable": true, + "solvable": true, + "desc": "pkh([ce0c7e14/0'/0'/5']0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65)#qldtsl65", + "safe": true + } +``` +Agora, já sabemos como configurar uma transação com o `bitcoin-cli`: +``` +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ recipient=tb1qycsmq3jas5wkhf8xrfn8k7438cm5pc8h9ae2k0 +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.0009 }''') +``` +Embora tenhamos colocado um destinatário e uma quantia na saída, é irrelevante, porque nós o reescreveremos. Um código mais elaborado poderia ler as informações `vout` existentes antes de reescrever, mas estamos mantendo as coisas muito próximas do nosso [código original](src/16_5_replacewithscript.c). + +Aqui está a única alteração necessária, para permitir que especifiquemos os satoshis no `vout`, sem ter que codificá-lo, como no original: +``` +... + int satoshis = atoi(argv[3]); +... + lw_response = wally_tx_output_init_alloc(satoshis,p2sh,sizeof(p2sh),&tx_output); +... +``` +Então executamos as coisas como antes: +``` +$ newtxhex=$(./replacewithscript $rawtxhex $script 9000) +``` +Esta é a aparência da transação original: +``` +$ bitcoin-cli decoderawtransaction $rawtxhex +{ + "txid": "438d50edd7abeaf656c5abe856a00a20af5ff08939df8fdb9f8bfbfb96234fcb", + "hash": "438d50edd7abeaf656c5abe856a00a20af5ff08939df8fdb9f8bfbfb96234fcb", + "version": 2, + "size": 82, + "vsize": 82, + "weight": 328, + "locktime": 0, + "vin": [ + { + "txid": "c0a110a7a84399b98052c6545018873b13ee3128fa74f7a697779174a36ea33a", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "0 2621b0465d851d6ba4e61a667b7ab13e3740e0f7", + "hex": "00142621b0465d851d6ba4e61a667b7ab13e3740e0f7", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qycsmq3jas5wkhf8xrfn8k7438cm5pc8h9ae2k0" + ] + } + } + ] +} +``` +E aqui está a transação reescrita pela Libwally para usar em um P2SH: +``` +standup@btctest:~/c$ bitcoin-cli decoderawtransaction $newtxhex +{ + "txid": "badb57622ab5fe029fc1a71ace9f7b76c695f933bceb0d38a155c2e5c984f4e9", + "hash": "badb57622ab5fe029fc1a71ace9f7b76c695f933bceb0d38a155c2e5c984f4e9", + "version": 2, + "size": 83, + "vsize": 83, + "weight": 332, + "locktime": 0, + "vin": [ + { + "txid": "c0a110a7a84399b98052c6545018873b13ee3128fa74f7a697779174a36ea33a", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 0 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 3f58b4f7b14847a9083694b9b3b52a4cea2569ed OP_EQUAL", + "hex": "a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2My2ApqGcoNXYceZC4d7fipBu4GodkbefHD" + ] + } + } + ] +} +``` +Depois, podemos assiná-la normalmente com o `bitcoin-cli`: +``` +$ signedtx=$(bitcoin-cli signrawtransactionwithwallet $newtxhex | jq -r '.hex') +``` +E como podemos ver, o resultado é uma transação legítima pronta para ir para a rede Bitcoin: +``` +$ bitcoin-cli decoderawtransaction $signedtx +{ + "txid": "3061ca8c01d029c0086adbf8b7d4280280c8aee151500bab7c4f783bbc8e75e6", + "hash": "3061ca8c01d029c0086adbf8b7d4280280c8aee151500bab7c4f783bbc8e75e6", + "version": 2, + "size": 189, + "vsize": 189, + "weight": 756, + "locktime": 0, + "vin": [ + { + "txid": "c0a110a7a84399b98052c6545018873b13ee3128fa74f7a697779174a36ea33a", + "vout": 1, + "scriptSig": { + "asm": "3044022026c81b6ff4a15135d10c7f4b1ae6e44ac4fdb25c4a3c03161b17b8ab8d04850502200b448d070f418de1ca07e76943d23d447bc95c7c5e0322bcc153cadb5d9befe0[ALL] 0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65", + "hex": "473044022026c81b6ff4a15135d10c7f4b1ae6e44ac4fdb25c4a3c03161b17b8ab8d04850502200b448d070f418de1ca07e76943d23d447bc95c7c5e0322bcc153cadb5d9befe001210368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65" + }, + "sequence": 0 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 3f58b4f7b14847a9083694b9b3b52a4cea2569ed OP_EQUAL", + "hex": "a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2My2ApqGcoNXYceZC4d7fipBu4GodkbefHD" + ] + } + } + ] +} +``` +Pronto! Esse é o poder da Libwally com o `bitcoin-cli`. + +Obviamente, também pode passar um PSBT usando as funções descritas na seção [§16.4](16_4_Using_PSBTs_in_Libwally.md) e essa é uma metodologia mais atualizada para o uso moderno do Bitcoin, mas em qualquer um dos exemplos, o conceito de passar transações do `bitcoin-cli` para código Libwally e vice-versa deve ser semelhante. + +## Importando e exportando seeds BIP39 + +Infelizmente, nem todas as interações entre a Libwally e o `bitcoin-cli` são fáceis. Por exemplo, seria bom se pudessemos exportar uma seed HD do `bitcoin-cli`, para gerar a frase mnemônica com a Libwally, ou gerar uma seed de uma frase mnemônica usando a Libwally e depois importá-la para o `bitcoin-cli `. Infelizmente, nada disso é possível neste momento. Uma frase mneômica é traduzida em uma seed usando HMAC-SHA512, o que significa que o resultado é 512 bits. No entanto, o `bitcoin-cli` exporta seeds HD (usando `dumpwallet`) e importa sementes HD (usando `sethdseed`) com um comprimento de 256 bits. Até que isso seja mudado, não podemos fazer nada sobre isso. + +> :book: ***Qual é a diferença entre entropia e uma seed?*** A Libwally diz que criamos nossas frases mnemônicas a partir da entropia. Isso é essencialmente a mesma coisa que uma seed, pois ambos são números grandes e aleatórios. Portanto, se o `bitcoin-cli` fosse compatível com as sementes de frase mnemônica de 512 bits, poderíamos usar uma para gerar as frases mnemônicas e obter os resultados esperados. + +> :book: ***Qual é a diferença entre entropia e entropia bruta?*** Nem toda entropia é a mesma. Quando inserimos entropia em um comando que cria uma seed mnemônica, ela tem um comprimento específico e bem conhecido. Mudar a entropia bruta em uma entropia requer alterar a entropia bruta até que tenha o comprimento e o formato corretos, e nesse ponto podemos reutilizar essa entropia (não bruta) para sempre recriar os mesmos mnemônicos (razão pela qual a entropia é efetivamente a mesma coisa que um seed naquele ponto, mas a entropia bruta não). + +## Importando chaves privadas + +Felizmente, podemos fazer quase a mesma coisa importando uma chave privada gerada na Libwally. Dê uma olhada no [genhd-for-import.c](src/16_7_genhd_for_import.c), uma versão simplificada do programa `genhd` da seção [§16.3](16_3_Using_BIP32_in_Libwally.md) que também usa a biblioteca `jansson` da seção [ §15.1](15_1_Accessing_Bitcoind_with_C.md) para saída regularizada. + +O código atualizado também contém uma alteração importante, pois ele solicita uma impressão digital da Libwally para que possa criar um caminho de derivação de maneira adequada: +``` + char account_fingerprint[BIP32_KEY_FINGERPRINT_LEN]; + lw_response = bip32_key_get_fingerprint(key_account,account_fingerprint,BIP32_KEY_FINGERPRINT_LEN); + + char *fp_hex; + lw_response = wally_hex_from_bytes(account_fingerprint,BIP32_KEY_FINGERPRINT_LEN,&fp_hex); +``` + +> :aviso: **AVISO:** Lembre-se de que a impressão digital nos caminhos de derivação é arbitrária. Como o Libwally fornece um, nós o estamos usando, mas se não tivermos um, poderemos adicionar um código hexadecimal arbitrário de 4 bytes como uma impressão digital em nosso caminho de derivação. + +Certifique-se de compilar o novo código com a biblioteca `jansson`, após instalá-lo (se necessário) de acordo com a seção [§15.1](15_1_Accessing_Bitcoind_with_C.md). +``` +$ cc genhd-for-import.c -lwallycore -lsodium -ljansson -o genhd-for-import +``` +Quando executamos o novo programa, ele nos dará uma lista de saída com todas as informações: +``` +$ ./genhd-for-import +{ + "mnemonic": "physical renew say quit enjoy eager topic remind riot concert refuse chair", + "account-xprv": "tprv8yxn8iFNgsLktEPkWKQpMqb7bcx5ViFQEbJMtqrGi8LEgvy8es6YeJvyJKrbYEPKMw8JbU3RFhNRQ4F2pataAtTNokS1JXBZVg62xfd5HCn", + "address": "tb1q9lhru6k0ymwrtr5w98w35n3lz22upml23h753n", + "derivation": "[d1280779/84h/1h/0h]" +} +``` +Temos o `mnemônico` que podemos recuperar, um `account-xprv` que podemos importar, uma `derivação` para usar para a importação e um `address` de amostra, que podemos usar para testar a importação. + +Agora podemos recorrer às lições aprendidas na seção [§3.5](03_5_Understanding_the_Descriptor.md) sobre como transformar esse xprv em um descritor e importá-lo. + +Primeiro, precisamos descobrir a soma de verificação: +``` +$ xprv=tprv8yxn8iFNgsLktEPkWKQpMqb7bcx5ViFQEbJMtqrGi8LEgvy8es6YeJvyJKrbYEPKMw8JbU3RFhNRQ4F2pataAtTNokS1JXBZVg62xfd5HCn +$ dp=[d1280779/84h/1h/0h] +$ bitcoin-cli getdescriptorinfo "wpkh($dp$xprv/0/*)" +{ + "descriptor": "wpkh([d1280779/84'/1'/0']tpubDWepH8HcqF2RmhRYPy5QmFFEAeU1f3SJotu9BMta8Q8dXRDuHFv8poYqUUtEiWftBjtKn1aNhi9Qg2P4NdzF66dShYvB92z78WJbYeHTLTz/0/*)#f8rmqc0z", + "checksum": "46c00dk5", + "isrange": true, + "issolvable": true, + "hasprivatekeys": true +} +``` + +Há três coisas a serem observadas aqui: + +1. Usamos o `wpkh` como a função em nosso caminho de derivação. Isso porque queremos gerar endereços Segwit modernos, não endereços legados. Isso corresponde ao uso na Libwally da função `wally_bip32_key_to_addr_segwit`. A coisa mais importante, entretanto, é ter as mesmas expectativas com a Libwally e o `bitcoin-cli` (e nosso descritor) de que tipo de endereço estamos gerando, para que tudo sê certo; +2. Usamos o caminho `/0/*` porque queríamos os endereços externos para esta conta. Se, em vez disso, quiséssemos alterar os endereços, usaríamos `/1/*`; +3. Não vamos usar a linha `descriptor` que foi retornada, pois é para um endereço `xpub`. Ao invés disso, aplicaremos o `checksum` retornado ao `xprv` que já temos. +``` +$ cs=$(bitcoin-cli getdescriptorinfo "wpkh($dp$xprv/0/*)" | jq -r ' .checksum') +``` +Então conectamos isso em um `importmulti` para importar esta chave no `bitcoin-cli`: +``` +$ bitcoin-cli importmulti '''[{ "desc": "wpkh('$dp''$xprv'/0/*)#'$cs'", "timestamp": "now", "range": 10, "watchonly": false, "label": "LibwallyImports", "keypool": false, "rescan": false }]''' +[ + { + "success": true + } +] + +``` +Aqui, importamos/geramos os primeiros dez endereços para a chave privada. + +Vamos examinar o novo rótulo `LibwallyImported`: +``` +$ bitcoin-cli getaddressesbylabel "LibwallyImports" +{ + "tb1qzeqrrt77xhvazq5g8sc9th0lzjwstknan8gzq7": { + "purpose": "receive" + }, + "tb1q9lhru6k0ymwrtr5w98w35n3lz22upml23h753n": { + "purpose": "receive" + }, + "tb1q8fsgxt0z9r9hfl5mst5ylxka2yljjxlxlvaf8j": { + "purpose": "receive" + }, + "tb1qg6dayhdk4qc6guutxvdweh6pctc9dpguu6awqc": { + "purpose": "receive" + }, + "tb1qdphaj0exvemxhgfpyh4p99wn84e2533u7p96l6": { + "purpose": "receive" + }, + "tb1qwv9mdqkpx6trtmvgw3l95npq8gk9pgllucvata": { + "purpose": "receive" + }, + "tb1qwh92pkrv6sps62udnmez65vfxe9n5ceuya56xz": { + "purpose": "receive" + }, + "tb1q4e98ln8xlym64qjzy3k8zyfyt5q60dgcn39d90": { + "purpose": "receive" + }, + "tb1qhzje887fyl65j4mulqv9ysmntwn95zpgmgvtqd": { + "purpose": "receive" + }, + "tb1q62xf9ec8zcfkh2qy5qnq4qcxrx8l0jm27dd8ru": { + "purpose": "receive" + }, + "tb1qlw85usfk446ssxejm9dmxsfn40kzsqce77aq20": { + "purpose": "receive" + } +} + +``` +O segundo em nossa lista realmente corresponde ao que temos de amostra (`tb1q9lhru6k0ymwrtr5w98w35n3lz22upml23h753n`). A importação desta chave privada e a derivação de dez endereços foram bem-sucedidas. + +Se olharmos agora para trás na seção [§7.3](07_3_Integrating_with_Hardware_Wallets.md), veremos que esta era a mesma metodologia que usamos para importar endereços de uma carteira física (embora desta vez também importamos a chave privada como prova de conceito). A maior diferença é que anteriormente a informação era criada por uma caixa preta (literalmente, pois era um dispositivo Ledger), e desta vez nós mesmos criamos a informação usando a Libwally, mostrando como podemos fazer esse tipo de trabalho de maneira airgaped ou em outro dispositivo remoto e, em seguida, levá-lo ao `bitcoin-cli`. + +## Importando endereços + +Obviamente, se podemos importar chaves privadas, também podemos importar endereços, o que geralmente significa importar endereços somente para observação _sem_ as chaves privadas. + +Uma maneira do fazer isso é utilizar a metodologia `importmulti` acima, mas neste caso, usamos o endereço fornecido XPUB (`wpkh([d1280779/84'/1'/0']tpubDWepH8HcqF2RmhRYPy5QmFFEAeU1f3SJotu9BMta8Q8dXRDuHFv8poYqUUtEiWftBjtKn1aNhi9Qg2P4NdzF66dShYvB92z78WJbYeHTLTz/0/*)#f8rmqc0z`) ao invés do xprv original. Essa é a melhor maneira de importar uma sequência inteira de endereços somente para observação. + +Como alternativa, podemos importar endereços individuais. Por exemplo, considere o único endereço de amostra retornado pelo programa `genhd-for-import`: +``` +$ ./genhd-for-import +{ + "mnemonic": "finish lady crucial walk illegal ride hamster strategy desert file twin nature", + "account-xprv": "tprv8xRujYeVN7CwBHxLoTHRdmzwdW7dKUzDfruSo56GqqfRW9QXtnxnaRG8ke7j65uNjxmCVfcagz5uuaMi2vVJ8jpiGZvLwahmNB8F3SHUSyv", + "address": "tb1qtvcchgyklp6cyleth85c7pfr4j72z2vyuwuj3d", + "derivation": "[6214ecff/84h/1h/0h]" +} +``` +Podemos importá-lo como um endereço de observação com `importaddress`: +``` +$ bitcoin-cli -named importaddress address=tb1qtvcchgyklp6cyleth85c7pfr4j72z2vyuwuj3d label=LibwallyWO rescan=false +$ bitcoin-cli getaddressesbylabel "LibwallyWO" +{ + "tb1qtvcchgyklp6cyleth85c7pfr4j72z2vyuwuj3d": { + "purpose": "receive" + } +} +} +``` + +## Resumo: Integrando o Libwally ao Bitcoin-CLI + +Com um conhecimento básico de Libwally, agora podemos complementar todo o trabalho das lições anteriores. A transferência de endereços, chaves, transações e PSBTs são apenas algumas das maneiras pelas quais podemos usar esses dois poderosos métodos de programação do Bitcoin juntos. Também há muito mais profundidade potencial se quisermos nos aprofundar na extensa biblioteca de funções do Libwally. + +> :fire: ***Qual é o poder de integrar Libwally e Bitcoin-CLI?*** Uma das maiores vantagens do Libwally é que ele tem muitas funções que podem ser usadas offline. Em comparação, o Bitcoin Core é um programa em rede. Isso pode ajudá-lo a aumentar a segurança fazendo com que o `bitcoin-cli` passe chaves, endereços, transações ou PSBTs para uma fonte offline (que estaria executando programas Libwally). Além disso, o Libwally pode fazer coisas que o Bitcoin Core não pode, como gerar uma seed a partir de um mnemônico BIP39 (e mesmo se não pudermos importá-la para o Bitcoin Core, _podemos_ importar a chave mestra, conforme mostrado aqui). + +## O Que Vem Depois? + +Saiba mais sobre outras linguagens de programação no [Capítulo 17: Conversando com o Bitcoind com Outras Linguagens](17_0_Talking_to_Bitcoind_Other.md). \ No newline at end of file From 7491a68ed7ca1a499752bf2bed9a5483fadd85be Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sun, 8 Aug 2021 10:19:25 -0300 Subject: [PATCH 059/155] Chapter 17 translation concluded --- pt/17_0_Talking_to_Bitcoind_Other.md | 26 ++ pt/17_1_Accessing_Bitcoind_with_Go.md | 421 ++++++++++++++++++ pt/17_2_Accessing_Bitcoind_with_Java.md | 332 +++++++++++++++ pt/17_3_Accessing_Bitcoind_with_NodeJS.md | 274 ++++++++++++ pt/17_4_Accessing_Bitcoind_with_Python.md | 495 ++++++++++++++++++++++ pt/17_5_Accessing_Bitcoind_with_Rust.md | 362 ++++++++++++++++ pt/17_6_Accessing_Bitcoind_with_Swift.md | 463 ++++++++++++++++++++ 7 files changed, 2373 insertions(+) create mode 100644 pt/17_0_Talking_to_Bitcoind_Other.md create mode 100644 pt/17_1_Accessing_Bitcoind_with_Go.md create mode 100644 pt/17_2_Accessing_Bitcoind_with_Java.md create mode 100644 pt/17_3_Accessing_Bitcoind_with_NodeJS.md create mode 100644 pt/17_4_Accessing_Bitcoind_with_Python.md create mode 100644 pt/17_5_Accessing_Bitcoind_with_Rust.md create mode 100644 pt/17_6_Accessing_Bitcoind_with_Swift.md diff --git a/pt/17_0_Talking_to_Bitcoind_Other.md b/pt/17_0_Talking_to_Bitcoind_Other.md new file mode 100644 index 0000000..60de440 --- /dev/null +++ b/pt/17_0_Talking_to_Bitcoind_Other.md @@ -0,0 +1,26 @@ +# Capítulo 17: Conversando com o Bitcoind com Outras Linguagens + +Agora devemos ter uma base sólida para trabalhar com Bitcoin usando a linguagem C, não apenas usando as bibliotecas RPC, JSON e ZMQ para interagir diretamente com o `bitcoind`, mas também, utilizando as bibliotecas Libwally para complementar esse trabalho. O C é uma ótima linguagem para prototipagem e abstração, porém provavelmente não é o que estamos usando para programar. Este capítulo, portanto, faz uma apresentação rápida por seis outras linguagens de programação, demonstrando a funcionalidade mais básica do Bitcoin em cada uma, permitindo que possamos expandir as lições da linha de comando e do C para a linguagem de programação que desejarmos escolha. + +Cada uma das seções contém aproximadamente as mesmas informações, o foco será: Criar uma conexão RPC, examinar a carteira, criando um novo endereço e criar uma transação. No entanto, há alguma mudança entre as linguagens, mostrando diferentes aspectos dos comandos RPC do Bitcoin em diferentes exemplos. Em particular, algumas linguagens usam a metodologia fácil do `sendtoaddress`, enquanto outras usam uma metodologia mais difícil para a criação de uma transação bruta do zero. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Preparar ambientes de desenvolvimento para o Bitcoin para uma variedade de linguagens; + * Usar as funções da carteira em várias linguagens; + * Usar funções de transação em uma variedade de linguagens. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Saiber mais sobre o Bitcoin RPC por meio de interações com uma variedade de linguagens. + +## Tabela de Conteúdo + + * [Seção 1: Acessando o Bitcoind com Go](17_1_Accessing_Bitcoind_with_Go.md) + * [Seção 2: Acessando o Bitcoind com Java](17_2_Accessing_Bitcoind_with_Java.md) + * [Seção 3: Acessando o Bitcoind com NodeJS](17_3_Accessing_Bitcoind_with_NodeJS.md) + * [Seção 4: Acessando o Bitcoind com Python](17_4_Accessing_Bitcoind_with_Python.md) + * [Seção 5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md) + * [Seção 6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md) \ No newline at end of file diff --git a/pt/17_1_Accessing_Bitcoind_with_Go.md b/pt/17_1_Accessing_Bitcoind_with_Go.md new file mode 100644 index 0000000..d42f925 --- /dev/null +++ b/pt/17_1_Accessing_Bitcoind_with_Go.md @@ -0,0 +1,421 @@ +# 17.1: Acessando o Bitcoind com Go + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esta seção explica como interagir com o `bitcoind` usando a linguagem de programação Go e o [btcd rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient). É importante observar que ele tem algumas peculiaridades e limitações. + +## Configurando o Go + +Para nos preparamos para o uso do Go em nossa máquina UNIX, primeiro precisamos instalar o curl, caso ainda não o tenhamos feito: + +``` +$ sudo apt install curl +``` + +Então, vamos ler a [página de downloads do Go](https://golang.org/dl/), para obtermos o link para o download mais recente e posteriormente fazer o download usando `curl`. Para uma configuração Debian, vamos querer usar a versão `linux-amd64`: + +``` +$ curl -O https://dl.google.com/go/go1.15.1.linux-amd64.tar.gz +``` +Assim que terminarmos o download, comparamos o hash com o hash na [página de downloads do Go](https://golang.org/dl/): + +``` +$ sha256sum go1.15.1.linux-amd64.tar.gz +70ac0dbf60a8ee9236f337ed0daa7a4c3b98f6186d4497826f68e97c0c0413f6 go1.15.1.linux-amd64.tar.gz +``` + +Os hashes devem corresponder. Em caso afirmativo, extraímos o tarball e instalamos o Go em nosso sistema: +``` +$ tar xfv go1.15.1.linux-amd64.tar.gz +$ sudo chown -R root:root ./go +$ sudo mv go /usr/local +``` + +Agora precisamos criar um caminho no Go para especificar nosso ambiente. Abra o arquivo `~ / .profile` com o editor de texto mais utilizado por nós e vamos escolher e adicionar o seguinte ao final dele: + +``` +export GOPATH=$HOME/work +export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin +``` + +Em seguida, atualizamos nosso perfil: + +``` +$ source ~/.profile +``` + +Por fim, vamos criar o diretório para o nosso espaço de trabalho Go: + +``` +$ mkdir $HOME/work +``` + +### Configurando o `btcd` e o `rpcclient` + +Usaremos o `rpcclient` que advém do `btcd`, uma implementação Bitcoin escrita em Go. Embora o `rpcclient` tenha sido originalmente projetado para funcionar com o full node `btcd` do Bitcoin, ele também funciona com o Bitcoin Core. Ele tem algumas peculiaridades que veremos mais adiante. + +Podemos usar o ```go get``` para baixá-lo: + +``` +$ go get github.com/btcsuite/btcd/rpcclient +``` + +Para testar seu funcionamento, vmaos navegar até o diretório com os exemplos do Bitcoin Core: + +``` +$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/bitcoincorehttp +``` + +Vamos modificar o arquivo `main.go` e inserir os detalhes associados à configuração do Bitcoin Core, que pode ser encontrado no caminho `~ /.bitcoin/bitcoin.conf`: + +``` + Host: "localhost:18332", + User: "StandUp", + Pass: "6305f1b2dbb3bc5a16cd0f4aac7e1eba", +``` +> **MAINNET VS TESTNET:** A porta seria 8332 para uma configuração na Mainnet. + +Agora podemos executar um teste: +``` +$ go run main.go +``` + +Devemos ver a contagem de blocos impressa: + +``` +2020/09/01 11:41:24 Block count: 1830861 +``` + +### Criando um projeto `rpcclient` + +Normalmente, iríamos criar projetos no diretório `~/work/src/myproject/bitcoin`: +``` +$ mkdir -p ~/work/src/myproject/bitcoin +$ cd ~/work/src/myproject/bitcoin +``` +Cada projeto deve ter os seguintes `imports`: +``` +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" +) +``` +Esta declaração `import` permite que importemos bibliotecas relevantes. Para cada exemplo aqui, precisaremos importar `"log","fmt"` e `"github.com/btcsuite/btcd/rpcclient"`. Podemos precisar importar bibliotecas adicionais em alguns exemplos. + + * O `log` é usado para mostrar mensagens de erro na tela. Após cada vez que o node Bitcoin for chamado, uma instrução `if` irá verificar se há algum erro. Se houver erros, o `log` é usado para imprimi-los; + * O `fmt` é usado para imprimir a saída; + * O `rpcclient` é obviamente a biblioteca do `rpcclient`; + +## Construindo nossa conexão + +Cada função do `bitcoind` no Go começa com a criação da conexão RPC, usando a função `ConnConfig`: +``` + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "StandUp", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() +``` +Os parâmetros da `connCfg` permitem que escolhamos a porta Bitcoin RPC, nome de usuário, senha e se estamos usando a testnet ou mainnet. + +> **NOTA:** Novamente, precisamos nos certificar de substituir o `User` e o `Pass` com aquele encontrado no nosso `~/.bitcoin/bitcon.conf`. + +A função `rpcclient.New(connCfg, nil)` configura o`client` para nos conectarmos ao nosso node de Bitcoin. + +A linha `defer client.Shutdown()` é para desconectar do nosso node Bitcoin, uma vez que a função `main()` termina de ser executada. Após a linha `defer client.Shutdown()` é onde as coisas interessantes acontecem, e será muito fácil de utilizar. Isso porque o `rpcclient` ajuda a transformar os comandos `bitcoin-cli` em funções, usando PascalCase. Por exemplo, `bitcoin-cli getblockcount` se transformará em `client.GetBlockCount` no Go. + +### Fazendo uma chamada RPC + +Agora, tudo o que é necessário é fazer uma chamada informativa como `GetBlockCount` ou` GetBlockHash` usando nosso `client`: +``` + blockCount, err := client.GetBlockCount() + if err != nil { + log.Fatal(err) + } + blockHash, err := client.GetBlockHash(blockCount) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%d\n", blockCount) + fmt.Printf("%s\n", blockHash.String()) +``` + +### Fazendo uma chamada RPC com argumentos + +As funções `rpcclient` também podem receber entradas, por exemplo, `client.GetBlockHash(blockCount)` recebe a contagem de blocos como uma entrada. O `client.GetBlockHash (blockCount)` de cima seria parecido com um comando `bitcoin-cli`: +``` +$ bitcoin-cli getblockhash 1830868 +00000000000002d53b6b9bba4d4e7dc44a79cebd1024d1bcfb9b3cc07d6cad9c +``` +No entanto, uma peculiaridade com hashes no `rpcclient` é que normalmente eles irão ser mostrados em uma codificação diferente se imprimirmos normalmente com o ` blockHash`. Para imprimi-los como uma string, precisamos usar o `blockHash.String()`. + +### Executando nosso código + +Podemos baixar o código completo do [diretório src](src / 17_1_blockinfo.go). + +Podemos então, executar: +``` +$ go run blockinfo.go +1830868 +00000000000002d53b6b9bba4d4e7dc44a79cebd1024d1bcfb9b3cc07d6cad9c +``` + +O último número do bloco junto com nosso hash deve ser impresso. + +## Pesquisando os fundos + +Devido às limitações do `btcd` no `rpcclient`, não pode fazer o uso da função `getwalletinfo`. No entanto, podemos usar o RPC `getbalance`: + +``` + wallet, err := client.GetBalance("*") + if err != nil { + log.Fatal(err) + } + + fmt.Println(wallet) +``` +O `client.GetBalance("*")` requer a entrada `"*"`, devido a uma peculiaridade do `btcd`. O asterisco significa que desejamos obter o saldo de todas as nossas carteiras. + +Se executarmos [o código src](src / 17_1_getbalance.go), deveremos obter uma saída semelhante a esta: +``` +$ go run getbalance.go +0.000689 BTC +``` + +## Criando um endereço + +Podemos gerar endereços em Go, mas não podemos especificar o tipo do endereço: + +Isso requer o uso de uma função especial `chaincfg`, para especificar para qual rede os endereços estão sendo criados. Esta especificação é necessária apenas durante a geração do endereço, por isso é usada apenas neste exemplo. Também podemos incluir isso nos demais exemplos, mas não é necessário. + +Be sure to import ```"github.com/btcsuite/btcd/chaincfg"```: +Vamos nos certificar de importar o `"github.com/btcsuite/btcd/chaincfg"`: +``` +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcd/chaincfg" +) +``` +Em seguida, vamos chamar o `connCfG` com o parâmetro `chaincfg.TestNet3Params.Name`: +``` + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + Params: chaincfg.TestNet3Params.Name, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() +``` +> **MAINNET VS TESTNET:** O `Params: chaincfg.TestNet3Params.Name` deve ser `Params: chaincfg.MainNetParams.Name,` na Mainnet. + +Podemos então criar nosso endereço: +``` + address, err := client.GetNewAddress("") + if err != nil { + log.Fatal(err) + } + fmt.Println(address) +``` +Uma peculiaridade com o `client.GetNewAddress("")` é que uma string vazia precisa ser incluída para que tudo funcione perfeitamente. + +Executando o [the source](17_1_getaddress.go) teremos os seguintes resultados: +``` +$ go run getaddress.go +tb1qutkcj34pw0aq7n9wgp3ktmz780szlycwddfmza +``` + +### Decodificando um endereço + +Criando um endereço exigia um trabalho extra, ao especificar a blockchain correta. Usar um endereço também funcionará, porque teremos que decodificá-lo antes de usá-lo. + +Isso significa que teremos que importar as bibliotecas `"github.com/btcsuite/btcutil"` e `"github.com/btcsuite/btcd/chaincfg"`. + + * O `btcutil` permite que um endereço Bitcoin seja decodificado de uma forma que o `rpcclient` possa entender. Isso é necessário ao trabalhar com endereços no `rpcclient`; + * O `chaincfg` é (novamente) usado para configurar nossa cadeia como a cadeia Testnet. Isso é necessário para a decodificação de endereços, pois os endereços usados na Mainnet e na Testnet são diferentes. + +``` +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcd/chaincfg" +) +``` +A variável defaultNet agora é usada para especificar se nosso node do Bitcoin que está na Testnet ou na Mainnet. Essa informação (e o objeto `btcutil`) é então usado para decodificar o endereço. + +> **MAINNET VS TESTNET:** `&chaincfg.TestNet3Params` deve ser `& chaincfg.MainNetParams` na Mainnet. + +``` + defaultNet := &chaincfg.TestNet3Params + addr, err := btcutil.DecodeAddress("mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha", defaultNet) + if err != nil { + log.Fatal(err) + } +``` + +> **NOTA:** Precisamos alterar o endereço (`mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha`) para um que seja da nossa carteira. Podemos usar o `bitcoin-cli listunspent` para encontrar alguns endereços com fundos para o teste. Se quisermos ser realmente sofisticados, podemos modificar o código Go para obter um argumento e, em seguida, escrever um script que executa o `listunspent`, para depois salvarmos a informação em uma variável e executar o código Go nela. + +Só depois disso usamos o RPC `getreceivedbyaddress`, no nosso endereço decodificado: +``` + wallet, err := client.GetReceivedByAddress(addr) + if err != nil { + log.Fatal(err) + } + + fmt.Println(wallet) +``` +Ao executar [o código](src/17_1_getamountreceived.go), devemos obter uma saída semelhante a esta: +``` +$ go run getamountreceived.go +0.0085 BTC +``` + +## Enviando uma transação + +Agora temos todas as peças do quebra-cabeça no lugar para enviar uma transação. Vamos querer: + +1. Importar as bibliotecas corretas, incluindo a `chaincfg` para especificar uma rede e o `btcutil` para decodificar um endereço; +2. Escolher um endereço para enviar; +3. Decodificar esse endereço; +4. Executar o `sendtoaddress` para enviar fundos da maneira mais fácil. +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcd/chaincfg" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "StandUp", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + defaultNet := &chaincfg.TestNet3Params + addr, err := btcutil.DecodeAddress("n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", defaultNet) + if err != nil { + log.Fatal(err) + } + sent, err := client.SendToAddress(addr, btcutil.Amount(1e4)) + if err != nil { + log.Fatal(err) + } + + fmt.Println(sent) +} +``` +Quando executamos [o código](src/17_1_sendtransaction.go), o txid da transação nos será retornado: + +``` +$ go run sendtransaction.go +9aa4cd6559e0d69059eae142c35bfe78b71a8084e1fcc2c74e2a9675e9e7489d +``` + +### Pesquisando uma transação + +Para consultar uma transação, como a que acabamos de enviar, precisaremos fazer mais uma vez algumas conversões, desta vez do txid. O `"github.com/btcsuite/btcd/chaincfg/chainhash"` é importado para permitir que os hashes sejam armazenados no código Go. O `chainhash.NewHashFromStr("hash")` converte um hash em uma string para um formato que funciona com o rpcclient. + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcd/chaincfg/chainhash" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "StandUp", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + chash, err := chainhash.NewHashFromStr("1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df") + if err != nil { + log.Fatal(err) + } + transactions, err := client.GetTransaction(chash) + if err != nil { + log.Fatal(err) + } + + fmt.Println(transactions) +} +``` +> **NOTA:** Novamente, vamos querer trocar o txid por um que realmente será reconhecido pelo nosso sistema. + +Ao executar [o código](src/17_1_lookuptransaction.go), ele imprimirá os detalhes associados a uma transação, como nosso valor e quantas vezes foi confirmado: + +``` +$ go run lookuptransaction.go +{ + "amount": 0.00100000, + "confirmations": 4817, + "blockhash": "000000006628870b0a8a66abea9cf0d4e815c491f079e3fa9e658a87b5dc863a", + "blockindex": 117, + "blocktime": 1591857418, + "txid": "1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df", + "walletconflicts": [ + ], + "time": 1591857343, + "timereceived": 1591857343, + "bip125-replaceable": "no", + "details": [ + { + "address": "mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha", + "category": "receive", + "amount": 0.00100000, + "label": "", + "vout": 0 + } + ], + "hex": "02000000000101e9e8c3bd057d54e73baadc60c166860163b0e7aa60cab33a03e89fb44321f8d5010000001716001435c2aa3fc09ea53c3e23925c5b2e93b9119b2568feffffff02a0860100000000001976a914600c8c6a4abb0a502ea4de01681fe4fa1ca7800688ac65ec1c000000000017a91425b920efb2fde1a0277d3df11d0fd7249e17cf8587024730440220403a863d312946aae3f3ef0a57206197bc67f71536fb5f4b9ca71a7e226b6dc50220329646cf786cfef79d60de3ef54f702ab1073694022f0618731902d926918c3e012103e6feac9d7a8ad1ac6b36fb4c91c1c9f7fff1e7f63f0340e5253a0e4478b7b13f41fd1a00" +} +``` + +## Resumo: Acessando o Bitcoind com Go + +Embora o `btcd` e o `rpcclient` tenham alguns limites, ainda podemos executar os principais comandos RPC no Go. A documentação para o `rpcclient` está disponível no [Godoc](https://godoc.org/github.com/btcsuite/btcd/rpcclient). Se a documentação não tiver o que procuramos, podemos consultar também o [repositório btcd](https://github.com/btcsuite/btcd). Geralmente é bem documentado e fácil de ler. Com base nesses exemplos, devemos ser capazes de incorporar o Bitcoin em um projeto Go e fazer coisas como enviar e receber moedas. + +## O Que Vem Depois? + +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.2: Acessando Bitcoin com Java](17_2_Accessing_Bitcoind_with_Java.md). \ No newline at end of file diff --git a/pt/17_2_Accessing_Bitcoind_with_Java.md b/pt/17_2_Accessing_Bitcoind_with_Java.md new file mode 100644 index 0000000..87e0c2e --- /dev/null +++ b/pt/17_2_Accessing_Bitcoind_with_Java.md @@ -0,0 +1,332 @@ +# 17.2: Acessando o Bitcoind com Java + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esta seção explica como interagir com `bitcoind` usando a linguagem de programação Java e o [JavaBitcoindRpcClient](https://github.com/Polve/JavaBitcoindRpcClient). + +## Configurando o Java + +Podemos instalar o Java em nosso servidor, usando o comando `apt-get`. Também precisaremos instalar o [Apache Maven](http://maven.apache.org/) para gerenciar as dependências. +``` +$ sudo apt-get install openjdk-11-jre-headless maven +``` + +Podemos verificar a instalação do Java usando o comando abaixo: +``` +$ java -version +openjdk version "11.0.8" 2020-07-14 +OpenJDK Runtime Environment (build 11.0.8+10-post-Debian-1deb10u1) +OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Debian-1deb10u1, mixed mode, sharing) +``` + +### Criando um projeto Maven + +Para programar o Bitcoin usando o java, criaremos um projeto Maven: +``` +$ mvn archetype:generate -DgroupId=com.blockchaincommons.lbtc -DartifactId=java-project -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false +``` +Isso irá baixar algumas dependências: +``` +Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom +Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom (4 KB at 4.2 KB/sec) +Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/22/maven-plugins-22.pom +Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/22/maven-plugins-22.pom (13 KB at 385.9 KB/sec) +Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/21/maven-parent-21.pom +Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/21/maven-parent-21.pom (26 KB at 559.6 KB/sec) +Downloading: https://repo.maven.apache.org/maven2/org/apache/apache/10/apache-10.pom +.............. +``` +Ele também criará um arquivo de configuração `pom.xml`: + +``` +$ cd java-project +$ ls -lagh +total 16K +drwxr-xr-x 3 sudo 4.0K Sep 1 13:58 . +drwxr-xr-x 15 sudo 4.0K Sep 1 13:58 .. +-rw-r--r-- 1 sudo 663 Sep 1 13:58 pom.xml +drwxr-xr-x 4 sudo 4.0K Sep 1 13:58 src +``` + +Para incluir o `JavaBitcoindRpcClient`, devemos adicionar nossa dependência a `` no arquivo `pom.xml`. + +```xml + + wf.bitcoin + bitcoin-rpc-client + 1.2.1 + +``` +Também precisa adicionar propriedades do compilador para indicar qual versão do JDK compilará o código-fonte. + +``` + + + UTF-8 + 11 + 11 + +``` + +Sempre que adicionarmos um código-fonte às nossas aulas, poderemos testá-lo com: +``` +$ mvn compile +``` +Também podemos executá-lo com `exec: java` +``` +$ mvn exec:java -Dexec.mainClass=com.blockchaincommons.lbtc.App +``` + +### Criando Projetos Alternativos + +Se usamos o [Gradle](https://gradle.org/releases/), podemos executar o seguinte comando: +```groovy +compile 'wf.bitcoin:JavaBitcoindRpcClient:1.2.1' +``` + +Se quisermos um projeto de amostra e algumas instruções sobre como executá-lo no servidor que acabamos de criar, podemos consultar o [Projeto de amostra do Bitcoind Java](https://github.com/brunocvcunha/bitcoind-java-client- amostra/). Também pode navegar por todo o código de origem do [bitcoin-rpc-client](https://github.com/Polve/bitcoin-rpc-client). + +## Construindo nossa conexão + +Para usar o `JavaBitcoindRpcClient`, precisamos criar uma instância `BitcoindRpcClient`. Fazemos isso criando um URL com argumentos de nome de usuário, senha, endereço IP e porta. Como devemos nos lembrar, o endereço IP é `127.0.0.1` e a porta `18332` devem estar corretos para a configuração testnet padrão descrita neste curso, enquanto podemos extrair o usuário e a senha abrindo o arquivo `~/.bitcoin/bitcoin.conf`. + +```java + BitcoindRpcClient rpcClient = new BitcoinJSONRPCClient("http://StandUp:6305f1b2dbb3bc5a16cd0f4aac7e1eba@localhost:18332"); +``` +Podemos observar que também precisaremos importar as informações apropriadas: +``` +import wf.bitcoin.javabitcoindrpcclient.BitcoinJSONRPCClient; +import wf.bitcoin.javabitcoindrpcclient.BitcoindRpcClient; +``` + +> **MAINNET VS TESTNET:** A porta seria 8332 para uma configuração da mainnet. + +Se o `rpcClient` for inicializado com sucesso, podemos enviar comandos RPC. + +Mais tarde, quando terminarmos nossa conexão `bitcoind`, precisamos fechá-la: +``` +rpcClient.stop(); +``` + +### Fazendo uma chamada RPC + +Você verá que o `BitcoindRpcClient` fornece a maioria das funcionalidades que podem ser acessadas através do `bitcoin-cli` ou outros métodos RPC, usando o mesmo método que o nome, mas em camelCase. + +Por exemplo, para executar o comando `getmininginfo` para obter as informações do bloco e a dificuldade na rede, devemos usar o método `getMiningInfo()`: +```java +MiningInfo info = rpcClient.getMiningInfo(); +System.out.println("Mining Information"); +System.out.println("------------------"); +System.out.println("Chain......: " + info.chain()); +System.out.println("Blocks.....: " + info.blocks()); +System.out.println("Difficulty.: " + info.difficulty()); +System.out.println("Hash Power.: " + info.networkHashps()); +``` +O retorno para esta linha deve algo próximo a isso: +``` +Mining Information +------------------ +Chain......: test +Blocks.....: 1830905 +Difficulty.: 4194304 +Hash Power.: 40367401348837.41 +``` +### Fazendo uma chamada RPC usando argumentos + +Podemos procurar os endereços em nossa carteira passando o endereço como um argumento para o comando `getAddressInfo`: + +```java + String addr1 = "mvLyH7Rs45c16FG2dfV7uuTKV6pL92kWxo"; + + AddressInfo addr1Info = rpcClient.getAddressInfo(addr1); + System.out.println("Address: " + addr1Info.address()); + System.out.println("MasterFingerPrint: " + addr1Info.hdMasterFingerprint()); + System.out.println("HdKeyPath: " + addr1Info.hdKeyPath()); + System.out.println("PubKey: " + addr1Info.pubKey()); +``` +O resultado será mais ou menos assim: +``` +Address: mvLyH7Rs45c16FG2dfV7uuTKV6pL92kWxo +MasterFingerPrint: ce0c7e14 +HdKeyPath: m/0'/0'/5' +PubKey: 0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65 +``` + +### Executando nosso código + +O código para esses exemplos pode ser encontrado no [diretório src/](src/17_2_App-getinfo.java) e deve ser instalado na estrutura de diretório padrão criada neste caso como `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. Ele pode então ser compilado e executado. + +``` +$ mvn compile +$ mvn exec:java -Dexec.mainClass=com.blockchaincommons.lbtc.App +Chain......: test +Blocks.....: 1831079 +Difficulty.: 4194304 +Hash Power.: 38112849943221.16 +Address: mvLyH7Rs45c16FG2dfV7uuTKV6pL92kWxo +MasterFingerPrint: ce0c7e14 +HdKeyPath: m/0'/0'/5' +PubKey: 0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65 +``` +Você também verá muito mais informações sobre a compilação, é claro. + +## Pesquisando os fundos + +Recuperando o saldo de uma conta inteira é tão fácil quanto: +``` + System.out.println("Balance: " + rpcClient.getBalance()); +``` + +## Criando um endereço + +Podemos criar um novo endereço em nossa carteira, anexando um rótulo específico a ela e até mesmo descartando nossa chave privada. + +```java + String address = rpcClient.getNewAddress("Learning-Bitcoin-from-the-Command-Line"); + System.out.println("New Address: " + address); + + String privKey = rpcClient.dumpPrivKey(address); + System.out.println("Priv Key: " + privKey); +``` +Retorno: +``` +New Address: mpsFtZ8qTJPRGZy1gaaUw37fHeUSPLkzzs +Priv Key: cTy2AnmAALsHokYzJzTdsUBSqBtypmWfmSNYgG6qQH43euUZgqic +``` + +## Enviando uma transação + +A biblioteca `JavaBitcoindRpcClient` possui algumas ferramentas interessantes que facilitam a criação de uma transação desde o início. + +### Criando uma transação + +Podemos criar uma transação bruta usando o método `createRawTransaction`, passando como argumentos dois objetos ArrayList contendo entradas e saídas a serem utilizadas. + +Primeiro configuramos nossos novos endereços, aqui um endereço existente em nosso sistema e um novo endereço. +``` + String addr1 = "tb1qdqkc3430rexxlgnma6p7clly33s6jjgay5q8np"; + System.out.println("Used address addr1: " + addr1); + + String addr2 = rpcClient.getNewAddress(); + System.out.println("Created address addr2: " + addr2); +``` +Então, podemos usar o RPC `listUnspent` para encontrar UTXOs para o endereço existente. +``` + List utxos = rpcClient.listUnspent(0, Integer.MAX_VALUE, addr1); + System.out.println("Found " + utxos.size() + " UTXOs (unspent transaction outputs) belonging to addr1"); +``` +Aqui está um resultado de todas as informações: +```java +System.out.println("Created address addr1: " + addr1); +String addr2 = rpcClient.getNewAddress(); +System.out.println("Created address addr2: " + addr2); +List generatedBlocksHashes = rpcClient.generateToAddress(110, addr1); +System.out.println("Generated " + generatedBlocksHashes.size() + " blocks for addr1"); +List utxos = rpcClient.listUnspent(0, Integer.MAX_VALUE, addr1); +System.out.println("Found " + utxos.size() + " UTXOs (unspent transaction outputs) belonging to addr1"); +``` +As transações são criadas com o comando `BitcoinRawTxBuilder`: +``` + BitcoinRawTxBuilder txb = new BitcoinRawTxBuilder(rpcClient); +``` +Primeiro preenchemos as entradas com os UTXOs que estamos gastando: +``` + TxInput in = utxos.get(0); + txb.in(in); +``` + +> :warning: **AVISO:** Obviamente, em um programa real, selecionaríamos um UTXO de forma inteligente, porém, neste caso, pegamos apenas o enésimo, uma tática que usaremos ao longo deste capítulo. + +Em segundo lugar, preenchemos as saídas, cada uma com um valor e um endereço: +``` + BigDecimal estimatedFee = BigDecimal.valueOf(0.00000200); + BigDecimal txToAddr2Amount = utxos.get(0).amount().subtract(estimatedFee); + txb.out(addr2, txToAddr2Amount); + + System.out.println("unsignedRawTx in amount: " + utxos.get(0).amount()); + System.out.println("unsignedRawTx out amount: " + txToAddr2Amount); +``` + +Agora estamos prontos para realmente criar a transação: +``` + String unsignedRawTxHex = txb.create(); + System.out.println("Created unsignedRawTx from addr1 to addr2: " + unsignedRawTxHex); +``` + +### Assinando uma transação + +Agora podemos assinar a transação com o método `signRawTransactionWithKey`. Este método recebe como parâmetros uma transação de string bruta não assinada, a chave privada do endereço de envio e o objeto TxInput. + +```java + SignedRawTransaction srTx = rpcClient.signRawTransactionWithKey( + unsignedRawTxHex, + Arrays.asList(rpcClient.dumpPrivKey(addr1)), // + Arrays.asList(in), + null); + System.out.println("signedRawTx hex: " + srTx.hex()); + System.out.println("signedRawTx complete: " + srTx.complete()); +``` + +### Enviando uma transação + +Finalmente, o envio requer o comando `sendRawTransaction`: +```java +String sentRawTransactionID = rpcClient.sendRawTransaction(srTx.hex()); +System.out.println("Sent signedRawTx (txID): " + sentRawTransactionID); +``` + +### Executando nosso código + +Agora podemos executar [o código da transação](src/17_2_App-sendtx.java) como `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. + +``` +$ mvn compile +$ mvn exec:java -Dexec.mainClass=com.blockchaincommons.lbtc.App +Used address addr1: tb1qdqkc3430rexxlgnma6p7clly33s6jjgay5q8np +Created address addr2: tb1q04q2wzlhfqlrnz95ynfj7gp4t3yynrj0542smv +Found 1 UTXOs (unspent transaction outputs) belonging to addr1 +unsignedRawTx in amount: 0.00850000 +unsignedRawTx out amount: 0.00849800 +Created unsignedRawTx from addr1 to addr2: 0200000001d2a90fc3b43e8eb4ae9452af43c9448112d359cac701f7f537aa8b6f39193bb90100000000ffffffff0188f70c00000000001600147d40a70bf7483e3988b424d32f20355c48498e4f00000000 +signedRawTx hex: 02000000000101d2a90fc3b43e8eb4ae9452af43c9448112d359cac701f7f537aa8b6f39193bb90100000000ffffffff0188f70c00000000001600147d40a70bf7483e3988b424d32f20355c48498e4f024730440220495fb64d8cf9dee9daa8535b8867709ac8d3763d693fd8c9111ce610645c76c90220286f39a626a940c3d9f8614524d67dd6594d9ee93818927df4698c1c8b8f622d01210333877967ac52c0d0ec96aca446ceb3f51863de906e702584cc4da2780d360aae00000000 +signedRawTx complete: true +Sent signedRawTx (txID): 82032c07e0ed91780c3369a1943ea8abf49c9e11855ffedd935374ecbc789c45 +``` + +## Ouvindo as transações ou blocos + +Tal como acontece com [C e nas nossas bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md), existem maneiras fáceis de usar o Java para ouvir a blockchain, além de executar o código específico quando algo acontece, como uma transação que envolve um endereço em nossa carteira, ou até a geração de um novo bloco na rede. + +Para fazer isso, podemos usar a classe `BitcoinAcceptor` do `JavaBitcoindRpcClient`, que permite anexar _listerners_ na rede. + +```java + String blockHash = rpcClient.getBestBlockHash(); + BitcoinAcceptor acceptor = new BitcoinAcceptor(rpcClient, blockHash, 6, new BitcoinPaymentListener() { + + @Override + public void transaction(Transaction tx) { + System.out.println("Transaction: " + tx); + } + + @Override + public void block(String block) { + System.out.println("Block: " + block); + } + }); + acceptor.run(); +``` + +Veja [o diretório src/](src / 17_2_App-listen.java) para o código completo. Cada vez que uma transação é enviada ou um novo bloco é gerado, devemos ver a saída em nosso console: +``` +Transaction: {account=Tests, address=mhopuJzgmTwhGfpNLCJ9CRknugY691oXp1, category=receive, amount=5.0E-4, label=Tests, vout=1, confirmations=0, trusted=false, txid=361e8fcff243b74ebf396e595a007636654f67c3c7b55fd2860a3d37772155eb, walletconflicts=[], time=1513132887, timereceived=1513132887, bip125-replaceable=unknown} + +Block: 000000004564adfee3738314549f7ca35d96c4da0afc6b232183917086b6d971 +``` + +### Resumo: Acessando o Bitcoind com Java + +Usando a biblioteca `javabitcoinrpc`, podemos acessar facilmente o `bitcoind` por meio de chamadas RPC no Java. Também teremos acesso a recursos adicionais interessantes, como o serviço de escuta usando o comando `bitcoinAcceptor`. + +## O Que Vem Depois? + +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.3: Acessando o Bitcoind com NodeJS](17_2_Accessing_Bitcoind_with_Java.md). \ No newline at end of file diff --git a/pt/17_3_Accessing_Bitcoind_with_NodeJS.md b/pt/17_3_Accessing_Bitcoind_with_NodeJS.md new file mode 100644 index 0000000..4ebf78a --- /dev/null +++ b/pt/17_3_Accessing_Bitcoind_with_NodeJS.md @@ -0,0 +1,274 @@ +# 17.3: Acessando o Bitcoind com NodeJS + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esta seção explica como interagir com o `bitcoind` usando a linguagem de programação NodeJS e o [pacote BCRPC](https://github.com/dgarage/bcrpc). + +## Set Up Node.js +## Configurando o Node.js + +O BCRPC é construído em node.js. Portanto, primeiro precisamos instalar os pacotes `node.js` e o `npm` (o gerenciador de pacotes do node) em nosso sistema. + +Se estiver usando uma máquina Ubuntu, podemos executar os seguintes comandos para obter uma nova versão do `node.js`, ao invés da versão terrivelmente desatualizada no sistema de pacotes do Ubuntu. + +``` +$ curl -sL https://deb.nodesource.com/setup_14.x | sudo bash - +$ sudo apt-get install -y nodejs +$ sudo npm install mocha -g +``` + +### Configurando o BCRPC + +Agora podemos clonar o pacote BCRPC do GitHub e instalar as dependências. + +``` +$ git clone https://github.com/dgarage/bcrpc.git +$ cd bcrpc +$ npm install +``` + +Para testar o pacote BCRPC, devemos primeiro definir as variáveis ​​ambientais para o rpcuser e rpcpassword. Como de costume, eles vêm do `~/.bitcoin/bitcoin.conf`. Também devemos definir a porta RPC como sendo 18332, que deve ser a correta para a configuração Testnet padrão descrita nos documentos. + +``` +$ export BITCOIND_USER=StandUp +$ export BITCOIND_PASS=d8340efbcd34e312044c8431c59c792c +$ export BITCOIND_PORT=18332 +``` + +> :warning: **AVISO:** Obviamente, nunca colocaria nossa senha definida em uma variável de ambiente em um ambiente de produção. + +> :link: **MAINNET VS TESTNET:** A porta seria 8332 para uma configuração na Mainnet. + +Agora podemos verificar se tudo está funcionando corretamente: + +``` +$ npm test + +> bcrpc@0.2.2 test /home/user1/bcrpc +> mocha tests.js + + BitcoinD + ✓ is running + + bcrpc + ✓ can get info + + 2 passing (36ms) +``` +Parabéns, agora temos um wrapper RPC pronto para usar o Bitcoin com o Node.js que está funcionando com nossa configuração do Bitcoin. + +### Criando um Projeto BCRPC + +Agora podemos criar um novo projeto Node.js e instalar o BCRPC via npm. + +``` +$ cd ~ +$ mkdir myproject +$ cd myproject +$ npm init + [continue with default options] +$ npm install bcrpc +``` +## Construindo nossa conexão + +Em nosso diretório `myproject`, criamos um arquivo `.js` onde nosso código JavaScript será executado. + +Podemos iniciar uma conexão RPC criando um `RpcAgent`: +``` +const RpcAgent = require('bcrpc'); +agent = new RpcAgent({port: 18332, user: 'StandUp', pass: 'd8340efbcd34e312044c8431c59c792c'}); +``` +Obviamente, nosso `user` e `pass` devem coincidir novamente com o que está em nosso `~/.bitcoin/bitcoin.conf`, e usamos a `porta 18332` se estivermos na Testnet. + +### Fazendo uma chamada RPC + +Usando o BCRPC, podemos usar os mesmos comandos RPC que normalmente usaríamos via `bitcoin-cli` com nosso `RpcAgent`, exceto que eles precisam estar em camelCase. Por exemplo, `getblockhash` seria `getBlockHash`. + +Para imprimir o número do bloco mais recente, basta chamar o `getBlockCount` através do nosso `RpcAgent`: + +``` +agent.getBlockCount(function (err, blockCount) { + if (err) + throw Error(JSON.stringify(err)); + console.log(blockCount.result); +}); +``` + +### Fazendo uma chamada RPC com argumentos + +As funções BCRPC podem aceitar argumentos. Por exemplo, o `getBlockHash` recebe o `blockCount.result` como uma entrada. + +``` + agent.getBlockHash(blockCount.result, function (err, hash) { + if (err) + throw Error(JSON.stringify(err)); + console.log(hash.result); + }) +``` + +O resultado das funções BCRPC é um objeto JSON contendo informações sobre quaisquer erros e o id da solicitação. Ao acessar nosso resultado, adicionamos o `.result` no final dele para especificar que estamos interessados no resultado real, não em informações sobre os erros. + +### Executando nosso código + +Podemos encontrar o código `getinfo` no [diretório src/](src / 17_3_getinfo.js). +``` +$ node getinfo.js +1831094 +00000000000002bf8b522a830180ad3a93b8eed33121f54b3842d8838580a53c +``` +Isto é o que a saída do exemplo acima pareceria se substituíssemos o `console.log(blockCount.result);` e o `console.log(hash.result);` por `console.log(blockCount);` e `console.log (hash);`, respectivamente: + +``` +{ result: 1774686, error: null, id: null } +{ + result: '00000000000000d980c495a2b7addf09bb0a9c78b5b199c8e965ee54753fa5da', + error: null, + id: null +} +``` + +## Pesquisando os fundos + +É útil ao aceitar Bitcoin verificar os Bitcoin recebidos em um endereço específico em nossa carteira. Por exemplo, se administrássemos uma loja online que aceita Bitcoin, para cada pagamento de um cliente, geraríamos um novo endereço, mostraríamos esse endereço ao cliente e, em seguida, verificaríamos o saldo do endereço após algum tempo, para certificar-se de que o montante foi recebido: + +``` +agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', function (err, addressInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(addressInfo.result); +}); +``` + +> :information_source: **NOTA:** Obviamente, precisaremos inserir um endereço reconhecido por nossa máquina. + +Por padrão, esta função verifica as transações que foram confirmadas uma vez, no entanto, podemos aumentar para um número maior, como 6: + +``` +agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', 6, function (err, addressInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(addressInfo.result); +}); +``` + +### Pesquisando informações da carteira + +Também podemos procurar informações adicionais sobre nossa carteira e visualizar nosso saldo, contagem de transações etc. + +``` +agent.getWalletInfo(function (err, walletInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(walletInfo.result); +}); +``` + +O código está disponível como [walletinfo.js](src/17_3_walletinfo.js). +``` +$ node walletinfo.js +0.008498 +{ + walletname: '', + walletversion: 169900, + balance: 0.010438, + unconfirmed_balance: 0, + immature_balance: 0, + txcount: 4, + keypoololdest: 1596567843, + keypoolsize: 999, + hdseedid: 'da5a1b058deb9e51ecffef1b0ddc069a5dfb2c5f', + keypoolsize_hd_internal: 1000, + paytxfee: 0, + private_keys_enabled: true, + avoid_reuse: false, + scanning: false +} +``` +Ao invés de imprimir todos os detalhes associados à nossa carteira, podemos imprimir informações específicas, como nosso saldo. Como um objeto JSON está sendo acessado, podemos fazer isso alterando a linha `console.log(walletInfo.result);` para `console.log(walletInfo.result.balance);`: + +## Criando um endereço + +Também podemos passar argumentos adicionais para os comandos RPC. Por exemplo, o seguinte gera um novo endereço legado, com o sinalizador `-addresstype`. + +``` +agent.getNewAddress('-addresstype', 'legacy', function (err, newAddress) { + if (err) + throw Error(JSON.stringify(err)); + console.log(newAddress.result); +}); +``` +Isso é o mesmo que executar o seguinte na linha de comando: +``` +$ bitcoin-cli getnewaddress -addresstype legacy +mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ +``` + +No BCRPC, geralmente podemos usar os mesmos sinalizadores que no `bitcoin-cli` no BCRPC. Embora usamos o camelCase (`getNewAddress`) para os métodos, os sinalizadores, que normalmente são separados por espaços na linha de comando, são colocados em strings e separados por vírgulas. + +## Enviando uma transação + +Podemos enviar saldos para um endereço muito facilmente, usando a função `sendToAddress`: + +``` +agent.sendToAddress(newAddress.result, 0.00001, function(err, txid) { + if (err) + throw Error(JSON.stringify(err)); + console.log(txid.result); +}); +``` + +Isso deve retornar o txid da transação: + +``` +1679bee019c61608340b79810377be2798efd4d2ec3ace0f00a1967af70666b9 +``` + +### Pesquisando uma transação + +Agora podemos desejar visualizar uma transação, como a que acabamos de enviar. +``` +agent.getTransaction(txid.result, function (err, transaction) { + if (err) + throw Error(JSON.stringify(err)); + console.log(transaction.result); +}); +``` + +Devemos obter uma saída semelhante a esta: + +``` +{ + amount: 0.001, + confirmations: 4776, + blockhash: '000000006628870b0a8a66abea9cf0d4e815c491f079e3fa9e658a87b5dc863a', + blockindex: 117, + blocktime: 1591857418, + txid: '1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df', + walletconflicts: [], + time: 1591857343, + timereceived: 1591857343, + 'bip125-replaceable': 'no', + details: [ + { + address: 'mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', + category: 'receive', + amount: 0.001, + label: '', + vout: 0 + } + ], + hex: '02000000000101e9e8c3bd057d54e73baadc60c166860163b0e7aa60cab33a03e89fb44321f8d5010000001716001435c2aa3fc09ea53c3e23925c5b2e93b9119b2568feffffff02a0860100000000001976a914600c8c6a4abb0a502ea4de01681fe4fa1ca7800688ac65ec1c000000000017a91425b920efb2fde1a0277d3df11d0fd7249e17cf8587024730440220403a863d312946aae3f3ef0a57206197bc67f71536fb5f4b9ca71a7e226b6dc50220329646cf786cfef79d60de3ef54f702ab1073694022f0618731902d926918c3e012103e6feac9d7a8ad1ac6b36fb4c91c1c9f7fff1e7f63f0340e5253a0e4478b7b13f41fd1a00' +} +``` + +O código completo está disponível no [sendtx.js](src/17_3_sendtx.js). + +## Resumo: Acessando o Bitcoind com NodeJS + +Com o BCRPC podemos acessar todos os comandos RPC disponíveis através do `bitcoin-cli`, usando o JavaScript. O [BCRPC README](https://github.com/dgarage/bcrpc) tem alguns exemplos que usam promises (os exemplos neste livro usam callbacks). O [JavaScript por trás dele](https://github.com/dgarage/bcrpc/blob/master/index.js) é curto e bem legível. + +Com base nesses exemplos, devemos ser capazes de incorporar Bitcoin em um projeto Node.js e fazer coisas como enviar e receber fundos. + +## O Que Vem Depois? + +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.4: Acessando o Bitcoind com Python](17_2_Accessing_Bitcoind_with_Java.md). \ No newline at end of file diff --git a/pt/17_4_Accessing_Bitcoind_with_Python.md b/pt/17_4_Accessing_Bitcoind_with_Python.md new file mode 100644 index 0000000..22066f1 --- /dev/null +++ b/pt/17_4_Accessing_Bitcoind_with_Python.md @@ -0,0 +1,495 @@ +# 17.4: Acessando o Bitcoind com Python + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esta seção explica como interagir com o `bitcoind` usando a linguagem de programação Python e o [Python-BitcoinRPC](https://github.com/jgarzik/python-bitcoinrpc). + +## Configurando o Python + +Se já temos o Bitcoin Core instalado, provavelmente temos o Python 3 disponível. +Podemos verificar isso executando: + +```$ python3 --version``` + +Se ele retornar um número de versão (por exemplo, `3.7.3` ou `3.8.3`), então temos o python3 instalado. + +No entanto, se não tivermos o Python instalado, precisaremos compilá-lo a partir do código-fonte. Podemos consultar como fazer isso, como mostrado no ["Construindo Python a partir da fonte"](17_4_Accessing_Bitcoind_with_Python.md # variant-build-python-from-source) antes de continuarmos. + +### Configurando o BitcoinRPC + +Quer tenhamos usado um Python existente ou compilado a partir da fonte, agora estamos prontos para instalar a biblioteca `python-bitcoinrpc`: + +``` +$ pip3 install python-bitcoinrpc +``` +Se você não instalamos o `pip`, precisaremos executar o seguinte: +``` +$ sudo apt install python3-pip +``` +Em seguida, vamos repetir o comando `pip3 install python-bitcoinrpc`. + +### Criar um projeto BitcoinRPC + +Geralmente, precisaremos incluir declarações apropriadas do `bitcoinrpc` em nosso projetos Bitcoin usando o Python. O seguinte fornecerá acesso aos comandos baseados em RPC: +```py +from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException +``` +Também podemos achar o seguinte comando útil: +```py +from pprint import pprint +import logging +``` +O `pprint` irá imprimir a resposta `json` do `bitcoind`. + +O `logging` irá imprimir a chamada que fizemos para o respose do `bitcoind` e o próprio `bitcoind`, o que é útil quando fazemos um monte de chamadas juntas. Se não quisermos um retorno muito grande no terminal, podemos comentar o bloco `logging`. + +## Construindo a nossa conexão + +Agora estamos prontos para começar a interagir com o `bitcoind` estabelecendo uma conexão. Vamos criar um arquivo chamado `btcrpc.py` e digitar o seguinte: + +```py +logging.basicConfig() +logging.getLogger("BitcoinRPC").setLevel(logging.DEBUG) +# rpc_user and rpc_password are set in the bitcoin.conf file +rpc_user = "StandUp" +rpc_pass = "6305f1b2dbb3bc5a16cd0f4aac7e1eba" +rpc_host = "127.0.0.1" +rpc_client = AuthServiceProxy(f"http://{rpc_user}:{rpc_pass}@{rpc_host}:18332", timeout=120) +``` + +Os argumentos na URL são `:@:`. Como de costume, o `user` e o `pass` são encontrados no arquivo `~/.bitcoin/bitcoin.conf`, enquanto o `host` é o nosso localhost, e a porta é `18332` para Testnet. O argumento `timeout` é especificado desde o tempo limite dos sockets sob grande demanda na rede principal. Se obtivermos a resposta `socket.timeout: timed out`, precisamos ser pacientes e aumentar o` timeout`. + +> :link: ** MAINNET VS TESTNET: ** A porta seria 8332 para uma configuração na Mainnet. + +### Fazendo uma chamada RPC + +Se o `rpc_client` for inicializado com sucesso, seremos capazes de enviar comandos RPC para o nosso node do Bitcoin. + +Para usar um método RPC do `python-bitcoinrpc`, usaremos o objeto `rpc_client` que criamos, que fornece a maior parte da funcionalidade que pode ser acessada através do `bitcoin-cli`, usando os mesmos nomes do método. + +Por exemplo, o comando a seguir irá recuperar a contagem de blocos do nosso node: + +```py +block_count = rpc_client.getblockcount() +print("---------------------------------------------------------------") +print("Block Count:", block_count) +print("---------------------------------------------------------------\n") +``` + +Devemos obter a seguinte resposta com o `logging` habilitado: + + +```sh +DEBUG:BitcoinRPC:-3-> getblockcount [] +DEBUG:BitcoinRPC:<-3- 1773020 +--------------------------------------------------------------- +Block Count: 1773020 +--------------------------------------------------------------- +``` + +### Fazendo uma chamada RPC enviando argumentos + +Podemos usar esse blockcount como um argumento para recuperar o blockhash de um bloco e também para recuperar os detalhes do bloco. + +Isso é feito enviando nossos comandos do objeto `rpc_client` com um argumento: +```py +blockhash = rpc_client.getblockhash(block_count) +block = rpc_client.getblock(blockhash) +``` + +O `getblockhash` retornará um único valor, enquanto o `getblock` retornará um array associativo de informações sobre o bloco, que inclui um array em `block['tx']` fornecendo detalhes sobre cada transação dentro do bloco: + +```py +nTx = block['nTx'] +if nTx > 10: + it_txs = 10 + list_tx_heading = "First 10 transactions: " +else: + it_txs = nTx + list_tx_heading = f"All the {it_txs} transactions: " +print("---------------------------------------------------------------") +print("BLOCK: ", block_count) +print("-------------") +print("Block Hash...: ", blockhash) +print("Merkle Root..: ", block['merkleroot']) +print("Block Size...: ", block['size']) +print("Block Weight.: ", block['weight']) +print("Nonce........: ", block['nonce']) +print("Difficulty...: ", block['difficulty']) +print("Number of Tx.: ", nTx) +print(list_tx_heading) +print("---------------------") +i = 0 +while i < it_txs: + print(i, ":", block['tx'][i]) + i += 1 +print("---------------------------------------------------------------\n") +``` + +### Executando nosso código + +Podemos usar [o código que está no src/](src/17_4_getinfo.py) e executá-lo com `python3`: + +``` +$ python3 getinfo.py +--------------------------------------------------------------- +Block Count: 1831106 +--------------------------------------------------------------- +--------------------------------------------------------------- +BLOCK: 1831106 +------------- +Block Hash...: 00000000000003b2ea7c2cdfffd86156ad1f5606ab58e128940a2534d1348b04 +Merkle Root..: 056a547fe59208167eef86fa694263728fb684119254b340c1f86bdd423a8082 +Block Size...: 52079 +Block Weight.: 128594 +Nonce........: 1775583700 +Difficulty...: 4194304 +Number of Tx.: 155 +First 10 transactions: +--------------------- +0 : d228d55112e3aa26265b0118cfdc98345c229d20fe074b9afb87107c03ce11b5 +1 : 92822e8e34fafb472b87c99ea3f3e16440452b3f361ed86c6fa62175173fb750 +2 : fa7c67600c14d4aa350a9674688f1429577954f4a6c5e4639d06c8964824f647 +3 : 3a91d1527e308e5603dafde7ab17824f441a73a779d2571d073466dc9e8451b2 +4 : 30fd0e5527b1522e7b26a4818b9edac80fe47c0c39fc34705478a49e684708d0 +5 : 24c5372b38c78cbaf5b0b305925502a491bc0c1b5758f50c0bd335abb6ae85f5 +6 : be70e125a5793efc5e32051fecba0668df971bdf371138c8261201c2a46b2d38 +7 : 41ebf52c847a59ba0aeb4425c74e89a01e91defa86a82785ff53ed4668054561 +8 : dc8211b4ce122f87692e7c203672e3eb1ffc44c0a307eafcc560323fcc5fae78 +9 : 59e2d8e11cad287eacf3207e64a373f65059286b803ef0981510193ae29cbc8c +--------------------------------------------------------------- +``` + +## Pesquisando fundos + +Da mesma forma, podemos recuperar as informações da nossa carteira com o RPC `getwalletinfo`: + +```py +wallet_info = rpc_client.getwalletinfo() +print("---------------------------------------------------------------") +print("Wallet Info:") +print("-----------") +pprint(wallet_info) +print("---------------------------------------------------------------\n") +``` + +Devemos obter um retorno semelhante ao que tivemos abaixo com o `logging` desabilitado: + +```sh +--------------------------------------------------------------- +Wallet Info: +----------- +{'avoid_reuse': False, + 'balance': Decimal('0.07160443'), + 'hdseedid': '6dko666b1cc0d69b7eb0539l89eba7b6390kdj02', + 'immature_balance': Decimal('0E-8'), + 'keypoololdest': 1542245729, + 'keypoolsize': 999, + 'keypoolsize_hd_internal': 1000, + 'paytxfee': Decimal('0E-8'), + 'private_keys_enabled': True, + 'scanning': False, + 'txcount': 9, + 'unconfirmed_balance': Decimal('0E-8'), + 'walletname': '', + 'walletversion': 169900} +--------------------------------------------------------------- +``` +Outros comandos informativos como `getblockchaininfo`, `getnetworkinfo`, `getpeerinfo` e `getblockchaininfo` funcionarão de forma semelhante. + +Outros comandos podem fornecer informações específicas sobre elementos selecionados na sua carteira. + +### Recuperando um Array + +O RPC `listtransactions` permite que observemos as 10 transações mais recentes do nosso sistema (ou algum conjunto arbitrário de transações usando os argumentos `count` e `skip`). Ele mostra como um comando RPC pode retornar uma matriz simples de ser manipulada: + +```py +tx_list = rpc_client.listtransactions() +pprint(tx_list) +``` + +### Explorando um UTXO + +Da mesma forma, podemos usar o `listunspent` para obter uma matriz de UTXOs: + +```py +print("Exploring UTXOs") +## List UTXOs +utxos = rpc_client.listunspent() +print("Utxos: ") +print("-----") +pprint(utxos) +print("------------------------------------------\n") +``` + +Para manipular uma matriz como a retornada de `listtransactions` ou` listunpsent`, você apenas pega o item apropriado do elemento apropriado da matriz: +``` +## Select a UTXO - first one selected here +utxo_txid = utxos[0]['txid'] +``` + +Para o `listunspent`, obtemos um `txid`. Podemos recuperar as informações sobre ele com o comando `gettransaction` e, em seguida, decodificá-lo com um `decoderawtransaction`: + + +``` +utxo_hex = rpc_client.gettransaction(utxo_txid)['hex'] + +utxo_tx_details = rpc_client.decoderawtransaction(utxo_hex) + +print("Details of Utxo with txid:", utxo_txid) +print("---------------------------------------------------------------") +print("UTXO Details:") +print("------------") +pprint(utxo_tx_details) +print("---------------------------------------------------------------\n") +``` + +Este código está disponível no arquivo [walletinfo.py](src/17_4_walletinfo.py). +``` +$ python3 walletinfo.py +--------------------------------------------------------------- +Wallet Info: +----------- +{'avoid_reuse': False, + 'balance': Decimal('0.01031734'), + 'hdseedid': 'da5a1b058deb9e51ecffef1b0ddc069a5dfb2c5f', + 'immature_balance': Decimal('0E-8'), + 'keypoololdest': 1596567843, + 'keypoolsize': 1000, + 'keypoolsize_hd_internal': 999, + 'paytxfee': Decimal('0E-8'), + 'private_keys_enabled': True, + 'scanning': False, + 'txcount': 6, + 'unconfirmed_balance': Decimal('0E-8'), + 'walletname': '', + 'walletversion': 169900} +--------------------------------------------------------------- + +Utxos: +----- +[{'address': 'mv9cjEnS2o1EygBMdrz99LzhM8KeEMoXDg', + 'amount': Decimal('0.00001000'), + 'confirmations': 1180, + 'desc': "pkh([ce0c7e14/0'/0'/25']02d0541b9211aecd25913f7fdecfc1b469215fa326d52067b1b3f7efbd12316472)#n06pq9q5", + 'label': '-addresstype', + 'safe': True, + 'scriptPubKey': '76a914a080d1a10f5e7a02d0a291f118982ed19e8cfcd788ac', + 'solvable': True, + 'spendable': True, + 'txid': '84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e', + 'vout': 0}, + {'address': 'tb1qrcf8c29966tvqxhwrtd2se3rj6jeqtll3r46a4', + 'amount': Decimal('0.01029734'), + 'confirmations': 1180, + 'desc': "wpkh([ce0c7e14/0'/1'/26']02c581259ba7e6aef6d7ea23adb08f7c7f10c4c678f2e097a4074639e7685d4805)#j3pctfhf", + 'safe': True, + 'scriptPubKey': '00141e127c28a5d696c01aee1adaa8662396a5902fff', + 'solvable': True, + 'spendable': True, + 'txid': '84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e', + 'vout': 1}, + {'address': 'mzDxbtYY3LBBBJ6HhaBAtnHv6c51BRBTLE', + 'amount': Decimal('0.00001000'), + 'confirmations': 1181, + 'desc': "pkh([ce0c7e14/0'/0'/23']0377bdd176f985b4af2f6bdbb22c2925b6007b6c07ba171f75e65990c002615e98)#3y6ef6vu", + 'label': '-addresstype', + 'safe': True, + 'scriptPubKey': '76a914cd339342b06042bb986a45e73d56db46acc1e01488ac', + 'solvable': True, + 'spendable': True, + 'txid': '1679bee019c61608340b79810377be2798efd4d2ec3ace0f00a1967af70666b9', + 'vout': 1}] +------------------------------------------ + +Details of Utxo with txid: 84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e +--------------------------------------------------------------- +UTXO Details: +------------ +{'hash': '0c6c27f58f122329bbc53a91f290b35ce23bd2708706b21a04cdc387dc8e2fd9', + 'locktime': 1831103, + 'size': 225, + 'txid': '84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e', + 'version': 2, + 'vin': [{'scriptSig': {'asm': '', 'hex': ''}, + 'sequence': 4294967294, + 'txid': '1679bee019c61608340b79810377be2798efd4d2ec3ace0f00a1967af70666b9', + 'txinwitness': ['3044022014b3e2359fb46d8cbc4cd30fa991b455edfa4b419a4c64a53fcdfc79e3ca89db022010cefc3268bc252d55f1982c426328b709b47d02332def9e2efb3b12de2cf0d301', + '0351b470e87b44e8e9607acf09b8d4543c51c93c17dc741176319e60202091f2be'], + 'vout': 0}], + 'vout': [{'n': 0, + 'scriptPubKey': {'addresses': ['mv9cjEnS2o1EygBMdrz99LzhM8KeEMoXDg'], + 'asm': 'OP_DUP OP_HASH160 ' + 'a080d1a10f5e7a02d0a291f118982ed19e8cfcd7 ' + 'OP_EQUALVERIFY OP_CHECKSIG', + 'hex': '76a914a080d1a10f5e7a02d0a291f118982ed19e8cfcd788ac', + 'reqSigs': 1, + 'type': 'pubkeyhash'}, + 'value': Decimal('0.00001000')}, + {'n': 1, + 'scriptPubKey': {'addresses': ['tb1qrcf8c29966tvqxhwrtd2se3rj6jeqtll3r46a4'], + 'asm': '0 1e127c28a5d696c01aee1adaa8662396a5902fff', + 'hex': '00141e127c28a5d696c01aee1adaa8662396a5902fff', + 'reqSigs': 1, + 'type': 'witness_v0_keyhash'}, + 'value': Decimal('0.01029734')}], + 'vsize': 144, + 'weight': 573} +--------------------------------------------------------------- +``` + +## Crindo um endereço + +Criar um novo endereço com Python 3 requer apenas o uso de um RPC como `getnewaddress` ou `getrawchangeaddress`. +``` +new_address = rpc_client.getnewaddress("Learning-Bitcoin-from-the-Command-Line") +new_change_address = rpc_client.getrawchangeaddress() +``` +Neste exemplo, usamos comando `getnewaddress` junto com um argumento: o rótulo `Learning-Bitcoin-from-the-Command-Line`. + +## Enviando uma transação + +A criação de uma transação no Python 3 requer a combinação de alguns dos exemplos anteriores, de criação de endereços e de recuperação de UTXOs, com alguns comandos novos do RPC para criar, assinar e enviar uma transação, da mesma forma que fizemos anteriormente na linha de comando. + +Existem cinco etapas: + +0. Criar dois endereços, um que funcionará como destinatário e outro para o troco; +1. Selecionar um UTXO e definir os detalhes da transação; +2. Criar uma transação bruta; +3. Assinar a transação bruta com a chave privada do UTXO; +4. Transmitir a transação na Testnet do bitcoin. + +### 1. Selecionando o UTXO e definindo os detalhes da transação + +No trecho de código a seguir, primeiro selecionaremos o UTXO que gostaríamos de gastar. Em seguida, iremos obter o endereço, id da transação e o índice vetorial da saída. + +```py +utxos = rpc_client.listunspent() +selected_utxo = utxos[0] # again, selecting the first utxo here +utxo_address = selected_utxo['address'] +utxo_txid = selected_utxo['txid'] +utxo_vout = selected_utxo['vout'] +utxo_amt = float(selected_utxo['amount']) +``` +Em seguida, também recuperamos o endereço do destinatário para o qual desejamos enviar os bitcoins, calculamos a quantidade de bitcoins que desejamos enviar e calculamos a taxa de minerador e o valor do troco. Aqui, o valor é dividido arbitrariamente em dois e uma taxa de minerador é definida arbitrariamente. + +```py +recipient_address = new_address +recipient_amt = utxo_amt / 2 # sending half coins to recipient +miner_fee = 0.00000300 # choose appropriate fee based on your tx size +change_address = new_change_address +change_amt = float('%.8f'%((utxo_amt - recipient_amt) - miner_fee)) +``` + +> :warning: **AVISO:** Obviamente, um programa real faria escolhas mais sofisticadas sobre qual UTXO usar, o que fazer com os fundos e que taxa de mineração pagar. + +### 2. Criando uma transação bruta + +Agora temos todas as informações para enviar uma transação, mas antes de enviá-la, devemos criar uma transação. + +```py +txids_vouts = [{"txid": utxo_txid, "vout": utxo_vout}] +addresses_amts = {f"{recipient_address}": recipient_amt, f"{change_address}": change_amt} +unsigned_tx_hex = rpc_client.createrawtransaction(txids_vouts, addresses_amts) +``` +Lembre-se de que o formato do comando `createrawtransaction` é: + +```$ bitcoin-cli createrawtransaction '[{"txid": , "vout": }]' '{"
": }'``` + +O `txids_vouts` é, portanto, uma lista e o `address_amts` é um dicionário python, para combinar com o formato de `createrawtransaction`. + +Se quisermos ver mais sobre os detalhes da transação que criamos, podemos usar `decoderawtransaction`, tanto no Python 3 quanto com `bitcoin-cli`. + +### 3. Assinar transação bruta + +Assinar uma transação geralmente é a parte mais complicada do envio de uma transação, quando olhamos a parte de programação. Aqui recuperamos uma chave privada de um endereço com `dumpprivkey` e a coloca em uma matriz: +```py +address_priv_key = [] # list of priv keys of each utxo +address_priv_key.append(rpc_client.dumpprivkey(utxo_address)) +``` +Depois, usamos esse array, que deve conter as chaves privadas de cada UTXO que está sendo gasto, para assinar nosso `unsigned_tx_hex`: +```py +signed_tx = rpc_client.signrawtransactionwithkey(unsigned_tx_hex, address_priv_key) +``` +Isso retornará um objeto JSON com o hex da transação assinada e, se foi assinado completamente ou não: + +### 4. Transmitindo a Transação + +Finalmente, estamos prontos para transmitir a transação assinada na rede Bitcoin: + +```py +send_tx = rpc_client.sendrawtransaction(signed_tx['hex']) +``` +### Executando nosso código + +[Este código](src/17_4_sendtx.py) está cheio de instruções com `print` para demonstrar todos os dados disponíveis em cada momento: +``` +$ python3 sendtx.py +Creating a Transaction +--------------------------------------------------------------- +Transaction Details: +------------------- +UTXO Address.......: mv9cjEnS2o1EygBMdrz99LzhM8KeEMoXDg +UTXO Txid..........: 84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e +Vector ID of Output: 0 +UTXO Amount........: 1e-05 +Tx Amount..........: 5e-06 +Recipient Address..: tb1qca0elxxqzw5xc0s3yq5qhapzzj90ka0zartu6y +Change Address.....: tb1qrveukqrvqm9h6fua99xvcxgnvdx507dg8e8hrt +Miner Fee..........: 3e-06 +Change Amount......: 2e-06 +--------------------------------------------------------------- + +--------------------------------------------------------------- +Unsigned Transaction Hex: 02000000015e53fb6f63b7defa28e61c28cfc3033361138a0d33dd1fad29ae58c6fe7f20840000000000ffffffff02f401000000000000160014c75f9f98c013a86c3e1120280bf422148afb75e2c8000000000000001600141b33cb006c06cb7d279d294ccc1913634d47f9a800000000 +--------------------------------------------------------------- + +--------------------------------------------------------------- +Signed Transaction: +---------------------- +{'complete': True, + 'hex': '02000000015e53fb6f63b7defa28e61c28cfc3033361138a0d33dd1fad29ae58c6fe7f2084000000006a47304402205da9b2234ea057c9ef3b7794958db6c650c72dedff1a90d2915147a5f6413f2802203756552aba0dd8ebd71b0f28341becc01b28d8b28af063d7c8ce89f9c69167f8012102d0541b9211aecd25913f7fdecfc1b469215fa326d52067b1b3f7efbd12316472ffffffff02f401000000000000160014c75f9f98c013a86c3e1120280bf422148afb75e2c8000000000000001600141b33cb006c06cb7d279d294ccc1913634d47f9a800000000'} +--------------------------------------------------------------- + +--------------------------------------------------------------- +TXID of sent transaction: 187f8baa222f9f37841d966b6bad59b8131cfacca861cbe9bfc8656bd16a44cc +``` + +## Resumo: Acessando o Bitcoind com Python + +Acessar Bitcoind com Python é muito fácil usando uma biblioteca `python-bitcoinrpc`. A primeira coisa a se fazer, é estabelecer uma conexão com nossa instância `bitcoind`, então podemos fazer todas as chamadas API bitcoin conforme descrito nos documentos do Bitcoin Core. Isso torna mais fácil criar programas pequenos ou grandes para gerenciar nosso próprio node, verificando saldos ou criando aplicações interessantes, conforme acessamos todo o poder do `bitcoin-cli`. + +## O Que Vem Depois? + +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md). + +## Variante: Construindo o Python a partir do código-fonte + +Se precisarmos instalar o Python 3 a partir do código-fonte, precisaremos seguir estas instruções e continuar da parte ["Criando um projeto BitcoinRPC"](17_4_Accessing_Bitcoind_with_Python.md#Creating-a-bitcoinrpc-project). + +### 1. Instalando as dependências +```sh +$ sudo apt-get install build-essential checkinstall +$ sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev +``` + +### 2. Baixando e extraindo o Python +```sh +$ wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz +$ tar -xzf Python-3.8.3.tgz +``` + +### 3. Compilando o código-fonte Python e verificando a instalação: + +```sh +$ cd Python-3.8.3 +$ sudo ./configure --enable-optimizations +$ sudo make -j 8 # enter the number of cores of your system you want to use to speed up the build process. +$ sudo make altinstall +$ python3.8 --version +``` + +Depois de obter o retorno da versão, podemos remover o arquivo de instalação: +```sh +$ rm Python-3.8.3.tgz +``` \ No newline at end of file diff --git a/pt/17_5_Accessing_Bitcoind_with_Rust.md b/pt/17_5_Accessing_Bitcoind_with_Rust.md new file mode 100644 index 0000000..f3133d8 --- /dev/null +++ b/pt/17_5_Accessing_Bitcoind_with_Rust.md @@ -0,0 +1,362 @@ +# 17.5: Acessando o Bitcoind com Rust + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esta seção explica como interagir com o `bitcoind` usando a linguagem de programação Rust e o [`bitcoincore-rpc` crate](https://github.com/rust-bitcoin/rust-bitcoincore-rpc). + +## Configurando o Rust + +Precisaremos instalar o Rust e o Cargo. + +Eles podem ser instalados via `curl`. Basta usar a instalação "padrão": +```vim +$ curl https://sh.rustup.rs -sSf | sh +``` +Se tudo correr bem, veremos: +```vim +Rust is installed now. Great! +``` +Em seguida, precisaremos fazer o logout e o login novamente ou então adicionar o diretório binário do Cargo ao nosso caminho manualmente: +``` +$ source $HOME/.cargo/env +``` + +### Configurando o `bitcoincore-rpc` + +Para a maioria das linguagens de programação, precisamos instalar uma biblioteca Bitcoin RPC antes de criar nosso primeiro projeto, mas aqui iremos fazer como parte da criação do nosso projeto. + +### Criando um projeto `bitcoincore-rpc` + +Podemos criar um novo projeto usando `cargo new btc_test`: + +``` +$ cargo new btc_test + Created binary (application) `btc_test` package +``` + +Isso criará um diretório `btc_test` que contém um exemplo de código-fonte "hello world" que está no `src/main.rs` e um arquivo `Cargo.toml`. + +Vamos compilar e executar nosso código com `cargo run`: +``` +$ cd btc_test +$ cargo run + Compiling btc_test v0.1.0 (/home/standup/btc_test) + Finished dev [unoptimized + debuginfo] target(s) in 0.14s + Running `target/debug/btc_test` +Hello, world! +``` + +> :information_source: **NOTA:** se encontrarmos o erro `linker‘ cc ’not found`, teremos que instalar um +Compilador C. Se estivermos no Linux, podemos instalar com as [ferramentas de desenvolvimento](https://www.ostechnix.com/install-development-tools-linux/). + +Para acessar o crate (biblioteca) `bitcoincore-rpc`, devemos adicioná-la ao nosso arquivo `Cargo.toml` na seção `dependencies`: + +```rust +[dependencies] +bitcoincore-rpc = "0.11.0" +``` + +Quando usarmos o comando `cargo run` novamente, ele irá instalar os crates e suas (numerosas) dependências. +``` +$ cargo run + Updating crates.io index + ... + Compiling bitcoin v0.23.0 + Compiling bitcoincore-rpc-json v0.11.0 + Compiling bitcoincore-rpc v0.11.0 + Compiling btc_test v0.1.0 (/home/standup/btc_test) + Finished dev [unoptimized + debuginfo] target(s) in 23.56s + Running `target/debug/btc_test` +Hello, world! +``` + +Quando estiver usando o `bitcoin-rpc`, normalmente precisaremos incluir o seguinte: +``` +use bitcoincore_rpc::{Auth, Client, RpcApi}; +``` + +## Construindo nossa conexão + +Para criarmos um `RPC client` do Bitcoin, vamos modificar o `src/main.rs`: + + +```rust +use bitcoincore_rpc::{Auth, Client, RpcApi}; + +fn main() { + let rpc = Client::new( + "http://localhost:18332".to_string(), + Auth::UserPass("StandUp".to_string(), "password".to_string()), + ) + .unwrap(); +} +``` + +Como de costume, vamos nos certificar de inserir nosso nome de usuário e senha corretos no `~/.bitcoin/bitcoin.conf`. Aqui, eles serão usados ​​como argumentos para `Auth :: UserPass`. + +> :link: **TESTNET vs MAINNET:** E, como de costume, vamos usar a porta 8332 para a Mainnet. + +Quando terminar, também deve fechar nossa conexão: +```rust + let _ = rpc.stop().unwrap(); +``` + +O `cargo run` deve compilar e executar o exemplo com sucesso com um aviso `warning: unused variable: rpc` + +### Fazendo uma chamada RPC + +As chamadas RPC são feitas usando o `rpc Client` que criamos: + +```rust +let mining_info = rpc.get_mining_info().unwrap(); +println!("{:#?}", mining_info); +``` +Geralmente, as palavras na chamada RPC são separadas por `_`s. Uma lista completa está disponível na [documentação do crate](https://crates.io/crates/bitcoincore-rpc). + +### Fazendo uma chamada RPC com argumentos + +O envio de uma chamada RPC com argumentos usando Rust requer apenas o conhecimento de como a função é apresentada. Por exemplo, a função `get_block` é definida da seguinte forma na [documentação](https://docs.rs/bitcoincore-rpc/0.11.0/bitcoincore_rpc/trait.RpcApi.html#method.get_block): + +```rust +fn get_block(&self, hash: &BlockHash) -> Result +``` +Só precisamos permitir que ele pegue emprestado um blockhash, que pode ser recuperado (por exemplo) usando o comando `get_best_block_hash`. + +Aqui está o código completo para recuperar um hash de bloco, transformando-o em um bloco e imprimi-lo. +``` + let hash = rpc.get_best_block_hash().unwrap(); + let block = rpc.get_block(&hash).unwrap(); + + println!("{:?}", block); +``` + +> **NOTA:** Outra chamada possível que consideramos para esta seção é a `get_address_info`, mas, infelizmente, no momento em que este livro foi escrito, a função `bitcoincore-rpc` não funciona com versões recentes do Bitcoin Core devido ao crate não abordar as mais recentes mudanças de API no Bitcoin Core. Esperamos que isso seja resolvido no próximo lançamento do crate, mas enquanto isso, damos essa atenção ao programador. + +### Executando nosso código + +Podemos acessar o [código src](src/17_5_main-getinfo.rs) e executá-lo. Infelizmente, a informação do "Block" sairá um pouco feia porque este exemplo não inclui uma biblioteca para embelezá-la. + +``` +$ cargo run + Compiling btc_test v0.1.0 (/home/standup/btc_test) + Finished dev [unoptimized + debuginfo] target(s) in 1.61s + Running `target/debug/btc_test` +GetMiningInfoResult { + blocks: 1832335, + current_block_weight: None, + current_block_tx: None, + difficulty: 4194304.0, + network_hash_ps: 77436285865245.1, + pooled_tx: 4, + chain: "test", + warnings: "Warning: unknown new rules activated (versionbit 28)", +} +Block { header: BlockHeader { version: 541065216, prev_blockhash: 000000000000027715981d5a3047daf6819ea3b8390b73832587594a2074cbf5, merkle_root: 4b2e2c2754b6ed9cf5c857a66ed4c8642b6f6b33b42a4859423e4c3dca462d0c, time: 1599602277, bits: 436469756, nonce: 218614401 }, txdata: [Transaction { version: 1, lock_time: 0, input: [TxIn { previous_output: OutPoint { txid: 0000000000000000000000000000000000000000000000000000000000000000, vout: 4294967295 }, script_sig: Script(OP_PUSHBYTES_3 8ff51b OP_PUSHBYTES_22 315448617368263538434f494e1d00010320a48db852 OP_PUSHBYTES_32 ), sequence: 4294967295, witness: [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] }], output: [TxOut { value: 19721777, script_pubkey: Script(OP_HASH160 OP_PUSHBYTES_20 011beb6fb8499e075a57027fb0a58384f2d3f784 OP_EQUAL) }, TxOut { value: 0, script_pubkey: Script(OP_RETURN OP_PUSHBYTES_36 aa21a9ed63363f3620ab5e38b8860a50c84050e5ec31af3636bbd73f01ba9f14103100ee) }] }, Transaction { version: 2, lock_time: 1832282, input: [TxIn { previous_output: OutPoint { txid: cbf880f73d421baf0aa4f0d28e63ba00e5bc6bd934b91eb0641354ce5ca42f7e, vout: 0 }, script_sig: Script(OP_PUSHBYTES_22 00146b8dbd32e5deb90d22934e1513bae6e70156cd50), sequence: 4294967294, witness: [[48, 68, 2, 32, 13, 89, 205, 30, 67, 24, 196, 83, 65, 224, 44, 138, 98, 58, 81, 135, 132, 209, 23, 166, 23, 44, 3, 228, 95, 102, 166, 214, 62, 38, 155, 147, 2, 32, 119, 2, 34, 246, 148, 255, 166, 10, 90, 52, 242, 32, 74, 241, 123, 148, 89, 199, 197, 3, 152, 134, 242, 215, 109, 61, 241, 241, 13, 70, 86, 207, 1], [2, 192, 145, 170, 206, 55, 4, 36, 138, 145, 217, 50, 19, 73, 130, 136, 245, 131, 184, 142, 239, 75, 13, 67, 17, 177, 57, 86, 151, 139, 89, 35, 109]] }], output: [TxOut { value: 1667908, script_pubkey: Script(OP_HASH160 OP_PUSHBYTES_20 908ca2b8b49ccf53efa2226afa85f6cc58dfd7e7 OP_EQUAL) }, TxOut { value: 9093, script_pubkey: Script(OP_DUP OP_HASH160 OP_PUSHBYTES_20 42ee67664ce16edefc68ad0e4c5b7ce2fc2ccc18 OP_EQUALVERIFY OP_CHECKSIG) }] }, ...] } +``` + +## Pesquisando os fundos + +Podemos procurar fundos sem argumentos opcionais usando a função `get_balance`: + +```rust +let balance = rpc.get_balance(None, None).unwrap(); +println!("Balance: {:?} BTC", balance.as_btc()); +``` +Conforme mostrado, a função `as_btc()` ajuda a gerar o saldo em um formato legível: +``` +Balance: 3433.71692741 BTC +``` + +## Criando um endereço + +A criação de um endereço demonstra como fazer uma chamada RPC com vários argumentos opcionais especificados (por exemplo, um rótulo e um tipo de endereço). + +```rust +// Generate a new address +let myaddress = rpc + .get_new_address(Option::Some("BlockchainCommons"), Option::Some(json::AddressType::Bech32)) + .unwrap(); +println!("address: {:?}", myaddress); +``` +Isso também exigirá que tragamos a definição `json` para o escopo: +```rust +use bitcoincore_rpc::{json, Auth, Client, RpcApi}; +``` + +## Enviando uma transação + +Agora temos tudo de que precisamos para criar uma transação, o que será feito em cinco partes: + +1. Listar UTXOs; +2. Preencher variáveis; +3. Criar transação bruta; +4. Assinar transação; +5. Enviar transação. + +### 1. Listando o UTXOs + +Para iniciar a criação de uma transação, primeiro encontramos um UTXO para usar. O seguinte leva o primeiro UTXO com pelo menos 0,01 BTC: + + +```rust +let unspent = rpc +.list_unspent( + None, + None, + None, + None, + Option::Some(json::ListUnspentQueryOptions { + minimum_amount: Option::Some(Amount::from_btc(0.01).unwrap()), + maximum_amount: None, + maximum_count: None, + minimum_sum_amount: None, + }), +) +.unwrap(); + +let selected_tx = &unspent[0]; + +println!("selected unspent transaction: {:#?}", selected_tx); +``` +Isso exigirá trazer mais estruturas para o escopo: + +```rust +use bitcoincore_rpc::bitcoin::{Address, Amount}; +``` + +Podemos observar que estamos passando cinco variáveis ​​ao comando `list_unspent`. Os primeiros quatro (`minconf`,` maxconf`, `address` e `include_unsafe`) não são usados ​​aqui. O quinto é o `query_options`, que não usamos antes, mas temos algumas opções de filtragem poderosas, incluindo a capacidade de olhar apenas para os UTXOs com um certo valor, mínimo ou máximo. + +### 2. Preenchendo as variáveis + +Para começar a preencher as variáveis ​​que precisaremos para criar uma nova transação, criamos a entrada do `txid` e do `vout` ao UTXO que selecionamos: +```rust +let selected_utxos = json::CreateRawTransactionInput { + txid: selected_tx.txid, + vout: selected_tx.vout, + sequence: None, +}; +``` +Em seguida, podemos calcular a quantia que vamos gastar subtraindo uma taxa de mineração dos fundos no UTXO: +``` +// send all bitcoin in the UTXO except a minor value which will be paid to miners +let unspent_amount = selected_tx.amount; +let amount = unspent_amount - Amount::from_btc(0.00001).unwrap(); +``` +Por fim, podemos criar um mapa do hash do endereço e da quantidade para formar a saída: +``` +let mut output = HashMap::new(); +output.insert( + myaddress.to_string(), + amount, +); +``` +Outra característica é necessária para a variável de saída: O `HashMap`. Ele permite que armazenemos +valores por chave, que iremos precisar para representar a informação `{address: amount}`. + +```rust +use std::collections::HashMap; +``` + +### 3. Criando a transação bruta + +Agora, estamos prontos para criar uma transação bruta: +```rust +let unsigned_tx = rpc + .create_raw_transaction(&[selected_utxos], &output, None, None) + .unwrap(); +``` +### 4. Assinando a transação + +A assinatura da transação pode ser feita com um simples uso do `sign_raw_transaction_with_wallet`: +```rust +let signed_tx = rpc + .sign_raw_transaction_with_wallet(&unsigned_tx, None, None) + .unwrap(); + +println!("signed tx {:?}", signed_tx.transaction().unwrap()); +``` + +### 5. Enviando a transação + +Finalmente, podemos transmitir a transação: +```rust +let txid_sent = rpc + .send_raw_transaction(&signed_tx.transaction().unwrap()) + .unwrap(); + +println!("{:?}", txid_sent); +``` + +### Executando nosso código + +Agora podemos executar o código completo do [src](src/17_5_main-sendtx.rs). + + +``` +$ cargo run + Compiling btc_test v0.1.0 (/home/standup/btc_test) +warning: unused variable: `unspent_amount` + --> src/main.rs:86:9 + | +86 | let unspent_amount = selected_tx.amount; + | ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unspent_amount` + | + = note: `#[warn(unused_variables)]` on by default + +warning: 1 warning emitted + + Finished dev [unoptimized + debuginfo] target(s) in 2.11s + Running `target/debug/btc_test` +Balance: 0.01031434 BTC +address: tb1qx5jz36xgt9q2rkh4daee8ewfj0g5z05v8qsua2 +selected unspent transaction: ListUnspentResultEntry { + txid: 84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e, + vout: 1, + address: Some( + tb1qrcf8c29966tvqxhwrtd2se3rj6jeqtll3r46a4, + ), + label: None, + redeem_script: None, + witness_script: None, + script_pub_key: Script(OP_0 OP_PUSHBYTES_20 1e127c28a5d696c01aee1adaa8662396a5902fff), + amount: Amount(1029734 satoshi), + confirmations: 1246, + spendable: true, + solvable: true, + descriptor: Some( + "wpkh([ce0c7e14/0\'/1\'/26\']02c581259ba7e6aef6d7ea23adb08f7c7f10c4c678f2e097a4074639e7685d4805)#j3pctfhf", + ), + safe: true, +} +unsigned tx Transaction { + version: 2, + lock_time: 0, + input: [ + TxIn { + previous_output: OutPoint { + txid: 84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e, + vout: 1, + }, + script_sig: Script(), + sequence: 4294967295, + witness: [], + }, + ], + output: [ + TxOut { + value: 1028734, + script_pubkey: Script(OP_0 OP_PUSHBYTES_20 352428e8c85940a1daf56f7393e5c993d1413e8c), + }, + ], +} +signed tx Transaction { version: 2, lock_time: 0, input: [TxIn { previous_output: OutPoint { txid: 84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e, vout: 1 }, script_sig: Script(), sequence: 4294967295, witness: [[48, 68, 2, 32, 98, 230, 199, 113, 156, 242, 158, 42, 148, 229, 239, 44, 9, 226, 127, 219, 72, 51, 26, 135, 44, 212, 179, 200, 213, 63, 56, 167, 0, 55, 236, 235, 2, 32, 41, 43, 30, 109, 60, 162, 124, 67, 20, 126, 4, 107, 124, 95, 9, 200, 132, 246, 147, 235, 176, 55, 59, 45, 190, 18, 211, 201, 143, 62, 163, 36, 1], [2, 197, 129, 37, 155, 167, 230, 174, 246, 215, 234, 35, 173, 176, 143, 124, 127, 16, 196, 198, 120, 242, 224, 151, 164, 7, 70, 57, 231, 104, 93, 72, 5]] }], output: [TxOut { value: 1028734, script_pubkey: Script(OP_0 OP_PUSHBYTES_20 352428e8c85940a1daf56f7393e5c993d1413e8c) }] } +b0eda3517e6fac69e58ae315d7fe7a1981e3a858996cc1e3135618cac9b79d1a +``` + +## Resumo: Acessando o Bitcoind com Rust + +O `bitcoincore-rpc` é um crate simples e robusto que permitirá que possamos interagir com o Bitcoin RPC usando Rust. No entanto, no momento em que este livro foi escrito, ele ficou para trás no Bitcoin Core, o que pode causar alguns problemas de uso. + +## O Que Vem Depois? + +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md). \ No newline at end of file diff --git a/pt/17_6_Accessing_Bitcoind_with_Swift.md b/pt/17_6_Accessing_Bitcoind_with_Swift.md new file mode 100644 index 0000000..4716dee --- /dev/null +++ b/pt/17_6_Accessing_Bitcoind_with_Swift.md @@ -0,0 +1,463 @@ +# 17.6: Acessando o Bitcoind com Swift + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esta seção explica como interagir com o `bitcoind` usando a linguagem de programação Swift e seu próprio cliente RPC. + +## Configurando o Swift no Mac + +Até o momento, construímos todos os nossos ambientes de desenvolvimento de linguagem de programação alternativa em nosso node virtual no Debian. No entanto, essa não é a melhor plataforma para o Swift. Embora haja uma versão do Swift disponível para plataformas Ubuntu, ela não possui todos os recursos e funciona de maneira um pouco diferente do Swift nativo do Mac. Uma "variante" no final desta seção explica como configurá-lo, mas esteja avisado de que estaremos em um território desconhecido. + +Ao invés disso, sugerimos a criação de um ambiente Swift ideal em um Mac. Existem quatro etapas principais para fazer isso. + +### 1. Instalando o Xcode + +Vamos precisar do `Xcode`, o ambiente de desenvolvimento integrado para o Swift e para o Objective-C. Isso pode ser facilmente instalado acessando a Mac App Store e o `Get` Xcode. + +#### Alternativa: Instalando manualmente + +Algumas pessoas desaconselham a instalação da App Store porque é tudo ou nada. Também não funcionará se estivermos usando o Mojave, pois iremos querer evitar as incompatibilidades da Catalina. Nesse caso, podemos fazer o download diretamente da [Área do desenvolvedor](https://developer.apple.com/download/more/) na Apple. + +Se estivermos usando o Mojave, precisaremos do arquivo `xip` para o Xcode 10.3.1. Caso contrário, podemos utilizar o mais recente. + +Depois de baixado, podemos clicar no `xip` para extraí-lo e mover o aplicativo Xcode para a pasta Aplicativos. + +De qualquer forma, devemos ter o Xcode instalado na pasta Aplicativos no final desta etapa. + +### 2. Instalando o servidor Gordian + +Também vamos precisar de um node Bitcoin em nosso Mac, para que possamos nos comunicar com ele. Tecnicamente, poderíamos usar um node remoto e acessá-lo com o login e senha RPC pela rede. No entanto, sugerimos a instalação do full node diretamente no Mac, porque essa é a configuração mais segura e limpa, garantindo que nenhuma das comunicações saia de nossa máquina. + +Para instalar facilmente um full node em nosso Mac, podemos usar Blockchain Commons '[GordianServer for MacOS](https://github.com/BlockchainCommons/GordianServer-macOS). Podemos seguir as [instruções de instalação](https://github.com/BlockchainCommons/GordianServer-macOS#installation-instructions) no README, mas geralmente tudo que precisamos fazer é baixar o arquivo `dmg` atual, abri-lo e instalar a aplicação em nosso diretório de aplicações. + +Depois, vamos executar o aplicativo GordianServer e dizer a ele para `Start` a Testnet. + +> :link: **TESTNET vs. MAINNET:** Ou `Start` na Mainnet. + +#### 3. Tornando nosso bitcoin-cli Gordian acessível + +Quando desejarmos acessar o `bitcoin-cli` criado pelo GordianServer em nosso Mac local, podemos encontrá-lo em `~/.standup/BitcoinCore/bitcoin-0.20.1/bin/bitcoin-cli`. + +Podemos criar um alias para isso: +``` +alias bitcoin-cli="~/.standup/BitcoinCore/bitcoin-0.20.1/bin/bitcoin-cli -testnet" +``` + +> :link: **TESTNET vs. MAINNET:** Obviamente, o parâmetro `-testnet` só é necessário se estivermos executando a testnet. + +### 4. Encontrando nossas informações do GordianServer + +Finalmente, precisaremos de nossas informações de `rpcuser` e `rpcpassword`. Essas informações estarão em `~/Library/Application Support/Bitcoin/bitcoin.conf` por padrão no Gordian. +``` +$ grep rpc ~/Library/Application\ Support/Bitcoin/bitcoin.conf +rpcuser=oIjA53JC2u +rpcpassword=ebVCeSyyM0LurvgQyi0exWTqm4oU0rZU +... +``` +## Construindo nossa conexão manualmente + +No momento em que este artigo foi escrito, não havia uma biblioteca Bitcoin RPC atualizada e simples de ser usada, que fosse específica para Swift, algo que pudesse entrar e começar a usar imediatamente. Portanto, faremos algo que nunca fizemos antes: Construir uma conexão RPC manualmente. + +### Grave o Transmissor RPC + +Isso requer apenas a escrita de uma função que passe os comandos RPC para o `bitcoind` no formato correto: +``` +func makeCommand(method: String, param: Any, completionHandler: @escaping (Any?) -> Void) -> Void { +``` + +As conexões RPC para o `bitcoind` usam o protocolo HTML, o que significa que precisamos fazer três coisas: Criar uma URL, fazer um URLRequest e, iniciar uma URLSession. + +#### 1. Criando um URL + +Dentro da função, precisamos criar uma URL a partir do nosso IP, porta, `rpcuser`, `rpcpassword` e wallet: +``` + let testnetRpcPort = "18332" + let nodeIp = "127.0.0.1:\(testnetRpcPort)" + let rpcusername = "oIjA53JC2u" + let rpcpassword = "ebVCeSyyM0LurvgQyi0exWTqm4oU0rZU" + let walletName = "" +``` +A conexão RPC real com o Bitcoin Core é construída usando um URL no formato "http://rpcusername:rpcpassword@nodeIp/walletName": +``` + let walletUrl = "http://\(rpcusername):\(rpcpassword)@\(nodeIp)/\(walletName)" + + let url = URL(string: walletUrl) +``` +Isso significa que nossas variáveis ​​de amostra resultam na seguinte URL: +``` +http://oIjA53JC2u:ebVCeSyyM0LurvgQyi0exWTqm4oU0rZU@127.0.0.1:18332/ +``` +Que deve se parecer muito com a URL usada em algumas das seções anteriores para conexões RPC. + +#### 2. Criando uma URLRequest + +Com essa URL em mãos, agora podemos criar um URLRequest, com o método `POST` e o tipo de conteúdo `text/plain`. O corpo HTTP será então o objeto JSON familiar que enviamos sempre que nos conectamos diretamente às portas RPC do Bitcoin Core, conforme demonstrado pela primeira vez ao usar o Curl na seção [§4.4](04_4__Interlude_Using_Curl.md). +``` + var request = URLRequest(url: url!) + request.httpMethod = "POST" + request.setValue("text/plain", forHTTPHeaderField: "Content-Type") + request.httpBody = "{\"jsonrpc\":\"1.0\",\"id\":\"curltest\",\"method\":\"\(method)\",\"params\":[\(param)]}".data(using: .utf8) +``` + +#### 3. Criando uma URLSession + +Finalmente, estamos prontos para construir uma URLSession em torno da nossa URLRequest. +``` + let session = URLSession(configuration: .default) + let task = session.dataTask(with: request as URLRequest) { data, response, error in +``` +O manipulador de conclusão para `dataTask` precisa verificar se há erros: +``` + do { + + if error != nil { + + //Handle the error + + } else { +``` +E então analisar os dados que estamos recebendo. Aqui, estamos pegando os resultados JSON e colocando-os em um `NSDictionary`: +``` + if let urlContent = data { + + do { + + let json = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableLeaves) as! NSDictionary +``` +Depois disso, há mais manipulação de erros e então podemos eventualmente retornar o `result` do dicionário usando o `CompletHandler` que definimos para a nova função `makeCommand`: +``` + if let errorCheck = json["error"] as? NSDictionary { + + if let errorMessage = errorCheck["message"] as? String { + + print("FAILED") + print(errorMessage) + + } + + } else { + + let result = json["result"] + completionHandler(result) + + } + + } catch { + + //Handle error here + + } +``` +Claro que eventualmente teremos que dizer à `task` para que ela seja iniciada: +``` + task.resume() +``` +E isso é "tudo" o que precisamos fazer nessa interação RPC manual, usando uma linguagem de programação como o Swift. + +> :pray: **AGRADECIMENTOS:** Obrigado a @Fonta1n3 que forneceu o [código principal](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues/137) para nosso Transmissor RPC. + +### Fazendo uma chamada RPC + +Tendo escrito a função RPC `makeCommand`, podemos enviar uma chamada RPC executando-a. Aqui está `getblockchaininfo`: +``` +let method = "getblockchaininfo" +let param = "" + +makeCommand(method: method,param: param) { result in + + print(result!) + +} +``` +### Fazendo uma chamada RPC com argumentos + +Poderíamos da mesma forma obter a contagem de bloco atual a partir dessa informação e usá-la de modo redundante para obter o hash do bloco atual, usando o parâmetro `param`: +``` +let method = "getblockchaininfo" +let param = "" + +makeCommand(method: method,param: param) { result in + + let blockinfo = result as! NSDictionary + let block = blockinfo["blocks"] as! NSNumber + + let method = "getblockhash" + makeCommand(method: method,param: block) { result in + print("Blockhash for \(block) is \(result!)") + } + +} +``` + +### Executando nosso código + +O código completo está disponível no [diretório src/](src / 17_6_getinfo.playground). Carregue-o no playground Xcode e, em seguida, "Editor -> Executar Playground" e devemos obter resultados como: +``` +{ + bestblockhash = 00000000000000069725608ebc5b59e520572a8088cbc57ffa5ba87b7f300ac7; + blocks = 1836745; + chain = test; + chainwork = 0000000000000000000000000000000000000000000001cc3e9f8e0bc6b71196; + difficulty = "16508683.81195478"; + headers = 1836745; + initialblockdownload = 0; + mediantime = 1601416765; + pruned = 0; + "size_on_disk" = 28205538354; + softforks = { + bip34 = { + active = 1; + height = 21111; + type = buried; + }; + bip65 = { + active = 1; + height = 581885; + type = buried; + }; + bip66 = { + active = 1; + height = 330776; + type = buried; + }; + csv = { + active = 1; + height = 770112; + type = buried; + }; + segwit = { + active = 1; + height = 834624; + type = buried; + }; + }; + verificationprogress = "0.999999907191804"; + warnings = "Warning: unknown new rules activated (versionbit 28)"; +} +Blockhash for 1836745 is 00000000000000069725608ebc5b59e520572a8088cbc57ffa5ba87b7f300ac7 +``` +## Pesquisando fundos + +Com nosso novo `makeCommand` para funções RPC, podemos executar um comando como `getwalletinfo` ou `getbalance`: +``` +var method = "getwalletinfo" +var param = "" + +makeCommand(method: method,param: param) { result in + + print(result!) + +} + +method = "getbalance" +makeCommand(method: method,param: param) { result in + + let balance = result as! NSNumber + print("Balance is \(balance)") + +} +``` +Que irá retornar: +``` +Balance is 0.01 +{ + "avoid_reuse" = 0; + balance = "0.01"; + hdseedid = bf493318f548df8e25c390d6a7f70758fd6b3668; + "immature_balance" = 0; + keypoololdest = 1599723938; + keypoolsize = 999; + "keypoolsize_hd_internal" = 1000; + paytxfee = 0; + "private_keys_enabled" = 1; + scanning = 0; + txcount = 1; + "unconfirmed_balance" = 0; + walletname = ""; + walletversion = 169900; +} +``` +## Criando um endereço + +Criar um endereço é bastante simples, mas que tal criar um endereço legado com um rótulo específico? Isso requer dois parâmetros na nossa chamada RPC. + +Uma vez que a simples função `makeCommand` desta seção apenas passa nossos `param`s como as entranhas de um objeto JSON, tudo o que precisamos fazer é formatar corretamente essas entranhas. Esta é uma maneira para fazermos isso: +``` +method = "getnewaddress" +param = "\"learning-bitcoin\", \"legacy\"" + +makeCommand(method: method,param: param) { result in + + let address = result as! NSString + print(address) +} +``` +Executá-lo no playground do Xcode produz o seguinte resultado: +``` +mt3ZRsmXHVMMqYQPJ8M74QjF78bmqrdHZF +``` +Esse resultado é obviamente um endereço legado, op rótulo pode então ser verificado na linha de comando: +``` +$ bitcoin-cli getaddressesbylabel "learning-bitcoin" +{ + "mt3ZRsmXHVMMqYQPJ8M74QjF78bmqrdHZF": { + "purpose": "receive" + } +} +``` +Sucesso! + +> :information_source: **NOTA:** Como costumamos dizer nesses exemplos de programação, um programa do mundo real seria muito mais sofisticado. Em particular, gostaríamos de poder enviar um objeto JSON real como um parâmetro e, em seguida, ter no nosso programa um `makeCommand` analisando-o e inserindo-o na URLSession de forma adequada. O que temos aqui maximiza a legibilidade e a simplicidade sem enfocar na facilidade de uso. + +## Enviando uma transação + +Como de costume, o envio de uma transação (da maneira mais difícil) é um processo de várias etapas: + +0. Gerar ou recebar um endereço de recebimento; +1. Encontrar um UTXO não gasto; +2. Criar uma transação bruta; +3. Assinar a transação bruta; +4. Enviar a transação bruta. + +Usando o `address` gerado na etapa anterior como nosso destinatário. + +### 1. Encontrando um UTXO não gasto + +O RPC `listunspent` permite que encontremos nosso UTXO: +``` + method = "listunspent" + param = "" + + makeCommand(method: method,param: param) { result in + + let unspent = result as! NSArray + let utxo = unspent[0] as! NSDictionary + + let txid = utxo["txid"] as! NSString + let vout = utxo["vout"] as! NSInteger + let amount = utxo["amount"] as! NSNumber + let new_amount = amount.floatValue - 0.0001 +``` +Como em outros exemplos, vamos arbitrariamente pegar o enésimo UTXO e pegar o `txid`,`vout` e `amount` dele. + +> :information_source **NOTA:** Mais uma vez, um programa real seria muito mais sofisticado. + +### 2. Criando uma transação bruta + +Criar uma transação bruta é a coisa mais complicada, porque precisamos acertar todos os nossos objetos JSON, arrays e aspas. Veja como fazer isso no Swift, usando a formatação `param` muito básica do transmissor: +``` + method = "createrawtransaction" + param="[ { \"txid\": \"\(txid)\", \"vout\": \(vout) } ], { \"\(address)\": \(new_amount)}" + makeCommand(method: method,param: param) { result in + + let hex = result as! NSString +``` +### 3. Assinando a transação bruta + +Assinar nossa transação requer apenas que executemos o RPC `signrawtransactionwithwallet`, usando nosso novo `hex`: +``` + method = "signrawtransactionwithwallet" + param = "\"\(hex)\"" + + makeCommand(method: method,param: param) { result in + + let signedhexinfo = result as! NSDictionary + let signedhex = signedhexinfo["hex"] as! NSString +``` + +### 4. Enviando a transação bruta + +Enviar nossa transação é igualmente simples: +``` + method = "sendrawtransaction" + param = "\"\(signedhex)\"" + + makeCommand(method: method,param: param) { result in + + let new_txid = result as! NSString + print("TXID: \(new_txid)") + + } + } + } + } +} +``` + +O código para este remetente de transação pode ser encontrado no [diretório src/](src/17_6_sendtx.playground). + +## Usando o Swift de outras maneiras + +Isso cobre nossas discussões habituais sobre a programação do Bitcoin RPC usando uma linguagem, mas o Swift é uma linguagem particularmente importante, pois pode ser implantada em dispositivos móveis, um dos principais locais para nossas carteiras. Como tal, podemos querer considerar algumas outras bibliotecas: + +* O Blockchain Commons [ios-Bitcoin framework](https://github.com/BlockchainCommons/iOS-Bitcoin) converte a biblioteca Libbitcoin de C++ para Swift; +* [Libwally Swift](https://github.com/blockchain/libwally-swift) é um wrapper Swift para a Libwally. + +## Resumo: Acessando o Bitcoind com Swift + +O Swift é uma linguagem de programação robusta e moderna que infelizmente ainda não tem nenhuma biblioteca RPC fácil de ser utilizada... O que apenas nos deu a oportunidade de escrever uma função de acesso ao RPC. Com isso em mãos, podemos interagir com o `bitcoind` em um Mac ou criar aplicativos complementares em um iPhone, o que é uma combinação perfeita para usar o Bitcoin com airgap. + +## O Que Vem Depois? + +Aprenda sobre o Lightning em [Capítulo 18: Compreendendo a configuração da Lightning](18_0_Understanding_Your_Lightning_Setup.md). + +## Variante: implantando o Swift no Ubuntu + +Se preferirmos implantar o Swift no Ubuntu, pode fazê-lo, embora a funcionalidade não seja a mesma. Parte do código neste capítulo provavelmente gerará erros que precisaremos resolver e também precisaremos trabalhar mais para vincular as bibliotecas C. + +Para começar, vamos instalar algumas bibliotecas Debian necessárias: +``` +$ sudo apt-get install clang +$ sudo apt-get install libcurl4 libpython2.7 libpython2.7-dev +``` +Se estivermos usando o Debian 10 ou superior (e realmente deveríamos estar usando), também precisaremos retroagir algumas bibliotecas para obter as versões mais antigas: +``` +$ sudo apt-get install libtinfo5 libncurses5 +``` +Posteriormente, podemos baixar e instalar o Swift: +``` +$ wget https://swift.org/builds/swift-5.1.3-release/ubuntu1804/swift-5.1.3-RELEASE/swift-5.1.3-RELEASE-ubuntu18.04.tar.gz +$ tar xzfv swift-5.1.3-RELEASE-ubuntu18.04.tar.gz +$ sudo mv swift-5.1.3-RELEASE-ubuntu18.04 /usr/share/swift +``` +Para poder usar nossa nova configuração do Swift, precisaremos atualizar nosso `PATH` em nosso arquivo `.bashrc`: +``` +$ echo "export PATH=/usr/share/swift/usr/bin:$PATH" >> ~/.bashrc +$ source ~/.bashrc +``` +Agora podemos testar o Swift com o argumento `--version`: +``` +$ swift --version +Swift version 5.1.3 (swift-5.1.3-RELEASE) +Target: x86_64-unknown-linux-gnu +``` + +### Criando um projeto +Depois de instalar o Swift em nossa máquina Ubuntu, podemos criar projetos com o comando `package init`: +``` +$ mkdir swift-project +$ cd swift-project/ +/swift-project$ swift package init --type executable +Creating executable package: swift-project +Creating Package.swift +Creating README.md +Creating .gitignore +Creating Sources/ +Creating Sources/swift-project/main.swift +Creating Tests/ +Creating Tests/LinuxMain.swift +Creating Tests/swift-projectTests/ +Creating Tests/swift-projectTests/swift_projectTests.swift +Creating Tests/swift-projectTests/XCTestManifests.swift +``` +Também editaremos o `Sources/.../main.swift` e quando estivermos pronto para compilar, podemos usar o comando `build`: +``` +$ swift build +[4/4] Linking swift-project +``` +Finalmente, seremos capazes de executar o programa a partir do diretório `.build/debug`: +``` +$ .build/debug/swift-project +Hello, world! +``` +Boa sorte! \ No newline at end of file From fdaaac3856f4fde0d8496b22edf84e0a2fcf3ff7 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sun, 8 Aug 2021 15:14:40 -0300 Subject: [PATCH 060/155] Chapter 18 translation concluded --- pt/18_0_Understanding_Your_Lightning_Setup.md | 26 ++ pt/18_1_Verifying_Your_Lightning_Setup.md | 288 +++++++++++++++ pt/18_2_Knowing_Your_lightning_Setup.md | 340 ++++++++++++++++++ ...rlude_Accessing_a_Second_Lightning_Node.md | 326 +++++++++++++++++ pt/18_3_Setting_Up_a_Channel.md | 185 ++++++++++ 5 files changed, 1165 insertions(+) create mode 100644 pt/18_0_Understanding_Your_Lightning_Setup.md create mode 100644 pt/18_1_Verifying_Your_Lightning_Setup.md create mode 100644 pt/18_2_Knowing_Your_lightning_Setup.md create mode 100644 pt/18_2__Interlude_Accessing_a_Second_Lightning_Node.md create mode 100644 pt/18_3_Setting_Up_a_Channel.md diff --git a/pt/18_0_Understanding_Your_Lightning_Setup.md b/pt/18_0_Understanding_Your_Lightning_Setup.md new file mode 100644 index 0000000..3a3a6bf --- /dev/null +++ b/pt/18_0_Understanding_Your_Lightning_Setup.md @@ -0,0 +1,26 @@ +# Capítulo 18: Compreendendo a configuração da Lightning + +> :information_source: **NOTA:** Este é um rascunho que está em andamento. Seu objetivo é que possa obter alguns comentários dos revisores iniciais. Ainda não está pronto para ser produzido. + +O capítulo anterior concluiu nosso trabalho com o Bitcoin propriamente dito, por meio do CLI, scripts e linguagens de programação. No entanto, existem muitos outros utilitários dentro do ecossistema Bitcoin. Neste capítulo e no próximo, iremos cobrir o que pode ser o maior e mais importante deles, a Lightning Network. Aqui, começaremos a trabalhar com a interface de linha de comando `lightning-cli`, entendendo a configuração do c-lightning e dos seus recursos, incluindo alguns exemplos e configuração básica. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Avaliar se um node c-lightning está instalado e atualizado; + * Executar comandos básicos de uma carteira Lightning ; + * Criar um canal na Lightning. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Compreender a configuração básica da Lightning; + * Compreender a interação dos canais Lightning; + * Entender como usar a Lightning. + +## Tabela de Conteúdo + +* [Seção 1: Verificando a configuração do c-lightning](18_1_Verifying_Your_Lightning_Setup.md) +* [Seção 2: Conhecendo a configuração do c-lightning](18_2_Knowing_Your_lightning_Setup.md) + * [Adendo: Acessando um segundo node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md) +* [Seção 3: Criando um canal na Lightning](18_3_Setting_Up_a_Channel.md) \ No newline at end of file diff --git a/pt/18_1_Verifying_Your_Lightning_Setup.md b/pt/18_1_Verifying_Your_Lightning_Setup.md new file mode 100644 index 0000000..5d3cb0c --- /dev/null +++ b/pt/18_1_Verifying_Your_Lightning_Setup.md @@ -0,0 +1,288 @@ +# 18.1: Verificando a configuração do c-lightning + +>: information_source: ** NOTA: ** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Nesta seção, instalaremos e verificaremos o c-lightning, nosso utilitário para acessar a Lightning Network. + +> :book: ***O que é a Lightning Network?*** A Rede Lightning é uma rede descentralizada que usa a funcionalidade de contrato inteligente da blockchain do Bitcoin para permitir pagamentos instantâneos em uma rede de participantes. A Lightning é construída como um protocolo de segunda camada que interage com o Bitcoin para permitir que os usuários troquem seus bitcoins "fora da blockchain (ou como muitos falam, offchain)". + +> :book: ***O que é um protocolo de segunda camada?*** A segunda camada refere-se a um protocolo secundário criado em cima do sistema de blockchain do Bitcoin. O objetivo principal desses protocolos é resolver a velocidade de transação e as dificuldades de escala que estão presentes no Bitcoin. O Bitcoin não é capaz de processar milhares de transações por segundo (TPS), então protocolos de segunda camada foram criados para resolver o problema de escalabilidade da blockchain . Essas soluções também são conhecidas como soluções de dimensionamento "offchain". + +## Instalando o C-Lightning + +Se já usamos os [Bitcoin Standup Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts), talvez já o tenhamos instalado no início deste curso. Podemos testar isso verificando se o `lightningd` está em execução: +``` +$ ps auxww | grep -i lightning +standup 31213 0.0 0.2 24144 10424 pts/0 S 15:38 0:00 lightningd --testnet +standup 31214 0.0 0.1 22716 7444 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/autoclean +standup 31215 0.0 0.2 22992 8248 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/bcli +standup 31216 0.0 0.1 22756 7604 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/keysend +standup 31217 0.0 0.1 22776 7648 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/pay +standup 31218 0.0 0.1 22720 7652 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/txprepare +standup 31219 0.0 0.1 22744 7716 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/spenderp +standup 31227 0.0 0.1 22748 7384 pts/0 SL 15:38 0:00 /usr/local/libexec/c-lightning/lightning_hsmd +standup 31228 0.0 0.2 23044 8192 pts/0 S 15:38 0:00 /usr/local/libexec/c-lightning/lightning_connectd +standup 31229 0.0 0.1 22860 7556 pts/0 S 15:38 0:00 /usr/local/libexec/c-lightning/lightning_gossipd +standup 32072 0.0 0.0 6208 888 pts/0 S+ 15:50 0:00 grep -i lightning +``` +Caso contrário, precisaremos instalá-lo agora. Infelizmente, se estivermos usando o Debian, precisaremos instalá-lo manualmente, compilando o código-fonte, mas ainda assim deve ser muito simples se seguirmos estas instruções. Se acontecer de estarmos em um sistema Ubuntu padrão, podemos tentar [Instalar a partir do Ubuntu ppa](#variant-install-from-ubuntu-ppa), e sempre pode tentar [Instalar os binários pré-compilados](#variant-install- binários pré-compilados). + +> :book: ***O que é a c-lightning?*** Existem três implementações diferentes da Lightning no momento: C-lightning, LND e Eclair. Todos devem ser funcionalmente compatíveis, com base nas mesmas [RFCs do BOLT](https://github.com/lightningnetwork/lightning-rfc/blob/master/00-introduction.md), mas os detalhes de implementação podem ser diferentes. Escolhemos a c-lightning como base do curso porque ela também faz parte do mesmo [Elements Project](https://github.com/ElementsProject) que também contém a Libwally. + +### Compilando o código-fonte da c-lightning + +A instalação da Lightning a partir do código-fonte deve ser bem simples se seguirmos estas instruções. + +_Provavelmente_ desejaremos fazer isso em um node não prunado, pois trabalhar com nodes prunados na Lightning pode causar problemas de instalação e uso. Se configuramos nosso node no início deste curso para ser prunado, podemos querer substituí-lo por um full node agora. Se estivermos usando a testnet, devemos conseguir usar o mesmo tipo de máquina que usamos para o node prunado. + +> :warning: **AVISO:** Realmente podemos executar o c-lightning em um node prunado. No entanto, conforme observamos no [repositório Lightning](https://github.com/ElementsProject/lightning#pruning), pode haver uma série de problemas. Para fazer isso funcionar, devemos garantir que o node da Lightning sempre tente atualizar informações sobre os blocos que o node do Bitcoin não excluiu. Para fazermos isso, devemos nos certificar de (1) que nosso node de Bitcoin está totalmente atualizado antes de iniciar nosso node da Lightning pela primeira vez e; (2) que nosso node Lightning nunca fique defasado do node do Bitcoin (para um node prunado em 550 blocos padrão, ele nunca pode ser desligado por 4 dias ou mais). Portanto, podemos usar o node assim, mas apresenta algum perigo, o que não é uma boa ideia se estivermos executando um serviço em produção. + +Dito isso, estamos prontos para instalar a Lightning: + +Primeiro, vamos instalar as dependências, incluindo requisitos de desenvolvimento. +``` +$ sudo apt-get install -y \ + autoconf automake build-essential git libtool libgmp-dev \ + libsqlite3-dev python3 python3-mako net-tools zlib1g-dev libsodium-dev \ + gettext +$ sudo apt-get install -y valgrind python3-pip libpq-dev +``` +Isso pode demorar um pouco, porque há várias dependências e algumas são bem grandes. + +Em segundo lugar, vamos clonar o repositório Lightning: +``` +$ cd ~ +$ git clone https://github.com/ElementsProject/lightning.git +$ cd lightning +``` +Agora podemos usar o `pip3` que instalamos para instalar requisitos adicionais para a compilação e posteriomente configurar tudo: +``` +$ pip3 install -r requirements.txt +$ ./configure +``` +Agora, vamos compilar. Isso pode levar algum tempo também, dependendo do processamento da nossa máquina. +``` +$ make +``` +Depois disso, o que precisamos fazer é instalar: +``` +$ sudo make install +``` + +## Verificando nossa instalação + +Podemos confirmar que tudo foi instalado o lightningd corretamente usando o parâmetro `help`: + +``` +$ lightningd --help +lightningd: WARNING: default network changing in 2020: please set network=testnet in config! +Usage: lightningd +A bitcoin lightning daemon (default values shown for network: testnet). +--conf= Specify configuration file +--lightning-dir= Set base directory: network-specific + subdirectory is under here + (default: "/home/javier/.lightning") +--network Select the network parameters (bitcoin, + testnet, regtest, litecoin or + litecoin-testnet) (default: testnet) +--testnet Alias for --network=testnet +--signet Alias for --network=signet +--mainnet Alias for --network=bitcoin +``` + +## Executar a Lightningd + +Começaremos a explorar a Lightning Network com o comando `lightning-cli`. No entanto, `lightningd` _deve_ estar rodando para podermos usar o `lightning-cli`, já que `lightning-cli` envia comandos JSON-RPC para o `lightningd` (tudo exatamente como o `bitcoin-cli` e o `bitcoind`). + +Se instalamos o `c-lightning` manualmente, precisaremos iniciá-lo: +``` +$ nohup lightningd --testnet & +``` + +### Executando o lightningd como um serviço + +Se preferirmos, podemos instalar o `lightningd` como um serviço que será executado toda vez que reiniciarmos nossa máquina. Os comandos seguintes farão isso e ele começará a funcionar imediatamente: + +``` +$ cat > ~/lightningd.service << EOF +# It is not recommended to modify this file in-place, because it will +# be overwritten during package upgrades. If you want to add further +# options or overwrite existing ones then use +# $ systemctl edit bitcoind.service +# See "man systemd.service" for details. +# Note that almost all daemon options could be specified in +# /etc/lightning/config, except for those explicitly specified as arguments +# in ExecStart= +[Unit] +Description=c-lightning daemon +[Service] +ExecStart=/usr/local/bin/lightningd --testnet +# Process management +#################### +Type=simple +PIDFile=/run/lightning/lightningd.pid +Restart=on-failure +# Directory creation and permissions +#################################### +# Run as standup +User=standup +# /run/lightningd +RuntimeDirectory=lightningd +RuntimeDirectoryMode=0710 +# Hardening measures +#################### +# Provide a private /tmp and /var/tmp. +PrivateTmp=true +# Mount /usr, /boot/ and /etc read-only for the process. +ProtectSystem=full +# Disallow the process and all of its children to gain +# new privileges through execve(). +NoNewPrivileges=true +# Use a new /dev namespace only populated with API pseudo devices +# such as /dev/null, /dev/zero and /dev/random. +PrivateDevices=true +# Deny the creation of writable and executable memory mappings. +MemoryDenyWriteExecute=true +[Install] +WantedBy=multi-user.target +EOF +$ sudo cp ~/lightningd.service /etc/systemd/system +$ sudo systemctl enable lightningd.service +$ sudo systemctl start lightningd.service +``` + +### Habilitando as conexões remotas + +Se tivermos algum tipo de firewall, precisaremos abrir a porta 9735 para permitir que outros nodes da Lightning interajam conosco. + +Se usarmos o `ufw` do Bitcoin Standup, podemos fazer da seguinte maneira: +``` +$ sudo ufw allow 9735 +``` + +## Verificando o nosso node + +Podemos verificar se o nosso node Lightning está pronto para funcionar comparando a saída de `bitcoin-cli getblockcount` com o resultado de do `blockheight` do `lightning-cli getinfo`. + +``` +$ bitcoin-cli -testnet getblockcount +1838587 +$ lightning-cli --testnet getinfo +{ + "id": "03d4592f1244cd6b5a8bb7fba6a55f8a91591d79d3ea29bf8e3c3a405d15db7bf9", + "alias": "HOPPINGNET", + "color": "03d459", + "num_peers": 0, + "num_pending_channels": 0, + "num_active_channels": 0, + "num_inactive_channels": 0, + "address": [ + { + "type": "ipv4", + "address": "74.207.240.32", + "port": 9735 + }, + { + "type": "ipv6", + "address": "2600:3c01::f03c:92ff:fe48:9ddd", + "port": 9735 + } + ], + "binding": [ + { + "type": "ipv6", + "address": "::", + "port": 9735 + }, + { + "type": "ipv4", + "address": "0.0.0.0", + "port": 9735 + } + ], + "version": "v0.9.1-96-g6f870df", + "blockheight": 1838587, + "network": "testnet", + "msatoshi_fees_collected": 0, + "fees_collected_msat": "0msat", + "lightning-dir": "/home/standup/.lightning/testnet" +} +``` +Neste caso, o `blockheight` é mostrado como `1838587` por ambos os comandos. + +Em vez disso, podemos obter um erro, dependendo da situação. + +Se o node Bitcoin ainda estiver sincronizando com a rede, devemos ver uma mensagem como esta: +``` +"warning_bitcoind_sync": "Bitcoind is not up-to-date with network." +``` +Se o nosso node Lightning não estiver atualizado, receberemos uma mensagem como esta: +``` +"warning_lightningd_sync": "Still loading latest blocks from bitcoind." +``` +Se tentarmos executar em uma blockchain prunada em que o node Bitcoin não estava atualizado quando iniciamos o node Lightning, receberemos as mensagens de erro em nosso log, parecidas como esta: +``` +bitcoin-cli -testnet getblock 0000000000000559febee77ab6e0be1b8d0bef0f971c7a4bee9785393ecef451 0 exited with status 1 +``` + +## Criando aliases + +Sugerimos a criação de alguns aliases para facilitar o uso do c-lightning. + +Podemos fazer isso colocando-os em nosso arquivo `.bash_profile`. +``` +cat >> ~/.bash_profile < :link: **TESTNET vs MAINNET:** Ao configurar nosso node, escolhemos criá-lo como um node Mainnet, Testnet ou Regtest. Embora este documento presuma uma configuração no Testenet, vale a pena entender como podemos acessar e usar os outros tipos de configuração, mesmo todos estando na mesma máquina! Mas, se formos um usuário iniciante, podemos pular esta parte, pois não é necessário para uma configuração básica. + +Quando o lightningd é inicializado, geralmente ele lê um arquivo de configuração cuja localização depende da rede que estamos usando (O padrão é: `~/.lightning/testnet/config`). Isso pode ser alterado com os sinalizadores `–conf` e `–lightning-dir`. + +``` +~/.lightning/testnet$ ls -la config +-rw-rw-r-- 1 user user 267 jul 12 17:08 config +``` +Também existe um arquivo de configuração geral (O padrão é: `~/.lightning/config`). Se desejarmos executar vários tipos diferentes de nodes simultaneamente. Devemos deixar o sinalizador testnet (ou regtest) fora deste arquivo de configuração. Devemos então escolher se estamos usando a mainnet, a testnet ou a regtest toda vez que executarmos o `lightningd` ou o `lightning-cli`. + +Nossa configuração pode não ter nenhum arquivo de configuração. O c-lightning será executado com uma boa configuração padrão, sem eles. + +## Resumo: Verificando a configuração do c-lightning + +Antes de começar a brincar com o lightning, devemos nos certificar de que nossos aliases estão configurados, nosso `lightningd` está rodando e nosso node está sincronizado. Também podemos querer configurar algum acesso a configurações alternativas da Lightning, em outras redes. + +## O Que Vem Depois? + +Vamos continuar "Compreendendo a configuração da Lightning" na seção [§18.2: Conhecendo a configuração do c-lightning](18_2_Knowing_Your_lightning_Setup.md). + +## Variante: Instalando no Ubuntu ppa + +Se estivermos usando uma versão do Ubuntu diferente do Debian, podemos instalar o c-lightning usando [Ubuntu ppa](https://launchpad.net/~lightningnetwork/+archive/ubuntu/ppa): + +``` +$ sudo apt-get install -y software-properties-common +$ sudo add-apt-repository -u ppa:lightningnetwork/ppa +$ sudo apt-get install lightningd +``` + +## Variante: Instale binários pré-compilados + +Outro método para instalar a Lightning é usar os binários pré-compilados no [repositório Github](https://github.com/ElementsProject/lightning/releases). Vamos escolher o tarball mais recente, como `clightning-v0.9.1-Ubuntu-20.04.tar.xz`. + +Depois de baixá-lo, precisaremos ir para o diretório raiz e descompactá-lo: +``` +$ cd / +$ sudo tar xf ~/clightning-v0.9.1-Ubuntu-20.04.tar.xz +``` +Aviso: Isso exigirá que tenhamos exatamente as mesmas bibliotecas que foram usadas para criar o binário. Geralmente é mais fácil apenas recompilar. \ No newline at end of file diff --git a/pt/18_2_Knowing_Your_lightning_Setup.md b/pt/18_2_Knowing_Your_lightning_Setup.md new file mode 100644 index 0000000..edb617c --- /dev/null +++ b/pt/18_2_Knowing_Your_lightning_Setup.md @@ -0,0 +1,340 @@ +# 18.2: Conhecendo a configuração do c-lightning + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Antes de começar a acessar a Lightning Network, devemos compreender melhor nossa configuração. + +## Conhecendo o diretório da c-lightning + +Ao usar o c-lightning, tudo será mantindo dentro do diretório `~/.lightning`. + +O diretório principal contém apenas os diretórios para as redes configuradas, neste caso da Testnet: +``` +$ ls ~/.lightning +testnet +``` +O diretório `~/.lightning/testnet` irá então conter a essência de nossa configuração: +``` +$ ls ~/.lightning/testnet3 +config gossip_store hsm_secret lightningd.sqlite3 lightningd.sqlite3-journal lightning-rpc +``` + +> :link: **TESTNET vs MAINNET:** Se estivermos usando a Mainnet, então _tudo_ será colocado no diretório principal `~/.lightning/bitcoin`. Essas várias configurações _empilham-se_ elegantemente, então se estivermos usando a Mainnet, Testnet e Regtest, descobriremos que `~/.lightning/bitcoin` contém os arquivos de configuração e os dados de mainnet, o diretório `~/.lightning/testnet` contém os dados da Testnet, e o diretório `~/.lightning/regtest` contém os dados Regtest. + +## Conhecendo os comandos lightning-cli + +A maior parte do nosso trabalho inicial será feito com o comando `lightning-cli`, que oferece uma interface fácil para a `lightningd`, assim como o `bitcoin-cli`. + +Já vimos que o comando `help` nos dará uma lista de outros comandos: + +``` +$ lightning-cli help +lightning-cli: WARNING: default network changing in 2020: please set network=testnet in config! +=== bitcoin === + +feerates style + Return feerate estimates, either satoshi-per-kw ({style} perkw) or satoshi-per-kb ({style} perkb). + +newaddr [addresstype] + Get a new {bech32, p2sh-segwit} (or all) address to fund a channel (default is bech32) + +reserveinputs outputs [feerate] [minconf] [utxos] + Reserve inputs and pass back the resulting psbt + +sendpsbt psbt + Finalize, extract and send a PSBT. + +signpsbt psbt + Sign this wallet's inputs on a provided PSBT. + +txdiscard txid + Abandon a transaction created by txprepare + +txprepare outputs [feerate] [minconf] [utxos] + Create a transaction, with option to spend in future (either txsend and txdiscard) + +txsend txid + Sign and broadcast a transaction created by txprepare + +unreserveinputs psbt + Unreserve inputs, freeing them up to be reused + +withdraw destination satoshi [feerate] [minconf] [utxos] + Send to {destination} address {satoshi} (or 'all') amount via Bitcoin transaction, at optional {feerate} + +=== channels === + +close id [unilateraltimeout] [destination] [fee_negotiation_step] + Close the channel with {id} (either peer ID, channel ID, or short channel ID). Force a unilateral close after {unilateraltimeout} seconds (default 48h). If {destination} address is provided, will be used as output address. + +fundchannel_cancel id + Cancel inflight channel establishment with peer {id}. + +fundchannel_complete id txid txout + Complete channel establishment with peer {id} for funding transactionwith {txid}. Returns true on success, false otherwise. + +fundchannel_start id amount [feerate] [announce] [close_to] [push_msat] + Start fund channel with {id} using {amount} satoshis. Returns a bech32 address to use as an output for a funding transaction. + +getroute id msatoshi riskfactor [cltv] [fromid] [fuzzpercent] [exclude] [maxhops] + Show route to {id} for {msatoshi}, using {riskfactor} and optional {cltv} (default 9). If specified search from {fromid} otherwise use this node as source. Randomize the route with up to {fuzzpercent} (default 5.0). {exclude} an array of short-channel-id/direction (e.g. [ '564334x877x1/0', '564195x1292x0/1' ]) or node-id from consideration. Set the {maxhops} the route can take (default 20). + +listchannels [short_channel_id] [source] + Show channel {short_channel_id} or {source} (or all known channels, if not specified) + +listforwards + List all forwarded payments and their information + +setchannelfee id [base] [ppm] + Sets specific routing fees for channel with {id} (either peer ID, channel ID, short channel ID or 'all'). Routing fees are defined by a fixed {base} (msat) and a {ppm} (proportional per millionth) value. If values for {base} or {ppm} are left out, defaults will be used. {base} can also be defined in other units, for example '1sat'. If {id} is 'all', the fees will be applied for all channels. + +=== network === + +connect id [host] [port] + Connect to {id} at {host} (which can end in ':port' if not default). {id} can also be of the form id@host + +disconnect id [force] + Disconnect from {id} that has previously been connected to using connect; with {force} set, even if it has a current channel + +listnodes [id] + Show node {id} (or all, if no {id}), in our local network view + +listpeers [id] [level] + Show current peers, if {level} is set, include logs for {id} + +ping id [len] [pongbytes] + Send peer {id} a ping of length {len} (default 128) asking for {pongbytes} (default 128) + +=== payment === + +createonion hops assocdata [session_key] + Create an onion going through the provided nodes, each with its own payload + +decodepay bolt11 [description] + Decode {bolt11}, using {description} if necessary + +delexpiredinvoice [maxexpirytime] + Delete all expired invoices that expired as of given {maxexpirytime} (a UNIX epoch time), or all expired invoices if not specified + +delinvoice label status + Delete unpaid invoice {label} with {status} + +invoice msatoshi label description [expiry] [fallbacks] [preimage] [exposeprivatechannels] + Create an invoice for {msatoshi} with {label} and {description} with optional {expiry} seconds (default 1 week), optional {fallbacks} address list(default empty list) and optional {preimage} (default autogenerated) + +listinvoices [label] + Show invoice {label} (or all, if no {label}) + +listsendpays [bolt11] [payment_hash] + Show sendpay, old and current, optionally limiting to {bolt11} or {payment_hash}. + +listtransactions + List transactions that we stored in the wallet + +sendonion onion first_hop payment_hash [label] [shared_secrets] [partid] + Send a payment with a pre-computed onion. + +sendpay route payment_hash [label] [msatoshi] [bolt11] [payment_secret] [partid] + Send along {route} in return for preimage of {payment_hash} + +waitanyinvoice [lastpay_index] [timeout] + Wait for the next invoice to be paid, after {lastpay_index} (if supplied). If {timeout} seconds is reached while waiting, fail with an error. + +waitinvoice label + Wait for an incoming payment matching the invoice with {label}, or if the invoice expires + +waitsendpay payment_hash [timeout] [partid] + Wait for payment attempt on {payment_hash} to succeed or fail, but only up to {timeout} seconds. + +=== plugin === + +autocleaninvoice [cycle_seconds] [expired_by] + Set up autoclean of expired invoices. + +estimatefees + Get the urgent, normal and slow Bitcoin feerates as sat/kVB. + +fundchannel id amount [feerate] [announce] [minconf] [utxos] [push_msat] + Fund channel with {id} using {amount} (or 'all'), at optional {feerate}. Only use outputs that have {minconf} confirmations. + +getchaininfo + Get the chain id, the header count, the block count, and whether this is IBD. + +getrawblockbyheight height + Get the bitcoin block at a given height + +getutxout txid vout + Get informations about an output, identified by a {txid} an a {vout} + +listpays [bolt11] + List result of payment {bolt11}, or all + +pay bolt11 [msatoshi] [label] [riskfactor] [maxfeepercent] [retry_for] [maxdelay] [exemptfee] + Send payment specified by {bolt11} with {amount} + +paystatus [bolt11] + Detail status of attempts to pay {bolt11}, or all + +plugin subcommand=start|stop|startdir|rescan|list + Control plugins (start, stop, startdir, rescan, list) + +sendrawtransaction tx + Send a raw transaction to the Bitcoin network. + +=== utility === + +check command_to_check + Don't run {command_to_check}, just verify parameters. + +checkmessage message zbase [pubkey] + Verify a digital signature {zbase} of {message} signed with {pubkey} + +getinfo + Show information about this node + +getlog [level] + Show logs, with optional log {level} (info|unusual|debug|io) + +getsharedsecret point + Compute the hash of the Elliptic Curve Diffie Hellman shared secret point from this node private key and an input {point}. + +help [command] + List available commands, or give verbose help on one {command}. + +listconfigs [config] + List all configuration options, or with [config], just that one. + +listfunds + Show available funds from the internal wallet + +signmessage message + Create a digital signature of {message} + +stop + Shut down the lightningd process + +waitblockheight blockheight [timeout] + Wait for the blockchain to reach {blockheight}, up to {timeout} seconds. + +=== developer === + +dev-listaddrs [bip32_max_index] + Show addresses list up to derivation {index} (default is the last bip32 index) + +dev-rescan-outputs + Synchronize the state of our funds with bitcoind + +--- +run `lightning-cli help ` for more information on a specific command +``` + +## Conhecendo as informações de Lightning + +Uma variedade de comandos `lightning-cli` podem fornecer informações adicionais sobre nosso node Lightning. Os mais comuns são: +``` +$ lightning-cli --testnet listconfigs +$ lightning-cli --testnet listfunds +$ lightning-cli --testnet listtransactions +$ lightning-cli --testnet listinvoices +$ lightning-cli --testnet listnodes +``` +* listconfigs: O comando RPC `listconfigs` lista todas as opções de configuração; +* listfunds: O comando RPC `listfunds` exibe todos os fundos disponíveis, seja em saídas não gastas (UTXOs) na carteira interna ou fundos bloqueados em canais abertos no momento; +* listtransactions: O comando RPC `listtransactions` retorna as transações rastreadas na carteira. Isso inclui depósitos, retiradas e transações relacionadas a canais; +* listinvoices: O comando RPC `listinvoices` recupera o status de um invoice específico, se houver, ou o status de todos os invoices, se não houver nenhum argumento; +* listnodes: O comando RPC `listnodes` retorna nodes que nosso servidor aprendeu através da comunicação com outros nodes, ou um específico se o id do node foi informado. + +Por exemplo, `lightning-cli listconfigs` fornece uma variedade de informações sobre nossa configuração: + +``` +c$ lightning-cli --testnet listconfigs +{ + "# version": "v0.8.2-398-g869fa08", + "lightning-dir": "/home/standup/.lightning", + "network": "testnet", + "allow-deprecated-apis": true, + "rpc-file": "lightning-rpc", + "plugin": "/usr/local/bin/../libexec/c-lightning/plugins/fundchannel", + "plugin": "/usr/local/bin/../libexec/c-lightning/plugins/autoclean", + "plugin": "/usr/local/bin/../libexec/c-lightning/plugins/bcli", + "plugin": "/usr/local/bin/../libexec/c-lightning/plugins/pay", + "plugin": "/usr/local/bin/../libexec/c-lightning/plugins/keysend", + "plugins": [ + { + "path": "/usr/local/bin/../libexec/c-lightning/plugins/fundchannel", + "name": "fundchannel" + }, + { + "path": "/usr/local/bin/../libexec/c-lightning/plugins/autoclean", + "name": "autoclean", + "options": { + "autocleaninvoice-cycle": null, + "autocleaninvoice-expired-by": null + } + }, + { + "path": "/usr/local/bin/../libexec/c-lightning/plugins/bcli", + "name": "bcli", + "options": { + "bitcoin-datadir": null, + "bitcoin-cli": null, + "bitcoin-rpcuser": null, + "bitcoin-rpcpassword": null, + "bitcoin-rpcconnect": null, + "bitcoin-rpcport": null, + "bitcoin-retry-timeout": null, + "commit-fee": "500" + } + }, + { + "path": "/usr/local/bin/../libexec/c-lightning/plugins/pay", + "name": "pay" + }, + { + "path": "/usr/local/bin/../libexec/c-lightning/plugins/keysend", + "name": "keysend" + } + ], + "disable-plugin": [], + "always-use-proxy": false, + "daemon": "false", + "wallet": "sqlite3:///home/user/.lightning/testnet/lightningd.sqlite3", + "wumbo": false, + "wumbo": false, + "rgb": "03fce2", + "alias": "learningBitcoin", + "pid-file": "/home/user/.lightning/lightningd-testnet.pid", + "ignore-fee-limits": false, + "watchtime-blocks": 144, + "max-locktime-blocks": 720, + "funding-confirms": 3, + "commit-fee-min": 200, + "commit-fee-max": 2000, + "cltv-delta": 6, + "cltv-final": 10, + "commit-time": 10, + "fee-base": 1, + "rescan": 15, + "fee-per-satoshi": 10, + "max-concurrent-htlcs": 483, + "min-capacity-sat": 10000, + "offline": "false", + "autolisten": true, + "disable-dns": "false", + "enable-autotor-v2-mode": "false", + "encrypted-hsm": false, + "rpc-file-mode": "0600", + "log-level": "DEBUG", + "log-prefix": "lightningd" +} +``` + +## Resumo: Conhecendo a configuração do c-lightning + +O diretório `~/.lightning` contém todos os arquivos, enquanto o comando `lightning-cli help` mostra uma variedade de informações dos comandos que podem ser usados para obter mais informações sobre nossa configuração e funcionamento da Lightning Network. + +## O Que Vem Depois? + +Precisaremos de um segundo node para testar o pagamento dos invoices. Se precisaremos de suporte para configurar um, podemos ler o [Adendo: Acessando um segundo node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md). + +Caso contrário, vamos continuar "Compreendendo sua configuração do Lightning" na seção [§18.3: Criando um canal na Lightning](18_3_Setting_Up_a_Channel.md). \ No newline at end of file diff --git a/pt/18_2__Interlude_Accessing_a_Second_Lightning_Node.md b/pt/18_2__Interlude_Accessing_a_Second_Lightning_Node.md new file mode 100644 index 0000000..cccd6ea --- /dev/null +++ b/pt/18_2__Interlude_Accessing_a_Second_Lightning_Node.md @@ -0,0 +1,326 @@ +# Adendo: Acessando um segundo node Lightning + +> :information_source: ** NOTA: ** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Quando estávamos brincando com o Bitcoin, estávamos acessando uma rede existente, e isso torna tudo relativamente fácil para se trabalhar. Apenas ligávamos o `bitcoind` e estávamos imediatamente interagindo com a rede. Agora, é assim que a Lightning funciona: É fundamentalmente uma rede ponto a ponto, construída a partir das conexões entre dois nodes individuais. Em outras palavras, para interagir com a Lightning Network, precisaremos primeiro encontrar um node ao qual podemos nos conectar. + +Existem quatro maneiras de fazermos isso, as três primeiras são possíveis para a nossa primeira conexão: + +## Pedindo informações sobre um node + +Se outra pessoa já tiver um node da Lightning Network na rede que escolhemos, podemos pedir o ID dele. + +Se estiverem executando o c-lightning, eles só precisam usar o comando `getinfo`: +``` +$ lightning-cli getinfo +lightning-cli: WARNING: default network changing in 2020: please set network=testnet in config! + "id": "03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687", + "alias": "VIOLETGLEE", + "color": "03240a", + "num_peers": 0, + "num_pending_channels": 0, + "num_active_channels": 0, + "num_inactive_channels": 0, + "address": [ + { + "type": "ipv4", + "address": "74.207.240.32", + "port": 9735 + } + ], + "binding": [ + { + "type": "ipv6", + "address": "::", + "port": 9735 + }, + { + "type": "ipv4", + "address": "0.0.0.0", + "port": 9735 + } + ], + "version": "v0.9.1-96-g6f870df", + "blockheight": 1862854, + "network": "testnet", + "msatoshi_fees_collected": 0, + "fees_collected_msat": "0msat", + "lightning-dir": "/home/standup/.lightning/testnet" +} +``` +Eles podem então poderão nos dizer o `ID` (`03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687`). Eles também precisarão informar o endereço IP (`74.207.240.32`) e porta (`9735`). + +## Criando um novo node c-lightning + +No entanto, para fins de teste, provavelmente iremos desejar ter um segundo node sob nosso próprio controle. A maneira mais fácil de fazer isso é criar um segundo node c-lightning em uma nova máquina, usando Bitcoin Standup, de acordo com a seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) ou compilando-o manualmente, de acordo com a seção [§18.1](18_1_Verifying_Your_Lightning_Setup .md). + +Depois de ter nosso node em execução, podemos executar o `getinfo` para recuperar nossas informações, como mostrado acima. + +## Criando um novo node LND + +No entanto, para nossos exemplos no próximo capítulo, vamos criar um node LND. Isso nos permitirá demonstrar um pouco da profundidade do ecossistema Lightning, mostrando como comandos semelhantes funcionam nas duas plataformas diferentes. + +Uma maneira de criar um node LND é executar os scripts Bitcoin Standup novamente em uma nova máquina, mas desta vez escolher a LND, de acordo com a seção [§2.1](2_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md). + +Outra forma é compilar o LND a partir do código-fonte em uma máquina em que já estejamos executando um node Bitcoin, como falaremos abaixo. + +### Compilando o código-fonte LND + +Primeiro, precisaremos baixar e instalar o Go: +``` +$ wget --progress=bar:force https://dl.google.com/go/"go1.14.4"."linux"-"amd64".tar.gz -O ~standup/"go1.14.4"."linux"-"amd64".tar.gz +$ /bin/tar xzf ~standup/"go1.14.4"."linux"-"amd64".tar.gz -C ~standup +$ sudo mv ~standup/go /usr/local +``` +Depois, precisamos nos certificar de que a versão Go é a mais atualizada (atualmente é a `go1.14.4`), e a plataforma e arquitetura são adequadas para nossa máquina. O item acima funcionará para o Debian. + +Vamos atulizar o caminho: +``` +$ export GOPATH=~standup/gocode +$ export PATH="$PATH":/usr/local/go/bin:"$GOPATH"/bin +``` +Em seguida, vamos nos certificar de que o `go` funciona: +``` +$ go version +go version go1.14.4 linux/amd64 +``` +Também precisaremos do `git` e do `make`: +``` +$ sudo apt-get install git +$ sudo apt-get install build-essential +``` +Agora estamos pronto para recuperar o LND. Certifique-se de obter a versão atual (no momento, é a `v0.11.0-beta.rc4`). +``` +$ go get -d github.com/lightningnetwork/lnd +``` +E agora podemos compilar: +``` +$ cd "$GOPATH"/src/github.com/lightningnetwork/lnd +$ git checkout v0.11.0-beta.rc4 +$ make +$ make install +``` +Os comandos acima irão instalar o Go na pasta `~/gocode/bin`, que é o `$GOPATH/bin`. + +Devemos alterá-la para os diretórios globais: +``` +$ sudo cp $GOPATH/bin/lnd $GOPATH/bin/lncli /usr/bin +``` + +### Criando um arquivo de configuração LND + +Ao contrário do c-lightning, precisaremos criar um arquivo de configuração padrão para o LND. + +No entanto, primeiro, iremos precisar habilitar o ZMQ em nosso Bitcoind, se ainda não o fizemos na seção [§15.3](15_3_Receiving_Bitcoind_Notifications_with_C.md). + +Isso requer adicionar o seguinte ao nosso arquivo `~/.bitcoin/bitcoin.conf` se ainda não estiver lá: +``` +zmqpubrawblock=tcp://127.0.0.1:28332 +zmqpubrawtx=tcp://127.0.0.1:28333 +``` + +Se estivermos usando um arquivo de configuração Bitcoin do Standup ou algum outro `conf` especializado, precisamos nos certificar de colocar nossos novos comandos na seção correta. Idealmente, devemos chegar perto do topo do arquivo, caso contrário, na seção `[test]` (assumindo, como de costume, que estamos testando na testnet). + +Devemos então, reiniciar o bitcoin (ou apenas reiniciar nossa máquina). Podemos testar se está tudo funcionando da seguinte maneira: +``` +$ bitcoin-cli getzmqnotifications +[ + { + "type": "pubrawblock", + "address": "tcp://127.0.0.1:28332", + "hwm": 1000 + }, + { + "type": "pubrawtx", + "address": "tcp://127.0.0.1:28333", + "hwm": 1000 + } +] +``` +Agora estamos prontos para criar um arquivo de configuração. + +Primeiro, precisamos recuperar nosso rpcuser e rpcpassword. Esta é uma maneira automatizada de fazer isso: +``` +$ BITCOINRPC_USER=$(cat ~standup/.bitcoin/bitcoin.conf | grep rpcuser | awk -F = '{print $2}') +$ BITCOINRPC_PASS=$(cat ~standup/.bitcoin/bitcoin.conf | grep rpcpassword | awk -F = '{print $2}') +``` + +> :warning: **AVISO:** Obviamente, nunca iremos armazenar nossa senha RPC em uma variável shell em um ambiente de produção. + +Em seguida, podemos gravar o arquivo: +``` +$ mkdir ~/.lnd +$ cat > ~/.lnd/lnd.conf << EOF +[Application Options] +maxlogfiles=3 +maxlogfilesize=10 +#externalip=1.1.1.1 # change to your public IP address if required. +alias=StandUp +listen=0.0.0.0:9735 +debuglevel=debug +[Bitcoin] +bitcoin.active=1 +bitcoin.node=bitcoind +bitcoin.testnet=true +[Bitcoind] +bitcoind.rpchost=localhost +bitcoind.rpcuser=$BITCOINRPC_USER +bitcoind.rpcpass=$BITCOINRPC_PASS +bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 +bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 +EOF +``` + +### Criando um serviço LND + +Finalmente, podemos criar um serviço LND para executar automaticamente o `lnd`: +``` +$ cat > ~/lnd.service << EOF +# It is not recommended to modify this file in-place, because it will +# be overwritten during package upgrades. If you want to add further +# options or overwrite existing ones then use +# $ systemctl edit lnd.service +# See "man systemd.service" for details. +# Note that almost all daemon options could be specified in +# /etc/lnd/lnd.conf, except for those explicitly specified as arguments +# in ExecStart= +[Unit] +Description=LND Lightning Network Daemon +Requires=bitcoind.service +After=bitcoind.service +[Service] +ExecStart=/usr/bin/lnd +ExecStop=/usr/bin/lncli --lnddir /var/lib/lnd stop +PIDFile=/run/lnd/lnd.pid +User=standup +Type=simple +KillMode=process +TimeoutStartSec=60 +TimeoutStopSec=60 +Restart=always +RestartSec=60 +[Install] +WantedBy=multi-user.target +EOF +``` +Em seguida, precisaremos instalar isso e iniciar as coisas: +``` +$ sudo cp ~/lnd.service /etc/systemd/system +$ sudo systemctl enable lnd +$ sudo systemctl start lnd +``` +É esperado que a primeira vez demore um tempo para a inicialização. + +### Habilitando as conexões remotas + +Assim como com o c-lightning, precisaremos tornar o LND acessível a outros nodes. Veja como fazer isso se usarmos o `ufw`, de acordo com as configurações do Bitcoin Standup: +``` +$ sudo ufw allow 9735 +``` + +### Criando uma carteira + +Na primeira vez que executamos o LND, devemos criar uma carteira: +``` +$ lncli --network=testnet create +``` +O LND pedirá uma senha e, em seguida, nos perguntará se desejaremos inserir um mnemônico existente (basta pressionar `n` para o último). + +Agora devemos ter um `lnd` funcionando, que pode ser verificado com o comando `getinfo`: +``` +$ lncli --network=testnet getinfo +{ + "version": "0.11.0-beta.rc4 commit=v0.11.0-beta.rc4", + "commit_hash": "fc12656a1a62e5d69430bba6e4feb8cfbaf21542", + "identity_pubkey": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "alias": "StandUp", + "color": "#3399ff", + "num_pending_channels": 0, + "num_active_channels": 0, + "num_inactive_channels": 0, + "num_peers": 2, + "block_height": 1862848, + "block_hash": "000000000000000ecb6fd95e1f486283d48683aa3111b6c23144a2056f5a1532", + "best_header_timestamp": "1602632294", + "synced_to_chain": true, + "synced_to_graph": false, + "testnet": true, + "chains": [ + { + "chain": "bitcoin", + "network": "testnet" + } + ], + "uris": [ + ], + "features": { + "0": { + "name": "data-loss-protect", + "is_required": true, + "is_known": true + }, + "5": { + "name": "upfront-shutdown-script", + "is_required": false, + "is_known": true + }, + "7": { + "name": "gossip-queries", + "is_required": false, + "is_known": true + }, + "9": { + "name": "tlv-onion", + "is_required": false, + "is_known": true + }, + "13": { + "name": "static-remote-key", + "is_required": false, + "is_known": true + }, + "15": { + "name": "payment-addr", + "is_required": false, + "is_known": true + }, + "17": { + "name": "multi-path-payments", + "is_required": false, + "is_known": true + } + } +} +``` +O ID deste node é `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543`. Embora este comando não mostre o endereço IP e a porta, eles devem ser o endereço IP da nossa máquina e a porta `9735`. + +## Ouvindo a Lightning + +Se já estivermos conectados à Lightning Network, nosso node já deve estar "fofocando" com seus pares, também já pode ser capaz de encontrar informações sobre os pares automaticamente, por meio do comando `listpeers`: +``` +c$ lightning-cli --network=testnet listpeers +{ + "peers": [ + { + "id": "0302d48972ba7eef8b40696102ad114090fd4c146e381f18c7932a2a1d73566f84", + "connected": true, + "netaddr": [ + "127.0.0.1:9736" + ], + "features": "02a2a1", + "channels": [] + } + ] +} +``` +No entanto, esse definitivamente não será o caso da nossa primeira interação com a Lightning Network. + +## Resumo: Adendo: Acessando um segundo node Lightning + +Sempre precisaremos de dois nodes Lightning para formar um canal. Se não tivermos outra pessoa que está testando as coisas conosco, precisaremos criar um segundo node, usando c-lightning ou (como faremos em nossos exemplos) usando a LND. + +## O Que Vem Depois? + +Embora possivelmente tenhamos criado um LND, o c-lightning permanecerá o coração dos nossos exemplos até que precisemos começar a usar os dois, no [Capítulo 19](19_0_Understanding_Your_Lightning_Setup.md). + +Vamos continuar "Compreendendo a configuração da Lightning" na seção [§18.3: Criando um canal na Lightning](18_3_Setting_Up_a_Channel.md). diff --git a/pt/18_3_Setting_Up_a_Channel.md b/pt/18_3_Setting_Up_a_Channel.md new file mode 100644 index 0000000..b193b06 --- /dev/null +++ b/pt/18_3_Setting_Up_a_Channel.md @@ -0,0 +1,185 @@ +# 18.3: Criando um canal na Lightning + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Agora que entendemos o básico da configuração da Lightning e, com sorte, já criamos ou recebemos informações sobre um segundo node Lightning. Estamos prontos para criar nosso primeiro canal na Lightning Network. Claro, precisaremos entender o que é e como é criado usando o c-lightning. + +> :book: ***O que é um canal Lightning?*** De maneira simples, um canal Lightning é um tubo de dinheiro que permite transferências rápidas, baratas e privadas sem enviar transações para a blockchain. Mais tecnicamente, um canal é uma transação de Bitcoin em cadeia com várias assinaturas 2 de 2 que estabelece um relacionamento financeiro sem confiança entre duas pessoas ou dois agentes. Uma certa quantia de dinheiro é depositada no canal, quando então se mantém um banco de dados local com saldo em bitcoins para ambas as partes, mantendo o registro de qual é o saldo de cada parte. Os dois usuários podem então trocar bitcoins por meio do canal Lightning sem nunca escrever na blockchain do Bitcoin. Somente quando desejam fechar o canal, eles liquidam os bitcoins na blockchain, com base no saldo final das moedas. + +> :book: ***Como os canais Lightning criam uma rede Lightning?*** Embora um canal Lightning só permita o pagamento entre dois usuários, os canais podem ser conectados para formar uma rede que permite pagamentos entre membros que não têm um canal direto entre eles. Isso cria uma rede entre várias pessoas, construída a partir de conexões em pares. + +Nesta seção, continuaremos usando nossa configuração c-lightning como nosso node principal. + +## Criando um canal + +A criação de um canal Lightning requer as seguintes etapas: + +* Financiar nossa carteira c-lightning com alguns satoshis; +* Conectar-se a um nó remoto como um par; +* Abrir um canal. + +### Financiando nossa carteira c-lightning + +Para mover fundos para um canal Lightning, primeiro é necessário financiar nossa carteira c-lightning. + +> :book: ***O que é uma carteira c-lightning?*** A implementação padrão a c-lightning vem com uma carteira Bitcoin integrada que permite enviar e receber transações bitcoin na blockchain. Esta carteira será usada para criar novos canais. + +A primeira coisa que precisamos fazer é enviar alguns satoshis para nossa carteira c-lightning. Podemos criar um novo endereço usando o comando `lightning-cli newaddr`. Isso gera um novo endereço que pode ser subsequentemente usado para financiar canais gerenciados pelo node c-lightning. Podemos especificar o tipo de endereço desejado. Se não for especificado, o endereço gerado será um bech32. + +``` +$ lightning-cli --testnet newaddr +{ + "address": "tb1qefule33u7ukfuzkmxpz02kwejl8j8dt5jpgtu6", + "bech32": "tb1qefule33u7ukfuzkmxpz02kwejl8j8dt5jpgtu6" +} +``` +Podemos então enviar fundos para este endereço usando `bitcoin-cli sendtoaddress` (ou qualquer outro método de preferência). Para este exemplo, fizemos o envio que pode ser observado na transação [11094bb9ac29ce5af9f1e5a0e4aac2066ae132f25b72bff90fcddf64bf2feb02](https://mempool.space/pt/testnet/tx/11094bb9ac29ce5af9f1e5a0e4aac2066ae132f25b72bff90fcddf64bf2feb02). + +Esta transação é chamada de [transação de financiamento](https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#funding-transaction-output) e precisa ser confirmada antes que os fundos possam ser utilizados. + +> :book: ***O que é uma transação de financiamento?*** Uma transação de financiamento é uma transação de Bitcoin que coloca dinheiro em um canal Lightning. Pode ser de financiamento único (por um participante) ou de financiamento duplo (por ambos). A partir daí, as transações da Lightning tratam de realocar a propriedade da transação de financiamento, mas só se ajustam na blockchain quando o canal é fechado. + +Para verificar nosso saldo local, devemos usar o comando `lightning-cli listfunds`: + +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [], + "channels": [] +} +``` + +Como os fundos ainda não têm seis confirmações, não há saldo disponível. Após seis confirmações, devemos ver o saldo alterado: +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "11094bb9ac29ce5af9f1e5a0e4aac2066ae132f25b72bff90fcddf64bf2feb02", + "output": 0, + "value": 300000, + "amount_msat": "300000000msat", + "scriptpubkey": "0014ca79fcc63cf72c9e0adb3044f559d997cf23b574", + "address": "tb1qefule33u7ukfuzkmxpz02kwejl8j8dt5jpgtu6", + "status": "confirmed", + "blockheight": 1780680, + "reserved": false + } + ], + "channels": [] +} + +``` +Observe que o valor está listado em satoshis ou microsatoshis, não em Bitcoin! + +> :book: ***O que são satoshis e msats?*** Já conhecemos os satoshis na seção [§3.4](03_4_Receiving_a_Transaction.md). Um satoshi é o centésimo milionésimo de um bitcoin, então 300.000 satoshis equivalem a 0,003 BTC. Um satoshi é a menor unidade monetária na rede Bitcoin. Mas, a rede Lightning pode ser menor, então 1.000 msat, ou milisatoshis, equivalem a um satoshi. Isso significa que 1 msat é o centésimo bilionésimo de um bitcoin e 300.000.000 msat equivalem a 0,003 BTC. + +Agora que financiamos nossa carteira c-lightning, precisaremos de informações sobre um node remoto para começar a criar o processo do canal. + +### Conectando a um node Remoto + +A próxima coisa que precisaremos fazer é conectar nosso node a um par. Isso é feito com o comando `lightning-cli connect`. Lembre-se que se quisermos mais informações sobre este comando, devemos digitar `lightning-cli help connect`. + +Para conectar nosso nodes a um par remoto, precisaremos do nosso id, que representa a chave pública do node de destino. Por conveniência, o `ID` pode ter a forma `id@host` ou `id@host:port`. Podemos ter recuperado isso com o `lightning-cli getinfo` (no c-lightning) ou `lncli --network=testnet getinfo` (no LND) conforme discutido no [adendo anterior](18_2__Interlude_Accessing_a_Second_Lightning_Node.md). + +Selecionamos o node LND, `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543`, que está localizado no endereço IP `45.33.35.151`, ao qual vamos nos conectar a partir de nosso node c-lightning: + +``` +$ lightning-cli --network=testnet connect 032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543@45.33.35.151 +{ + "id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "features": "02a2a1" +} +``` + +### Abrindo um canal + +O comando fundchannel do RPC abre um canal de pagamento com um par ao comprometer uma transação de financiamento para o blockchain. Devemos usar o comando `lightning-cli fundchannel` para fazer isso, com os seguintes parâmetros: + +* **id** é o retorno do id do peer da conexão; +* **amount** é o valor em satoshis retirado da carteira interna para financiar o canal. O valor não pode ser inferior ao limite mínimo, atualmente definido como 546 satoshis, nem superior a 16.777.215 satoshis (a menos que grandes canais tenham sido negociados com o par). +* **feerate** é o feerate opcional usado para a transação de abertura e como feerate inicial para transações de confirmação e HTLC. +* **announce** é um sinalizador opcional que aciona o anúncio deste canal ou não. O padrão é verdadeiro. Se desejarmos criar um canal privado, precisamos definí-lo como falso. +* **minconf** especifica o número mínimo de confirmações que devem ter saídas usadas no processo de abertura de canal. O padrão é 1. +* **utxos** especifica os utxos a serem usados ​​para financiar o canal, como uma matriz de “txid:vout”. + +Agora podemos abrir o canal assim: + +``` +$ lightning-cli --testnet fundchannel 032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543 100000 urgent true 1 +{ + "tx": "0200000000010193dc3337837f091718f47b71f2eae8b745ec307231471f6a6aab953c3ea0e3b50100000000fdffffff02a0860100000000002200202e30365fe321a435e5f66962492163302f118c13e215ea8928de88cc46666c1d07860100000000001600142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c024730440220668a7c253c9fd83fc1b45e4a52823fb6bc5fad30da36240d4604f0d6981a6f4502202aeb1da5fbbc8790791ef72b3378005fe98d485d22ffeb35e54a6fbc73178fb2012103b3efe051712e9fa6d90008186e96320491cfe1ef1922d74af5bc6d3307843327c76c1c00", + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "channel_id": "1d3cf2126ae36e12be3aee893b385ed6a2e19b1da7f4e579e3ef15ca234d6966", + "outnum": 0 +} +``` +Para confirmar o status do canal, vamos usar o comando `lightning-cli listfunds`: + +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "unconfirmed", + "reserved": false + }, + { + "txid": "b5e3a03e3c95ab6a6a1f47317230ec45b7e8eaf2717bf41817097f833733dc93", + "output": 1, + "value": 200000, + "amount_msat": "200000000msat", + "scriptpubkey": "0014ed54b65eae3da99b23a48bf8827c9acd78079469", + "address": "tb1qa42tvh4w8k5ekgay30ugyly6e4uq09rfpqf9md", + "status": "confirmed", + "blockheight": 1862831, + "reserved": true + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": true, + "state": "CHANNELD_AWAITING_LOCKIN", + "channel_sat": 100000, + "our_amount_msat": "100000000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} + +``` +Embora este novo canal com 100.000 satoshis não esteja confirmado, nosso estado será `CHANNELD_AWAITING_LOCKIN`. Observe que a alteração não confirmada de satoshis `99847` também está aparecendo como uma nova transação na carteira. Depois que todas as seis confirmações forem concluídas, o canal mudará para o estado `CHANNELD_NORMAL`, que será o estado permanente. Nesse momento, um `short_channel_id` também aparecerá, como: +``` +"short_channel_id": "1862856x29x0", +``` +Esses valores indicam onde a transação de financiamento pode ser encontrada na blockchain. Ele aparece na forma `bloco x txid x vout`. + +Neste caso, `1862856x29x0` significa: + +* Criado no bloco 1862856; +* Com um `txid` de 29 e; +* Um `vout` de 0. + +Podemos precisar usar este `short_channel_id` para certos comandos na Lightning. + +Esta transação de financiamento também pode ser encontrada onchain pelo TXID [66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d] (https://mempool.space/pt/testnet/tx/66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d) + +> :book: ***O que é a capacidade do canal?*** Em um canal Lightning, ambos os lados do canal possuem uma parte da capacidade. O valor do lado do canal é chamado de *saldo local (local balance)* e o valor do outro lado é chamado de *saldo remoto (remote balance)*. Ambos os saldos podem ser atualizados muitas vezes sem fechar o canal (quando o saldo final é enviado para a blockchain), mas a capacidade do canal não pode mudar sem fechá-lo. A capacidade total de um canal é a soma do saldo de cada participante do canal. + +## Resumo: Criando um canal na Lightning + +Precisaremos criar um canal com um node remoto para poder receber e enviar dinheiro pela Lightning Network. + +## O Que Vem Depois? + +Você está pronto para passar para o [Capítulo 19: Usando Lightning](19_0_Using_Lightning.md). \ No newline at end of file From e537667287abf1d1618df1a8a0ccf13b79e77626 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Mon, 9 Aug 2021 11:30:39 -0300 Subject: [PATCH 061/155] Chapter19 translation concluded --- 19_0_Using_Lightning.md | 27 +++ pt/19_0_Using_Lightning.md | 25 +++ pt/19_1_Generate_a_Payment_Request.md | 184 ++++++++++++++++++ pt/19_2_Paying_a_Invoice.md | 206 ++++++++++++++++++++ pt/19_3_Closing_a_Channel.md | 259 ++++++++++++++++++++++++++ pt/19_4_Lightning_Network_Review.md | 60 ++++++ 6 files changed, 761 insertions(+) create mode 100644 pt/19_0_Using_Lightning.md create mode 100644 pt/19_1_Generate_a_Payment_Request.md create mode 100644 pt/19_2_Paying_a_Invoice.md create mode 100644 pt/19_3_Closing_a_Channel.md create mode 100644 pt/19_4_Lightning_Network_Review.md diff --git a/19_0_Using_Lightning.md b/19_0_Using_Lightning.md index 04ef4c3..008cb7c 100644 --- a/19_0_Using_Lightning.md +++ b/19_0_Using_Lightning.md @@ -23,3 +23,30 @@ Supporting objectives include the ability to: * [Section Two: Paying an Invoice](19_2_Paying_a_Invoice.md) * [Section Three: Closing a Lightning Channel](19_3_Closing_a_Channel.md) * [Section Four: Expanding the Lightning Network](19_4_Lightning_Network_Review.md) + + +# Capítulo dezenove: usando um raio + +>: Informação_Source: ** Nota: ** Este é um rascunho em andamento, para que eu possa obter algum feedback dos iniciantes. Ainda não está pronto para aprender. + +Neste capítulo, você continuará trabalhando com a interface de linha de comando "Lightning-Cli` Você criará faturas, executará pagamentos e canais fechados - todas as principais atividades para usar o Lightning. + +## Objetivos para este capítulo + +Depois de trabalhar através deste capítulo, um desenvolvedor será capaz de: + + * Execute pagamentos na rede relâmpago. + * Aplique o fechamento para um canal de relâmpago. + +Objetivos de apoio incluem a capacidade de: + + * Compreender o formato das faturas. + * Entenda o ciclo de vida dos pagamentos de rede de raios. + * Saber como expandir a rede relâmpago. + +## Índice + +* [Seção One: Gerando uma solicitação de pagamento] (19_1_Generate_A_Payment_Request.md) +* [Seção dois: pagando uma fatura] (19_2_Paying_a_invoice.md) +* [Seção três: fechando um canal de raio] (19_3_closing_a_channel.md) +* [Seção Quatro: Expandindo a rede Lightning] (19_4_lightning_network_review.md) \ No newline at end of file diff --git a/pt/19_0_Using_Lightning.md b/pt/19_0_Using_Lightning.md new file mode 100644 index 0000000..d783afe --- /dev/null +++ b/pt/19_0_Using_Lightning.md @@ -0,0 +1,25 @@ +# Capítulo 19: Usando a Lightning + +> :information_source: **NOTA:** Este é um rascunho que está em andamento, para que possa obter alguns comentários dos revisores iniciais. Ainda não está pronto. + +Neste capítulo, continuaremos trabalhando com a interface de linha de comando `lightning-cli`. Criaremos invoices, realizaremos pagamentos e fecharemos canais, todas as principais atividades para se usar a Lightning. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Efetuar pagamentos na Lightning Network; + * Aplicar o fechamento a um canal Lightning. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Compreender o formato dos invoices; + * Entender o ciclo de vida dos pagamentos da Lightning Network; + * Saber como expandir a Lightning Network. + +## Tabela de Conteúdo + +* [Seção 1: Gerando um Invoice](19_1_Generate_a_Payment_Request.md) +* [Seção 2: Pagando um Invoice](19_2_Paying_a_Invoice.md) +* [Seção 3: Fechando um canal na Lightning](19_3_Closing_a_Channel.md) +* [Seção 4: Expandindo a Lightning Network](19_4_Lightning_Network_Review.md) diff --git a/pt/19_1_Generate_a_Payment_Request.md b/pt/19_1_Generate_a_Payment_Request.md new file mode 100644 index 0000000..e56860c --- /dev/null +++ b/pt/19_1_Generate_a_Payment_Request.md @@ -0,0 +1,184 @@ +# 19.1: Gerando um Invoice + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esta seção descreve como os pagamentos funcionam na Lightning Network, como criar uma solicitação de pagamento (ou _invoice_) e, finalmente, como entendê-la. A emissão de invoices depende de termos um segundo node Lightning, conforme descrito na seção [Acessando um segundo node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md). Esses exemplos usarão um node LND como nosso node secundário, para demonstrar ainda mais as possibilidades da Lightning Network. Para diferenciar entre os nodes nestes exemplos, os prompts serão mostrados como `c $` para o node c-lightning e `lnd $` para o node LND. Se quisermos reproduzir essas etapas, devemos [instalar nosso próprio node LND secundário](18_2__Interlude_Accessing_a_Second_Lightning_Node.md#Creating-a-new-lnd-node). + +> :book: ***O que é um invoice?*** Quase todos os pagamentos feitos na Lightning Network exigem um invoice, que nada mais é do que um **pedido de pagamento** feito pelo destinatário do dinheiro e enviado por qualquer meio para o usuário que irá pagar. Todos os invoices são de uso único. Os invoices da Lightning usam a codificação bech32, que já é usada pela Segregated Witness para Bitcoin. + +## Criando um invoice + +Para criar um novo invoice na c-lightning, usaríamos o comando `lightning-cli --testnet invoice`. + +Vamos ver como funcionaria com o c-lightning, usando argumentos de um valor (em milisats), um rótulo e uma descrição. +``` +c$ lightning-cli --testnet invoice 100000 joe-payment "The money you owe me for dinner" +{ + "payment_hash": "07a1c4bd7a38b4dea35f301c173cd8f9aac253b66bd8404d7ad829f226342490", + "expires_at": 1603305795, + "bolt11": "lntb1u1p0cw3krpp5q7suf0t68z6dag6lxqwpw0xclx4vy5akd0vyqnt6mq5lyf35yjgqdpj235x2grddahx27fq09hh2gr0wajjqmt9ypnx7u3qv35kumn9wgxqyjw5qcqp2sp5r3puay46tffdyzldjv39fw6tzdgu2hnlszamqhnmgjsuxqxavpgs9qy9qsqatawvx44x5qa22m7td84jau5450v7j6sl5224tlv9k5v7wdygq9qr4drz795lfnl52gklvyvnha5e5lx72lzzmgzcfnp942va5thmhsp5sx7c2", + "warning_capacity": "No channels", + "warning_mpp_capacity": "The total incoming capacity is still insufficient even if the payer had MPP capability." +} +``` +No entanto, para este exemplo, vamos gerar um invoice em um node LND e, em seguida, pagá-la no node c-lightning. Isso requer o comando `addinvoice` ligeiramente diferente na LND. Podemos usar o argumento `--amt` para indicar a quantia a ser paga (em milisats) e adicionar uma descrição usando o argumento `--memo`. + +``` +lnd$ lncli -n testnet addinvoice --amt 10000 --memo "First LN Payment - Learning Bitcoin and Lightning from the Command line." +{ + "r_hash": "6cacdedc95b89eec15e5244bd0957b88c0ab58b153eee549735b995344bc16bb", + "payment_request": "lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd", + "add_index": "1" +} +``` +Observe que esses invoices não fazem referência direta ao canal que criamos: isso é necessário para o pagamento, mas não para solicitar o pagamento. + +## Compreendendo um invoice + +O `bolt11 payment_request` que criamos é composto de duas partes: uma é legível por humanos e a outra são apenas dados. + +> :book: **O que é um BOLT?** Os BOLTs são as [especificações individuais da Lightning Network](https://github.com/lightningnetwork/lightning-rfc). + +### Lendo a parte legível do invoice + +A parte legível dos invoices começa com um `ln`. É `lnbc` para Bitcoin mainnet, `lntb` para Bitcoin testnet ou `lnbcrt` para Bitcoin regtest. +Em seguida, listamos os fundos solicitados no invoice. + +Por exemplo, vamos olhar para a nossa fatura do node LND: +``` +lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd +``` +A parte legível por humanos é `ln` +`tb` + `100u`. + +O `lntb` diz que esta é um invoice da Lightning Network para bitcoins Testnet. + +O `100u` diz que é para 100 bitcoins vezes o multiplicador microsatoshi. Existem quatro multiplicadores de fundos (opcionais): + +* `m` (mili): multiplique por 0,001 +* `u` (micro): multiplique por 0,000001 +* `n` (nano): multiplique por 0,000000001 +* `p` (pico): multiplique por 0,000000000001 + +100 BTC * 0,000001 = 0,0001 BTC, que é o mesmo que 10.000 satoshis. + +### Lendo a parte do invoice referente aos dados + +O resto do invoice ( `1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd`) contém um marcador de tempo, dados especificamente marcados, e uma assinatura. Obviamente, não pode ler sem decodificá-lo, mas podemos pedir ao `lightning-cli` para fazer isso com o comando `decodepay`: +``` +c$ lightning-cli --testnet decodepay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd +{ + "currency": "tb", + "created_at": 1602702347, + "expiry": 3600, + "payee": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "msatoshi": 10000000, + "amount_msat": "10000000msat", + "description": "First LN Payment - Learning Bitcoin and Lightning from the Command line.", + "min_final_cltv_expiry": 40, + "payment_secret": "e946403bcb54764994306c743ed3bf1303af8ae6e7687d3cabcc3ee06dbf904d", + "features": "028200", + "payment_hash": "6cacdedc95b89eec15e5244bd0957b88c0ab58b153eee549735b995344bc16bb", + "signature": "304402202e73ebd1ef974594eb117e8301be781f2ba289041ab6abc558d432351d8365e902202a8151c3fd13419b9390c2b976503d2d064f2a6748b14cb0db64424cf4e572f4" +} + +``` +Aqui temos o que os elementos mais relevantes significam: + +1. `currency`: A moeda a ser paga; +2. `created_at`: Momento em que a fatura foi criada. O valor é dado em tempo UNIX, que é segundos desde 1970. +3. `expiry`: O momento em que nosso node marca a fatura como inválida. O padrão é 1 hora ou 3600 segundos. +4. `payee`: A chave pública da pessoa (node) que recebe o pagamento da Lightning Network; +5. `msatoshi` e `amount_msat`: O valor de satoshis a ser pago; +6. `description`: A descrição informada pelo usuário; +7. `payment_hash`: O hash da pré-imagem que é usado para bloquear o pagamento. Só podemos resgatar um pagamento bloqueado com a pré-imagem correspondente ao hash de pagamento. Isso permite o roteamento na Lightning Network sem confiar em terceiros, criando um **Pagamento Condicional** a ser preenchido; +8. `signature`: A assinatura codificada por DER. + +> :book: ***O que são pagamentos condicionais?*** Embora os canais Lightning sejam criados entre dois participantes, vários canais podem ser conectados juntos, formando uma rede de pagamento que permite envio de valores entre todos os participantes da rede, mesmo aqueles sem um canal direto entre eles. Isso é feito usando um contrato inteligente denominado **Hashed Time Locked Contract**. + +> :book: ***O que é um Hashed Time Locked Contract (HTLC)?*** Um HTLC é um pagamento condicional que usa hashlocks e timelocks para garantir a segurança do pagamento. O destinatário deve apresentar uma pré-imagem do pagamento ou gerar um comprovante criptográfico de pagamento antes de um determinado prazo, caso contrário o pagador pode cancelar o contrato gastando-o. Esses contratos são criados como saídas da **Transação de compromisso**. + +> :book: ***O que é uma transação de compromisso?*** Uma transação de compromisso é uma transação que gasta a transação de financiamento original. Cada par possui a assinatura do outro par, o que significa que qualquer um pode gastar sua transação do compromisso como quiser. Depois que cada nova transação de confirmação é criada, a antiga é revogada. A transação de confirmação é uma maneira pela qual a transação de financiamento pode ser desbloqueada na blockchain, conforme discutiremos na seção [§19.3](19_3_Closing_a_Channel.md). + +### Verificando nosso invoice + +Existem dois elementos cruciais para verificar o invoice. O primeiro, obviamente, é o valor do pagamento, que já examinamos na parte legível. O segundo é o dado do `payee`, que é o pubkey do destinatário (node): +``` + "payee": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", +``` +Precisamos verificar se ele é o destinatário esperado. + +Olhando nas seções anteriores, mais precisamente na seção [§18.3](18_3_Setting_Up_a_Channel.md#opening-a-channel), podemos observar que é de fato o ID do par que usamos quando criamos nosso canal. Também podemos verificá-lo no outro node com o comando `getinfo`. +``` +lnd$ lncli -n testnet getinfo +{ + "version": "0.11.0-beta.rc4 commit=v0.11.0-beta.rc4", + "commit_hash": "fc12656a1a62e5d69430bba6e4feb8cfbaf21542", + "identity_pubkey": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "alias": "StandUp", + "color": "#3399ff", + "num_pending_channels": 0, + "num_active_channels": 1, + "num_inactive_channels": 0, + "num_peers": 3, + "block_height": 1862983, + "block_hash": "00000000000000c8c2f58f6da2ae2a3884d6e84f55d0e1f585a366f9dfcaa860", + "best_header_timestamp": "1602702331", + "synced_to_chain": true, + "synced_to_graph": true, + "testnet": true, + "chains": [ + { + "chain": "bitcoin", + "network": "testnet" + } + ], + "uris": [ + ], + "features": { + "0": { + "name": "data-loss-protect", + "is_required": true, + "is_known": true + }, + "5": { + "name": "upfront-shutdown-script", + "is_required": false, + "is_known": true + }, + "7": { + "name": "gossip-queries", + "is_required": false, + "is_known": true + }, + "9": { + "name": "tlv-onion", + "is_required": false, + "is_known": true + }, + "13": { + "name": "static-remote-key", + "is_required": false, + "is_known": true + }, + "15": { + "name": "payment-addr", + "is_required": false, + "is_known": true + }, + "17": { + "name": "multi-path-payments", + "is_required": false, + "is_known": true + } + } +} +``` +No entanto, o `payee` também pode ser alguém novo, caso em que provavelmente precisaremos verificar com a pessoa que emitiu o invoice para garantir que está tudo correto. + +## Resumo: Gerando um Invoice + +Na maioria dos casos, precisamos receber um invoice para usar os pagamentos da Lightning Network. Neste exemplo, criamos um manualmente, mas se estivermos em um ambiente de produção, provavelmente teria sistemas fazendo isso automaticamente sempre que alguém adquirir produtos ou serviços. Claro, depois de receber um invoice, precisamos saber como lê-lo! + +## O Que Vem Depois? + +Vamos continuar "Usando a Lightning" na seção [§19.2: Pagando um Invoice](06_3_Sending_an_Automated_Multisig.md). \ No newline at end of file diff --git a/pt/19_2_Paying_a_Invoice.md b/pt/19_2_Paying_a_Invoice.md new file mode 100644 index 0000000..d464dfa --- /dev/null +++ b/pt/19_2_Paying_a_Invoice.md @@ -0,0 +1,206 @@ +# 19.2: Pagando um Invoice + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Neste capítulo, aprenderemos como pagar um invoice usando o comando `lightning-cli pay`. Presume-se que já sabemos como analisar um invoice, de acordo com a seção [§19.1](19_1_Generate_a_Payment_Request.md) e sabemos que ele é válido. + +## Verificando o saldo + +Obviamente, a primeira coisa que precisamos fazer é nos certificarmos de que possuímos fundos suficientes para pagar o invoice. Neste caso, o canal configurado anteriormente com `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543` contém 100.000 satoshis. Este será o canal de pagamento do inoice. + +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "confirmed", + "blockheight": 1862856, + "reserved": false + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": true, + "state": "CHANNELD_NORMAL", + "short_channel_id": "1862856x29x0", + "channel_sat": 100000, + "our_amount_msat": "100000000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} +``` +Se não tivermos fundos suficientes, precisamos criar um novo canal. + +## Pagando nosso invoice + +Vamos usar o comando `lightning-cli pay` para pagar o invoice. Ele tentará encontrar uma rota para o destino fornecido, para posteriormente enviar os fundos solicitados. Isso é muito simples porque há um canal direto entre o pagador e o destinatário: +``` +c$ lightning-cli --testnet pay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd +{ + "destination": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "payment_hash": "6cacdedc95b89eec15e5244bd0957b88c0ab58b153eee549735b995344bc16bb", + "created_at": 1602704828.948, + "parts": 1, + "msatoshi": 10000000, + "amount_msat": "10000000msat", + "msatoshi_sent": 10000000, + "amount_sent_msat": "10000000msat", + "payment_preimage": "1af4a9bb830e49b6bc8f0bef980630e189e3794ad1705f06ad1b9c71571dce0c", + "status": "complete" +} +``` +Vamos observar todos os valores que estão em `msats`, não em `sats`! + +### Pagando o invoice pela Lightning + +No entanto, _não_ precisamos ter um canal com um node para pagá-lo. Só precisamos ter uma rota razoável pela Lightning Network. + +Imagine que recebemos esta minúscula solicitação de pagamento de 11.111 msat: +``` +c$ lightning-cli --testnet decodepay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7h058g9u4mthcaf9rl2f7g8zxsdp2t9hh2gr0wajjqmt9ypnx7u3qv35kumn9wgs8gmm0yyxqyjw5qcqp2sp5kj4xhrthmfgcgyl84zaqpl9vvdjwm5x368kr09fu5nym74setw4s9qy9qsq8hxjr73ee77vat0ay603e4w9aa8ag9sa2n55xznk5lsfrjffxxdj2k0wznvcfa98l4a57s80j7dhg0cc03vwqdwehkujlzxgm0xyynqqslwhvl +{ + "currency": "tb", + "created_at": 1602704929, + "expiry": 604800, + "payee": "02f3d74746934494fa378235e5bc44cfdbb5b8779d839263fb7f9218be032f6f61", + "msatoshi": 11111, + "amount_msat": "11111msat", + "description": "You owe me for dinner too!", + "min_final_cltv_expiry": 10, + "payment_secret": "b4aa6b8d77da518413e7a8ba00fcac6364edd0d1d1ec37953ca4c9bf56195bab", + "features": "028200", + "payment_hash": "e3e689117f7688ece226f1eb2eff35337d77d0e82f2bb5df1d4947f527c8388d", + "signature": "304402203dcd21fa39cfbcceadfd269f1cd5c5ef4fd4161d54e9430a76a7e091c929319b02202559ee14d984f4a7fd7b4f40ef979b743f187c58e035d9bdb92f88c8dbcc424c" +} +``` +Se tentássemos pagar e não tivéssemos uma rota para o destinatário por meio da Lightning Network, poderíamos esperar um erro como este: +``` +c$ lightning-cli --testnet pay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7h058g9u4mthcaf9rl2f7g8zxsdp2t9hh2gr0wajjqmt9ypnx7u3qv35kumn9wgs8gmm0yyxqyjw5qcqp2sp5kj4xhrthmfgcgyl84zaqpl9vvdjwm5x368kr09fu5nym74setw4s9qy9qsq8hxjr73ee77vat0ay603e4w9aa8ag9sa2n55xznk5lsfrjffxxdj2k0wznvcfa98l4a57s80j7dhg0cc03vwqdwehkujlzxgm0xyynqqslwhvl +{ + "code": 210, + "message": "Ran out of routes to try after 11 attempts: see `paystatus`", + "attempts": [ + { + "status": "failed", + "failreason": "Error computing a route to 02f3d74746934494fa378235e5bc44cfdbb5b8779d839263fb7f9218be032f6f61: \"Could not find a route\" (205)", + "partid": 1, + "amount": "11111msat" + }, +... +``` +Mas e se um host com o qual tínhamos um canal aberto é o destinatário pretendido? + +Nesse caso, quando formos pagar a fatura, ele _automaticamente funcionará_! +``` +c$ lightning-cli --testnet pay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7h058g9u4mthcaf9rl2f7g8zxsdp2t9hh2gr0wajjqmt9ypnx7u3qv35kumn9wgs8gmm0yyxqyjw5qcqp2sp5kj4xhrthmfgcgyl84zaqpl9vvdjwm5x368kr09fu5nym74setw4s9qy9qsq8hxjr73ee77vat0ay603e4w9aa8ag9sa2n55xznk5lsfrjffxxdj2k0wznvcfa98l4a57s80j7dhg0cc03vwqdwehkujlzxgm0xyynqqslwhvl +{ + "destination": "02f3d74746934494fa378235e5bc44cfdbb5b8779d839263fb7f9218be032f6f61", + "payment_hash": "e3e689117f7688ece226f1eb2eff35337d77d0e82f2bb5df1d4947f527c8388d", + "created_at": 1602709081.324, + "parts": 1, + "msatoshi": 11111, + "amount_msat": "11111msat", + "msatoshi_sent": 12111, + "amount_sent_msat": "12111msat", + "payment_preimage": "ec7d1b28a7b877cd92b83be396899e8bfc3ecb0b4f944f65afb4be7d0ee72617", + "status": "complete" +} +``` +Essa é a verdadeira beleza da Lightning Network: Sem nenhum esforço dos participantes ponto a ponto, nossos canais individuais se tornam uma rede! + +> :book: ***Como funcionam os pagamentos na rede?*** Digamos que o node A tem um canal aberto com o node B, o node B tem um canal aberto com o node C e o node A recebe uma fatura do node C de 11.111 msat. O node A paga ao node B 11.111 msat, mais uma pequena taxa, e então o node B paga 11.111 msat ao node C. Muito fácil. Mas lembre-se de que todos os canais são, na verdade, apenas registros de quem é o proprietário e de quanto é a Transação de Financiamento. Então o que realmente acontece é 11.111 msat da Transação de Financiamento no canal AB muda de A para B e, em seguida, 11.111 msat da Transação de Financiamento no canal BC muda de B para C. Isso significa que duas coisas são necessárias para que este pagamento funcione: Primeiro, cada canal deve ter capacidade suficiente para o pagamento e; Segundo, o pagador em cada canal deve possuir o suficiente da capacidade para fazer o pagamento. + +Observe que, neste exemplo, 12.111 msat foram enviados para pagar uma fatura de 11.111 msat: o extra sendo uma taxa fixa muito pequena (não uma porcentagem) que foi paga ao intermediário. + +## Verificando nosso saldo + +Após efetuar um pagamento com sucesso, veremos que nossos fundos foram alterados corretamente. + +Aqui está a aparência dos fundos para o node pagador após o pagamento inicial de 10.000 satoshis: +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "confirmed", + "blockheight": 1862856, + "reserved": false + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": true, + "state": "CHANNELD_NORMAL", + "short_channel_id": "1862856x29x0", + "channel_sat": 90000, + "our_amount_msat": "90000000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} +``` +Observe que a capacidade do canal permanece em 100.000 satoshis (isso nunca irá mudar!), Mas que o `our_amount` agora é de apenas 90.000 satoshis (ou 90.000.000 msat). + +Depois de pagar a segunda fatura, de 11.111 msat, os fundos mudam novamente: +``` +$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "confirmed", + "blockheight": 1862856, + "reserved": false + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": true, + "state": "CHANNELD_NORMAL", + "short_channel_id": "1862856x29x0", + "channel_sat": 89987, + "our_amount_msat": "89987000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} +``` +O `our_amount` agora é de apenas 89.987 satoshis, tendo pago 11.111 msat mais uma taxa de 1.000 msat. + +## Resumo: Pagando um Invoice + +Depois de recebermos um invoice, é fácil pagar com um único comando na Lightning. Mesmo se não tivermos um canal para o destinatário, o pagamento é simples, desde que haja uma rota entre nós e o node de destino. + +## O Que Vem Depois? + +Vamos continuar "Usando a Lightning" na seção [§19.3: Fechando um Canal na Lightning](19_3_Closing_a_Channel.md). \ No newline at end of file diff --git a/pt/19_3_Closing_a_Channel.md b/pt/19_3_Closing_a_Channel.md new file mode 100644 index 0000000..bfb8881 --- /dev/null +++ b/pt/19_3_Closing_a_Channel.md @@ -0,0 +1,259 @@ +# 19.3: Fechando um canal + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Neste capítulo, aprenderemos como fechar um canal usando a interface de linha de comando `lightning-cli close`. Fechar um canal significa que nós e a nossa contraparte enviarão o saldo do canal acordado para a blockchain, pelo qual devemos pagar as taxas de transação e esperar que a mesma seja posta em um bloco. Um fechamento pode ser cooperativo ou não, mas funciona de qualquer maneira. + +Para fechar um canal, primeiro precisamos saber o ID do node remoto. Podemos recuperá-lo de duas maneiras. + +## Encontrando nossos canais pelos saldos + +Podemos usar o comando `lightning-cli listfunds` para ver nossos canais. Este comando RPC exibe todos os fundos disponíveis, em `outputs` não gastos (UTXOs) na carteira interna ou bloqueados em `channels` (canais) abertos. +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "confirmed", + "blockheight": 1862856, + "reserved": false + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": true, + "state": "CHANNELD_NORMAL", + "short_channel_id": "1862856x29x0", + "channel_sat": 89987, + "our_amount_msat": "89987000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} + + "message_flags": 1, + "channel_flags": 2, + "active": true, + "last_update": 1595508075, + "base_fee_millisatoshi": 1000, + "fee_per_millionth": 1, + "delay": 40, + "htlc_minimum_msat": "1000msat", + "htlc_maximum_msat": "280000000msat", + "features": "" +} +``` + +Poderíamos também recuperar o ID do enésimo canal em uma variável como esta: +``` +c$ nodeidremote=$(lightning-cli --testnet listfunds | jq '.channels[0] | .peer_id') +``` + +## Encontrando os canais usando o JQ + +A outra maneira de encontrar canais para serem fechados é usando o comando `listchannels`. Ele retorna dados dos canais que são conhecidos pelo node. Como os canais podem ser bidirecionais, até dois nodes serão retornados por cada canal (um para cada direção). + +No entanto, assim como no mundo real, a fofoca (gossip) da Lightning Network é muito eficaz e, em pouco tempo, iremos conhecer os milhares de canais. Isso é ótimo para enviar pagamentos via Lightning Network, mas é pouco útil para descobrir os nossos próprios canais. Fazer isso requer um pouco de trabalho do `jq`. + +Primeiro, precisamos saber nosso próprio ID do node, que pode ser recuperado com o `getinfo`: +``` +c$ nodeid=$(lightning-cli --testnet getinfo | jq .id) +c$ echo $nodeid +"03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687" +c$ +``` +Podemos então usar isso para procurar nos `listchannels` quaisquer canais onde nosso node seja a origem ou o destino: +``` +c$ lightning-cli --testnet listchannels | jq '.channels[] | select(.source == '$nodeid' or .destination == '$nodeid')' +{ + "source": "03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687", + "destination": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "short_channel_id": "1862856x29x0", + "public": true, + "satoshis": 100000, + "amount_msat": "100000000msat", + "message_flags": 1, + "channel_flags": 0, + "active": true, + "last_update": 1602639570, + "base_fee_millisatoshi": 1, + "fee_per_millionth": 10, + "delay": 6, + "htlc_minimum_msat": "1msat", + "htlc_maximum_msat": "99000000msat", + "features": "" +} +``` +Aqui está nosso node favorito `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543` novamente, como sendo o destino. + +Depois de saber o que temos, podemos armazená-lo em uma variável: +``` +c$ nodeidremote=$(lightning-cli --testnet listchannels | jq '.channels[] | select(.source == '$nodeid' or .destination == '$nodeid') | .destination') +``` + +## Fechando um canal + +Agora que temos um ID do node remoto, estamos prontos para usar o comando `lightning-cli close` para fechar um canal. Por padrão, ele tentará fechar o canal cooperativamente com o par, se quisermos fechá-lo unilateralmente, precisamos definir o argumento `unilateraltimeout` com o número de segundos de espera. Se definirmos como sendo 0 e o par estiver online, um fechamento mútuo ainda irá ser tentado. Para este exemplo, tentaremos um fechamento mútuo. +``` +c$ lightning-cli --testnet close $nodeidremote 0 +{ + "tx": "02000000011d3cf2126ae36e12be3aee893b385ed6a2e19b1da7f4e579e3ef15ca234d69660000000000ffffffff021c27000000000000160014d39feb57a663803da116402d6cb0ac050bf051d9cc5e01000000000016001451c88b44420940c52a384bd8a03888e3676c150900000000", + "txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f", + "type": "mutual" +} +``` +A transação de fechamento na cadeia é [f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f] (https://blockstream.info/testnet/tx/f68de52d80a1076e36c67795f9f9db4f13048519489593f]. + +É essa transação de fechamento que realmente gasta os fundos que foram negociados de um lado para outro por meio de transações Lightning. Isso pode ser visto examinando a transação: +``` +$ bitcoin-cli --named getrawtransaction txid=f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f verbose=1 +{ + "txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f", + "hash": "3a6b3994932ae781bab80e159314bad06fc55d3d33453a1d663f9f9415c9719c", + "version": 2, + "size": 334, + "vsize": 169, + "weight": 673, + "locktime": 0, + "vin": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "txinwitness": [ + "", + "304402207f8048e29192ec86019bc83be8b4cac5d1fc682374538bed0707f58192d41c390220512ebcde122d53747feedd70c09153a40c56d09a5fec02e47642afdbb20aa2ac01", + "3045022100d686a16084b60800fa0f6b14c25dca1c13d10a55c5fb7c6a3eb1c5f4a2fb20360220555f5b6e672cf9ef82941f7d46ee03dd52e0e848b9f094a41ff299deb8207cab01", + "522102f7589fd8366252cdbb37827dff65e3304abd5d17bbab57460eff71a9e32bc00b210343b980dff4f2723e0db99ac72d0841aad934b51cbe556ce3a1b257b34059a17052ae" + ], + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00010012, + "n": 0, + "scriptPubKey": { + "asm": "0 d39feb57a663803da116402d6cb0ac050bf051d9", + "hex": "0014d39feb57a663803da116402d6cb0ac050bf051d9", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q6w07k4axvwqrmggkgqkkev9vq59lq5we5fcrzn" + ] + } + }, + { + "value": 0.00089804, + "n": 1, + "scriptPubKey": { + "asm": "0 51c88b44420940c52a384bd8a03888e3676c1509", + "hex": "001451c88b44420940c52a384bd8a03888e3676c1509", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q28ygk3zzp9qv223cf0v2qwygudnkc9gfp30ud4" + ] + } + } + ], + "hex": "020000000001011d3cf2126ae36e12be3aee893b385ed6a2e19b1da7f4e579e3ef15ca234d69660000000000ffffffff021c27000000000000160014d39feb57a663803da116402d6cb0ac050bf051d9cc5e01000000000016001451c88b44420940c52a384bd8a03888e3676c1509040047304402207f8048e29192ec86019bc83be8b4cac5d1fc682374538bed0707f58192d41c390220512ebcde122d53747feedd70c09153a40c56d09a5fec02e47642afdbb20aa2ac01483045022100d686a16084b60800fa0f6b14c25dca1c13d10a55c5fb7c6a3eb1c5f4a2fb20360220555f5b6e672cf9ef82941f7d46ee03dd52e0e848b9f094a41ff299deb8207cab0147522102f7589fd8366252cdbb37827dff65e3304abd5d17bbab57460eff71a9e32bc00b210343b980dff4f2723e0db99ac72d0841aad934b51cbe556ce3a1b257b34059a17052ae00000000", + "blockhash": "000000000000002a214b1ffc3a67c64deda838dd24d12154c15d3a6f1137e94d", + "confirmations": 1, + "time": 1602713519, + "blocktime": 1602713519 +} +``` +A entrada da transação é `66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d`, que foi a transação de financiamento feita na seção [§18.3](18_3_Setting_Up_a_Channel.md). A transação tem duas saídas, uma para o node remoto e outra para a carteira local da c-lightning. A saída no índice 0 corresponde ao node remoto com um valor de 0,00010012 BTC e, a saída no índice 1 corresponde ao node local com um valor de 0,00089804 BTC. + +A Lightning mostrará da mesma forma 89.804 satoshis retornados como um novo UTXO em nossa carteira: + +``` +$ lightning-cli --network=testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "confirmed", + "blockheight": 1862856, + "reserved": false + }, + { + "txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f", + "output": 1, + "value": 89804, + "amount_msat": "89804000msat", + "scriptpubkey": "001451c88b44420940c52a384bd8a03888e3676c1509", + "address": "tb1q28ygk3zzp9qv223cf0v2qwygudnkc9gfp30ud4", + "status": "confirmed", + "blockheight": 1863006, + "reserved": false + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": false, + "state": "ONCHAIN", + "short_channel_id": "1862856x29x0", + "channel_sat": 89987, + "our_amount_msat": "89987000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} + +``` + +### Compreendendo os tipos de canais de fechamento. + +O comando `close` do RPC tenta fechar um canal cooperativamente com nosso par ou unilateralmente após o argumento `unilateraltimeout` expirar. Isso traz alguma discussão adicional, pois vai ao cerne do design que não precisa de nenhuma confiança da Lightning: + +Cada participante de um canal pode criar tantos pagamentos Lightning para a contraparte quanto os fundos permitirem. Na maioria das vezes não haverá desentendimentos entre os participantes, portanto, haverá apenas duas transações na rede, uma abrindo e outra fechando o canal. No entanto, pode haver cenários em que um par não está online ou não concorda com o estado final do canal ou quando alguém tenta roubar fundos da outra parte. É por isso que existem fechamentos cooperativos e forçados. + +#### Fechamento Cooperativo + +No caso de um fechamento cooperativo, ambos os participantes do canal concordam em fechar o canal e estabelecer o estado final na blockchain. Ambos os participantes devem estar online, pois o fechamento é realizado transmitindo um gasto incondicional da transação de financiamento com uma saída para cada par. + +#### Fechamento Forçado + +No caso de fechamento forçado, apenas um participante está online ou os participantes discordam sobre o estado final do canal. Nessa situação, um par pode realizar um fechamento unilateral do canal sem a cooperação do outro node. É executado transmitindo uma transação de confirmação que confirma o estado do canal anterior que ambas as partes concordaram. Esta transação de compromisso contém o estado do canal dividido em duas partes: O saldo de cada participante e todos os pagamentos pendentes (HTLCs). + +Para realizar este tipo de fechamento, devemos especificar um argumento `unilateraltimeout`. Se este valor não for zero, o comando de fechamento fechará unilateralmente o canal quando esse número de segundos for atingido: +``` +c$ lightning-cli --network=testnet close $newidremote 60 +{ + "tx": "0200000001a1091f727e6041cc93fead2ea46b8402133f53e6ab89ab106b49638c11f27cba00000000006a40aa8001df85010000000000160014d22818913daf3b4f86e0bcb302a5a812d1ef6b91c6772d20", + "txid": "02cc4c647eb3e06f37fcbde39871ebae4333b7581954ea86b27b85ced6a5c4f7", + "type": "unilateral" +} + +``` +## Resumo: Fechando um canal + +Ao fechar um canal, realizamos uma transação na blockchain encerrando nosso relacionamento financeiro com o node remoto. Para fechar um canal, devemos levar em consideração nosso status e o tipo de fechamento que desejamos executar. + +## O Que Vem Depois? + +Vamos continuar "Usando a Lightning" na seção [§19.4: Expandindo a rede Lightning](19_3_Closing_a_Channel.md). \ No newline at end of file diff --git a/pt/19_4_Lightning_Network_Review.md b/pt/19_4_Lightning_Network_Review.md new file mode 100644 index 0000000..acee240 --- /dev/null +++ b/pt/19_4_Lightning_Network_Review.md @@ -0,0 +1,60 @@ +# 19.4: Expandindo a Lightning Network + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +Esses dois capítulos cobriram apenas algumas das atividades mais importantes da Lightning. Há muito mais que pode ser feito e muitas variedades possíveis. A seguir, daremos algumas dicas importantes. + +## Usando plugins c-lightning + +O c-lightning é uma implementação leve, altamente personalizável e compatível com o padrão do protocolo Lightning Network. Ele estende a funcionalidade usando plugins. Principalmente, esses são subprocessos que são iniciados pelo daemon `lightningd` e podem interagir com o `lightningd` de várias maneiras: + +* As opções de linha de comando permitem que os plugins registrem os próprios argumentos usando a linha de comando, que são então expostos por meio do `lightningd`; +* A passagem de comando JSON-RPC permite que os plugins adicionem os próprios comandos à interface JSON-RPC; +* As assinaturas de fluxo de eventos fornecem plug-ins com um mecanismo de notificação baseados em push para o `lightnind`; +* Hooks são uma opção primitiva que permite que os plugins sejam notificados sobre eventos no daemon `lightningd` e modifiquem o comportamento ou transmitam comportamentos personalizados. + +Um plugin pode ser escrito em qualquer linguagem e pode se comunicar com o `lightningd` através do stdin e stdout do plugin. O JSON-RPCv2 é usado como protocolo no topo dos dois fluxos, com o plugin atuando como servidor e `lightningd` atuando como cliente. + +O repositório `lightningd` GitHub mantém uma lista atualizada de [plugins](https://github.com/lightningd/plugins) disponíveis. + +## Usando Mobile Wallets + +Atualmente, sabemos de duas carteiras de dispositivos móveis da Lightning que suportam a implementação do c-lightning. + +Para dispositivos iOS, o FullyNoded é uma carteira de Bitcoin iOS open source que se conecta através do serviço autenticado Tor V3 ao nosso próprio full node. A funcionalidade FullyNoded está atualmente em desenvolvimento ativo e na fase beta inicial de testes. + +* [FullyNoded](https://github.com/Fonta1n3/FullyNoded/blob/master/Docs/Lightning.md) + +O SparkWallet é uma carteira GUI minimalista para a c-lightning, acessível pela web ou por meio de aplicativos móveis e de desktop para Android. + +* [SparkWallet](https://github.com/shesek/spark-wallet) + +## Usando diferentes implementações da Lightning + +O c-lightning não é a nossa única opção. Hoje, existem três implementações amplamente utilizadas para a Lightning Network. Todos seguem as [Documentações Base para a Tecnologia Lightning (BOLT)](https://github.com/lightningnetwork/lightning-rfc), que descrevem um protocolo de segunda camada para transferências de bitcoins offchain. As especificações são atualmente um trabalho em andamento que ainda está sendo elaborado. + +| Nome | Descrição | BitcoinStandup | Linguagem | Repositório | +| ------------- | ------------- | :---: | ------------- | ------------- | +| C-lighting | Blockstream | X | C | [Download](https://github.com/ElementsProject/lightning) | +| LND | Lightning Labs | X | Go | [Download](https://github.com/lightningnetwork/lnd) | +| Eclair | ACINQ | - | Scala | [Download](https://github.com/ACINQ/eclair) | + +## Fazendo backups + +Nosso node Lightning precisa estar online o tempo todo, caso contrário, nossa contraparte pode enviar um status de canal anterior e roubar nossos fundos. No entanto, há outro cenário em que os fundos podem ser perdidos, que é quando ocorre uma falha no hardware que impede o node de estabelecer um fechamento cooperativo com a contraparte. Isso provavelmente significará que, se não tivermos uma cópia exata do estado do canal antes da falha, teremos um estado inválido que pode fazer com que o outro node o considere como uma tentativa de fraude e use a transação penalizada. Nesse caso, todos os fundos serão perdidos. Para evitar esta situação indesejável, uma solução baseada na alta disponibilidade do banco de dados postgresQL [existe](https://github.com/gabridome/docs/blob/master/c-lightning_with_postgresql_reliability.md). + +PS: Não testamos esta solução. + +## Resumo: Expandindo a Lightning Network + +Podemos usar diferentes implementações, plugins, carteiras para celular e backups para expandir nossa experiência com a Lightning. + +## O Que Vem Depois? + +Concluímos todo o livro Aprendendo sobre o Bitcoin usando a Linha de Comando, embora não precise visitar os [Apêndices](A0_Apêndices.md) que possuem configurações alternativas, podemos fazer isso agora. + +Caso contrário, nós o encorajamos a ingressar nas comunidades de desenvolvedores e programadores e também, colocar nosso novo conhecimento para funcionar. + +Também podemos nos ajudar aqui em Blockchain Commons com issues ou PRs para aprender sobre o Bitcoin ou para qualquer um de nossos outros repositórios, ou podemos até mesmo nos tornar um [patrocinador](https://github.com/sponsors/BlockchainCommons). Também podemos ajudar divulgando o trabalho, contando às pessoas nas redes sociais sobre o curso e o que aprendemos com ele! + +Agora vá lá e faça da comunidade do Bitcoin um lugar melhor! \ No newline at end of file From f726c60359ca2a6ece916b970c4bc094b4e238b7 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Mon, 9 Aug 2021 11:32:40 -0300 Subject: [PATCH 062/155] Fixing changes --- 19_0_Using_Lightning.md | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/19_0_Using_Lightning.md b/19_0_Using_Lightning.md index 008cb7c..04ef4c3 100644 --- a/19_0_Using_Lightning.md +++ b/19_0_Using_Lightning.md @@ -23,30 +23,3 @@ Supporting objectives include the ability to: * [Section Two: Paying an Invoice](19_2_Paying_a_Invoice.md) * [Section Three: Closing a Lightning Channel](19_3_Closing_a_Channel.md) * [Section Four: Expanding the Lightning Network](19_4_Lightning_Network_Review.md) - - -# Capítulo dezenove: usando um raio - ->: Informação_Source: ** Nota: ** Este é um rascunho em andamento, para que eu possa obter algum feedback dos iniciantes. Ainda não está pronto para aprender. - -Neste capítulo, você continuará trabalhando com a interface de linha de comando "Lightning-Cli` Você criará faturas, executará pagamentos e canais fechados - todas as principais atividades para usar o Lightning. - -## Objetivos para este capítulo - -Depois de trabalhar através deste capítulo, um desenvolvedor será capaz de: - - * Execute pagamentos na rede relâmpago. - * Aplique o fechamento para um canal de relâmpago. - -Objetivos de apoio incluem a capacidade de: - - * Compreender o formato das faturas. - * Entenda o ciclo de vida dos pagamentos de rede de raios. - * Saber como expandir a rede relâmpago. - -## Índice - -* [Seção One: Gerando uma solicitação de pagamento] (19_1_Generate_A_Payment_Request.md) -* [Seção dois: pagando uma fatura] (19_2_Paying_a_invoice.md) -* [Seção três: fechando um canal de raio] (19_3_closing_a_channel.md) -* [Seção Quatro: Expandindo a rede Lightning] (19_4_lightning_network_review.md) \ No newline at end of file From 6f18e057cd7f1c53f3b422ff61330631ca6cdb30 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Mon, 9 Aug 2021 12:47:20 -0300 Subject: [PATCH 063/155] Appendix translation concluded. --- pt/A0_Appendices.md | 22 +++ pt/A1_0_Understanding_Bitcoin_Standup.md | 51 ++++++ pt/A2_0_Compiling_Bitcoin_from_Source.md | 127 ++++++++++++++ pt/A3_0_Using_Bitcoin_Regtest.md | 206 +++++++++++++++++++++++ 4 files changed, 406 insertions(+) create mode 100644 pt/A0_Appendices.md create mode 100644 pt/A1_0_Understanding_Bitcoin_Standup.md create mode 100644 pt/A2_0_Compiling_Bitcoin_from_Source.md create mode 100644 pt/A3_0_Using_Bitcoin_Regtest.md diff --git a/pt/A0_Appendices.md b/pt/A0_Appendices.md new file mode 100644 index 0000000..c324e3f --- /dev/null +++ b/pt/A0_Appendices.md @@ -0,0 +1,22 @@ +# Apêndice + +O foco principal deste curso sugere uma configuração bastante padrão para os testes de Bitcoin. À seguir, vamos ver alguns apêndices que irão explicar melhor a configuração e algumas opções alternativas. + +## Objetivos deste apêndice + +Depois de trabalhar nestes apêndices, um desenvolvedor será capaz de: + + * Decidir entre vários métodos de como criar uma blockchain do Bitcoin. + +Os objetivos secundários do apêndice incluem a capacidade de: + + * Compreender a configuração do Bitcoin Standup; + * Fazer uma compilação de Bitcoin à mão; + * Compreender o poder do Regtest; + * Use um ambiente Regtest. + +## Tabela de conteúdo + + * [Apêndice 1: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md) + * [Apêndice 2: Compilando Bitcoin na Fonte](A2_0_Compiling_Bitcoin_from_Source.md) + * [Apêndice 3: Usando o Bitcoin Regtest](A3_0_Using_Bitcoin_Regtest.md) \ No newline at end of file diff --git a/pt/A1_0_Understanding_Bitcoin_Standup.md b/pt/A1_0_Understanding_Bitcoin_Standup.md new file mode 100644 index 0000000..c10c2a1 --- /dev/null +++ b/pt/A1_0_Understanding_Bitcoin_Standup.md @@ -0,0 +1,51 @@ +# Apêndice 1: Compreendendo o Bitcoin Standup + +Na seção [§2.1: Configurando um Bitcoin Core VPS com StackScript](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) explicamos o processo de criação de um node de Bitcoin usando [Bitcoin-Standup-Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup -Scripts). O apêndice à seguir explica o que as principais seções do script fazem. Podemos acompanhar em [Linode Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) em outra janela. + +## Etapa 1: Nome do host + +O nome do seu host é armazenado em `/etc/hostname` e definido com o comando `hostname`. Ele também aparece em `/etc/hosts`. + +## Etapa 2: Fuso horário + +O fuso horário do nosso host é armazenado em `/etc/timezone`, então um arquivo apropriado do `/usr/share/zoneinfo/` é copiado para o `/etc/localtime`. + +## Etapa 3: Atualizando o Debian + +O gerenciador de pacotes `apt-get` é usado para deixar nossa máquina atualizada e instalar o `gnupg`, o gerador de números aleatórios `haveged`, e o firewall simples `ufw`. + +Nossa máquina está configurada para se manter automaticamente atualizada com o `echo" unattended-upgrades unattended-upgrades / enable_auto_updates boolean true "| debconf-set-selections`. + +## Etapa 4: Configurando um usuário + +Um usuário `standup` é criado, o qual será usado para nossas aplicações do Bitcoin. Ele também tem permissões `sudo`, permitindo que executemos ações privilegiadas com esta usuário. + +Se fornecemos uma chave SSH, ela permitirá o acesso a esta conta (caso contrário, devemos usar a senha criada na configuração). + +Se fornecemos um endereço IP, o acesso `ssh` será limitado a esse endereço, de acordo com `/etc/hosts.allow`. + +## Etapa 5: Configurando o Tor + +O Tor é instalado para fornecer serviços protegidos (ocultos) para acessar os comandos RPC do Bitcoin através do nosso servidor. Podemos consultar a seção [§14.1: Verificando a Configuração do Tor]14_1_Verifying_Your_Tor_Setup.md) para obter mais informações sobre a configuração. + +Se criarmos um cliente autorizado para os serviços ocultos, o acesso será limitado a essa chave, que está em `/var/lib/tor/standup/authorized_clients`. Caso contrário, na seção [§14.2](14_2_Changing_Your_Bitcoin_Hidden_Services.md) explicamos como podemos fazê-la depois. + +## Etapa 6: Instalando o Bitcoin + +Bitcoin é instalado no `~standup/.bitcoin`. Nossa configuração é armazenada no `~standup/.bitcoin/bitcoin.conf`. + +Precisamos nos certificar de que as somas de verificação foram analisadas de acordo com a seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), caso contrário, podemos estar expostos a um ataque à blockchain. + +## Etapa 7: Instalando o Codificador QR + +Para manter tudo compatível com [GordianSystem](https://github.com/BlockchainCommons/GordianSystem), um código QR é criado e está em `/qrcode.png`. Isso pode ser lido em um cliente QuickConnect como [GordianWallet](https://github.com/BlockchainCommons/GordianWallet-iOS). + +## Conclusão - Compreendendo o Bitcoin Standup + +O Bitcoin Standup usa scripts para tentar combinar muitas das funcionalidades de um [GordianNode](https://github.com/BlockchainCommons/GordianNode-macOS). Ele deve fornecer a nós um ambiente Bitcoin seguro construído em uma base de Bitcoin Core com Tor para nos comunicarmos com o RPC. + +## O Que Vem Depois? + +Se estivermos no processo de criação de um node Bitcoin para o uso neste curso, devemos voltar para a seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md). + +Se estivermos lendo os apêndices, podemos continuar no [Apêndice 2: Compilando Bitcoin na Fonte](A2_0_Compiling_Bitcoin_from_Source.md). \ No newline at end of file diff --git a/pt/A2_0_Compiling_Bitcoin_from_Source.md b/pt/A2_0_Compiling_Bitcoin_from_Source.md new file mode 100644 index 0000000..88cf08f --- /dev/null +++ b/pt/A2_0_Compiling_Bitcoin_from_Source.md @@ -0,0 +1,127 @@ +# Apêndice 2: Compilando Bitcoin na Fonte + +Este curso presume que usará um script para criar um ambiente Bitcoin, seja usando o Bitcoin Standup do Linode de acordo com o especificado na seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou por algum outro meio de acordo com a seção [§2.2](02_2_Setting_Up_Bitcoin_Core_Other.md). No entanto, podemos querer compilar o Bitcoin manualmente. + +Isso tem os seguintes benefícios: + +1. Sempre estará atualizados com a versão mais recente. Mas atenção! Estar sempre atualizado não é necessário para o Bitcoin Core, pois o software é sempre compatível com versões anteriores, o que significa que uma versão antiga do Bitcoin Core ainda poderá participar da rede Bitcoin, embora possamos não ter os recursos mais recentes. Devemos sempre verificar os recursos de uma nova versão antes de atualizarmos. +2. Não precisaremos depender de binários do Bitcoin Core pré-compilados. Isso requer menos confiança. Mesmo que os mantenedores do Bitcoin Core façam um ótimo trabalho em manter a integridade do código, um binário pré-compilado é removido algumas etapas do código-fonte. Quando compilamos a partir do código-fonte, o código pode ser inspecionado antes da compilação. +3. Podemos personalizar a construção, fazendo coisas como desabilitar a carteira ou a GUI. + +## Preparando nosso ambiente + +Este tutorial usa o sistema operacional Debian 10.4.kv0 em uma arquitetura amd64 (computadores de 64 bits), mas podemos usar este tutorial em qualquer sistema baseado no Debian (por exemplo, Ubuntu, Mint, etc). Para outros sistemas Linux, podemos adaptar as etapas a seguir com o gerenciador de pacotes do sistema. + +Podemos ter pouca familiaridade ou nenhuma com a linha de comando, desde que tenhamos vontade de aprender. O terminal é o nosso aliado mais poderoso, não algo a ser temido. Podemos simplesmente copiar e colar os seguintes comandos para compilar Bitcoin. Um comando com um "$" é um comando do usuário normal e um com um "#" é um comando de super usuário/root. + +Se o nosso usuário não estiver na lista dos super usuários, podemos o seguinte: + +``` +$ su root + +# apt-get install sudo +# usermod -aG sudo +# reboot +``` + +## Instalando o Bitcoin + +### Etapa 1: atualizando nosso sistema + +Primeiro, vamos atualizar o sistema usando: +``` +$ sudo apt-get update +``` + +### Etapa 2: Instalando o Git e as dependências + +Vamos instalar o `git`, que permitirá que baixemos o código-fonte, e o `build-essential`, que compila o código: +``` +$ sudo apt-get install git build-essential -y +``` + +Depois, vamos instalar as dependências restantes: +``` +$ sudo apt-get install libtool autotools-dev automake pkg-config bsdmainutils python3 libssl-dev libevent-dev libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libminiupnpc-dev libzmq3-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler ccache -y +``` + +### Etapa 3: Baixando o código-fonte + +Assim que as dependências forem instaladas, baixamos o repositório (repo) que contém o código-fonte do Bitcoin no github: +``` +$ git clone https://github.com/bitcoin/bitcoin.git +``` +Vamos verificar o conteúdo do repo: +``` +$ ls bitcoin +``` +Devemos corresponder aproximadamente ao seguinte conteúdo: + +![clonando o repo](./public/LBftCLI-compiling_bitcoin-git.png) + +### Etapa 4: Instalando o Berkley DB v4.8 + +1. Vamos entrar no diretório `contrib`:`$ cd bitcoin/contrib/`; +2. Vamos executar o seguinte comando: ```$ ./install_db4.sh `pwd` ```. + +Depois de fazer o download, veremos o seguinte retorno. Podemos observar o retorno, e o usaremos para configurar o bitcoin durante o build: + +![db4](./public/LBftCLI-compiling_bitcoin-db4.png) + +### Etapa 5: Compilando o Bitcoin Core + +É recomendado que compilemos a partir de um branch com tag, que é mais estável, a menos que queiramos experimentar as últimas novidades do desenvolvimento do bitcoin. Vamos executar o seguinte comando para obter a lista de tags, ordenada a partir das mais recentes: +``` +$ git tag -n | sort -V +``` +Em seguida, vamos escolha uma tag, por exemplo a `v0.20.0`: +``` +$ git checkout +``` + +Depois de selecionar um ramo da tag, vamos executar o seguinte, dentro do diretório `bitcoin`. O `` deve ser o retorno do script `install_db4.sh`. + +``` +$ ./autogen.sh +$ export BDB_PREFIX='/db4' +$ ./configure BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include" +$ make # build bitcoin core +``` + +### Etapa 6: Testando o build + +Se quisermos verificar nossa compilação (o que é uma boa ideia), podemos executar os seguintes testes: + +1. `$ make check` irá executar os Testes de Unidade, que devem retornar `PASS`; +2. `$ test/functional/test_runner.py --extended` executará os testes funcionais estendidos. Podemos retirar a sinalização `--extended` se quisermos pular alguns testes. Isso vai demorar um pouco. + +### Etapa 7: Executando ou instalando o Bitcoin Core + +Agora que compilou o Bitcoin Core a partir da fonte, podemos começar a usá-lo ou instalá-lo. + +#### Executando o Bitcoin Core sem instalar + +Para executar o Bitcoin Core: + +`$ src/qt/bitcoin-qt` para iniciar a GUI; +`$ src/bitcoind` para executar bitcoin na linha de comando. + +### Instalando Bitcoin Core + +Para instalar: + +`$ sudo make install` irá instalar o Bitcoin Core globalmente. Uma vez instalado, podemos executar o bitcoin de qualquer lugar usando a linha de comando, assim como qualquer outro software, como: `$ bitcoin-qt` para a GUI ou `bitcoind` e então `bitcoin-cli` para a linha de comando. + +## Finalizando Nosso Sistema + +Ao compilar Bitcoin a partir da fonte, aumentamos a confiança que temos em nossa configuração. No entanto, estamos muito aquém de toda a segurança adicional fornecida por uma configuração Bitcoin Standup. Para resolver isso, podemos percorrer todo o [Linode Stackscript](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) e executar passo a passo todos os comandos. O único lugar que precisamos ter cuidado é na Etapa 6, que instala o Bitcoin. Pulando o ponto onde já verificamos os binários e continuemos a partir daí. + +## Resumo: Compilando Bitcoin na Fonte + +Se quisermos aumentar a segurança da instalação do Bitcoin a partir da fonte, agora podemos fazer ter isso. Felizmente, também passamos pelo Linode Stackscript para configurar um servidor mais seguro. + +## O Que Vem Depois? + +Se estávamos no processo de criação de um node de Bitcoin para usar neste curso, devemos continuar com o [Capítulo 3: Compreendendo a configuração do node Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). + +Se estivermos lendo os apêndices, vamos continuar com o [Apêndice 3: Usando o Bitcoin Regtest](A3_0_Using_Bitcoin_Regtest.md). \ No newline at end of file diff --git a/pt/A3_0_Using_Bitcoin_Regtest.md b/pt/A3_0_Using_Bitcoin_Regtest.md new file mode 100644 index 0000000..362b5d9 --- /dev/null +++ b/pt/A3_0_Using_Bitcoin_Regtest.md @@ -0,0 +1,206 @@ +# Apêndice 3: Usando o Bitcoin Regtest + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. + +A maior parte deste curso presume que usaremos a Mainnet ou a Testnet. No entanto, essas não são as únicas opções. Ao desenvolver aplicações no Bitcoin, podemos querer manter nossos aplicativos isolados das blockchains públicas. Para fazer isso, podemos criar um blockchain do zero usando o Regtest, que tem uma outra grande vantagem sobre a Testnet. Escolhemos quando criar novos blocos, para ter controle total sobre o ambiente. + +## Iniciando o Bitcoind no Regtest + +Depois de [configurar nosso VPS no Bitcoin-Core ](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) ou depois que o [compilamos na fonte](A2_0_Compiling_Bitcoin_from_Source.md), podemos usar o regtest. Para iniciar o `bitcoind` no regtest e criar uma Blockchain privada, iremos usar o seguinte comando: +``` +$ bitcoind -regtest -daemon -fallbackfee=1.0 -maxtxfee=1.1 +``` + +Os argumentos `-fallbackfee=1.0 -maxtxfee=1.1` irão prevenir o erro `Fee estimation failed. Fallbackfee is disabled`. + +No teste, geralmente não há transações suficientes, então o bitcoind não pode dar uma estimativa confiável e, sem ela, a carteira não criará transações a menos que seja explicitamente definida a taxa. + +### Redefinindo a Blockchain Regtest + +Se desejarmos, podemos reiniciar nossa Regtest posteriormente com uma nova blockchain. + +As carteiras do Regtest e o estado do blockchain (chainstate) são salvos no subdiretório regtest do diretório de configuração do Bitcoin: +``` +user@mybtc:~/.bitcoin# ls +bitcoin.conf regtest testnet3 +``` + +Para iniciar uma nova Blockchain usando o regtest, tudo que precisamos fazer é excluir a pasta `regtest` e reiniciar o Bitcoind: +``` +$ rm -rf regtest +``` +## Gerando uma carteira do Regtest + +Antes de gerar os blocos, é necessário carregar uma carteira usando `loadwallet` ou criar uma nova com `createwallet`. Desde a versão 0.21, o Bitcoin Core não cria automaticamente novas carteiras na inicialização. + +O argumento `descriptors=true` cria uma carteira de descritores nativos, que armazena informações no scriptPubKey usando descritores de saída. Se for `false`, ele criará uma carteira legada, onde as chaves são usadas para gerar scriptPubKeys e endereços implicitamente. +``` +$ bitcoin-cli -regtest -named createwallet wallet_name="regtest_desc_wallet" descriptors=true +``` + +## Geraando Blocos + +Podemos gerar (minerar) novos blocos em uma blockchain de regtest usando o método RPC `generate` com um argumento para quantos blocos queremos gerar. Só faz sentido usar esse método na regtest, devido à grande dificuldade, é muito improvável que ele produza novos blocos na rede principal ou na rede de teste: +``` +$ bitcoin-cli -regtest -generate 101 +[ + "57f17afccf28b9296048b6370312678b6d8e48dc3a7b4ef7681d18ed3d91c122", + "631ff7b8135ce633c774828be3b8505726459eb65c339aab981b10363befe5a7", + ... + "1162dbfe025c7da94ee1128dc26d518a94508f532c19edc0de6bc673a909d02c", + "20cb2e815c3d42d6a117a204a0b5e726ab641c826e441b5b3417aca33f2aba48" +] +``` + +> :warning: **AVISO**. Note que devemos adicionar o argumento `-regtest` após cada comando `bitcoin-cli` para acessar corretamente nosso ambiente Regtest. Se preferirmos, podemos incluir um comando `regtest=1` em nosso arquivo de configuração em `~/.bitcoin/bitcoin.conf`. + +Como um bloco deve ter 100 confirmações antes que a recompensa possa ser gasta, iremos gerar 101 blocos, fornecendo acesso à transação da coinbase do bloco #1. Como este é uma nova blockchain usando as regras padrão do Bitcoin, os primeiros blocos pagam uma recompensa de bloco de 50 bitcoins. Ao contrário do mainnet, no modo regtest apenas os primeiros 150 blocos pagam uma recompensa de 50 bitcoins. A recompensa diminui pela metade após 150 blocos, então paga 25, 12,5 e assim por diante... + +A saída é o hash de bloco de cada bloco gerado. + +> :book: ***O que é uma transação do tipo coinbase?*** Uma coinbase é a transação sem entrada criada quando um novo bloco é extraído e entregue ao minerador. É assim que novos bitcoins entram no ecossistema. O valor das transações coinbase decai com o tempo. Na rede principal, ele cai pela metade a cada 210.000 transações e termina inteiramente com o bloco 6.929.999, que está previsto atualmente para o século 22. Em maio de 2020, a recompensa pela coinbase é 6,25 BTC. + +### Verificando nosso saldo + +Depois de minerar blocos e receber as recompensas, podemos verificar o saldo em nossa carteira: +``` +$ bitcoin-cli -regtest getbalance +50.00000000 +``` + +## Usando o Regtest + +Agora devemos ser capazes de usar este saldo para qualquer tipo de interação em nossa Blockchain privada, como o envio de transações Bitcoin de acordo com o [Capítulo 4](04_0_Sending_Bitcoin_Transactions.md). + +É importante notar que para que qualquer transação seja concluída, teremos que gerar (minerar) novos blocos, para que as transações possam ser incluídas. + +Por exemplo, para criar uma transação e incluí-la em um bloco, devemos primeiro usar o comando `sendtoaddress`: +``` +$ bitcoin-cli -regtest sendtoaddress [address] 15.1 +e834a4ac6ef754164c8e3f0be4f34531b74b768199ffb244ab9f6cb1bbc7465a +``` + +A saída é o hash da transação incluída na blockchain. Podemos verificar os detalhes usando `gettransaction`: +``` +$ bitcoin-cli -regtest gettransaction e834a4ac6ef754164c8e3f0be4f34531b74b768199ffb244ab9f6cb1bbc7465a +{ + "amount": 0.00000000, + "fee": -0.00178800, + "confirmations": 0, + "trusted": false, + "txid": "e834a4ac6ef754164c8e3f0be4f34531b74b768199ffb244ab9f6cb1bbc7465a", + "walletconflicts": [ + ], + "time": 1513204730, + "timereceived": 1513204730, + "bip125-replaceable": "unknown", + "details": [ + { + "account": "", + "address": "mjtN3C97kuWMgeBbxdB7hG1bjz24Grx2vA", + "category": "send", + "amount": -15.10000000, + "label": "", + "vout": 1, + "fee": -0.00178800, + "abandoned": false + }, + { + "account": "", + "address": "mjtN3C97kuWMgeBbxdB7hG1bjz24Grx2vA", + "category": "receive", + "amount": 15.10000000, + "label": "", + "vout": 1 + } + ], + "hex": "020000000f00fe2c7b70b925d0d40011ce96f8991fee5aba9537bd1b6913b37c37b041a57c00000000494830450221009ad02bfeee2a49196a99811ace20e2e7fefd16d33d525884edbc64bf6e2b1db502200b94f4000556391b0998932edde3033ba2517733c7ddffb87d91f6b756629fe201feffffff06a9301a2b39875b68f8058b8e2ad0b658f505e44a67e1e1d039140ae186ed1f0000000049483045022100c65cd13a85af6fcfba74d2852276a37076c89a7642429aa111b7986eea7fd6c7022012bbcb633d392ed469d5befda8df0a6b96e1acfa342f559877edebc2af7cb93401feffffff434b6f67e5e068401553e89f739a3edc667504597f29feb8edafc2b081cc32d90000000049483045022100b86ecc43e602180c787c36465da7fc8d1e8bfba23d6f49c37190c20889f2dfa0022032c3aec3ceefbb7a33c040ef19090cacbfd6bc9c5cd8e94252eb864891c6f34501feffffff4c65b43f8568ce58fc4c55d24ba0742e9878a031fdfae0fadac7247f42cc1f8e0000000049483045022100d055acfce852259dde051dc61792f94277d094c5da96752f925582b8e739868f02205e69add76e6b001073ad6b7df5f32a681fc8513ee0f6e126ee1c2d45149bd91d01feffffff5a72d60b58300974c5d4731e29b437ea61b87b6733bb3ca6ce5548ef8887d05b0000000049483045022100a7f5b2ee656a5a904fb27f982210de6858dfb165777ec969a77ea1c2c82975a4022001a1a563dbc3714047ec855f7aee901e756b851e255f35435e85c2ba7b0abd8401feffffff60d68e9d5650d55bc9e0b2a65ed27a3b9bceac4955760aa1560408854c3b148d000000004948304502210081a6f0c8232c52f3eaca825965077e88b816e503834989be4afb3f44f87eb98202207ae8becb99efe379fb269f477e7bb70d117dcb83e106c53b7addaa9715029da101feffffff63e2239425aad544f6e1157d5ee245d2500d4e9e9daf8049e0a38add6246da890000000049483045022100e0ab1752e8fbb244b63f7dd5649f2222e0dc42fae293b758e0c28082f77560b60220013f72fbe50acf4af197890b4d18fa89094055ed66f9226a6b461cc4ff560f8e01feffffff6aad4151087f4209ace714193dd64f770305dfb89470b79cca538b88253fbbef0000000049483045022100fee4a5f7ec6e8b55bd6aa0e93b5399af724039171d998b926e8095b70953d5f202203db0d4ef9d1bd57aeff0fe3d47d4358ec0559135dac8107507741eef0638279201feffffff7ddbca5854e25e6a2dfeacfe5828267cd1ef5d86e1da573fe2c2b21b45ecd6ce0000000049483045022100bf45241525592df4625642972dbc940ef74771139dd844bc6a9517197d01488c02203c99ca98892cc2693e8fbb9a600962eec84494fb8596acf0d670822624e497c901feffffff8672949de559e76601684c4ac3731599fd965d0c412e7df9f8ec16038d4420a60000000049483045022100b5a9bd3c6718c6bd2a8300bbd1d9de0ff1c5d02aeb6a659c52bb88958e7e3b0302207f710db1ef975c22edf54e063169aae31bbe470166cc0e5c34fd27b730b8e7d001feffffff8e006b0bb8cef2c5c2a11c8c2aa7d3ba01cb4386c7f780c45bc1014142b425f00000000048473044022046dc9db8daeb09b7c0b9f48013c8af2d0a71f688adaa8d91b40891768c852d4a02204fa15da6d58851191344a56c63bf51a540ec03f73117a3446230bb58a8a4bcce01feffffffbad05b8f86182b9b7c9c5aaa9ce3dc8d08a76848e49a2d9b8dcfb0f764bb26ca000000004847304402200682379dc36cb486309eac4913f41ac19638525677edad45ca8d9a2b0728b12f02203fb44f8a46cbc4c02f5699d7d4d9cd810bdf7e7c981b421218ccbcb7b73845f501feffffffd35228fe9ef0a742eacffc4a13f15ed7ba23854e6cb49d5010810ac11b5bdf690000000048473044022030045b882500808bd707f4654becc63de070818c82716310d39576decdd724e3022034d3b41cb5e939f0011bb5251be7941b6077fde5f4eff59afd8e49a2844288f701fefffffff5ae4cbd4ae8d68b5a34be3231cdc88b660447175f39cf7a86397f37641d4aa70000000049483045022100afe16f0de96a8629d6148f93520d690f30126c37e7f7f05300745a1273d7eb7202200933f6b371c4ea522570f3ec2aee9be2b59730b634e828f543bcdb019cf4749901fefffffff633f61ac61683221cc3d2665cf4bcf193af1c8ffe9d3d756ba83cc5eb7643250000000049483045022100ef0b8853c94d60634eff2fc1d4d75872aacb0a2d3242308b7ee256b24739c614022069fe9be8288bdd635871c263c46be710c001729d43f6fbc1350ed1a693c4646301feffffff0250780000000000001976a91464ed7fb2fe0b06f4cad0d731b122222e3e91088a88ac80c5005a000000001976a9142fed0f02d008f89f6a874168e506e2d4f9bcbfb888acd32b0000" +} +``` +No entanto, agora devemos finalizá-la criando blocos na blockchain. +A maioria das aplicações requer seis confirmações de bloco para considerar a transação como irreversível. Se for esse o nosso caso, podemos minerar seis blocos adicionais em nossa blockchain de teste: +``` +$ bitcoin-cli -regtest -generate 6 +[ + "33549b2aa249f0a814db4a2ba102194881c14a2ac041c23dcc463b9e4e128e9f", + "2cc5c2012e2cacf118f9db4cdd79582735257f0ec564418867d6821edb55715e", + "128aaa99e7149a520080d90fa989c62caeda11b7d06ed1965e3fa7c76fa1d407", + "6037cc562d97eb3984cca50d8c37c7c19bae8d79b8232b92bec6dcc9708104d3", + "2cb276f5ed251bf629dd52fd108163703473f57c24eac94e169514ce04899581", + "57193ba8fd2761abf4a5ebcb4ed1a9ec2e873d67485a7cb41e75e13c65928bf3" +] +``` + + +## Testando com NodeJS + +Quando estamos fazendo testes, somos capazes de simular casos extremos e ataques que podem acontecer no mundo real, como o problema de gasto duplo. + +Conforme discutido em outro lugar neste curso, o uso de bibliotecas de software pode fornecer acesso mais sofisticado a alguns comandos RPC. Nesse caso, o [bitcointest criado por dgarage](https://github.com/dgarage/bitcointest) para o NodeJS pode ser usado para simular uma transação de uma carteira para outra; podemos verificar [a documentação](https://www.npmjs.com/package/bitcointest) para simularmos ataque mais específicos, como o de gasto duplo. + +Vejamos a seção [§17.3](17_3_Accessing_Bitcoind_with_NodeJS.md) para as informações mais atualizadas sobre a instalação do NodeJS, em seguida, podemos adicionar ao `bitcointest`: +``` +$ npm install -g bitcointest +``` + +Depois de instalar o `bitcointest`, podemos criar um arquivo `test.js` com o seguinte conteúdo: +```javascript +file: test.js + +const { BitcoinNet, BitcoinGraph } = require('bitcointest'); +const net = new BitcoinNet('/usr/local/bin', '/tmp/bitcointest/', 22001, 22002); +const graph = new BitcoinGraph(net); + +try { + + console.log('Launching nodes...'); + + const nodes = net.launchBatchS(4); + const [ n1, n2 ] = nodes; + net.waitForNodesS(nodes, 20000); + + console.log('Connected!'); + const blocks = n1.generateBlocksS(110); + console.info('Generated 110 blocks'); + + console.log(`n2.balance (before) = ${n2.getBalanceS()}`); + + const sometxid = n1.sendToNodeS(n2, 100); + console.log(`Generated transaction = ${sometxid}`); + n1.generateBlocksS(110); + n2.waitForBalanceChangeS(0); + + const sometx = n2.getTransactionS(sometxid); + console.log(`n2.balance (after) = ${n2.getBalanceS()}`); + + +} catch (e) { + console.error(e); + net.shutdownS(); + throw e; +} +``` + +Conforme mostrado, isso irá gerar blocos e uma transação: +``` +$ node test.js +Launching nodes... +Connected! +Generated 110 blocks +n2.balance (before) = 0 +Generated transaction = 91e0040c26fc18312efb80bad6ec3b00202a83465872ecf495c392a0b6afce35 +n2.after (before) = 100 + +``` + +## Resumo: Usando o Bitcoin Regtest + +Um ambiente regtest para o Bitcoin funciona como qualquer ambiente testnet, exceto que teremos a capacidade de gerar blocos de maneira rápida e fácil. + + > :fire: ***Qual é o poder da regtest?*** O maior poder da regtest é que podemos minerar blocos rapidamente, permitindo que nos apressemos na blockchain, para testar transações, timelocks e outros recursos que podemos querer, caso contrário, teríamos de sentar e esperar. No entanto, o outro poder é que podemos executar de forma privada, sem nos conectarmos a uma blockchain pública, nos permitindo testar nossas ideias antes de liberá-las para o mundo. + +## O Que Vem Depois? + +Se estamos visitando o Apêndice enquanto trabalhamos em alguma outra parte do curso, devemos voltar para lá. + +Mas, caso contrário, chegamos ao fim! Outras pessoas que trabalharam neste curso tornaram-se desenvolvedores e engenheiros profissionais no mundo do Bitcoin, incluindo alguns dos quais contribuíram para o [Blockchain Commons](https://www.blockchaincommons.com/). Nós o encorajamos a fazer o mesmo! Basta sair e começar a trabalhar em alguns dos códigos do Bitcoin usando o que aprendemos. \ No newline at end of file From e612796ff86c7e161eea859735404240b62135ab Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 10:19:16 -0300 Subject: [PATCH 064/155] Review 12_0 --- pt/12_0_Expanding_Bitcoin_Scripts.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pt/12_0_Expanding_Bitcoin_Scripts.md b/pt/12_0_Expanding_Bitcoin_Scripts.md index 2354278..ec48dfc 100644 --- a/pt/12_0_Expanding_Bitcoin_Scripts.md +++ b/pt/12_0_Expanding_Bitcoin_Scripts.md @@ -2,7 +2,7 @@ Ainda há um pouco mais sobre os Scripts do Bitcoin que precisamos saber. As condicionais fornecem acesso total ao controle de fluxo, enquanto uma variedade de outros opcodes podem expandir nossas possibilidades. -## Objetivos deste capítulo +## Objetivos Deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: @@ -11,10 +11,10 @@ Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: Os objetivos secundários do capítulo incluem a capacidade de: - * Compreender toda a gama de possibilidades do script; + * Compreender toda a gama de possibilidades de programação; * Identificar como aprender mais sobre os opcodes. -## Tabela de conteúdo +## Tabela de Conteúdo -* [Seção 1: Usando condicionais no script](12_1_Using_Script_Conditionals.md) -* [Seção 2: Usando outros comandos no script](12_2_Using_Other_Script_Commands.md) \ No newline at end of file +* [Seção 1: Usando Condicionais no Script](12_1_Using_Script_Conditionals.md) +* [Seção 2: Usando Outros Comandos no Script](12_2_Using_Other_Script_Commands.md) \ No newline at end of file From a0e422b75e53d6286687a70654272df6bc2a1a2c Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 10:40:21 -0300 Subject: [PATCH 065/155] Review 12_1 --- pt/12_1_Using_Script_Conditionals.md | 50 ++++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/pt/12_1_Using_Script_Conditionals.md b/pt/12_1_Using_Script_Conditionals.md index aab7ad9..88ce03a 100644 --- a/pt/12_1_Using_Script_Conditionals.md +++ b/pt/12_1_Using_Script_Conditionals.md @@ -1,32 +1,32 @@ -# 12.1: Usando condicionais no script +# 12.1: Usando Condicionais no Script Há um aspecto importante na criação de Script de Bitcoin que é crucial para expandir o seu verdadeiro poder. Os condicionais permitem que criemos vários caminhos de execução. ## Entendendo as Verificações -Já vimos um condicional dentro do script, o ```op_verify``` (0x69). Ele retira o item superior na pilha e verifica se é verdade. Se não for _ele termina a execução do script_. +Já vimos um condicional dentro do script, o ```op_verify``` (0x69). Ele retira o item superior na pilha e verifica se é verdade. Se não for, _ele termina a execução do script_. -A verificação é geralmente incorporada em outros opcodes. Já vimos o ```OP_EQUALVERIFY``` (0xad), o ```OP_CHECKLOCKTIMEVERIFY``` (0xb1) e o ```OP_CHECKSEQUENCEVERIFY``` (0xb2). Cada um desses opcodes faz nossa ação central (equal, checklocktime ou checkscence) e então faz uma verificação posteriormente. Os outros opcodes de verificação que ainda não vimos são: ```OP_NUMEQUALVERIFY``` (0x9d), ```OP_CHECKSIGVERIFY``` (0xad), e ```OP_CHECKMULTISIGVERIFY``` (0xaf). +A verificação é geralmente incorporada em outros opcodes. Já vimos o ```OP_EQUALVERIFY``` (0xad), o ```OP_CHECKLOCKTIMEVERIFY``` (0xb1) e o ```OP_CHECKSEQUENCEVERIFY``` (0xb2). Cada um desses opcodes faz nossa ação central (equal, checklocktime ou checksequence) e então faz uma verificação posteriormente. Os outros opcodes de verificação que ainda não vimos são: ```OP_NUMEQUALVERIFY``` (0x9d), ```OP_CHECKSIGVERIFY``` (0xad), e ```OP_CHECKMULTISIGVERIFY``` (0xaf). -Então, como o ```OP_VERIFY``` é um condicional? É o tipo mais poderoso de condicional. Usando o ```OP_VERIFY```, _SE_ uma condição é verdadeira, o script continua executando, _SENÃO_ o script para a execução. É assim que verificamos as condições que são absolutamente necessárias para que um script tenha sucesso. Por exemplo, o script P2PKH (```OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG```) tem duas condições necessárias: (1) a chave pública fornecida precisa corresponder ao hash da chave pública e; (2) a assinatura fornecida precisa corresponder a essa chave pública. Um ```OP_EQUALVERIFY``` é usado para a comparação do hash da chave pública e a chave pública do hash porque é uma condição absolutamente necessária. Não _QUEREMOS_ que o script continue caso venha a falhar. +Então, como o ```OP_VERIFY``` é um condicional? É o tipo mais poderoso de condicional. Usando o ```OP_VERIFY```, _se_ uma condição é verdadeira, o script continua executando, _senão_ o script pára a execução. É assim que verificamos as condições que são absolutamente necessárias para que um script tenha sucesso. Por exemplo, o script P2PKH (```OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG```) tem duas condições necessárias: (1) a chave pública fornecida precisa corresponder ao hash da chave pública e; (2) a assinatura fornecida precisa corresponder à essa chave pública. Um ```OP_EQUALVERIFY``` é usado para a comparação do hash da chave pública e a chave pública do hash porque é uma condição absolutamente necessária. Não _queremos_ que o script continue caso isto falhe. -Podemos notar que não há ```OP_VERIFY``` no final deste (ou da maioria dos demais) script, apesar da condição final também ser necessária. Isso porque o Bitcoin efetivamente faz um ```OP_VERIFY``` no final de cada roteiro, para garantir que o resultado final da pilha seja verdadeiro. Não podemos fazer um ```OP_VERIFY``` antes do final do script, porque precisamos deixar algo na pilha para ser testado! +Podemos notar que não há ```OP_VERIFY``` no final deste script (ou da maioria dos demais), apesar da condição final também ser necessária. Isso porque o Bitcoin efetivamente faz um ```OP_VERIFY``` no final de cada script, para garantir que o resultado final da pilha seja verdadeiro. Não podemos fazer um ```OP_VERIFY``` antes do final do script, porque precisamos deixar algo na pilha para ser testado! -## Entendendo o If/Then (Se/Então) +## Compreendendo o If/Then (Se/Então) -O outro condicional principal no script do Bitcoin é o clássico ```OP_IF``` (0x63) / ```OP_ELSE``` (0x67) / ```OP_ENDIF``` (0x68). Este é o controle típico do fluxo: Se o ```OP_IF``` detectar uma afirmação verdadeira, executa o bloco abaixo dele, caso contrário, se houver um ```OP_ELSE```, executa-o e; o ```OP_ENDIF``` marca o final do bloco. +O outro condicional principal no script do Bitcoin é o clássico ```OP_IF``` (0x63) / ```OP_ELSE``` (0x67) / ```OP_ENDIF``` (0x68). Este é o controle típico de fluxo: se o ```OP_IF``` detectar uma afirmação verdadeira, ele executa o bloco abaixo dele, caso contrário, se houver um ```OP_ELSE```, ele o executa; e o ```OP_ENDIF``` marca o final do bloco. > :warning: **AVISO:** Estes condicionais tecnicamente são opcodes também, mas como são pequenos números, vamos deixar o prefixo do ```OP_``` desligado para manter a brevidade e a clareza. Assim, vamos escrever ```IF```, ```ELSE```, e ```ENDIF``` ao invés de ```OP_IF```, ```OP_ELSE```, e ```OP_ENDIF```. -### Entendendo a Ordem do If/Then +### Compreendendo a Ordem do If/Then Existem duas grandes sacadas nos condicionais. Eles dificultam a leitura e determinam os scripts se não tivermos cuidado. -Primeiro, o ```IF``` condicional verifica a verdade do que é _antes dele_ (em outras palavras, o que está na pilha), não o que está depois dele. +Primeiro, o condicional ```IF``` verifica a verdade do que é _antes dele_ (em outras palavras, o que está na pilha), e não o que está depois dele. -Segundo, o ```IF``` condicional tende a estar no script de bloqueio e o que é verificado tende a estar no script de desbloqueio. +Segundo, o condicional ```IF``` tende a estar no script de bloqueio e o que é verificado tende a estar no script de desbloqueio. -Claro, podemos dizer, é assim que funciona o Script do Bitcoin. Condicionais usam notação polonesa reversa e adotam o paradigma padrão de desbloqueio/bloqueio, assim como todos os scripts do bitcoin. Isso é tudo verdade, mas também vai ao contrário da maneira padrão que lemos IF/ELSE condicionais em outras linguagens de programação. Assim, é fácil lermos inconscientemente errado os condicionais do Bitcoin. +Claro, podemos dizer, é assim que funciona o Script do Bitcoin. Condicionais usam notação polonesa reversa e adotam o paradigma padrão de desbloqueio/bloqueio, assim como todos os scripts do bitcoin. Isso é tudo verdade, mas também é o contrário da maneira padrão de ler-se condicionais IF/ELSE em outras linguagens de programação. Assim, é fácil lermos errado, inconscientemente, os condicionais do Bitcoin. Vamos observar o seguinte código: `IF OP_DUP OP_HASH160 ELSE OP_DUP OP_HASH160 ENDIF OP_EQUALVERIFY OP_CHECKSIG`. @@ -43,7 +43,7 @@ ENDIF OP_EQUALVERIFY OP_CHECKSIG ``` -Então, podemos pensar, se o ```OP_DUP``` é verdadeiro, então nós vamos fazer o primeiro bloco, senão, o segundo. Mas isso não faz sentido! Por que o ```OP_DUP``` não daria verdadeiro?! +Então, podemos pensar, se o ```OP_DUP``` é verdadeiro, então nós vamos fazer o primeiro bloco, senão, o segundo. Mas isso não faz sentido! Por que o ```OP_DUP``` não executaria com sucesso?! E, de fato, não faz nenhum sentido, porque acidentalmente lemos a declaração usando a notação errada. A leitura correta é: ``` @@ -59,13 +59,13 @@ ENDIF OP_EQUALVERIFY OP_CHECKSIG ``` -A declaração que avaliará para é ```True``` ou ```False``` é colocada na pilha _antes_ de executar o ```IF```, então o bloco correto do código será executado com base nesse resultado. +A declaração que avaliará para ```True``` ou ```False``` é colocada na pilha _antes_ de executar o ```IF```, então o bloco correto do código será executado com base naquele resultado. -Este exemplo específico de código é destinado a uma simples multisig 1-de-2. O proprietário da `````` colocaria ``` TRUE``` no script de desbloqueio, enquanto o proprietário da `````` colocaria ``` FALSE``` no script de desbloqueio. Aquele que for rastreado como ```TRUE``` ou ```FALSE``` é o que é verificado pela instrução ```IF```/```ELSE```. Ele conta ao script qual o hash da chave pública é para verificar, então o ```OP_EQUALVERIFY``` e o ```OP_CHECKSIG``` no final fazem o verdadeiro trabalho. +Este exemplo específico de código é destinado a um simples multisig 1-de-2. O proprietário da `````` colocaria ``` TRUE``` no script de desbloqueio, enquanto o proprietário da `````` colocaria ``` FALSE``` no script de desbloqueio. Aquele que for rastreado como ```TRUE``` ou ```FALSE``` é o que é verificado pela instrução ```IF```/```ELSE```. Ele conta ao script qual o hash da chave pública é para verificar, então o ```OP_EQUALVERIFY``` e o ```OP_CHECKSIG``` no final fazem o verdadeiro trabalho. ### Executando um If/Then com Multisig -Com uma compreensão central dos condicionais do Bitcoin, estamos prontos para executar scripts utilizando-os. Nós vamos começar, criando uma ligeira variante da multisig 1-de-2 do exemplo, onde nossos usuários não precisam lembrar se eles são ```TRUE``` ou ```FALSE```. Ao invés disso, se necessário, o script verifica os hashes de chave pública, apenas exigindo um único sucesso: +Com uma compreensão central dos condicionais do Bitcoin, estamos prontos para executar scripts os utilizando. Nós vamos começar criando uma ligeira variante do multisig 1-de-2 do exemplo, onde nossos usuários não precisam lembrar se eles são ```TRUE``` ou ```FALSE```. Ao invés disso, se necessário, o script verifica os hashes de chave pública, apenas exigindo um único sucesso: ``` OP_DUP OP_HASH160 OP_EQUAL IF @@ -74,7 +74,7 @@ ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF ``` -Precisamos lembrar da notação polonesa reversa! Aquela instrução ```IF``` está referindo-se ao ```OP_EQUAL``` antes dela, não ao `OP_CHECKSIG` posterior! +Precisamos lembrar da notação polonesa reversa! Aquela instrução ```IF``` está se referindo ao ```OP_EQUAL``` antes dela, não ao `OP_CHECKSIG` posterior! #### Executando a Parte Verdadeira @@ -88,7 +88,7 @@ Primeiro, colocamos as constantes na pilha: Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF Stack: [ ] ``` -Em seguida, nós executamos os primeiros, comandos óbvios, ```OP_DUP``` e ```OP_HASH160``` e colocamos outra constante: +Em seguida, nós executamos os primeiros comandos óbvios, ```OP_DUP``` e ```OP_HASH160```, e colocamos outra constante: ``` Script: OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF Running: OP_DUP @@ -107,7 +107,7 @@ Script: IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CH Running: OP_EQUAL Stack: [ True ] ``` -Agora, o ```IF``` executa, e desde que seja um ```TRUE```, ele só executa o primeiro bloco, eliminando todo o resto: +Agora, o ```IF``` executa, e desde que haja um ```TRUE```, ele só executa o primeiro bloco, eliminando todo o resto: ``` Script: OP_CHECKSIG Running: True IF @@ -122,7 +122,7 @@ Stack: [ True ] #### Executando a Parte Falsa -Veja como ele iria executar se fossemos desbloquear com ``` ```: +Veja como ele iria executar se fôssemos desbloquear com ``` ```: ``` Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF Stack: [ ] @@ -132,7 +132,7 @@ Primeiro, colocamos as constantes na pilha: Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF Stack: [ ] ``` -Em seguida, executamos os primeiros, comandos óbvios, ```OP_DUP``` e ```OP_HASH160``` e adicionamos outra constante: +Em seguida, executamos os primeiros comandos óbvios, ```OP_DUP``` e ```OP_HASH160```, e adicionamos outra constante: ``` Script: OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF Running: OP_DUP @@ -178,7 +178,7 @@ Script: Running: OP_CHECKSIG Stack: [ True ] ``` -Isso provavelmente não é tão eficiente quanto um verdadeiro multisig do Bitcoin, mas é um bom exemplo de como os resultados adicionados a pilha devido a testes anteriores podem ser usados para alimentar futuros condicionais. Neste caso, é o fracasso da primeira assinatura que diz a condicional que deve ir verificar a segunda. +Isso provavelmente não é tão eficiente quanto um verdadeiro multisig do Bitcoin, mas é um bom exemplo de como os resultados adicionados à pilha devido a testes anteriores podem ser usados para alimentar condicionais futuros. Neste caso, é o fracasso da primeira assinatura que diz ao condicional que deve ir verificar a segunda. ## Entendendo os Demais Condicionais @@ -188,12 +188,12 @@ Há também um ```OP_IFDUP``` (0x73), que duplica o item de pilha superior somen Essas opções são usadas com muito menos frequência do que a construção usando ```IF```/```ELSE```/```ENDIF```. -## Resumo: Usando condicionais no script +## Resumo: Usando Condicionais no Script -Os condicionais no script do Bitcoin permitem deter o script (usando o ```OP_VERIFY```) ou para escolher diferentes ramos de execução (usando ```OP_IF```). No entanto, a ler o ```OP_IF``` pode ser um pouco complicado. Precisamos lembrar de que é o item adicionado a pilha _antes_ do operador ```OP_IF``` ser executado que controla a sua execução. Esse item normalmente fará parte do script de desbloqueio (ou será um resultado direto de itens do script de desbloqueio). +Os condicionais no script do Bitcoin permitem parar o script (usando o ```OP_VERIFY```) ou escolher diferentes ramos de execução (usando ```OP_IF```). No entanto, ler o ```OP_IF``` pode ser um pouco complicado. Precisamos lembrar de que é o item adicionado à pilha _antes_ do operador ```OP_IF``` ser executado que controla a sua execução. Esse item normalmente fará parte do script de desbloqueio (ou será um resultado direto de itens do script de desbloqueio). -> :fire: ***Qual é o poder dos condicionais?*** Os condicionais do script são o principal bloco de construção no script do Bitcoin. Eles transformam os scripts simples e estáticos do Bitcoin em scripts de bitcoin complexos e dinâmicos que podem avaliar de maneira diferente com base em diferentes momentos, diferentes circunstâncias ou diferentes entradas de usuário. Em outras palavras, eles são o último pilar dos contratos inteligentes. +> :fire: ***Qual é o poder dos condicionais?*** Os condicionais do script são o principal bloco de construção no Bitcoin Script. Eles transformam os scripts simples e estáticos do Bitcoin em scripts de Bitcoin complexos e dinâmicos que podem avaliar de maneira diferente com base em diferentes momentos, diferentes circunstâncias ou diferentes entradas de usuário. Em outras palavras, eles são o último pilar dos contratos inteligentes. ## O Que Vem Depois? -Vamos continuar "Expandindo os Scripts do Bitcoin" na seção [§12.2: Usando outros comandos no script](12_2_using_other_script_commands.md). \ No newline at end of file +Vamos continuar "Expandindo os Scripts do Bitcoin" na seção [§12.2: Usando Outros Comandos no Script](12_2_using_other_script_commands.md). \ No newline at end of file From 4f380e5180b40f841f139172414108378ff31ca3 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 10:53:32 -0300 Subject: [PATCH 066/155] Review 12_2 --- pt/12_2_Using_Other_Script_Commands.md | 34 +++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/pt/12_2_Using_Other_Script_Commands.md b/pt/12_2_Using_Other_Script_Commands.md index d44c1fb..88055ae 100644 --- a/pt/12_2_Using_Other_Script_Commands.md +++ b/pt/12_2_Using_Other_Script_Commands.md @@ -1,8 +1,8 @@ -# 12.2: Usando outros comandos no script +# 12.2: Usando Outros Comandos no Script -Já temos em mãos a maioria dos opcodes do script do Bitcoin que iremos usar na maioria dos nossos scripts. No entanto, o script do Bitcoin oferece muito mais opções, o que pode vir a ser exatamente o que precisamos para criar o nosso instrumento financeiro dos nossos sonhos. +Provavelmente já temos em mãos a maioria dos opcodes do Bitcoin Script que iremos usar na maioria dos nossos scripts. No entanto, o Bitcoin Script oferece muito mais opções, o que pode vir a ser exatamente o que precisamos para criar o instrumento financeiro dos nossos sonhos. -Devemos consultar a [página do script do Bitcoin](https://en.bitcoin.it/wiki/script) para termos uma lista mais completa de todos esses e muitos outros comandos. Esta seção destaca apenas os opcodes mais notáveis. +Devemos consultar a [página do script do Bitcoin](https://en.bitcoin.it/wiki/script) para termos uma lista mais completa de todos esses e muitos outros comandos. Esta seção destaca apenas os opcodes mais notáveis. ## Entendendo os Opcodes Aritméticos @@ -13,10 +13,10 @@ Manipulam um número: * OP_1ADD (0x8b) - Adiciona uma unidade; * OP_1SUB (0x8C) - Subtrai uma unidade; * OP_NEGATE (0x8f) - Inverte o sinal do número; -* OP_ABS (0x90) - O número fica positivo; +* OP_ABS (0x90) - Torna o número positivo; * OP_NOT (0x91) - Troca 1 por 0, senão 0. -É legal saber sobre o ```OP_0NOTEQUAL``` (0x92). +Veja também: ```OP_0NOTEQUAL``` (0x92). Manipulam dois números matematicamente: @@ -38,15 +38,15 @@ Testa dois números: * OP_LESSTHANOREQUAL (0xA1) - 1 se o primeiro número for menor ou igual ao segundo, senão 0; * OP_GREATERTHANOREQUAL (0xA2) - 1 se o primeiro número for maior ou igual a segundo, senão 0. -É legal saber também: O ```OP_NUMEQUALVERIFY``` (0x9d) e o ```OP_NUMNOTEQUAL``` (0x9e) +Veja também: ```OP_NUMEQUALVERIFY``` (0x9d) e ```OP_NUMNOTEQUAL``` (0x9e) Testa três números: * OP_WITHIN (0xA5) - 1 se um número estiver no intervalo de dois outros números. -## Entendendo a Opcodes de Pilha +## Compreendendo os Opcodes de Pilha -Há um número chocante de opcodes de pilha, mas além de ```OP_DROP```, ```OP_DUP```, e às vezes, ```OP_SWAP``` geralmente não serão necessários se tivermos cuidado com a ordem da pilha. No entanto, aqui estão alguns dos mais interessantes: +Há um número chocante de opcodes de pilha, mas além de ```OP_DROP```, ```OP_DUP```, e às vezes ```OP_SWAP```, eles geralmente não serão necessários se tivermos cuidado com a ordem da pilha. No entanto, aqui estão alguns dos mais interessantes: * OP_DEPTH (0x74) - Aumenta o tamanho da pilha; * OP_DROP (0x75) - Retira o item superior da pilha; @@ -55,11 +55,11 @@ Há um número chocante de opcodes de pilha, mas além de ```OP_DROP```, ```OP_D * OP_ROLL (0x7a) - Move o enésimo item para o topo da pilha; * OP_SWAP(0x7C) - Troca os dois principais itens da pilha. -É legal saber também: O `OP_TOALTSTACK` (0x6b), `OP_FROMALTSTACK` (0x6c), `OP_2DROP` (0x6d), `OP_2DUP` (0x6e), `OP_3DUP` (0x6f), `OP_2OVER` (0x70), `OP_2ROT` (0x71), `OP_2SWAP` (0x72), `OP_IFDUP` (0x73), `OP_NIP` (0x77), `OP_OVER` (0x78), `OP_ROT` (0x7b), e o `OP_TUCK` (0x7d). +Veja também: `OP_TOALTSTACK` (0x6b), `OP_FROMALTSTACK` (0x6c), `OP_2DROP` (0x6d), `OP_2DUP` (0x6e), `OP_3DUP` (0x6f), `OP_2OVER` (0x70), `OP_2ROT` (0x71), `OP_2SWAP` (0x72), `OP_IFDUP` (0x73), `OP_NIP` (0x77), `OP_OVER` (0x78), `OP_ROT` (0x7b), e `OP_TUCK` (0x7d). -## Entendendo os Opcodes Criptográficos +## Compreendendo os Opcodes Criptográficos -Finalmente, uma variedade de opcodes para dar suporte ao hashing e a verificação da assinatura: +Finalmente, uma variedade de opcodes para dar suporte ao hashing e à verificação de assinatura: Hash: @@ -71,15 +71,15 @@ Hash: Verifica as assinaturas: -* Op_checksig (0xac) - Verifica uma assinatura; -* Op_checkmultisig (0xae) - Verifica uma multisig M-DE-N. +* OP_CHECKSIG (0xac) - Verifica uma assinatura; +* OP_CHECKMULTISIG (0xae) - Verifica um multisig m-de-n. -É legal saber também: O `OP_CODESEPARATOR` (0xab), `OP_CHECKSIGVERIFY` (0xad), e o `OP_CHECKMULTISIGVERIFY` (0xaf). +Veja também: `OP_CODESEPARATOR` (0xab), `OP_CHECKSIGVERIFY` (0xad), e `OP_CHECKMULTISIGVERIFY` (0xaf). -## Resumo: Usando outros comandos no script +## Resumo: Usando Outros Comandos no Script -O script do Bitcoin inclui uma ampla gama de opcodes aritméticos, de pilha e criptográficos. A maioria desses opcodes adicionais provavelmente não serão tão comuns quanto os discutidos nas seções anteriores, mas, no entanto, estão disponíveis, para sabermos que existem caso precisemos utilizá-los para escrever nosso script! +O Bitcoin Script inclui uma ampla gama de opcodes aritméticos, de pilha e criptográficos. A maioria desses opcodes adicionais provavelmente não serão tão comuns quanto os discutidos nas seções anteriores, mas, no entanto, estão disponíveis caso precisemos utilizá-los para escrever nosso script! ## O Que Vem Depois? -Vamos avançar do "Expandindo os Scripts do Bitcoin" para o [Capítulo 13: Projetando Scripts Reais no Bitcoin](13_0_Designing_real_bitcoin_scripts.md). \ No newline at end of file +Vamos avançar "Expandindo os Scripts do Bitcoin" com o [Capítulo 13: Projetando Scripts Reais no Bitcoin](13_0_Designing_real_bitcoin_scripts.md). \ No newline at end of file From 54e37d4f5bf67395d05ae1d64b9e94cb62be4e7b Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 11:04:42 -0300 Subject: [PATCH 067/155] Review 13_0 --- pt/13_0_Designing_Real_Bitcoin_Scripts.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pt/13_0_Designing_Real_Bitcoin_Scripts.md b/pt/13_0_Designing_Real_Bitcoin_Scripts.md index a602de6..76c5645 100644 --- a/pt/13_0_Designing_Real_Bitcoin_Scripts.md +++ b/pt/13_0_Designing_Real_Bitcoin_Scripts.md @@ -1,21 +1,22 @@ # Capítulo 13: Projetando Scripts Reais no Bitcoin -Nossos scripts do Bitcoin até agora têm sido exemplos teóricos, porque ainda estamos montando as peças do quebra-cabeça. Agora, com o repertório completo do Script do Bitcoin em mãos, estamos prontos para nos aprofundar em vários scripts do mundo real e ver como eles funcionam. +Até então, nossos scripts no Bitcoin têm sido exemplos teóricos, porque ainda estamos montando as peças do quebra-cabeça. Agora, com o repertório completo do Bitcoin Script em mãos, estamos prontos para nos aprofundarmos em vários scripts do mundo real e ver como eles funcionam. -## Objetivos deste Capítulo +## Objetivos Deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - * Avaliar os scripts do Bitcoin do mundo real; - * Criar scripts do Bitcoin no mundo real. - +* Avaliar scripts do Bitcoin do mundo real; +* Criar scripts do Bitcoin no mundo real. + + Os objetivos secundários incluem a capacidade de: - * Entender os scripts do Bitcoin existentes; - * Compreender a importância das assinaturas. +* Entender os scripts do Bitcoin existentes; +* Compreender a importância das assinaturas. ## Tabela de Conteúdo - * [Seção 1: Escrevendo Puzzles com Scripts](13_1_Writing_Puzzle_Scripts.md) - * [Seção 2: Escrevendo Scripts Multisig Complexos](13_2_Writing_Complex_Multisig_Scripts.md) - * [Seção 3: Expandindo o Bitcoin com os Scripts](13_3_Empowering_Bitcoin_with_Scripts.md) \ No newline at end of file + * [Seção 1: Escrevendo Scripts de Quebra-Cabeças](13_1_Writing_Puzzle_Scripts.md) + * [Seção 2: Escrevendo Scripts Complexos de Multisig](13_2_Writing_Complex_Multisig_Scripts.md) + * [Seção 3: Capacitando o Bitcoin com Scripts](13_3_Empowering_Bitcoin_with_Scripts.md) \ No newline at end of file From 3347fc570b69eb0ad6ea1fa546ec532b90f600f0 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 11:38:01 -0300 Subject: [PATCH 068/155] Review 13_1 --- pt/13_1_Writing_Puzzle_Scripts.md | 49 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/pt/13_1_Writing_Puzzle_Scripts.md b/pt/13_1_Writing_Puzzle_Scripts.md index 961a253..3b4ce1f 100644 --- a/pt/13_1_Writing_Puzzle_Scripts.md +++ b/pt/13_1_Writing_Puzzle_Scripts.md @@ -1,22 +1,22 @@ -# 13.1: Escrevendo Puzzles com Scripts +# 13.1: Escrevendo Scripts de Quebra-Cabeça -Os scripts de Bitcoin realmente _não_ precisam depender do conhecimento de uma chave secreta. Ao invés disso, podemos criar puzzles de qualquer tipo. +Os scripts de Bitcoin realmente _não_ precisam depender do conhecimento de uma chave secreta. Ao invés disso, eles podem ser quebra-cabeças de qualquer tipo. ## Escrevendo Scripts de Álgebra Simples -Nosso primeiro script real, da seção [§9.2: Executando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md) foi um puzzle simples. Esse script Bitcoin, ```OP_ADD 99 OP_EQUAL```, poderia ter sido descrito da seguinte forma: ```x + y = 99```. +Nosso primeiro script real, da seção [§9.2: Executando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md) foi um quebra-cabeça simples. Esse script Bitcoin, ```OP_ADD 99 OP_EQUAL```, poderia ter sido descrito da seguinte forma: ```x + y = 99```. Esse tipo de script não tem muita aplicabilidade no mundo real, pois é muito fácil reivindicar os fundos. Mas, um quebra-cabeça que distribui pequenos valores em Bitcoin pode ser um entretenimento divertido. -Mais notavelmente, a criação de puzzles algébricos fornece uma boa compreensão de como funcionam as funções aritméticas no script do Bitcoin. +Mais notavelmente, a criação de quebra-cabeças algébricos fornece uma boa compreensão de como funcionam as funções aritméticas no Bitcoin Script. -### Escrevendo um script multiplicador +### Escrevendo um Script Multiplicador -O Script do Bitcoin possui vários opcodes que foram desativados para manter a segurança do sistema. Um deles é o ```OP_MUL```, que teria permitido a multiplicação, mas, está desabilitado. +O Bitcoin Script possui vários opcodes que foram desativados para manter a segurança do sistema. Um deles é o ```OP_MUL```, que teria permitido a multiplicação, mas, está desabilitado. Então, como escreveríamos uma função algébrica como ```3x + 7 = 13```? -A resposta mais óbvia é usando o ```OP_DUP``` o número inserido no script de bloqueio duas vezes. Então podemos colocar o ```7``` e continuar adicionando até obter o total. O script de bloqueio completo ficaria assim: ```OP_DUP OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL```. +A resposta mais óbvia é usando o ```OP_DUP``` no número inserido no script de bloqueio duas vezes. Então podemos colocar o ```7``` e continuar adicionando até obter o total. O script de bloqueio completo ficaria assim: ```OP_DUP OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL```. Veja como seria executado o script de desbloqueio correto do ```2```: ``` @@ -175,7 +175,7 @@ script | stack ``` ### Escrevendo um Sistema de Equações -E se quiséssemos escrever um sistema de equações, como ```x + y = 3```,```y + z = 5``` e ```x + z = 4```? A álgebra diz que as respostas resultariam em ```x = 1```,```y = 2``` e ```z = 3```. Mas, como faríamos este script? +E se quiséssemos escrever um sistema de equações, como ```x + y = 3```,```y + z = 5``` e ```x + z = 4```? A álgebra diz que as respostas resultariam em ```x = 1```,```y = 2``` e ```z = 3```. Mas, como programamos isso? Obviamente, depois que o remetente inserir os três números, precisaremos de duas cópias de cada número, uma vez que cada número entra em duas equações diferentes. O ```OP_3DUP``` cuida disso e resulta em```x y z x y z``` estando na pilha. Tirar dois itens de cada vez resultará em ```y z```,```z x``` e ```x y```. Pronto! Essas são as três equações, então só precisamos adicioná-las e testá-las na ordem correta! Aqui está o script completo: ```OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL```. @@ -421,13 +421,13 @@ script | stack | 01 ``` -> :warning: **ATENÇÃO** O ```btcdeb``` não é útil apenas para fornecer a visualização desses scripts, mas também para verificar os resultados. Com certeza, erramos na primeira vez, testando as equações na ordem errada. É tão fácil cometer um erro financeiramente fatal em um script Bitcoin, e é por isso que todo script deve ser testado exaustivamente. +> :warning: **ATENÇÃO** O ```btcdeb``` não é útil apenas para fornecer a visualização desses scripts, mas também para verificar os resultados. Com certeza, erramos na primeira vez, testando as equações na ordem errada. É tão fácil cometer um erro financeiramente fatal em um script do Bitcoin, e é por isso que todo script deve ser testado exaustivamente. ## Escrevendo Scripts Computacionais Simples -Embora os scripts de puzzle sejam triviais, podem realmente ter utilidade no mundo real se quisermos terceirizar uma computação. Podemos simplesmente criar um script que requer a resposta do cálculo e enviar fundos para o endereço P2SH como recompensa. Assim, a recompensa ficará lá até que alguém dê a resposta. +Embora os scripts de quebra-cabeça sejam triviais, podem realmente ter utilidade no mundo real se quisermos terceirizar uma computação. Podemos simplesmente criar um script que requer a resposta do cálculo e enviar fundos para o endereço P2SH como recompensa. Assim, a recompensa ficará lá até que alguém dê a resposta. -Por exemplo, Peter Todd [ofereceu recompensas](https://bitcointalk.org/index.php?topic=293382.0) por resolver equações que demonstram colisões para algoritmos criptográficos padrão. Aqui estava o script para confirmar uma colisão SHA1: ```OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL```. Requer duas entradas, que serão os dois números que colidem. +Por exemplo, Peter Todd [ofereceu recompensas](https://bitcointalk.org/index.php?topic=293382.0) para resolver equações que demonstram colisões para algoritmos criptográficos padrão. Aqui estava o script para confirmar uma colisão SHA1: ```OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL```. Requer duas entradas, que serão os dois números que colidem. Veja como funciona com as respostas corretas. @@ -443,8 +443,7 @@ Script: OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL Running: OP_2DUP Stack: [ ] ``` -Then, we make sure the two numbers aren't equal, exiting if they are: -Em seguida, certificamo-nos de que os dois números não são iguais, saindo se forem: +Em seguida, nos certificamos de que os dois números não são iguais, saindo se forem: ``` Script: OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL Running: OP_EQUAL @@ -458,7 +457,6 @@ Script: OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL Running: True OP_VERIFY Stack: [ ] — Does Not Exit ``` -We now create two SHAs: Agora criamos dois SHAs: ``` Script: OP_SWAP OP_SHA1 OP_EQUAL @@ -473,40 +471,39 @@ Script: OP_EQUAL Running: OP_SHA1 Stack: [ ] ``` -Finally, we see if they match. Finalmente, vemos se eles combinam. ``` Script: Running: OP_EQUAL Stack: [ True ] ``` -Este é um bom script porque mostra o uso cuidadoso da lógica (com o ```OP_NOT``` e o ```OP_VERIFY```) e bom uso das funções de pilha (com o ```OP_SWAP```). Trata-se de um ótimo exemplo de função do mundo real. E isso é muito real. Quando o [SHA-1 foi quebrado](https://shattered.io/), 2,48 BTC foram rapidamente liberados do endereço, com um valor total de cerca de $3.000 na época. +Este é um bom script porque mostra o uso cuidadoso da lógica (com o ```OP_NOT``` e o ```OP_VERIFY```) e bom uso das funções de pilha (com o ```OP_SWAP```). Trata-se de um ótimo exemplo de uma função do mundo real. E isso é muito real. Quando o [SHA-1 foi quebrado](https://shattered.io/), 2,48 BTC foram rapidamente liberados do endereço, com um valor total de cerca de $3.000 na época. O ```btcdeb``` pode ser executado para provar a colisão (e o script): ``` btcdeb $ btcdeb '[255044462d312e330a25e2e3cfd30a0a0a312030206f626a0a3c3c2f57696474682032203020522f4865696768742033203020522f547970652034203020522f537562747970652035203020522f46696c7465722036203020522f436f6c6f7253706163652037203020522f4c656e6774682038203020522f42697473506572436f6d706f6e656e7420383e3e0a73747265616d0affd8fffe00245348412d3120697320646561642121212121852fec092339759c39b1a1c63c4c97e1fffe017f46dc93a6b67e013b029aaa1db2560b45ca67d688c7f84b8c4c791fe02b3df614f86db1690901c56b45c1530afedfb76038e972722fe7ad728f0e4904e046c230570fe9d41398abe12ef5bc942be33542a4802d98b5d70f2a332ec37fac3514e74ddc0f2cc1a874cd0c78305a21566461309789606bd0bf3f98cda8044629a1 255044462d312e330a25e2e3cfd30a0a0a312030206f626a0a3c3c2f57696474682032203020522f4865696768742033203020522f547970652034203020522f537562747970652035203020522f46696c7465722036203020522f436f6c6f7253706163652037203020522f4c656e6774682038203020522f42697473506572436f6d706f6e656e7420383e3e0a73747265616d0affd8fffe00245348412d3120697320646561642121212121852fec092339759c39b1a1c63c4c97e1fffe017346dc9166b67e118f029ab621b2560ff9ca67cca8c7f85ba84c79030c2b3de218f86db3a90901d5df45c14f26fedfb3dc38e96ac22fe7bd728f0e45bce046d23c570feb141398bb552ef5a0a82be331fea48037b8b5d71f0e332edf93ac3500eb4ddc0decc1a864790c782c76215660dd309791d06bd0af3f98cda4bc4629b1 OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL'] ``` -As outras [recompensas](https://bitcointalk.org/index.php?topic=293382.0) de Peter Todd permanecem intocadas, pelo menos até o momento da redação deste artigo. Elas são todas escritos da mesma maneira que o exemplo SHA-1 acima. +As outras [recompensas](https://bitcointalk.org/index.php?topic=293382.0) de Peter Todd permanecem intocadas, pelo menos até o momento da redação deste artigo. Elas são todas escritas da mesma maneira que o exemplo SHA-1 acima. -## Compreendendo as Limitações dos Scripts de Puzzle +## Compreendendo as Limitações dos Scripts de Quebra-Cabeça -Os scripts de puzzle são ótimos para examinar mais detalhadamente os scripts do Bitcoin, mas só os veremos em uso no mundo real se estiverem mantendo pequenas quantias de fundos ou se forem destinados ao resgate por usuários muito habilidosos. Há uma razão para isso: Eles não são seguros. +Os scripts de quebra-cabeça são ótimos para examinar mais detalhadamente a programação no Bitcoin, mas só os veremos em uso no mundo real se estiverem mantendo pequenas quantias de fundos ou se forem destinados ao resgate por usuários muito habilidosos. Há uma razão para isso: eles não são seguros. É aqui que a segurança cai: -Primeiro, qualquer um pode resgatá-los sem saber muito sobre um segredo. Eles precisam ter o ```redeemScript```, que oferece alguma proteção, mas uma vez que consigam, esse é provavelmente o único segredo necessário, a menos que nosso puzzle seja _realmente_ difícil, como um quebra-cabeça computacional. +Primeiro, qualquer um pode resgatá-los sem saber muito sobre um segredo. Eles precisam ter o ```redeemScript```, sim, que oferece alguma proteção, mas uma vez que consigam, esse é provavelmente o único segredo necessário, a menos que nosso quebra-cabeça seja _realmente_ difícil, como um quebra-cabeça computacional. -Em segundo lugar, o resgate real não é seguro. Normalmente, uma transação de Bitcoin é protegida pela assinatura. Como a assinatura cobre a transação, ninguém na rede pode reescrever essa transação para enviar para o endereço sem invalidar a assinatura (e, portanto, a transação). Isso não é verdade com transações cujas entradas são apenas números. Qualquer um poderia pegar a transação e reescrevê-la para permitir o roubo dos fundos. Se eles conseguirem colocar a transação em um bloco antes da nossa transação, eles ganham e nós não receberemos o dinheiro do puzzle. Existem soluções para isso, mas elas envolvem a mineração do bloco por conta própria ou um pool confiável para minerá-lo, e nenhuma dessas opções é racional para um usuário comum do Bitcoin. +Em segundo lugar, o resgate real não é seguro. Normalmente, uma transação de Bitcoin é protegida pela assinatura. Como a assinatura cobre a transação, ninguém na rede pode reescrever essa transação para enviar para o endereço sem invalidar a assinatura (e, portanto, a transação). Isso não é verdade com transações cujas entradas são apenas números. Qualquer um poderia pegar a transação e reescrevê-la para permitir o roubo dos fundos. Se eles conseguirem colocar a transação em um bloco antes da nossa transação, eles ganham e nós não receberemos o dinheiro do quebra-cabeça. Existem soluções para isso, mas elas envolvem a mineração do bloco por conta própria ou um pool confiável para minerá-lo, e nenhuma dessas opções é racional para um usuário comum do Bitcoin. -Ainda assim, as recompensas criptográficas de Peter Todd provam que os scripts de quebra-cabeça têm alguma aplicação no mundo real. +Ainda assim, as recompensas criptográficas de Peter Todd provam que os scripts de quebra-cabeça têm sim alguma aplicação no mundo real. -## Resumo: Escrevendo Puzzles com Scripts +## Resumo: Escrevendo Quebra-Cabeças com Scripts -Os scripts de puzzles são uma ótima introdução aos scripts do Bitcoin mais realistas e complexos. Eles demonstram o poder das funções matemáticas e de pilha no script do Bitcoin e como podem ser cuidadosamente combinadas para criar perguntas que requerem respostas muito específicas. No entanto, o uso no mundo real também é limitado pelos problemas de segurança inerentes às transações Bitcoin não assinadas. +Os scripts de quebra-cabeça são uma ótima introdução aos scripts do Bitcoin mais realistas e complexos. Eles demonstram o poder das funções matemáticas e de pilha no Bitcoin Script e como podem ser cuidadosamente combinadas para criar perguntas que requerem respostas muito específicas. No entanto, o uso no mundo real também é limitado pelos problemas de segurança inerentes às transações no Bitcoin não assinadas. -> :fire: ***Qual é o poder do script de puzzles?*** Apesar das limitações, os scripts de puzzles têm sido usados ​​no mundo real como prêmios para recompensas computacionais. Qualquer pessoa que consiga descobrir um quebra-cabeça complexo, cuja solução provavelmente tenha algum impacto no mundo real, pode ganhar a recompensa. Se vão conseguir sacar para seus endereços, é outra questão. +> :fire: ***Qual é o poder do script de quebra-cabeça?*** Apesar das limitações, os scripts de quebra-cabeça têm sido usados ​​no mundo real como prêmios para recompensas computacionais. Qualquer pessoa que consiga descobrir um quebra-cabeça complexo, cuja solução provavelmente tenha algum impacto no mundo real, pode ganhar a recompensa. Se vão conseguir sacar para seus endereços, é outra questão. ## O Que Vem Depois? -Vamos continuar "Projetando Scripts Reais no Bitcoin" na seção [§13.2: Escrevendo Scripts Multisig Complexos](13_2_Writing_Complex_Multisig_Scripts.md). \ No newline at end of file +Vamos continuar "Projetando Scripts Reais no Bitcoin" na seção [§13.2: Escrevendo Scripts Complexos de Multisig](13_2_Writing_Complex_Multisig_Scripts.md). \ No newline at end of file From 67a386ae85c4577b71481596708748aaed89c907 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 12:08:52 -0300 Subject: [PATCH 069/155] Review 13_2 --- pt/13_2_Writing_Complex_Multisig_Scripts.md | 38 ++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/pt/13_2_Writing_Complex_Multisig_Scripts.md b/pt/13_2_Writing_Complex_Multisig_Scripts.md index d10286f..5b54736 100644 --- a/pt/13_2_Writing_Complex_Multisig_Scripts.md +++ b/pt/13_2_Writing_Complex_Multisig_Scripts.md @@ -2,15 +2,15 @@ Até o momento, os multisigs descritos nesses documentos têm sido inteiramente simples, na forma m-de-n ou n-de-n. No entanto, podemos desejar multisigs mais complexos, onde as pessoas que assinam as transações variam ou onde diferentes opções podem se tornar disponíveis ao longo do tempo. -## Escrevendo uma Multisig Variável +## Escrevendo um Multisig Variável -Uma multisig variável requer diferentes números de pessoas para assinar, dependendo de quem está assinando. +Um multisig variável requer diferentes números de pessoas para assinar, dependendo de quem está assinando. -### Escrevendo uma Multisig com um único assinante ou com vários assinantes +### Escrevendo um Multisig com um Único Assinante ou Cossignatários Imagine uma empresa em que o presidente ou dois em cada três vice-presidentes concordem com o uso dos fundos. -Podemos escrever isso criando uma instrução ```IF```/```ELSE```/```ENDIF``` que tem dois blocos, um para o presidente e sua assinatura um-de-um e um para os vice-presidentes e suas dois-de-três assinaturas. Podemos então, determinar qual bloco usar com base em quantas assinaturas estão no script de desbloqueio. Se usarmos ```OP_DEPTH 1 OP_EQUAL``` estaremos dizendo que há um item na pilha, e iremos partir daí. +Podemos escrever isso criando uma instrução ```IF```/```ELSE```/```ENDIF``` que tem dois blocos, um para o presidente e sua assinatura um-de-um e um para os vice-presidentes e suas assinaturas dois-de-três. Podemos então determinar qual bloco usar com base em quantas assinaturas estão no script de desbloqueio. Se usarmos ```OP_DEPTH 1 OP_EQUAL``` estaremos dizendo que há um item na pilha, e iremos partir daí. O script de bloqueio completo seria ```OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF```. @@ -78,15 +78,15 @@ Script: Running: 0 2 3 OP_CHECKMULTISIG Stack: [ ] ``` -Podemos notar que a assinatura do presidente usa apenas um simples ```OP_CHECKSIGNATURE``` ao invés do código mais complexo normalmente exigido para um P2PKH. Podemos nos safar incluindo a chave pública no script de bloqueio, evitando um trabalhão padrão, porque é o hash e não será revelado (por meio do ```redeemScript```) até que a transação seja desbloqueada. Isso também permite que todos os possíveis assinantes assinem usando a mesma metodologia. +Podemos notar que a assinatura do presidente usa apenas um simples ```OP_CHECKSIGNATURE``` ao invés do código mais complexo normalmente exigido para um P2PKH. Podemos nos safar em incluir a chave pública no script de bloqueio, evitando um trabalhão padrão, porque é um hash e não será revelado (por meio do ```redeemScript```) até que a transação seja desbloqueada. Isso também permite que todos os possíveis assinantes assinem usando a mesma metodologia. -O único problema é se o presidente estiver distraído e acidentalmente assinar uma transação com um dos vice-presidentes, porque ele se lembra de ser um multisig 2 de 3. Uma opção é decidir que essa é uma condição de falha aceitável, porque o presidente está usando o multsig incorretamente. Outra opção é transformar o multisig 2 de 3 em um multisig 2 de 4, caso o presidente não tolere falhas: ```OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 < pubKeyVPC> 4 OP_CHECKMULTISIG ENDIF```. Isso permitiria ao presidente assinar por engano com qualquer vice-presidente, mas não afetaria as coisas se dois vice-presidentes quisessem assinar (corretamente). +O único problema é se o presidente estiver distraído e acidentalmente assinar uma transação com um dos vice-presidentes, porque ele se lembra de ser um multisig 2-de-3. Uma opção é decidir que essa é uma condição de falha aceitável, porque o presidente está usando o multisig incorretamente. Outra opção é transformar o multisig 2-de-3 em um multisig 2-de-4, caso o presidente não tolere falhas: ```OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 < pubKeyVPC> 4 OP_CHECKMULTISIG ENDIF```. Isso permitiria ao presidente assinar por engano com qualquer vice-presidente, mas não afetaria as coisas se dois vice-presidentes quisessem assinar (corretamente). -### Escrevendo um Multisig com um assinante obrigatório +### Escrevendo um Multisig com um Assinante Obrigatório -Outra possibilidade de multisig envolve ter um multisig m-of-n onde um dos assinantes é necessário. Isso geralmente pode ser gerenciado dividindo o multisig em vários m de n-1 multisigs. Por exemplo, um multisig 2 de 3 em que um dos signatários é necessário seria, na verdade, dois multisig 2 de 2, cada um incluindo o signatário necessário. +Outra possibilidade de multisig envolve ter um multisig m-de-n onde um dos assinantes é necessário. Isso geralmente pode ser gerenciado dividindo o multisig em vários m de n-1 multisigs. Por exemplo, um multisig 2 de 3 em que um dos signatários é necessário seria, na verdade, dois multisigs 2-de-2, cada um incluindo o signatário necessário. -Esta é uma maneira simples de criar um script para isso: +Aqui está uma maneira simples de criar um script para isso: ``` OP_3DUP 2 2 OP_CHECKMULTISIG @@ -100,15 +100,15 @@ Primeiro, o script verifica as assinaturas no ``` ```. O resultado do ```OP_CHECKMULTISIG``` final que foi executado será deixado no topo da pilha (embora haja um resto abaixo dele se o primeiro for bem-sucedido). -## Escrevendo um Escrow Multisig +## Escrevendo um Multisig de Garantia -Falamos muito sobre escrows. Os multisigs complexos combinados com timelocks oferecem uma maneira automatizada de criá-los de maneira robusta. +Falamos muito sobre garantia. Os multisigs complexos combinados com timelocks oferecem uma maneira automatizada de criá-las de maneira robusta. -Imagine a compradora de imóveis Alice e o vendedor de imóveis Bob que estão trabalhando com um agente de garantia. A maneira fácil de fazer o script seria como um multisig onde qualquer uma das três partes poderia liberar o dinheiro: Ou o vendedor e o comprador concordam ou o agente de garantia assume o controle e concorda com uma das partes: ```2 3 OP_CHECKMULTISG```. +Imagine a compradora de imóveis Alice e o vendedor de imóveis Bob que estão trabalhando com um agente de garantia. A maneira fácil de fazer o script seria como um multisig onde qualquer uma das três partes poderia liberar o dinheiro: ou o vendedor e o comprador concordam ou o agente de garantia assume o controle e concorda com uma das partes: ```2 3 OP_CHECKMULTISG```. No entanto, isso enfraquece o poder do agente de garantia e permite que o vendedor e o comprador acidentalmente tomem uma decisão errada entre eles. O que é uma das coisas que um sistema de garantia deve evitar. Portanto, pode ser que o que realmente desejamos seja o sistema que acabamos de criar, onde o agente de custódia é uma parte necessária no multisig 2 de 3: ```OP_3DUP 2 2 OP_CHECKMULTISIG NOTIF 2 2 OP_CHECKMULTISIG ENDIF```. -No entanto, isso não passa no teste de entrar na frente de um ônibus. Se o agente de custódia morre ou foge para as Bahamas durante o processo, o comprador e o vendedor ficam sem o dinheiro. É aqui que entra um bloqueio de tempo. Podemos criar um teste adicional que só será executado se tivermos passado o final do nosso período de garantia. Nessa situação, permitimos que o comprador e o vendedor assinem juntos: +No entanto, isso não passa no teste de entrar na frente de um ônibus. Se o agente de custódia morre ou foge para as Bahamas durante o processo, o comprador e o vendedor ficam sem o dinheiro. É aqui que entra o timelock. Podemos criar um teste adicional que só será executado se tivermos passado o final do nosso período de garantia. Nessa situação, permitimos que o comprador e o vendedor assinem juntos: ``` OP_3DUP 2 2 OP_CHECKMULTISIG @@ -123,9 +123,9 @@ ENDIF ``` Primeiro, testamos uma assinatura para o comprador e o agente de garantia e, em seguida, uma assinatura para o vendedor e o agente de garantia. Se ambos falharem e 30 dias se passaram, também permitimos uma assinatura para o comprador e o vendedor. -### Escrevendo um Multisig de Compromisso Centrado no Comprador +### Escrevendo um Multisig de Garantia Centrado no Comprador -O [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki#Escrow_with_Timeout) oferece um exemplo diferente deste tipo de garantia que não tem proteções extras para evitar o agente de garantia, mas que dá a Alice controle total se a garantia falhar. +O [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki#Escrow_with_Timeout) oferece um exemplo diferente deste tipo de garantia que não tem proteções extras para evitar a não-participação do agente de garantia, mas que dá à Alice controle total se a garantia falhar. ``` IF 2 3 OP_CHECKMULTISIG @@ -136,16 +136,16 @@ ENDIF ``` Aqui, qualquer um dos três assinantes pode liberar o dinheiro a qualquer momento, mas depois de 30 dias, Alice pode recuperar o dinheiro por conta própria. -Observe que este script requer que um ```True``` ou ```False``` seja passado para identificar qual caminho será utilizado. Esta é uma maneira mais simples e menos computacionalmente intensiva de oferecer suporte aos caminhos usando o script de Bitcoin. É algo bem comum. +Observe que este script requer que um ```True``` ou ```False``` seja passado para identificar qual caminho será utilizado. Esta é uma maneira mais simples e menos intensiva computacionalmente de oferecer suporte a ramificações no Bitcoin Script. É algo bem comum. No início, o seguinte ```sigScript``` seria permitido: ```0 True```. Após 30 dias, Alice poderia produzir um ```sigScript``` como este: ``` False```. ## Resumo: Escrevendo Scripts Multisig Complexos -Os multisigs mais complexos podem ser normalmente criados combinando assinaturas ou multi assinaturas com condicionais e testes. Os multisigs resultantes podem ser variáveis, exigindo diferentes números de assinantes com base em quem são e quando estão assinando. +Os multisigs mais complexos podem ser normalmente criados combinando assinaturas ou multi-assinaturas com condicionais e testes. Os multisigs resultantes podem ser variáveis, exigindo diferentes números de assinantes com base em quem são e quando estão assinando. -> :fire: ***Qual é o poder dos scripts complexos com multisigs?*** Mais do que qualquer coisa que vimos até agora, os scripts multisig complexos são contratos realmente inteligentes. Eles podem ser muito precisos sobre quem tem permissão para assinar e quando. Empresas com vários níveis, parcerias e escrows podem utilizar soluções semelhantes. O uso de outros recursos poderosos como os timelocks pode proteger ainda mais esses fundos, permitindo que sejam liberados ou mesmo devolvidos em determinados momentos. +> :fire: ***Qual é o poder dos scripts complexos de multisigs?*** Mais do que qualquer outra coisa que vimos até agora, os scripts complexos de multisig são contratos realmente inteligentes. Eles podem ser muito precisos sobre quem tem permissão para assinar e quando. Empresas com vários níveis, parcerias e garantias podem utilizar soluções semelhantes. O uso de outros recursos poderosos como os timelocks pode proteger ainda mais esses fundos, permitindo que sejam liberados ou mesmo devolvidos em determinados momentos. ## O Que Vem Depois? -Vamos continuar "Projetando Scripts Reais no Bitcoin" na seção [§13.3: Expandindo o Bitcoin com os Scripts] (13_3_Empowering_Bitcoin_with_Scripts.md). \ No newline at end of file +Vamos continuar "Projetando Scripts Reais no Bitcoin" na seção [§13.3: Capacitando o Bitcoin com Scripts] (13_3_Empowering_Bitcoin_with_Scripts.md). \ No newline at end of file From ecfa758cc506ccb9d2d108cdaf055515bcf9b324 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 16:47:58 -0300 Subject: [PATCH 070/155] Review 13_3 --- pt/13_3_Empowering_Bitcoin_with_Scripts.md | 66 +++++++++++----------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/pt/13_3_Empowering_Bitcoin_with_Scripts.md b/pt/13_3_Empowering_Bitcoin_with_Scripts.md index d9970e7..03334e8 100644 --- a/pt/13_3_Empowering_Bitcoin_with_Scripts.md +++ b/pt/13_3_Empowering_Bitcoin_with_Scripts.md @@ -1,20 +1,20 @@ -# 13.3: Expandindo o Bitcoin com os Scripts +# 13.3: Capacitando o Bitcoin com Scripts -Os scripts de Bitcoin podem ir muito além dos instrumentos financeiros relativamente simples detalhados até o momento. Eles também são a base dos usos mais complexos da rede Bitcoin, conforme demonstrado por esses exemplos do mundo real de funcionalidade fora da cadeia (offchain), extraídos dos exemplos da Lightning Network no [BIP 112](https://github.com/bitcoin /bips/blob/master/bip-0112.mediawiki). +Os scripts do Bitcoin podem ir muito além dos instrumentos financeiros relativamente simples detalhados até o momento. Eles também são a base dos usos mais complexos da rede Bitcoin, conforme demonstrado por esses exemplos do mundo real de funcionalidade fora da blockchain (off-chain), extraídos dos exemplos da Lightning Network no [BIP 112](https://github.com/bitcoin /bips/blob/master/bip-0112.mediawiki). ## Bloqueio para a Lightning Network -A [Lightning Network](https://rusty.ozlabs.org/?p=450) é um canal de pagamento que permite aos usuários retirar fundos offchain e se envolver em várias micro-transações antes de finalizar o canal de pagamento e trazer os fundos de volta para Bitcoin. Os benefícios incluem taxas mais baixas e velocidades de transação mais rápidas. Iremos discutir com riqueza maior de detalhes, com exemplos de como utilizá-la usando a linha de comando, começando no [Capítulo 18](18_0_Understanding_Your_Lightning_Setup.md). +A [Lightning Network](https://rusty.ozlabs.org/?p=450) é um canal de pagamento que permite aos usuários retirar fundos off-chain e se envolver em várias micro-transações antes de finalizar o canal de pagamento e trazer os fundos de volta para o Bitcoin. Os benefícios incluem taxas mais baixas e velocidades de transação mais rápidas. Iremos discutir em mais detalhes, com exemplos de como utilizá-la usando a linha de comando, começando no [Capítulo 19](19_0_Understanding_Your_Lightning_Setup.md). -O [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) contém alguns exemplos de como essas transações offchain podem ser geradas, usando scripts de bloqueio do Bitcoin. +O [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) contém alguns exemplos de como essas transações off-chain poderiam ser geradas, usando scripts de bloqueio do Bitcoin. -### Bloqueio com transações de compromisso revogáveis +### Bloqueio com Transações de Compromisso Revogáveis -O truque do Lightning é o fato de ele estar fora da blockchain. Para usar a Lightning, os participantes bloqueiam fundos em conjunto na blockchain do Bitcoin com uma transação multisig n-de-n. Em seguida, eles se envolvem em uma série de transações entre si. Cada nova "transação de compromisso" (commitment transaction) divide esses fundos de uma maneira diferente. Essas transações são parcialmente assinadas, mas _não são colocadas na blockchain_. +O truque com a Lightning é o fato de ela estar off-chain. Para usar a Lightning, os participantes bloqueiam fundos em conjunto na blockchain do Bitcoin com uma transação multisig n-de-n. Em seguida, eles se envolvem em uma série de transações entre si. Cada nova "transação de compromisso" (commitment transaction) divide esses fundos de uma maneira diferente. Essas transações são parcialmente assinadas, mas _não são colocadas na blockchain_. -Se temos uma massa de transações não publicadas, qualquer uma delas _pode_ ser colocada na Blockchain, portanto, como evitamos que um dos participantes volte a uma transação antiga que é mais benéfica para eles? A resposta é _revogação_. Um exemplo simplificado no BIP 112, que oferece um dos trampolins para o Lightning, mostra o processo. Nós damos ao participante que seria prejudicado pela reversão de uma transação revogada a capacidade de retirar os fundos ele mesmo se o outro participante tentar usar ilegitimamente a transação revogada. +Se temos uma massa de transações não publicadas, qualquer uma delas _pode_ ser colocada na Blockchain, portanto, como evitamos que um dos participantes reverta a uma transação antiga que é mais benéfica para eles? A resposta é _revogação_. Um exemplo simplificado no BIP 112, que oferece um dos trampolins para a Lightning, mostra o processo. Nós damos ao participante que seria prejudicado pela reversão de uma transação revogada a capacidade de retirar os fundos ele mesmo se o outro participante tentar usar ilegitimamente a transação revogada. -Por exemplo, suponha que Alice e Bob atualizem a transação de compromisso para dar mais fundos a Bob (Ou seja, Alice enviou fundos a Bob por meio da rede Lightning). Eles assinam parcialmente novas transações, mas cada um também oferece seu próprio ```revokeCode``` para as transações anteriores. Isso efetivamente garante que nenhum deles irão publicar as transações anteriores, porque isso permitiria que a contraparte reivindicasse os fundos anteriores. +Por exemplo, suponha que Alice e Bob atualizem a transação de compromisso para dar mais fundos a Bob (ou seja, Alice enviou fundos a Bob por meio da rede Lightning). Eles assinam parcialmente novas transações, mas cada um também oferece seu próprio ```revokeCode``` para as transações anteriores. Isso efetivamente garante que nenhum deles irão publicar as transações anteriores, porque isso permitiria que a contraparte reivindicasse os fundos anteriores. Então, como se parece a transação antiga? Foi uma transação de compromisso mostrando fundos destinados a Alice, antes que ela os desse a Bob. Ele tinha um script de bloqueio da seguinte maneira: ``` @@ -31,11 +31,11 @@ ELSE ENDIF OP_CHECKSIG ``` -O bloco ```ELSE``` é onde Alice conseguiu os fundos, após um atraso de 24 horas. No entanto, agora foi substituído. Afinal, esse é o ponto principal de um canal de pagamento na Lightning. Nesta situação, esta transação nunca deve ser publicada. Bob não tem incentivo para isso porque ele tem uma transação mais recente, que o beneficia mais porque ele recebeu parte dos fundos de Alice. Alice também não tem incentivo, porque ela perde o dinheiro se tentar retirar mais do que deve, por conta do ```revokeCode```. Assim, ninguém coloca a transação na blockchain e as transações offchain continuam. +O bloco ```ELSE``` é onde Alice conseguiu os fundos, após um atraso de 24 horas. No entanto, agora foi substituído. Afinal, esse é o ponto principal de um canal de pagamento na Lightning. Nesta situação, esta transação nunca deve ser publicada. Bob não tem incentivo para isso porque ele tem uma transação mais recente, que o beneficia mais porque ele recebeu parte dos fundos de Alice. Alice também não tem incentivo, porque ela perde o dinheiro se tentar retirar mais do que deve, por conta do ```revokeCode```. Assim, ninguém coloca a transação na blockchain e as transações off-chain continuam. Vale a pena explorar como esse script funcionaria em uma variedade de situações, a maioria das quais envolve Alice tentando trapacear, revertendo para a transação mais antiga, que descreve os fundos _antes_ da Alice enviar os satoshis para Bob. -#### Executando o script de bloqueio para enganar Alice, com código de revogação +#### Executando o Script de Bloqueio para a Alice Trapaceira, com Código de Revogação Alice poderia tentar usar o código de revogação que ela deu a Bob para reivindicar imediatamente os fundos. Ela escreve um script de bloqueio de ``` ```: ``` @@ -56,7 +56,7 @@ Script: IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP OP_EQUAL Stack: [ True ] ``` -O ```OP_EQUAL``` alimenta a instrução ```IF```. Como Alice usa o ```revokeCode```, ela entra no caminho que permite gatar os fundos imediatamente, reduzindo o resto do script para `````` (dentro da condicional) e com o ```OP_CHECKSIG``` (depois). +O ```OP_EQUAL``` alimenta a instrução ```IF```. Como Alice usa o ```revokeCode```, ela entra no caminho que permite gatar os fundos imediatamente, reduzindo o resto do script para `````` (dentro do condicional) e com o ```OP_CHECKSIG``` (depois). ``` Script: OP_CHECKSIG Running: True IF @@ -71,9 +71,9 @@ Script: Running: OP_CHECKSIG Stack: [ False ] ``` -#### Executando o script de bloqueio para enganar Alice, sem código de revogação +#### Executando o Script de Bloqueio para a Alice Trapaceira, sem Código de Revogação -E daí se Alice tentar usar sua própria assinatura, sem o ```revokeCode```? Ela usa o seguinte script de desbloqueio ``` ```. +E se Alice tentar usar sua própria assinatura, sem o ```revokeCode```? Ela usa um script de desbloqueio de ``` ```. ``` Script: 0 OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG Stack: [ ] @@ -92,7 +92,7 @@ Script: IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP OP_EQUAL Stack: [ False ] ``` -Agora reduzimos para a instrução ```ELSE``` e o que vem depois da condicional: +Agora reduzimos para a instrução ```ELSE``` e o que vem depois do condicional: ``` Script: <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKSIG Running: False IF @@ -107,7 +107,7 @@ Script: OP_DROP OP_CHECKSIG Running: <+24Hours> OP_CHECKSEQUENCEVERIFY Stack: [ <+24Hours> ] — Script EXITS ``` -#### Executando o script de bloqueio para a vitima, o Bob +#### Executando o Script de Bloqueio para o Bob Vitimizado O que isso significa é que Bob tem 24 horas para recuperar os fundos se Alice tentar trapacear, usando o `````` e a assinatura como script de desbloqueio: ``` @@ -139,21 +139,21 @@ Script: Running: OP_CHECKSIG Stack: [ True ] ``` -#### Executando o Script de Bloqueio para a Virtuosa Alice +#### Executando o Script de Bloqueio para a Alice Virtuosa -Todas as transações de confirmação de Alice são bloqueadas com este mesmo script de bloqueio, quer tenham sido revogadas ou não. Isso significa que a transação de confirmação mais recente, que é a válida atualmente, também está bloqueada com ela. Alice nunca enviou uma transação mais recente para Bob e, portanto, nunca enviou a ele o ```revokeCode``` anterior. +Todas as transações de confirmação da Alice são bloqueadas com este mesmo script de bloqueio, quer tenham sido revogadas ou não. Isso significa que a transação de confirmação mais recente, que é a válida atualmente, também está bloqueada com ela. Alice nunca enviou uma transação mais recente para Bob e, portanto, nunca enviou a ele o ```revokeCode``` anterior. -Nessa situação, ela poderia publicar virtuosamente a transação, fechando o canal. Ela coloca a transação na cadeia e espera 24 horas. Bob não pode fazer nada a respeito porque não possui o código de recuperação. Então, após a espera, Alice recupera os fundos. Bob pode fazer a mesma coisa com sua própria transação final. +Nessa situação, ela poderia publicar virtuosamente a transação, fechando o canal. Ela coloca a transação na blockchain e espera 24 horas. Bob não pode fazer nada a respeito porque não possui o código de recuperação. Então, após a espera, Alice recupera os fundos. Bob pode fazer a mesma coisa com sua própria transação final. -### Bloqueando com Contratos de Bloqueio de Tempo com Hash +### Bloqueando com Contratos de Bloqueio de Tempo em Hash -As Transações de Compromisso Revogável foram apenas um trampolim para a Lightning. A Lightning Network real usa um mecanismo mais complexo chamado [Contrato de Bloqueio de Tempo com Hash (ou no inglês, Hashed TimeLock Contract)](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) ou mais conhecido como HTLC. +As Transações de Compromisso Revogável foram apenas um trampolim para a Lightning. A Lightning Network real usa um mecanismo mais complexo chamado [Contrato de Bloqueio de Tempo em Hash (ou no inglês, Hashed TimeLock Contract)](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts), mais conhecido como HTLC. O principal objetivo dos HTLCs é criar uma rede abrangente de participantes. As transações não são mais apenas entre um par de participantes que entraram na rede juntos, mas agora podem ser várias pessoas que não estão associadas diretamente. Quando os fundos são enviados, uma string de transações é criada, cada uma delas bloqueada com um ```secretHash```. Quando o ```secretCode``` correspondente é revelado, toda a sequência de transações pode ser gasta. Isso é o que permite que transações singulares realmente se tornem uma rede. Também há um pouco mais de complexidade nos scripts de bloqueio da Lightning Network. Existem bloqueios separados para o remetente e o destinatário de cada transação que são mais amplamente divergentes do que as diferentes transações de compromisso mencionadas na seção anterior. Vamos mostrar os dois, para demonstrar o poder desses scripts de bloqueio, mas não vamos explicar como eles interagem entre si. -#### Bloqueando a transação do destinatário +#### Bloqueando a Transação do Destinatário Mais uma vez, vamos começar a olhar para a transação de compromisso da Alice, que mostra os fundos que ela recebeu: ``` @@ -182,11 +182,11 @@ A chave para esses novos HTLCs é o ```secretHash```, que dissemos que é o que Após o ```secretCode``` ter sido revelado, o caminho do ```IF``` é utilizado. Alice pode reivindicar os fundos 24 horas após a transação ser colocada na rede Bitcoin. -No entanto, também há a oportunidade de Bob recuperar os fundos, que aparecem no caminho do ```ELSE```. Ele pode fazer isso se a transação foi revogada, mas Alice a coloca na blockchain de qualquer maneira, _ou se_ um tempo limite absoluto ocorrer. +No entanto, também há a oportunidade de Bob recuperar os fundos, que aparecem no caminho do ```ELSE```. Ele pode fazer isso se a transação foi revogada (mas Alice a coloca na blockchain de qualquer maneira), _ou se_ um tempo absoluto se esgotar (timeout). -#### Bloqueando a transação do remetente +#### Bloqueando a Transação do Remetente -Este é o script de bloqueio de transação de confirmação alternativo usado pelo remetente: +Este é o script alternativo de bloqueio da transação de confirmação usado pelo remetente: ``` OP_HASH160 OP_DUP @@ -246,31 +246,31 @@ Initial Script: Running: OP_ADD Stack: [ ] ``` -A execução do script revela que as verificações iniciais, acima do ```IF```/```ELSE```/```ENDIF```, determinam se o hash era _tanto_ o ```secretCode``` _ou_ o ```revokeCode```. Nesse caso, Alice pode pegar os fundos no primeiro bloco. Do contrário, Bob pode pegar os fundos, mas somente depois que Alice tiver sua chance e depois que o tempo limite de 24 horas e o tempo limite absoluto tiverem passado. +A execução do script revela que as verificações iniciais, acima do ```IF```/```ELSE```/```ENDIF```, determinam se o hash era _tanto_ o ```secretCode``` _ou_ o ```revokeCode```. Nesse caso, Alice pode pegar os fundos no primeiro bloco. Do contrário, Bob pode pegar os fundos, mas somente depois que Alice tiver sua chance e depois que o tempo limite de 24 horas e o tempo limite absoluto tiverem se esgotado. #### Compreendendo os HTLCs -Os HTLCs são bastante complexos e esta seção não tenta explicar todas as suas complexidades. A [visão geral](https://rusty.ozlabs.org/?p=462) escrita por Rusty Russell explica bem mais, e há ainda mais detalhes no seu artigo [Deployable-lightning](https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf). Mas não se preocupe se algumas das complexidades ainda ficarem meio nebulosas para nós, especialmente sobre o funcionamento das inter-relações dos dois scripts. +Os HTLCs são bastante complexos e esta seção não tenta explicar todas as suas complexidades. A [visão geral](https://rusty.ozlabs.org/?p=462) escrita por Rusty Russell explica bem mais, e há ainda mais detalhes no seu artigo [Deployable-lightning](https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf). Mas não se preocupe se algumas das complexidades ainda não ficaram claras para você, especialmente sobre o funcionamento das inter-relações dos dois scripts. Para os fins deste tutorial, existem duas lições importantes em relação aos HTLCs: - * Entender que uma estrutura muito complexa como um HTLC pode ser criada usando o Script do Bitcoin; + * Entender que uma estrutura muito complexa como um HTLC pode ser criada usando o Bitcoin Script; * Analisar como executar cada um dos scripts HTLC. Vale a pena executar cada um dos dois scripts HTLC em cada uma de permutações, um item da pilha de cada vez. -## Resumo: Expandindo o Bitcoin com os Scripts +## Resumo: Capacitando o Bitcoin com Scripts -Estamos encerrando o exame dos scripts do bitcoin com uma visão de como eles podem ser realmente poderosos. Com 20 opcodes ou menos, um script Bitcoin pode formar a base de todo um canal de pagamento fora da blockchain. Da mesma forma, sidechains com conexões bidirecionais são o produto de menos de vinte opcodes, como também observado brevemente em [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki). +Estamos encerrando o exame dos scripts do Bitcoin com uma visão de como eles podem ser realmente poderosos. Com 20 opcodes ou menos, um script Bitcoin pode formar a base de todo um canal de pagamento fora da blockchain. Da mesma forma, sidechains com conexões bidirecionais são o produto de menos de vinte opcodes, como também observado brevemente no [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki). -Se já vimos a funcionalidade complexa do Bitcoin ou os sistemas adjacentes ao Bitcoin, eles provavelmente foram construídos em scripts Bitcoin. E agora temos todas as ferramentas para fazer o mesmo. +Se você já viu funcionalidades complexas do Bitcoin ou sistemas adjacentes ao Bitcoin, eles provavelmente foram construídos em Bitcoin Script. E agora temos todas as ferramentas para fazer o mesmo. ## O Que Vem Depois? -Vamos ficar "Usando o Tor" no [Capítulo 14: Usando o Tor](14_0_Using_Tor.md). +Vamos ficar "Usando o Tor" no [Capítulo Quatorze: Usando o Tor](14_0_Using_Tor.md). Ou, se preferir, existem dois caminhos alternativos: -Se quiser manter o foco no Bitcoin, vá para o "Programando com o RPC" no [Capítulo Quinze: Conversando com Bitcoind usando C](15_0_Talking_to_Bitcoind.md). +Se quiser manter o foco no Bitcoin, siga em frente para "Programando com o RPC" no [Capítulo Quinze: Conversando com Bitcoind usando C](15_0_Talking_to_Bitcoind.md). -Ou, se quisermos manter o foco na linha de comando porque não somos programadores, podemos pular para o [Capítulo Dezoito: Entendendo Nossa Configuração da Lightning](18_0_Understanding_Your_Lightning_Setup.md) para continuar nossa aula usando a linha de comando com a Lightning Network. \ No newline at end of file +Ou, se quiser manter o foco na linha de comando porque não é um programador, pode pular para o [Capítulo Dezoito: Entendendo Nossa Configuração da Lightning](18_0_Understanding_Your_Lightning_Setup.md) para continuar seus estudos da linha de comando com a Lightning Network. \ No newline at end of file From 256d54e831534f69b16cbc630c2e306f7b8132b0 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 16:49:44 -0300 Subject: [PATCH 071/155] Fix 13_2 --- pt/13_2_Writing_Complex_Multisig_Scripts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pt/13_2_Writing_Complex_Multisig_Scripts.md b/pt/13_2_Writing_Complex_Multisig_Scripts.md index 5b54736..e76e463 100644 --- a/pt/13_2_Writing_Complex_Multisig_Scripts.md +++ b/pt/13_2_Writing_Complex_Multisig_Scripts.md @@ -108,7 +108,7 @@ Imagine a compradora de imóveis Alice e o vendedor de imóveis Bob que estão t No entanto, isso enfraquece o poder do agente de garantia e permite que o vendedor e o comprador acidentalmente tomem uma decisão errada entre eles. O que é uma das coisas que um sistema de garantia deve evitar. Portanto, pode ser que o que realmente desejamos seja o sistema que acabamos de criar, onde o agente de custódia é uma parte necessária no multisig 2 de 3: ```OP_3DUP 2 2 OP_CHECKMULTISIG NOTIF 2 2 OP_CHECKMULTISIG ENDIF```. -No entanto, isso não passa no teste de entrar na frente de um ônibus. Se o agente de custódia morre ou foge para as Bahamas durante o processo, o comprador e o vendedor ficam sem o dinheiro. É aqui que entra o timelock. Podemos criar um teste adicional que só será executado se tivermos passado o final do nosso período de garantia. Nessa situação, permitimos que o comprador e o vendedor assinem juntos: +No entanto, isso não nos reguarda contra imprevistos. Se o agente de custódia morre ou foge para as Bahamas durante o processo, o comprador e o vendedor ficam sem o dinheiro. É aqui que entra o timelock. Podemos criar um teste adicional que só será executado se tivermos passado o final do nosso período de garantia. Nessa situação, permitimos que o comprador e o vendedor assinem juntos: ``` OP_3DUP 2 2 OP_CHECKMULTISIG @@ -148,4 +148,4 @@ Os multisigs mais complexos podem ser normalmente criados combinando assinaturas ## O Que Vem Depois? -Vamos continuar "Projetando Scripts Reais no Bitcoin" na seção [§13.3: Capacitando o Bitcoin com Scripts] (13_3_Empowering_Bitcoin_with_Scripts.md). \ No newline at end of file +Vamos continuar "Projetando Scripts Reais no Bitcoin" na seção [§13.3: Capacitando o Bitcoin com Scripts](13_3_Empowering_Bitcoin_with_Scripts.md). \ No newline at end of file From 802d0e9f109f7642d18d06d51939944d28401788 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 10:21:55 -0300 Subject: [PATCH 072/155] Review 14_0 --- pt/14_0_Using_Tor.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pt/14_0_Using_Tor.md b/pt/14_0_Using_Tor.md index b5b31df..dc6b633 100644 --- a/pt/14_0_Using_Tor.md +++ b/pt/14_0_Using_Tor.md @@ -7,15 +7,15 @@ O Tor é um dos programas padrão instalados pelo [Bitcoin Standup](https://gith Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: * Usar uma configuração Tor; - * Executar a manutenção do Tor. + * Fazer a manutenção do Tor. Os objetivos secundários incluem a capacidade de: * Compreender a rede Tor; - * Entender as várias portas do Bitcoin. + * Compreender as várias portas do Bitcoin. ## Tabela de Conteúdo -* [Seção 1: Verificando a Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) -* [Seção 2: Mudando os Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) +* [Seção 1: Verificando a Sua Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) +* [Seção 2: Mudando os Seus Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) * [Seção 3: Adicionando um Serviço SSH Oculto](14_3_Adding_SSH_Hidden_Services.md) \ No newline at end of file From f3a6cc7e5527ad761b724465302674f24802aa8f Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 10:43:13 -0300 Subject: [PATCH 073/155] Review 14_1 --- pt/14_1_Verifying_Your_Tor_Setup.md | 44 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/pt/14_1_Verifying_Your_Tor_Setup.md b/pt/14_1_Verifying_Your_Tor_Setup.md index 8da66c6..2fce253 100644 --- a/pt/14_1_Verifying_Your_Tor_Setup.md +++ b/pt/14_1_Verifying_Your_Tor_Setup.md @@ -2,11 +2,11 @@ > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Se fizéssemos uma instalação padrão com o [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup), provavelmente já teríamos o Tor configurado como parte do nosso node de Bitcoin. O Tor está instalado e já foi criado os serviços ocultos para as Portas RPC do Bitcoin, enquanto um endereço Onion também foi criado para o ```bitcoind```. Esta seção iremos discutir tudo isso e o que fazer com essas informações e ferramentas. +Se fizéssemos uma instalação padrão com o [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup), provavelmente já teríamos o Tor configurado como parte do nosso node Bitcoin. O Tor está instalado e já criou os serviços ocultos para as portas RPC do Bitcoin, enquanto um endereço Onion também foi criado para o ```bitcoind```. Nesta seção iremos discutir tudo isso e o que fazer com essas informações e ferramentas. > :book: ***O que é o Tor?*** O Tor é uma rede de sobreposição e anonimato de baixa latência baseada no design de roteamento e construção de caminhos para permitir a comunicação anônima. É um software gratuito e open source com o nome derivado da sigla do nome do projeto de software original: "The Onion Router". -> :book: ***Por que usar o Tor com o Bitcoin?*** A rede Bitcoin é uma rede de ponto a ponto que escuta as transações e as propaga usando um endereço IP público. Ao conectar-se à rede sem o Tor, iríamos compartilhar nosso endereço IP, o que poderia expor nossa localização, o tempo de atividade e outros detalhes a terceiros, o que é uma prática de privacidade indesejável. Para nos proteger virtualmente, devemos usar ferramentas como o Tor para ocultar os detalhes da nossa conexão. O Tor permite melhorar nossa privacidade online, pois os dados são codificados criptograficamente e passam por nodes diferentes, cada um decodificando uma única camada (por isso a metáfora da cebola). +> :book: ***Por que usar o Tor com o Bitcoin?*** A rede Bitcoin é uma rede peer-to-peer que escuta as transações e as propaga usando um endereço IP público. Ao conectar-se à rede sem o Tor, iríamos compartilhar nosso endereço IP, o que poderia expor nossa localização, o tempo de atividade e outros detalhes a terceiros, o que é uma prática de privacidade indesejável. Para nos protegermos virtualmente, devemos usar ferramentas como o Tor para ocultar os detalhes da nossa conexão. O Tor permite melhorar nossa privacidade online, pois os dados são codificados criptograficamente e passam por nodes diferentes, cada um decodificando uma única camada (por isso a metáfora da cebola). ## Entendendo o Tor @@ -23,30 +23,30 @@ Agora, com o Tor, muito menos informações sobre as máquinas reais são transm 21:06:52.744602 IP bitcoin.58776 > 195-xxx-xxx-x.rev.pxxxxxm.eu.9999: Flags [P.], seq 264139:265189, ack 3519373, win 3410, options [nop,nop,TS val 209009853 ecr 3018177498], length 1050 21:06:52.776968 IP 195-xxx-xxx-x.rev.pxxxxxm.eu.9999 > bitcoin.58776: Flags [.], ack 265189, win 501, options [nop,nop,TS val 3018177533 ecr 209009853], length 0 ``` -Resumindo: O Tor criptografa nossos dados de forma a ocultar nossa origem, destino e quais serviços estamos usando, enquanto um protocolo de criptografia padrão como TLS *apenas* protege o conteúdo dos nossos dados. +Resumindo: o Tor criptografa nossos dados de forma a ocultar nossa origem, destino e quais serviços estamos usando, enquanto um protocolo de criptografia padrão como TLS *apenas* protege o conteúdo dos nossos dados. -### Compreendendo a Arquitetura de Rede Tor +### Compreendendo a Arquitetura da Rede Tor A arquitetura básica da rede Tor é composta pelos seguintes componentes: * **Cliente Tor (OP ou Onion Proxy).** Um cliente Tor instala o software local que atua como um proxy onion. Ele empacota os dados do aplicativo em células do mesmo tamanho (512 bytes), que então envia para a rede Tor. Uma célula é a unidade básica de transmissão do Tor. -* **Onion Node (OR ou Onion Router).** Um Onion Node transmite células provenientes do cliente Tor e de servidores online. Existem três tipos de Onion Nodes: Nós de entrada (Guarda), Nós intermediários (Meio) e Nós de saída (Saída). -* **Servidor de Diretório.** Um servidor de diretório armazena informações sobre roteadores e servidores onion (serviços ocultos), como as chaves públicas. +* **Node Onion (OR ou Onion Router).** Um Node Onion transmite células provenientes do cliente Tor e de servidores online. Existem três tipos de Nodes Onion: nodes de entrada (Guarda), nodes intermediários (Meio) e nodes de saída (Saída). +* **Servidor de Diretório.** Um servidor de diretório armazena informações sobre roteadores e servidores onion (serviços ocultos), como as suas chaves públicas. * **Onion Server (Servidor Oculto).** Um servidor onion oferece suporte a aplicativos TCP, como páginas da web ou IRC, como serviços. -### Compreendendo as limitações do Tor +### Compreendendo as Limitações do Tor -O Tor não é uma ferramenta perfeita. Como as informações da rede Tor são descriptografadas nos nodes de saída antes de serem enviadas aos destinos finais, teoricamente um observador poderia coletar os metadados suficientes para comprometer o anonimato e potencialmente identificar os usuários. +O Tor não é uma ferramenta perfeita. Como as informações da rede Tor são descriptografadas nos nodes de saída antes de serem enviadas aos destinos finais, teoricamente um observador poderia coletar metadados suficientes para comprometer o anonimato e potencialmente identificar os usuários. Também há estudos que sugerem que possíveis explorações da proteção anti-DoS do Bitcoin podem permitir que um invasor force outros usuários que usam o Tor a se conectar exclusivamente por meio dos nodes de saída do Tor ou dos seus pares Bitcoin, isolando o cliente do resto da rede Bitcoin e expondo-o a censura, correlação e demais ataques. -Da mesma forma, os usuários do Bitcoin Tor podem ser atacados por impressão digital definindo um cookie de endereço nos nodes. Isso também permitiria a correlação e, portanto, acabando com o anonimato. +Da mesma forma, os usuários do Bitcoin Tor podem ser atacados por impressão digital (fingerprinting) definindo um cookie de endereço nos nodes. Isso também permitiria a correlação e, portanto, acabando com o anonimato. Enquanto isso, mesmo no Tor, o Bitcoin é apenas um serviço pseudo-anônimo devido aos muitos perigos de correlação que se originam do próprio livro-razão permanente. Isso significa que o uso do Bitcoin sobre o Tor tem mais probabilidade de _perder o anonimato_ do que outros serviços (e pode levar ao anonimato de outras atividades). Com isso dito, o Tor é geralmente considerado mais seguro do que a alternativa, que é a navegação não anônima. -## Verificando a configuração do Tor +## Verificando a Nossa Configuração do Tor Então, como verificamos se o Tor está ativado? Se o instalamos com o Bitcoin Standup, podemos verificar se o Tor está sendo executado em nosso sistema: ``` @@ -62,7 +62,7 @@ Configuration was valid ``` > :warning: **AVISO:** Isso significa apenas que o Tor está sendo executado, não que está sendo usado para todas (ou algumas) conexões. -### Verificando nossa configuração Tor para o RPC +### Verificando a Nossa Configuração do Tor para o RPC O propósito mais importante do Tor, conforme instalado pelo Bitcoin Standup, é oferecer serviços ocultos para as portas RPC que são usadas para enviar comandos para o ```bitcoind```. @@ -80,9 +80,9 @@ HiddenServicePort 1309 127.0.0.1:8332 > :information_source: **NOTA:** O ```HiddenServiceDir``` é onde todos os arquivos são mantidos para este serviço em particular. Se precisarmos pesquisar nosso endereço onion, chaves de acesso ou adicionar clientes autorizados, é aqui que iremos alterar! -A maneira fácil de testar o nosso RPC Hidden Service é usar o [QuickConnect API](https://github.com/BlockchainCommons/Bitcoin-Standup/blob/master/Docs/Quick-Connect-API.md) integrado ao Bitcoin Standup . Basta baixar o código QR que encontramos em ```/qrcode.png``` e digitalizá-lo usando uma carteira ou node que suporte o QuickConnect, como [The Gordian Wallet](https://github.com/BlockchainCommons/FullyNoded-2). Ao escanear o QR, devemos ver a carteira sincronizada com o nosso node. Estaremos fazendo isso usando os serviços ocultos do RPC. +A maneira fácil de testar o nosso Serviço Oculto RPC é usar o [QuickConnect API](https://github.com/BlockchainCommons/Bitcoin-Standup/blob/master/Docs/Quick-Connect-API.md) integrado ao Bitcoin Standup. Basta baixar o código QR que encontramos em ```/qrcode.png``` e digitalizá-lo usando uma carteira ou node que suporte o QuickConnect, como [a Gordian Wallet](https://github.com/BlockchainCommons/FullyNoded-2). Ao escanear o QR, devemos ver a carteira sincronizada com o nosso node. Estaremos fazendo isso usando os serviços ocultos do RPC. -A maneira mais difícil de testar nosso RPC Hidden Service é enviar um comando ```bitcoin-cli``` com o ```torify```, que permite traduzir um comando UNIX normal para um comando protegido por Tor. É algo difícil porque precisamos obter três informações. +A maneira difícil de testar nosso Serviço Oculto RPC é enviar um comando ```bitcoin-cli``` com o ```torify```, que permite traduzir um comando UNIX normal para um comando protegido por Tor. É algo difícil porque precisamos obter três informações. 1. **Nossa porta de serviço oculta.** Isso pode ser obtido em ```/etc/tor/torrc/```. Por padrão, é a porta 1309. 2. **Nosso endereço Tor.** Essa informação encontra-se no arquivo ```hostname``` no diretório ```HiddenServiceDir``` definido em ```/etc/tor/torrc```. Por padrão, o arquivo pode ser encontrado em ```/var/lib/tor/standup/hostname```. Ele está protegido, então precisaremos usar o ```sudo``` para acessá-lo: @@ -97,11 +97,11 @@ Quando tivermos todas essas informações, podemos emitir um comando ```bitcoin- $ torify bitcoin-cli -rpcconnect=mgcym6je63k44b3i5uachhsndayzx7xi4ldmwrm7in7yvc766rykz6yd.onion -rpcport=1309 -rpcuser=StandUp -rpcpassword=685316cc239c24ba71fd0969fa55634f getblockcount ``` -### Verificando a configuração do Tor para o Bitcoind +### Verificando Nossa Configuração do Tor para o Bitcoind O Bitcoin Standup também garante que nosso ```bitcoind``` esteja configurado para se comunicar opcionalmente em um endereço onion. -Podemos verificar a configuração inicial do Tor para o ```bitcoind``` executando grep usando "tor" no ```debug.log``` em nosso diretório de dados: +Podemos verificar a configuração inicial do Tor para o ```bitcoind``` executando grep para "tor" no ```debug.log``` em nosso diretório de dados: ``` $ grep "tor:" ~/.bitcoin/testnet3/debug.log 2021-06-09T14:07:04Z tor: ADD_ONION successful @@ -138,7 +138,7 @@ $ bitcoin-cli getnetworkinfo ``` Isso mostra três endereços para acessarmos nosso servidor Bitcoin, um endereço IPv4 (```173.255.245.83```), um endereço IPv6 (```2600:3c01::f03c:92ff:fe86:f26```), e um endereço Tor (```vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7htgtgaq2qudsc```). -> :warning: **AVISO:** Obviamente, nunca podemos revelar seu endereço Tor de uma forma que esteja associada ao nosso nome ou outras PII! +> :warning: **AVISO:** Obviamente, nunca podemos revelar seu endereço Tor de uma forma que esteja associada ao nosso nome ou a outras PII ("personably identifiable information", ou informações de identificação pessoal)! Podemos ver algumas informações semelhantes com o ```getnetworkinfo```. ``` @@ -205,7 +205,7 @@ Este serviço oculto permitirá conexões anônimas com o nosso ```bitcoind``` a > :warning: **AVISO:** Executar o Tor e ter um serviço oculto do Tor não nos obriga a usar o Tor. -### Verificando a configuração do Tor para os Peers +### Verificando Nossa Configuração do Tor para os Peers Usando o comando RPC ```getpeerinfo```, podemos ver quais nodes estão conectados ao nosso node e verificar se eles estão conectados ao Tor. @@ -350,16 +350,16 @@ Alguns podem não estar, como esta conexão IPv6: } ... ``` -Ter um endereço Tor para nosso ```bitcoind``` é provavelmente um pouco menos útil do que ter um endereço Tor para nossas conexões RPC. Isso é verdade porque não é recomendado tentar enviar todas as nossas conexões Bitcoin via Tor, e em parte porque proteger nossos comandos RPC é o que realmente importa. É muito mais provável que façamos isso remotamente, a partir de uma carteira de software como a The Gordian Wallet, enquanto o nosso próprio servidor tem mais probabilidade de estar no escritório, no porão ou em um bunker. +Ter um endereço Tor para nosso ```bitcoind``` é provavelmente um pouco menos útil do que ter um endereço Tor para nossas conexões RPC. Isso é verdade porque não é recomendado tentar enviar todas as nossas conexões Bitcoin via Tor, e em parte porque proteger nossos comandos RPC é o que realmente importa. É muito mais provável que façamos isso remotamente, a partir de uma carteira de software como a Gordian Wallet, enquanto o nosso próprio servidor tem mais probabilidade de estar no escritório, no porão ou em um bunker. No entanto, existem maneiras de fazer o ```bitcoind``` usar mais o Tor, conforme iremos discutir na próxima seção. -## Resumo: Verificando a Configuração do Tor +## Resumo: Verificando Nossa Configuração do Tor -O Tor é um pacote de software instalado como parte do Bitcoin Standup que permite a troca de comunicações anonimamente. Ele protegerá nossas portas RPC (8332 ou 18332) e nossas portas do ```bitcoind``` (8333 ou 18333), porém, teremos que nos conectar ativamente ao endereço onion para utilizá-las! O Tor é um pilar fundamental da privacidade e segurança para a configuração do nosso Bitcoin, e podemos verificar se ele está disponível e vinculado ao Bitcoin com alguns comandos simples. +O Tor é um pacote de software instalado como parte do Bitcoin Standup que permite a troca de comunicações anonimamente. Ele protegerá nossas portas RPC (8332 ou 18332) e nossas portas do ```bitcoind``` (8333 ou 18333), porém, teremos que nos conectar ativamente ao endereço onion para utilizá-las! O Tor é um pilar fundamental da privacidade e segurança para a nossa configuração do Bitcoin, e podemos verificar se ele está disponível e vinculado ao Bitcoin com alguns comandos simples. -> :fire: ***Qual é o poder do Tor?*** Muitos ataques a usuários de Bitcoins precisam saber quem é a vítima e se ela possui Bitcoins. O Tor pode nos proteger disso, escondendo onde estamos e o que estamos fazendo. É particularmente importante se desejamos nos conectar ao nosso próprio node remotamente por meio de uma carteira de software, e pode ser crucial se fizermos isso em algum país onde não vê com bons olhos quem usa Bitcoins. Se precisarmos acessar nossos serviços Bitcoin remotamente, precisamos nos certificar de que nossa carteira seja totalmente compatível com o Tor e envie todos os comandos RPC ao nosso servidor usando esse protocolo. +> :fire: ***Qual é o poder do Tor?*** Muitos ataques a usuários de Bitcoin dependem da informação de quem é a vítima e que ela possui Bitcoins. O Tor pode nos proteger disso, escondendo onde estamos e o que estamos fazendo. É particularmente importante se desejamos nos conectar ao nosso próprio node remotamente por meio de uma carteira de software, e pode ser crucial se fizermos isso em algum país onde o uso de Bitcoin é mal visto. Se precisarmos acessar nossos serviços Bitcoin remotamente, precisamos nos certificar de que nossa carteira seja totalmente compatível com o Tor e envie todos os comandos RPC ao nosso servidor usando esse protocolo. ## O Que Vem Depois? -Vamos continuar "Usando o Tor" na seção [§14.2: Mudando os Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md). \ No newline at end of file +Vamos continuar "Usando o Tor" na seção [§14.2: Mudando Nossos Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md). \ No newline at end of file From 46683fbfd9034b7a5c00e675c555d11fcfa3cf4c Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 10:48:13 -0300 Subject: [PATCH 074/155] Review 14_2 --- ..._2_Changing_Your_Bitcoin_Hidden_Services.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pt/14_2_Changing_Your_Bitcoin_Hidden_Services.md b/pt/14_2_Changing_Your_Bitcoin_Hidden_Services.md index 5dad6a1..c91ebee 100644 --- a/pt/14_2_Changing_Your_Bitcoin_Hidden_Services.md +++ b/pt/14_2_Changing_Your_Bitcoin_Hidden_Services.md @@ -1,12 +1,12 @@ -# 14.2: Mudando os Serviços Ocultos do Bitcoin +# 14.2: Mudando Nossos Serviços Ocultos do Bitcoin > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Temos um serviço Tor funcionando, mas com o tempo talvez queiramos reiniciá-lo ou ajustá-lo de outra forma. -## Protejendo nossos serviços ocultos +## Protejendo Nossos Serviços Ocultos -O Tor permite que limitemos quais clientes conversam com nossos serviços ocultos. Se ainda não autorizamos nosso cliente durante a configuração do servidor, na primeira oportunidade, devemos fazer o seguinte: +O Tor permite que limitemos quais clientes conversam com nossos serviços ocultos. Se ainda não autorizamos nosso cliente durante a configuração do servidor, na primeira oportunidade devemos fazer o seguinte: 1. Solicitar uma chave pública de autenticação Tor V3 do nosso cliente. (Na [GordianWallet](https://github.com/BlockchainCommons/GordianWallet-iOS), está disponível no menu de configurações). 2. Vamos para o subdiretório apropriado para nosso serviço oculto do Bitcoin. Se usamos o Bitcoin Standup é ```/var/lib/tor/standup/```. @@ -16,7 +16,7 @@ O Tor permite que limitemos quais clientes conversam com nossos serviços oculto Depois de adicionar um arquivo ```.auth``` ao subdiretório ```authorized_client```, somente os clientes autorizados serão capazes de se comunicar com esse serviço oculto. Podemos adicionar mais ou menos 330 chaves públicas diferentes para habilitar clientes diferentes. -## Redefinindo nosso endereço Onion do ```bitcoind``` +## Redefinindo Nosso Endereço Onion do ```bitcoind``` Se quisermos redefinir nosso endereço onion para o ```bitcoind```, podemos apenas remover o ```onion_private_key``` do nosso diretório de dados, no `~/.bitcoin/testnet`: ``` @@ -39,7 +39,7 @@ $ sudo /etc/init.d/tor restart > :warning: **AVISO:** Redefinir o endereço onion do RPC desconectará quaisquer carteiras mobile ou outros serviços que contamos usando a API Quicklink. Por isso, temos que tomar bastante cuidado. -## Forçar o ```bitcoind``` a usar o Tor +## Forçando o ```bitcoind``` a Usar o Tor Finalmente, podemos forçar o ```bitcoind``` a usar o onion adicionando o seguinte ao nosso arquivo ```bitcoin.conf```: ``` @@ -61,14 +61,14 @@ addnode=address.onion ``` Depois, basta reiniciar o ```tor``` e o ```bitcoind```. -Agora devemos estar nos comunicando exclusivamente com o Tor. Mas, a menos que estejamos em um local hostil, esse nível de anonimato provavelmente não é necessário. Também não é particularmente recomendado, pois podemos diminuir muito o número potenciais peers, criando problemas de censura ou mesmo de correlação. Também podemos começar a sofrer com alta latência. E essa configuração pode nos dar uma falsa sensação de anonimato que realmente não existe na rede Bitcoin. +Agora devemos estar nos comunicando exclusivamente com o Tor. Mas, a menos que estejamos em um local hostil, esse nível de anonimato provavelmente não é necessário. Também não é particularmente recomendado, pois podemos diminuir muito o número de potenciais peers, criando problemas de censura ou mesmo de correlação. Também podemos começar a sofrer com alta latência. E essa configuração pode nos dar uma falsa sensação de anonimato que realmente não existe na rede Bitcoin. > :warning: **AVISO:** Esta configuração não foi testada! Use por sua conta e risco! -## Resumo: Mudando os Serviços Ocultos do Bitcoin +## Resumo: Mudando Nossos Serviços Ocultos do Bitcoin -Provavelmente nós não iremos precisará brincar com os nossos serviços onion depois de verificá-los, mas caso precisemos, veja como redefinir um endereço Tor que foi comprometido ou passar a usar exclusivamente o Tor com nosso ```bitcoind``` . +Provavelmente nós não precisaremos brincar com os nossos serviços onion depois de verificá-los, mas caso precisemos, aqui está como redefinir um endereço Tor que foi comprometido ou passar a usar exclusivamente o Tor com nosso ```bitcoind``` . ## O Que Vem Depois? -Vamos continuar "Usando o Tor" na seção [14.3: Adicionando SSH e Hidden Services](14_3_Adding_SSH_Hidden_Services.md). \ No newline at end of file +Vamos continuar "Usando o Tor" na seção [14.3: Adicionando Serviços SSH Ocultos](14_3_Adding_SSH_Hidden_Services.md). \ No newline at end of file From c8258c1e694de056dc0ec138cac1e6a07e3f280f Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 10:54:31 -0300 Subject: [PATCH 075/155] Review 14_3 --- pt/14_3_Adding_SSH_Hidden_Services.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pt/14_3_Adding_SSH_Hidden_Services.md b/pt/14_3_Adding_SSH_Hidden_Services.md index ef9de32..56e7bec 100644 --- a/pt/14_3_Adding_SSH_Hidden_Services.md +++ b/pt/14_3_Adding_SSH_Hidden_Services.md @@ -18,7 +18,7 @@ EOF Eis o que cada coisa significa: * HiddenServiceDir: Indica que temos um diretório de serviço oculto com a configuração necessária para este caminho. -* HiddenServicePort: Indica a porta Tor a ser usada, no caso do SSH, geralmente é a 22. +* HiddenServicePort: Indica a porta Tor a ser usada; no caso do SSH, geralmente é a 22. Depois de adicionar as linhas apropriadas ao nosso arquivo ```torrc```, precisaremos reiniciar o Tor: ``` @@ -54,6 +54,6 @@ Agora que instalamos o Tor e sabemos como usá-lo, podemos adicionar outros serv > :fire: ***Qual é o poder de utilizar outros serviços ocultos?*** Cada vez que acessamos um serviço em nosso servidor remotamente, deixamos pegadas na rede. Mesmo que os dados sejam criptografados usando SSH (ou TLS), os vigias da rede podem ver de onde estamos nos conectando, para onde estamos conectando e qual serviço estamos usando. Isso realmente importa pra nós? Esta é a pergunta que devemos fazer. Mas se a resposta for "Sim", podemos proteger a conexão com um serviço oculto. -Vamos seguir "Programando com o RPC" no [Capítulo Quinze: Conversando com Bitcoind usando C](15_0_Talking_to_Bitcoind.md). +Vamos seguir "Programando com o RPC" no [Capítulo Dezesseis: Conversando com o Bitcoind usando C](16_0_Talking_to_Bitcoind.md). -Ou, se não formos programadores, podemos pular para o [Capítulo Dezoito: Entendendo Nossa Configuração da Lightning](18_0_Understanding_Your_Lightning_Setup.md) para aumentar nosso conhecimento sobre a Lightning Network usando a linha de comando. \ No newline at end of file +Ou, se você não for um programador, pode pular para o [Capítulo Dezenove: Entendendo Nossa Configuração da Lightning](19_0_Understanding_Your_Lightning_Setup.md) para aumentar nosso conhecimento sobre a Lightning Network usando a linha de comando. \ No newline at end of file From df8686f3ede5b4bd04e6a1df5bc9076ac6b56df4 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 10:58:59 -0300 Subject: [PATCH 076/155] Update chapter 15 to 16 number --- pt/16_0_Talking_to_Bitcoind.md | 27 ++ pt/16_1_Accessing_Bitcoind_with_C.md | 294 +++++++++++++++ pt/16_2_Programming_Bitcoind_with_C.md | 354 ++++++++++++++++++ ...Receiving_Bitcoind_Notifications_with_C.md | 155 ++++++++ 4 files changed, 830 insertions(+) create mode 100644 pt/16_0_Talking_to_Bitcoind.md create mode 100644 pt/16_1_Accessing_Bitcoind_with_C.md create mode 100644 pt/16_2_Programming_Bitcoind_with_C.md create mode 100644 pt/16_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/pt/16_0_Talking_to_Bitcoind.md b/pt/16_0_Talking_to_Bitcoind.md new file mode 100644 index 0000000..88bde29 --- /dev/null +++ b/pt/16_0_Talking_to_Bitcoind.md @@ -0,0 +1,27 @@ + +# Capítulo 15: Conversando com Bitcoind usando C + +Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. + +Esta seção se concentra em três diferentes bibliotecas que podem ser usadas como base de programação C sofisticada: Uma biblioteca RPC e uma biblioteca JSON que juntas permitem recriar muito do que fazemos nos scripts de shell, porém, usando C; enquanto uma biblioteca ZMQ nos conecta a notificações, algo que não conseguiríamos acessar até agora. (O próximo capítulo cobrirá uma biblioteca ainda mais sofisticada chamada Libwally, para finalizar esta introdução à programação do Bitcoin com C). + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Criar programas C que usam RPC para conversar com o Bitcoind; + * Criar programas C que usam ZMQ para conversar com o Bitcoind. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Entender como usar uma biblioteca RPC; + * Entender como usar uma biblioteca JSON; + * Compreender as capacidades do ZMQ; + * Entender como usar uma biblioteca ZMQ. + +## Tabela de conteúdo + + * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) + * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) + * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) + \ No newline at end of file diff --git a/pt/16_1_Accessing_Bitcoind_with_C.md b/pt/16_1_Accessing_Bitcoind_with_C.md new file mode 100644 index 0000000..2e97e1c --- /dev/null +++ b/pt/16_1_Accessing_Bitcoind_with_C.md @@ -0,0 +1,294 @@ + +# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. + +Você já viu uma maneira alternativa de acessar as portas RPC do Bitcoind: Usando o ``curl``, que cobrimos no [Capítulo 4 Prefácio](04_4__interlude_using_curl.md). Interagir com o ``Bitcoind`` através de uma biblioteca de RPC usando C não é diferente do que já vimos, só precisamos de boas bibliotecas para nos auxiliar. Esta seção introduz um pacote chamado ``libbitcoinrpc``, que permite acessar a porta JSON-RPC do ``bitcoind``. Ele usa uma biblioteca ``curl`` para acessar os dados e usa a biblioteca ``jansson`` para codificar e decodificar o JSON. + +## Configurando o libbitcoinrpc + +Para usar o ``libbitcoinrpc``, precisaremos instalar uma configuração básica C e os pacotes dependentes, que são ``libcurl``, ``libjansson``, e ``libuuid``. Depois faremos isso no seu servidor Standup Bitcoin (ou em qualquer outro servidor Ubuntu). + +``` +$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev +Suggested packages: + libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev +The following NEW packages will be installed: + libcurl4-openssl-dev libjansson-dev uuid-dev +0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. +Need to get 358 kB of archives. +After this operation, 1.696 kB of additional disk space will be used. +Do you want to continue? [Y/n] y +``` +Agora, podemos baixar o [libbitcoinrpc no github](https://github.com/gitmarek/libbitcoinrpc/blob/master/readme.md). Vamos clonar ou pegar um arquivo zip, do jeito que preferir. + +``` +$ sudo apt-get install git +$ git clone https://github.com/gitmarek/libbitcoinrpc +``` + +> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. + +### Compilando o libbitcoinrpc. + +Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: +``` +$ PATH="/sbin:$PATH" +``` + +Para o Ubuntu, também precisaremos ajustar o ``install_libpath`` no ``makefile`` do ``libbitcoinrpc`` para instalar no ``/usr/lib`` ao invés do ``/usr/local/lib``: + +``` +$ emacs ~/libbitcoinrpc/Makefile +... +INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib +``` + +(Se preferir não usar o ``/usr/lib``, precisará alterar o ``etc/ld.so.conf`` ou os arquivos dependentes de maneira apropriada... Porém, para uma configuração de teste em uma máquina de teste, acredito que isso não seja um problema). + +Da mesma forma, vamos precisar ajustar o ``install_headerpath`` no ``Makefile`` do ``libbitcoinrpc`` para instalar no caminho ``/usr/include`` ao invés do ``/usr/local/inclusve``: + +``` +... +INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include +``` + +Agora, podemos compilar: +``` +$ cd libbitcoinrpc +~/libbitcoinrpc$ make + +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ +src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ +-o .lib/libbitcoinrpc.so.0.2 \ +-Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl +ldconfig -v -n .lib +.lib: + libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) +ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so +``` +Se tudo correr bem, podemos instalar o pacote: +``` +$ sudo make install +Installing to +install .lib/libbitcoinrpc.so.0.2 /usr/local/lib +ldconfig -n /usr/local/lib +ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so +install -m 644 src/bitcoinrpc.h /usr/local/include +Installing docs to /usr/share/doc/bitcoinrpc +mkdir -p /usr/share/doc/bitcoinrpc +install -m 644 doc/*.md /usr/share/doc/bitcoinrpc +install -m 644 CREDITS /usr/share/doc/bitcoinrpc +install -m 644 LICENSE /usr/share/doc/bitcoinrpc +install -m 644 Changelog.md /usr/share/doc/bitcoinrpc +Installing man pages +install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 +``` + +## Preparando o código + +``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. + +Para usar o ``libbitcoinrpc``, é importante certificar de que nossos arquivos do código incluam os cabeçalhos apropriados: +``` c +#include +#include +``` + +Precisaremos também vincular as bibliotecas apropriadas sempre que possamos compilar: + +``` +$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode +``` + +## Construindo a conexão + +Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. + +Primeiro, inicialize a biblioteca: +``` +bitcoinrpc_global_init(); +``` +Em seguida, vamos conectar ao ``Bitcoind`` com ``bitcoinrpc_cl_init_params``. Os quatro argumentos necessários para o ``bitcoinrpc_cl_init_params`` são o nome de usuário, a senha, o endereço IP e a porta. A esta altura, você deve saber todas essas informações, já que foram necessárias para realizar o trabalho com o [curl](04_4__interlude_using_curl.md). Apenas para recordar, o endereço de IP é 127.0.0.1 e a porta 18332 devem estar corretos para a configuração padrão da testenet descrita neste documento, enquanto podemos encontrar o usuário e a senha no arquivo ``~/.bitcoin/bitcoin.conf``. +``` +$ cat bitcoin.conf +server=1 +dbcache=1536 +par=1 +maxuploadtarget=137 +maxconnections=16 +rpcuser=StandUp +rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba +rpcallowip=127.0.0.1 +debug=tor +prune=550 +testnet=1 +[test] +rpcbind=127.0.0.1 +rpcport=18332 +[main] +rpcbind=127.0.0.1 +rpcport=8332 +[regtest] +rpcbind=127.0.0.1 +rpcport=18443 +``` +Com essas informações, vamos colocá-las no ``bitcoinrpc_cl_init_params``: +``` c +bitcoinrpc_cl_t *rpc_client; +rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); +``` + +> **MAINNET VS TESTNET:** A porta seria a 8332 caso estivéssemos usando a configuração da rede principal. + +Se o ``rpc_client`` for inicializado com sucesso, poderemos enviar os comandos do RPC. + +Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fechar da seguinte maneira: +``` c +bitcoinrpc_global_cleanup(); +``` + +### Testando o código de teste + +O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). + +Podemos compilar e executar o código da seguinte maneira: +``` +$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin +$ ./testbitcoin +Successfully connected to server! +``` + +> :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. + +## Fazendo uma chamada ao RPC + +Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). +``` c +bitcoinrpc_method_t *getmininginfo = NULL; +getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); +``` +Normalmente definiríamos os parâmetros em seguida, mas o ``GetMiningInfo`` não requer parâmetros, por isso podemos pular essa parte. + +Também devemos criar outros dois objetos, um "objeto de resposta" e um "objeto de erro". Eles podem ser inicializados da seguinte forma: +``` c +bitcoinrpc_resp_t *btcresponse = NULL; +btcresponse = bitcoinrpc_resp_init(); + +bitcoinrpc_err_t btcerror; +``` +Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos adicionar nosso método ``getmininginfo`` e os outros dois objetos: +``` c +bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); +``` + +### Mostrando o retorno da chamada + +Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: +``` c +json_t *jsonresponse = NULL; +jsonresponse = bitcoinrpc_resp_get(btcresponse); +``` +Se quisermos gerar os resultados completos da chamada RPC no JSON, podemos fazer com uma simples invocação do ``json_dumps``, da biblioteca ``jansson``: +``` c +printf("%s\n", json_dumps(j, JSON_INDENT(2))); +``` +No entanto, como agora estamos escrevendo programas completos, provavelmente iremos querer fazer um trabalho mais sutil, como retirar valores individuais do JSON para algum uso específico. A [Referência do Jansson](https6//jansson.readthedocs.Io/en/2.10/apiref.html) traz detalhes de como fazer. + +Assim como estávamos usando o [curl](04_4__interlude_using_curl.md), descobrimos que o RPC retorna um objeto JSON contendo um ``ID``, um ``error`` e, mais importante, um objeto JSON do tipo ``result``. + +A função ``json_object_get`` permite recuperar um valor (como o ``result``) de um objeto JSON usando chaves: +``` c +json_t *jsonresult = NULL; +jsonresult = json_object_get(jsonresponse,"result"); +printf("%s\n", json_dumps(jsonresult, JSON_INDENT(2))); +``` + +No entanto, provavelmente iremos querer analisar informações ainda mais profundas, para obter uma variável específica. Depois de recuperar o valor apropriado, precisaremos convertê-lo em um objeto C padrão usando a função ``JSON_*_value``. Por exemplo, para acessar um integer usamos o ``json_integer_value``: +``` c +json_t *jsonblocks = NULL; +jsonblocks = json_object_get(jsonresult,"blocks"); + +int blocks; +blocks = json_integer_value(jsonblocks); +printf("Block Count: %d\n",blocks); +``` + +> :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. + +### Testando o código de informação + +Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). +``` +$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo +$ ./getmininginfo +Full Response: { + "result": { + "blocks": 1804406, + "difficulty": 4194304, + "networkhashps": 54842097951591.781, + "pooledtx": 127, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" + }, + "error": null, + "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" +} + +Just the Result: { + "blocks": 1804406, + "difficulty": 4194304, + "networkhashps": 54842097951591.781, + "pooledtx": 127, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" +} + +Block Count: 1804406 +``` + +## Fazendo uma chamada RPC usando argumentos + +Mas e se a sua chamada RPC tiver argumentos? + +### Criando uma matriz JSON + +Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. + +Vamos criar a matriz JSON usando a função ``json_array do`` do ``jansson``: +``` c +json_t *params = NULL; +params = json_array(); +``` +Vamos fazer o processo inverso que fizemos para acessar valores do JSON: Vamos converter objetos no C para objetos no JSON usando as funções ``JSON_*``. Depois, vamos anexar tudo à matriz: +``` c +json_array_append_new(params,json_string(tx_rawhex)); +``` + +Observe que existem duas variantes para o comando de anexação: ``json_array_apend_new``, que acrescenta uma variável recém-criada, e ``json_array_apend``, que anexa uma variável existente. + +Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. + +### Atribuindo os parâmetros + +Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: +``` c +bitcoinrpc_method_set_params(rpc_method, params) +``` +Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. + +## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC + +Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. + +* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. + +## O Que Vem Depois? + +Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). diff --git a/pt/16_2_Programming_Bitcoind_with_C.md b/pt/16_2_Programming_Bitcoind_with_C.md new file mode 100644 index 0000000..c1fdc38 --- /dev/null +++ b/pt/16_2_Programming_Bitcoind_with_C.md @@ -0,0 +1,354 @@ + +# 15.2: Programando o Bitcoind usando C com bibliotecas RPC + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. + +A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. + +## Planejando o código + +Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: + + 1. Solicitar um endereço e uma quantia; + 2. Definir uma taxa arbitrária; + 3. Preparar nosso RPC; + 4. Encontrar um UTXO que seja grande o suficiente para pagar o valor + a taxa; + 5. Criar uma mudança de endereço; + 6. Criar uma transação bruta que envie o UTXO para o endereço e altere o endereço; + 7. Assinar a transação; + 8. Enviar a transação. + +### Planejando para o futuro + +Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: + + 1. Testar e/ou higienizar as entradas; + 2. Calcular uma taxa automaticamente; + 3. Pensar logicamente sobre qual UTXO seria válido utilizar; + 4. Combinar vários UTXOs, caso seja necessário; + 5. Ficar atento a mais erros nos comandos ``libbitcoinrpc`` ou no ``jansson``; + 6. Observar se há erros nas respostas RPC. + +Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. + +## Escrevendo o sistema de transação + +Agora estamos prontos para realizar o passo a passo do nosso plano + +### Etapa 1: Solicitando um endereço e uma quantia + +Inserir as informações é bem simples se usarmos os argumentos na linha de comando: +``` c +if(argc != 3) { + + printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); + exit(-1); + +} + +char *tx_recipient = argv[1]; +float tx_amount = atof(argv[2]); + +printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); +``` + +> :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. + +### Etapa 2: Definindo uma taxa arbitrária + +Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: + +``` c +float tx_fee = 0.0005; +float tx_total = tx_amount + tx_fee; +``` + +> :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. + +### Etapa 3: Preparando nosso RPC + +Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: +``` c +bitcoinrpc_global_init(); +rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); +btcresponse = bitcoinrpc_resp_init(); +``` + +### Etapa 4: Encontrando um UTXO + +Para encontrar um UTXO, precisaremos chamar a função RPC ``listunspent``: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +``` + +No entanto, o verdadeiro trabalho consiste em decodificar a resposta. Na seção anterior vimos que a biblioteca ``jansson`` era "um tanto quanto desajeitada" e esta é a razão: Precisamos criar (e limpar) um conjunto muito grande de objetos ``json_t`` para descobrir o que queremos. + +Primeiro, precisamos nos recuperar o campo ``result`` do JSON: +``` c +json_t *lu_response = NULL; +json_t *lu_result = NULL; + +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); +``` + +> :warning: **ATENÇÃO:** Só obteremos um resultado se não houver nenhum erro. Aqui temos um momento para melhorar nossa verificação de erros no código que iremos colocar em produção. + +Em seguida, vamos fazer um laço, examinando cada transação que não foi gasta, que aparece como um elemento em sua matriz do resultado JSON: +``` c +int i; + +const char *tx_id = 0; +int tx_vout = 0; +double tx_value = 0.0; + +for(i = 0 ; i < json_array_size(lu_result) ; i++) { + + json_t *lu_data = NULL; + lu_data = json_array_get(lu_result, i); + + json_t *lu_value = NULL; + lu_value = json_object_get(lu_data,"amount"); + tx_value = json_real_value(lu_value); +``` + +O UTXO é grande o suficiente para pagar sua transação? Se sim, pegue-o! + +> :warning: **ATENÇÃO:** Um programa em produção pensaria com mais cuidado sobre qual UTXO utilizar, com base no tamanho e em outros fatores. Provavelmente não pegaria apenas o primeiro mais simples e pronto. + +``` c + if(tx_value > tx_total) { + + json_t *lu_txid = NULL; + lu_txid = json_object_get(lu_data,"txid"); + tx_id = strdup(json_string_value(lu_txid)); + + json_t *lu_vout = NULL; + lu_vout = json_object_get(lu_data,"vout"); + tx_vout = json_integer_value(lu_vout); + + json_decref(lu_value); + json_decref(lu_txid); + json_decref(lu_vout); + json_decref(lu_data); + break; + + } +``` +Você também deve limpar os principais elementos do JSON: +``` c +} + +json_decref(lu_result); +json_decref(lu_response); +``` + +> :warning: **ATENÇÃO:** Um programa em produção também se certificaria de que os UTXOs são passíveis de serem `gastos`. + +Se não encontramos nenhum UTXOs grande o suficiente, teremos que relatar este infortúnio ao usuário... E talvez, sugerir que ele deva usar um programa melhor, que irá mesclar os UTXOs de maneira correta. +``` c +if(!tx_id) { + + printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); + exit(-1); +} +``` + +> **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. + +### Etapa 5: Criando um endereço de troco + +Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); + +if(!rpc_method) { + + printf("ERROR: Unable to initialize listunspent method!\n"); + exit(-1); + +} + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); + +if(btcerror.code != BITCOINRPCE_OK) { + +printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); + + exit(-1); + +} + +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); +char *changeaddress = strdup(json_string_value(lu_result)); +``` +A única diferença é quais informações específicas são extraídas do objeto JSON. + +> :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. + +### Etapa 6: Criando uma transação bruta + +Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. + +Para criarmos esses parâmetros corretamente, precisaremos revisar o que o RPC ``createrawtransaction`` espera que passemos como argumento. Felizmente, isso é fácil de determinar usando a funcionalidade ``bitcoin-cli help``: +``` +$ bitcoin-cli help createrawtransaction +createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) +``` + +Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. + +#### Etapa 6.1: Criando os parâmetros de entrada + +Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): +``` c +json_t *inputtxid = NULL; +inputtxid = json_object(); + +json_object_set_new(inputtxid,"txid",json_string(tx_id)); +json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); +``` + +Pode-se notar que teremos que traduzir novamente cada tipo de variável C em um tipo de variável JSON usando a função apropriada, como ``json_string`` ou ``json_integer``. + +Para criar o array de entrada para todos os UTXOs, vamos usar o ``json_array`` e, em seguida, preenchê-lo com os objetos usando o ``json_array_append``: +``` c +json_t *inputparams = NULL; +inputparams = json_array(); +json_array_append(inputparams,inputtxid); +``` + +#### Etapa 6.2: Criando os parâmetros de saída + +Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: +``` c +json_t *outputparams = NULL; +outputparams = json_object(); + +char tx_amount_string[32]; +sprintf(tx_amount_string,"%.8f",tx_amount); +char tx_change_string[32]; +sprintf(tx_change_string,"%.8f",tx_value - tx_total); + +json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); +json_object_set(outputparams, changeaddress, json_string(tx_change_string)); +``` + +> :warning: **ATENÇÃO:** É possível pensar que teremos que inserir os valores do Bitcoin como sendo números, usando a função ``json_real``. Infelizmente, isso expõe um dos maiores problemas com a integração da biblioteca ``jansson`` e o Bitcoin. O Bitcoin só é válido até oito dígitos depois da casa decimal. Devemos nos lembrar que 0,00000001 BTC é um satoshi, e essa é a menor divisão possível de um Bitcoin. O tipo ``double`` no C oferecem mais dígitos do que precisamos, embora sejam frequentemente imprecisos depois das oito casas decimais. Se tentarmos convertê-los diretamente do nosso valor ``double`` no C (ou de um tipo ``float``, neste caso) para um valor Bitcoin, a imprecisão frequentemente criará um valor Bitcoin com mais de oito dígitos. Antes da versão Bitcoin Core 0.12, isso não era problema, e podíamos usar a função ``json_real``. Mas à partir dessa versão, se tentarmos usar a função ``createrawtransaction`` com mais do que oito dígitos, obteremos um erro e a transação não será criada. Como resultado, se o valor do Bitcoin _sempre_ se tornar um ``double`` ou ``float``, devemos deixar com apenas oito casas decimais antes de transformá-lo em uma ``string``. Obviamente, isso é um erro, portanto, certifique-se disso para que o código continue funcionando nas versões mais novas do Bitcoin Core. + +#### Etapa 6.3: Criando a Matriz de Parâmetros + +Para terminarmos de criar os parâmetros, só precisaremos agrupá-los em uma matriz JSON: +``` c +json_t *params = NULL; +params = json_array(); +json_array_append(params,inputparams); +json_array_append(params,outputparams); +``` + +#### Etapa 6.4: Fazendo a chamada ao RPC + +Vamos usar o método normal para criar uma chamada ao RPC: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); +``` +Agora, porém, devemos adicionar os nossos parâmetros. Isso pode ser feito facilmente com a função ``bitcoinrpc_method_set_params``: +``` c +if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf(stderr, "Error: Could not set params for createrawtransaction"); + +} +``` +Depois, é só executar o RPC e obter os resultados: +``` c +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); + +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); + +char *tx_rawhex = strdup(json_string_value(lu_result)); +``` +### Etapa 7. Assinando a transação + +É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: +``` c +params = json_array(); +json_array_append_new(params,json_string(tx_rawhex)); +``` +Por fim, vamos assinar a transação seguindo o rigamarole típico para criar uma chamada RPC: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); +if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf(stderr, "Error: Could not set params for signrawtransaction"); + +} + +json_decref(params); + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +lu_response = bitcoinrpc_resp_get(btcresponse); +``` +Novamente, usar a função ``jansson`` para acessar a saída pode ser complicado. Devemos lembrar que ``hex`` é parte de um objeto JSON, não um resultado independente, como era quando criamos a transação bruta. Claro, sempre podemos acessar essas informações a partir da ajuda da linha de comando: ``bitcoin-cli help signrawtransaction`` +``` c +lu_result = json_object_get(lu_response,"result"); +json_t *lu_signature = json_object_get(lu_result,"hex"); +char *tx_signrawhex = strdup(json_string_value(lu_signature)); +json_decref(lu_signature); +``` +> :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. + +### Etapa 8. Enviando a transação + +Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: +``` c +params = json_array(); +json_array_append_new(params,json_string(tx_signrawhex)); + +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); + +if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf(stderr, "Error: Could not set params for sendrawtransaction"); + +} + +json_decref(params); + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); + +char *tx_newid = strdup(json_string_value(lu_result)); + +printf("Txid: %s\n",tx_newid); +``` + +O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. + +## Testando o código + +O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). + +Compile-o como de costume: +``` +$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress +``` +Agora, é possível utilizá-lo para enviar fundos para um endereço: + +``` +./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 +Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 +``` +Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). + +## Resumo do Programando o Bitcoind usando C com bibliotecas RPC + +Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. + +## O Que Vem Depois? + +Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md new file mode 100644 index 0000000..fe166ac --- /dev/null +++ b/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md @@ -0,0 +1,155 @@ + +# 15.3 Recebendo notificações usando C com a biblioteca ZMQ + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. + +As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. + +> :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). + +## Configurando o ZMQ + +Antes de podemos ouvir a blockchain, precisaremos configurar o ``bitcoind`` para permitir as notificações ZMQ. Por isso, precisamos instalar a biblioteca ZMQ para tirar proveito dessas notificações. + +### Configurando o ``bitcoind`` para usar o ZMQ + +O Bitcoin Core está pronto para ZMQ, mas devemos especificar os endpoints do ZMQ. O ZeroMQ publish-sockets prefixa cada item de dados com um prefixo de tópico arbitrário que permite aos clientes assinantes solicitarem apenas os itens com um prefixo correspondente. Existem atualmente quatro tópicos suportados pelo ``bitcoind``: +``` +$ bitcoind --help | grep zmq | grep address + -zmqpubhashblock=
+ -zmqpubhashtx=
+ -zmqpubrawblock=
+ -zmqpubrawtx=
+``` + +Podemos executar o ``bitcoind`` com argumentos de linha de comando para endpoints ZMQ, como mostrado acima, mas também podemos criar um endpoint acessível adicionando linhas apropriadas ao nosso arquivo ``~/.bitcoin/bitcoin.conf`` e reiniciando o sistema. + +``` +zmqpubrawblock=tcp://127.0.0.1:28332 +zmqpubrawtx=tcp://127.0.0.1:28333 +``` +Podemos então testar se os nossos endpoints estão funcionando usando o RPC ``getzmqnotifications``: + +``` +$ bitcoin-cli getzmqnotifications +[ + { + "type": "pubrawblock", + "address": "tcp://127.0.0.1:28332", + "hwm": 1000 + }, + { + "type": "pubrawtx", + "address": "tcp://127.0.0.1:28333", + "hwm": 1000 + } +] +``` +Nosso ``bitcoind`` agora irá emitir as notificações ZMQ + +### Instalando o ZMQ + +Para aproveitar essas notificações, precisamos de uma biblioteca ZMQ para usar com o C, portanto, estaremos usando uma nova biblioteca ZMQ ao invés da biblioteca ``libbitcoinrpc`` nesta seção, mas no futuro, podemos combinar ambas. + +Felizmente, as bibliotecas ZMQ estão disponíveis por meio de pacotes Debian padrão: +``` +$ sudo apt-get install libzmq3-dev +$ sudo apt-get install libczmq-dev +``` +Agora estamos pronto para escrever o código! + +## Escrevendo o programa de notificação + +O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. + +O programa requer dois parâmetros: O primeiro é o "servidor", que é o ponto de conexão TCP exposto pelo ``bitcoind``. O segundo é o "tópico", que atualmente é o ``zmqpubhashblock``,``zmqpubhashtx``, ``zmqpubrawblock`` ou ``zmqpubrawtx``. O tópico precisa ter suporte do ``bitcoin.conf`` e o endereço IP e a porta do servidor devem corresponder ao que está definido no arquivo de configuração. + +``` c +#include +int main(int argc, char ** argv) { + + char *zmqserver; + char *topic; + + if(argc < 3) { + printf("\nUSAGE:\nchainlistener \n\n"); + return 0; + } else { + zmqserver = argv[1]; + topic = argv[2]; + } +``` +Abriremos um soquete ZMQ para o servidor e para o tópico definido: +``` c + zsock_t *socket = zsock_new_sub(zmqserver, topic); + assert(socket); +``` +Depois, vamos esperar: +``` c + while(1) { + zmsg_t *msg; + int rc = zsock_recv(socket, "m", &msg); + assert(rc == 0); + + char *header = zmsg_popstr(msg); + zframe_t *zdata = zmsg_pop(msg); + unsigned int *no = (unsigned int*)zmsg_popstr(msg); + + char *data = zframe_strhex(zdata); + int len = zframe_size(zdata); + printf("Size: %d\n", len); + printf("Data: %s", data); + printf("\nNo: %d\n", *no); + + free(header); + free(data); + free(no); + free(zdata); + zmsg_destroy(&msg); + sleep(1); + } +``` +Enquanto esperamos, observamos as mensagens no soquete ZMQ. Sempre que recebermos uma mensagem, iremos retirá-la da pilha, relatando o número, comprimento e, o os dados que foram importante para nós. + +É isso! + +Claro, quando terminar o processo, precisamos limpar tudo: +``` c + zsock_destroy(&socket); + return 0; +} +``` + +### Testando o código de notificação + +O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: +``` +$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq +``` +Depois, podemos executá-lo com os tópicos e endereços que definimos no nosso ``bitcoin.conf``: +``` +$ ./chainlistener tcp://127.0.0.1:28333 rawtx +Size: 250 +Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 +No: 67 +Size: 249 +Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 +No: 68 +Size: 250 +Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 +No: 69 +Size: 250 +Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 +No: 70 +....... +``` + +### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ + +Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. + +> :fire: ***Qual é o poder das notificações?*** Com as notificações, não dependemos mais dos usuários para emitir os comandos. Ou seja, podemos criar programas que monitoram o blockchain do Bitcoin e tomar as ações apropriadas quando certas coisas ocorrem. Isso, por sua vez, pode ser utilizado juntamente com os comandos RPC que programamos nas seções anteriores. Este também é um grande passo além do que poderíamos fazer com os scripts shell: Certamente, podemos criar scripts shell que fica ouvindo infinitamente, mas existem outras linguagens de programação que possuem ferramentas melhores para isso. + +## O Que Vem Depois? + +Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file From c75011293f39de59a5aeaeb46ad611c9d0ca1f8d Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 11:00:49 -0300 Subject: [PATCH 077/155] Delete old files chapter 15 --- pt/15_0_Talking_to_Bitcoind.md | 27 -- pt/15_1_Accessing_Bitcoind_with_C.md | 294 --------------- pt/15_2_Programming_Bitcoind_with_C.md | 354 ------------------ ...Receiving_Bitcoind_Notifications_with_C.md | 155 -------- 4 files changed, 830 deletions(-) delete mode 100644 pt/15_0_Talking_to_Bitcoind.md delete mode 100644 pt/15_1_Accessing_Bitcoind_with_C.md delete mode 100644 pt/15_2_Programming_Bitcoind_with_C.md delete mode 100644 pt/15_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/pt/15_0_Talking_to_Bitcoind.md b/pt/15_0_Talking_to_Bitcoind.md deleted file mode 100644 index 88bde29..0000000 --- a/pt/15_0_Talking_to_Bitcoind.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Capítulo 15: Conversando com Bitcoind usando C - -Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. - -Esta seção se concentra em três diferentes bibliotecas que podem ser usadas como base de programação C sofisticada: Uma biblioteca RPC e uma biblioteca JSON que juntas permitem recriar muito do que fazemos nos scripts de shell, porém, usando C; enquanto uma biblioteca ZMQ nos conecta a notificações, algo que não conseguiríamos acessar até agora. (O próximo capítulo cobrirá uma biblioteca ainda mais sofisticada chamada Libwally, para finalizar esta introdução à programação do Bitcoin com C). - -## Objetivos deste capítulo - -Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - - * Criar programas C que usam RPC para conversar com o Bitcoind; - * Criar programas C que usam ZMQ para conversar com o Bitcoind. - -Os objetivos secundários do capítulo incluem a capacidade de: - - * Entender como usar uma biblioteca RPC; - * Entender como usar uma biblioteca JSON; - * Compreender as capacidades do ZMQ; - * Entender como usar uma biblioteca ZMQ. - -## Tabela de conteúdo - - * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) - * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) - * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) - \ No newline at end of file diff --git a/pt/15_1_Accessing_Bitcoind_with_C.md b/pt/15_1_Accessing_Bitcoind_with_C.md deleted file mode 100644 index 2e97e1c..0000000 --- a/pt/15_1_Accessing_Bitcoind_with_C.md +++ /dev/null @@ -1,294 +0,0 @@ - -# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -Você já viu uma maneira alternativa de acessar as portas RPC do Bitcoind: Usando o ``curl``, que cobrimos no [Capítulo 4 Prefácio](04_4__interlude_using_curl.md). Interagir com o ``Bitcoind`` através de uma biblioteca de RPC usando C não é diferente do que já vimos, só precisamos de boas bibliotecas para nos auxiliar. Esta seção introduz um pacote chamado ``libbitcoinrpc``, que permite acessar a porta JSON-RPC do ``bitcoind``. Ele usa uma biblioteca ``curl`` para acessar os dados e usa a biblioteca ``jansson`` para codificar e decodificar o JSON. - -## Configurando o libbitcoinrpc - -Para usar o ``libbitcoinrpc``, precisaremos instalar uma configuração básica C e os pacotes dependentes, que são ``libcurl``, ``libjansson``, e ``libuuid``. Depois faremos isso no seu servidor Standup Bitcoin (ou em qualquer outro servidor Ubuntu). - -``` -$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev -Suggested packages: - libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev -The following NEW packages will be installed: - libcurl4-openssl-dev libjansson-dev uuid-dev -0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. -Need to get 358 kB of archives. -After this operation, 1.696 kB of additional disk space will be used. -Do you want to continue? [Y/n] y -``` -Agora, podemos baixar o [libbitcoinrpc no github](https://github.com/gitmarek/libbitcoinrpc/blob/master/readme.md). Vamos clonar ou pegar um arquivo zip, do jeito que preferir. - -``` -$ sudo apt-get install git -$ git clone https://github.com/gitmarek/libbitcoinrpc -``` - -> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. - -### Compilando o libbitcoinrpc. - -Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: -``` -$ PATH="/sbin:$PATH" -``` - -Para o Ubuntu, também precisaremos ajustar o ``install_libpath`` no ``makefile`` do ``libbitcoinrpc`` para instalar no ``/usr/lib`` ao invés do ``/usr/local/lib``: - -``` -$ emacs ~/libbitcoinrpc/Makefile -... -INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib -``` - -(Se preferir não usar o ``/usr/lib``, precisará alterar o ``etc/ld.so.conf`` ou os arquivos dependentes de maneira apropriada... Porém, para uma configuração de teste em uma máquina de teste, acredito que isso não seja um problema). - -Da mesma forma, vamos precisar ajustar o ``install_headerpath`` no ``Makefile`` do ``libbitcoinrpc`` para instalar no caminho ``/usr/include`` ao invés do ``/usr/local/inclusve``: - -``` -... -INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include -``` - -Agora, podemos compilar: -``` -$ cd libbitcoinrpc -~/libbitcoinrpc$ make - -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ -src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ --o .lib/libbitcoinrpc.so.0.2 \ --Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl -ldconfig -v -n .lib -.lib: - libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) -ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so -``` -Se tudo correr bem, podemos instalar o pacote: -``` -$ sudo make install -Installing to -install .lib/libbitcoinrpc.so.0.2 /usr/local/lib -ldconfig -n /usr/local/lib -ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so -install -m 644 src/bitcoinrpc.h /usr/local/include -Installing docs to /usr/share/doc/bitcoinrpc -mkdir -p /usr/share/doc/bitcoinrpc -install -m 644 doc/*.md /usr/share/doc/bitcoinrpc -install -m 644 CREDITS /usr/share/doc/bitcoinrpc -install -m 644 LICENSE /usr/share/doc/bitcoinrpc -install -m 644 Changelog.md /usr/share/doc/bitcoinrpc -Installing man pages -install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 -``` - -## Preparando o código - -``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. - -Para usar o ``libbitcoinrpc``, é importante certificar de que nossos arquivos do código incluam os cabeçalhos apropriados: -``` c -#include -#include -``` - -Precisaremos também vincular as bibliotecas apropriadas sempre que possamos compilar: - -``` -$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode -``` - -## Construindo a conexão - -Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. - -Primeiro, inicialize a biblioteca: -``` -bitcoinrpc_global_init(); -``` -Em seguida, vamos conectar ao ``Bitcoind`` com ``bitcoinrpc_cl_init_params``. Os quatro argumentos necessários para o ``bitcoinrpc_cl_init_params`` são o nome de usuário, a senha, o endereço IP e a porta. A esta altura, você deve saber todas essas informações, já que foram necessárias para realizar o trabalho com o [curl](04_4__interlude_using_curl.md). Apenas para recordar, o endereço de IP é 127.0.0.1 e a porta 18332 devem estar corretos para a configuração padrão da testenet descrita neste documento, enquanto podemos encontrar o usuário e a senha no arquivo ``~/.bitcoin/bitcoin.conf``. -``` -$ cat bitcoin.conf -server=1 -dbcache=1536 -par=1 -maxuploadtarget=137 -maxconnections=16 -rpcuser=StandUp -rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba -rpcallowip=127.0.0.1 -debug=tor -prune=550 -testnet=1 -[test] -rpcbind=127.0.0.1 -rpcport=18332 -[main] -rpcbind=127.0.0.1 -rpcport=8332 -[regtest] -rpcbind=127.0.0.1 -rpcport=18443 -``` -Com essas informações, vamos colocá-las no ``bitcoinrpc_cl_init_params``: -``` c -bitcoinrpc_cl_t *rpc_client; -rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); -``` - -> **MAINNET VS TESTNET:** A porta seria a 8332 caso estivéssemos usando a configuração da rede principal. - -Se o ``rpc_client`` for inicializado com sucesso, poderemos enviar os comandos do RPC. - -Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fechar da seguinte maneira: -``` c -bitcoinrpc_global_cleanup(); -``` - -### Testando o código de teste - -O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). - -Podemos compilar e executar o código da seguinte maneira: -``` -$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin -$ ./testbitcoin -Successfully connected to server! -``` - -> :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. - -## Fazendo uma chamada ao RPC - -Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). -``` c -bitcoinrpc_method_t *getmininginfo = NULL; -getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); -``` -Normalmente definiríamos os parâmetros em seguida, mas o ``GetMiningInfo`` não requer parâmetros, por isso podemos pular essa parte. - -Também devemos criar outros dois objetos, um "objeto de resposta" e um "objeto de erro". Eles podem ser inicializados da seguinte forma: -``` c -bitcoinrpc_resp_t *btcresponse = NULL; -btcresponse = bitcoinrpc_resp_init(); - -bitcoinrpc_err_t btcerror; -``` -Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos adicionar nosso método ``getmininginfo`` e os outros dois objetos: -``` c -bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); -``` - -### Mostrando o retorno da chamada - -Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: -``` c -json_t *jsonresponse = NULL; -jsonresponse = bitcoinrpc_resp_get(btcresponse); -``` -Se quisermos gerar os resultados completos da chamada RPC no JSON, podemos fazer com uma simples invocação do ``json_dumps``, da biblioteca ``jansson``: -``` c -printf("%s\n", json_dumps(j, JSON_INDENT(2))); -``` -No entanto, como agora estamos escrevendo programas completos, provavelmente iremos querer fazer um trabalho mais sutil, como retirar valores individuais do JSON para algum uso específico. A [Referência do Jansson](https6//jansson.readthedocs.Io/en/2.10/apiref.html) traz detalhes de como fazer. - -Assim como estávamos usando o [curl](04_4__interlude_using_curl.md), descobrimos que o RPC retorna um objeto JSON contendo um ``ID``, um ``error`` e, mais importante, um objeto JSON do tipo ``result``. - -A função ``json_object_get`` permite recuperar um valor (como o ``result``) de um objeto JSON usando chaves: -``` c -json_t *jsonresult = NULL; -jsonresult = json_object_get(jsonresponse,"result"); -printf("%s\n", json_dumps(jsonresult, JSON_INDENT(2))); -``` - -No entanto, provavelmente iremos querer analisar informações ainda mais profundas, para obter uma variável específica. Depois de recuperar o valor apropriado, precisaremos convertê-lo em um objeto C padrão usando a função ``JSON_*_value``. Por exemplo, para acessar um integer usamos o ``json_integer_value``: -``` c -json_t *jsonblocks = NULL; -jsonblocks = json_object_get(jsonresult,"blocks"); - -int blocks; -blocks = json_integer_value(jsonblocks); -printf("Block Count: %d\n",blocks); -``` - -> :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. - -### Testando o código de informação - -Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). -``` -$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo -$ ./getmininginfo -Full Response: { - "result": { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" - }, - "error": null, - "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" -} - -Just the Result: { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" -} - -Block Count: 1804406 -``` - -## Fazendo uma chamada RPC usando argumentos - -Mas e se a sua chamada RPC tiver argumentos? - -### Criando uma matriz JSON - -Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. - -Vamos criar a matriz JSON usando a função ``json_array do`` do ``jansson``: -``` c -json_t *params = NULL; -params = json_array(); -``` -Vamos fazer o processo inverso que fizemos para acessar valores do JSON: Vamos converter objetos no C para objetos no JSON usando as funções ``JSON_*``. Depois, vamos anexar tudo à matriz: -``` c -json_array_append_new(params,json_string(tx_rawhex)); -``` - -Observe que existem duas variantes para o comando de anexação: ``json_array_apend_new``, que acrescenta uma variável recém-criada, e ``json_array_apend``, que anexa uma variável existente. - -Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. - -### Atribuindo os parâmetros - -Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: -``` c -bitcoinrpc_method_set_params(rpc_method, params) -``` -Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. - -## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC - -Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. - -* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. - -## O Que Vem Depois? - -Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). diff --git a/pt/15_2_Programming_Bitcoind_with_C.md b/pt/15_2_Programming_Bitcoind_with_C.md deleted file mode 100644 index c1fdc38..0000000 --- a/pt/15_2_Programming_Bitcoind_with_C.md +++ /dev/null @@ -1,354 +0,0 @@ - -# 15.2: Programando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. - -## Planejando o código - -Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: - - 1. Solicitar um endereço e uma quantia; - 2. Definir uma taxa arbitrária; - 3. Preparar nosso RPC; - 4. Encontrar um UTXO que seja grande o suficiente para pagar o valor + a taxa; - 5. Criar uma mudança de endereço; - 6. Criar uma transação bruta que envie o UTXO para o endereço e altere o endereço; - 7. Assinar a transação; - 8. Enviar a transação. - -### Planejando para o futuro - -Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: - - 1. Testar e/ou higienizar as entradas; - 2. Calcular uma taxa automaticamente; - 3. Pensar logicamente sobre qual UTXO seria válido utilizar; - 4. Combinar vários UTXOs, caso seja necessário; - 5. Ficar atento a mais erros nos comandos ``libbitcoinrpc`` ou no ``jansson``; - 6. Observar se há erros nas respostas RPC. - -Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. - -## Escrevendo o sistema de transação - -Agora estamos prontos para realizar o passo a passo do nosso plano - -### Etapa 1: Solicitando um endereço e uma quantia - -Inserir as informações é bem simples se usarmos os argumentos na linha de comando: -``` c -if(argc != 3) { - - printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); - exit(-1); - -} - -char *tx_recipient = argv[1]; -float tx_amount = atof(argv[2]); - -printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); -``` - -> :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. - -### Etapa 2: Definindo uma taxa arbitrária - -Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: - -``` c -float tx_fee = 0.0005; -float tx_total = tx_amount + tx_fee; -``` - -> :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. - -### Etapa 3: Preparando nosso RPC - -Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: -``` c -bitcoinrpc_global_init(); -rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); -btcresponse = bitcoinrpc_resp_init(); -``` - -### Etapa 4: Encontrando um UTXO - -Para encontrar um UTXO, precisaremos chamar a função RPC ``listunspent``: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -``` - -No entanto, o verdadeiro trabalho consiste em decodificar a resposta. Na seção anterior vimos que a biblioteca ``jansson`` era "um tanto quanto desajeitada" e esta é a razão: Precisamos criar (e limpar) um conjunto muito grande de objetos ``json_t`` para descobrir o que queremos. - -Primeiro, precisamos nos recuperar o campo ``result`` do JSON: -``` c -json_t *lu_response = NULL; -json_t *lu_result = NULL; - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -``` - -> :warning: **ATENÇÃO:** Só obteremos um resultado se não houver nenhum erro. Aqui temos um momento para melhorar nossa verificação de erros no código que iremos colocar em produção. - -Em seguida, vamos fazer um laço, examinando cada transação que não foi gasta, que aparece como um elemento em sua matriz do resultado JSON: -``` c -int i; - -const char *tx_id = 0; -int tx_vout = 0; -double tx_value = 0.0; - -for(i = 0 ; i < json_array_size(lu_result) ; i++) { - - json_t *lu_data = NULL; - lu_data = json_array_get(lu_result, i); - - json_t *lu_value = NULL; - lu_value = json_object_get(lu_data,"amount"); - tx_value = json_real_value(lu_value); -``` - -O UTXO é grande o suficiente para pagar sua transação? Se sim, pegue-o! - -> :warning: **ATENÇÃO:** Um programa em produção pensaria com mais cuidado sobre qual UTXO utilizar, com base no tamanho e em outros fatores. Provavelmente não pegaria apenas o primeiro mais simples e pronto. - -``` c - if(tx_value > tx_total) { - - json_t *lu_txid = NULL; - lu_txid = json_object_get(lu_data,"txid"); - tx_id = strdup(json_string_value(lu_txid)); - - json_t *lu_vout = NULL; - lu_vout = json_object_get(lu_data,"vout"); - tx_vout = json_integer_value(lu_vout); - - json_decref(lu_value); - json_decref(lu_txid); - json_decref(lu_vout); - json_decref(lu_data); - break; - - } -``` -Você também deve limpar os principais elementos do JSON: -``` c -} - -json_decref(lu_result); -json_decref(lu_response); -``` - -> :warning: **ATENÇÃO:** Um programa em produção também se certificaria de que os UTXOs são passíveis de serem `gastos`. - -Se não encontramos nenhum UTXOs grande o suficiente, teremos que relatar este infortúnio ao usuário... E talvez, sugerir que ele deva usar um programa melhor, que irá mesclar os UTXOs de maneira correta. -``` c -if(!tx_id) { - - printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); - exit(-1); -} -``` - -> **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. - -### Etapa 5: Criando um endereço de troco - -Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); - -if(!rpc_method) { - - printf("ERROR: Unable to initialize listunspent method!\n"); - exit(-1); - -} - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -if(btcerror.code != BITCOINRPCE_OK) { - -printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); - - exit(-1); - -} - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -char *changeaddress = strdup(json_string_value(lu_result)); -``` -A única diferença é quais informações específicas são extraídas do objeto JSON. - -> :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. - -### Etapa 6: Criando uma transação bruta - -Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. - -Para criarmos esses parâmetros corretamente, precisaremos revisar o que o RPC ``createrawtransaction`` espera que passemos como argumento. Felizmente, isso é fácil de determinar usando a funcionalidade ``bitcoin-cli help``: -``` -$ bitcoin-cli help createrawtransaction -createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) -``` - -Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. - -#### Etapa 6.1: Criando os parâmetros de entrada - -Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): -``` c -json_t *inputtxid = NULL; -inputtxid = json_object(); - -json_object_set_new(inputtxid,"txid",json_string(tx_id)); -json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); -``` - -Pode-se notar que teremos que traduzir novamente cada tipo de variável C em um tipo de variável JSON usando a função apropriada, como ``json_string`` ou ``json_integer``. - -Para criar o array de entrada para todos os UTXOs, vamos usar o ``json_array`` e, em seguida, preenchê-lo com os objetos usando o ``json_array_append``: -``` c -json_t *inputparams = NULL; -inputparams = json_array(); -json_array_append(inputparams,inputtxid); -``` - -#### Etapa 6.2: Criando os parâmetros de saída - -Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: -``` c -json_t *outputparams = NULL; -outputparams = json_object(); - -char tx_amount_string[32]; -sprintf(tx_amount_string,"%.8f",tx_amount); -char tx_change_string[32]; -sprintf(tx_change_string,"%.8f",tx_value - tx_total); - -json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); -json_object_set(outputparams, changeaddress, json_string(tx_change_string)); -``` - -> :warning: **ATENÇÃO:** É possível pensar que teremos que inserir os valores do Bitcoin como sendo números, usando a função ``json_real``. Infelizmente, isso expõe um dos maiores problemas com a integração da biblioteca ``jansson`` e o Bitcoin. O Bitcoin só é válido até oito dígitos depois da casa decimal. Devemos nos lembrar que 0,00000001 BTC é um satoshi, e essa é a menor divisão possível de um Bitcoin. O tipo ``double`` no C oferecem mais dígitos do que precisamos, embora sejam frequentemente imprecisos depois das oito casas decimais. Se tentarmos convertê-los diretamente do nosso valor ``double`` no C (ou de um tipo ``float``, neste caso) para um valor Bitcoin, a imprecisão frequentemente criará um valor Bitcoin com mais de oito dígitos. Antes da versão Bitcoin Core 0.12, isso não era problema, e podíamos usar a função ``json_real``. Mas à partir dessa versão, se tentarmos usar a função ``createrawtransaction`` com mais do que oito dígitos, obteremos um erro e a transação não será criada. Como resultado, se o valor do Bitcoin _sempre_ se tornar um ``double`` ou ``float``, devemos deixar com apenas oito casas decimais antes de transformá-lo em uma ``string``. Obviamente, isso é um erro, portanto, certifique-se disso para que o código continue funcionando nas versões mais novas do Bitcoin Core. - -#### Etapa 6.3: Criando a Matriz de Parâmetros - -Para terminarmos de criar os parâmetros, só precisaremos agrupá-los em uma matriz JSON: -``` c -json_t *params = NULL; -params = json_array(); -json_array_append(params,inputparams); -json_array_append(params,outputparams); -``` - -#### Etapa 6.4: Fazendo a chamada ao RPC - -Vamos usar o método normal para criar uma chamada ao RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); -``` -Agora, porém, devemos adicionar os nossos parâmetros. Isso pode ser feito facilmente com a função ``bitcoinrpc_method_set_params``: -``` c -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for createrawtransaction"); - -} -``` -Depois, é só executar o RPC e obter os resultados: -``` c -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_rawhex = strdup(json_string_value(lu_result)); -``` -### Etapa 7. Assinando a transação - -É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_rawhex)); -``` -Por fim, vamos assinar a transação seguindo o rigamarole típico para criar uma chamada RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for signrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -``` -Novamente, usar a função ``jansson`` para acessar a saída pode ser complicado. Devemos lembrar que ``hex`` é parte de um objeto JSON, não um resultado independente, como era quando criamos a transação bruta. Claro, sempre podemos acessar essas informações a partir da ajuda da linha de comando: ``bitcoin-cli help signrawtransaction`` -``` c -lu_result = json_object_get(lu_response,"result"); -json_t *lu_signature = json_object_get(lu_result,"hex"); -char *tx_signrawhex = strdup(json_string_value(lu_signature)); -json_decref(lu_signature); -``` -> :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. - -### Etapa 8. Enviando a transação - -Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_signrawhex)); - -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); - -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for sendrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_newid = strdup(json_string_value(lu_result)); - -printf("Txid: %s\n",tx_newid); -``` - -O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. - -## Testando o código - -O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). - -Compile-o como de costume: -``` -$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress -``` -Agora, é possível utilizá-lo para enviar fundos para um endereço: - -``` -./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 -Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 -``` -Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). - -## Resumo do Programando o Bitcoind usando C com bibliotecas RPC - -Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. - -## O Que Vem Depois? - -Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md deleted file mode 100644 index fe166ac..0000000 --- a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md +++ /dev/null @@ -1,155 +0,0 @@ - -# 15.3 Recebendo notificações usando C com a biblioteca ZMQ - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. - -> :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). - -## Configurando o ZMQ - -Antes de podemos ouvir a blockchain, precisaremos configurar o ``bitcoind`` para permitir as notificações ZMQ. Por isso, precisamos instalar a biblioteca ZMQ para tirar proveito dessas notificações. - -### Configurando o ``bitcoind`` para usar o ZMQ - -O Bitcoin Core está pronto para ZMQ, mas devemos especificar os endpoints do ZMQ. O ZeroMQ publish-sockets prefixa cada item de dados com um prefixo de tópico arbitrário que permite aos clientes assinantes solicitarem apenas os itens com um prefixo correspondente. Existem atualmente quatro tópicos suportados pelo ``bitcoind``: -``` -$ bitcoind --help | grep zmq | grep address - -zmqpubhashblock=
- -zmqpubhashtx=
- -zmqpubrawblock=
- -zmqpubrawtx=
-``` - -Podemos executar o ``bitcoind`` com argumentos de linha de comando para endpoints ZMQ, como mostrado acima, mas também podemos criar um endpoint acessível adicionando linhas apropriadas ao nosso arquivo ``~/.bitcoin/bitcoin.conf`` e reiniciando o sistema. - -``` -zmqpubrawblock=tcp://127.0.0.1:28332 -zmqpubrawtx=tcp://127.0.0.1:28333 -``` -Podemos então testar se os nossos endpoints estão funcionando usando o RPC ``getzmqnotifications``: - -``` -$ bitcoin-cli getzmqnotifications -[ - { - "type": "pubrawblock", - "address": "tcp://127.0.0.1:28332", - "hwm": 1000 - }, - { - "type": "pubrawtx", - "address": "tcp://127.0.0.1:28333", - "hwm": 1000 - } -] -``` -Nosso ``bitcoind`` agora irá emitir as notificações ZMQ - -### Instalando o ZMQ - -Para aproveitar essas notificações, precisamos de uma biblioteca ZMQ para usar com o C, portanto, estaremos usando uma nova biblioteca ZMQ ao invés da biblioteca ``libbitcoinrpc`` nesta seção, mas no futuro, podemos combinar ambas. - -Felizmente, as bibliotecas ZMQ estão disponíveis por meio de pacotes Debian padrão: -``` -$ sudo apt-get install libzmq3-dev -$ sudo apt-get install libczmq-dev -``` -Agora estamos pronto para escrever o código! - -## Escrevendo o programa de notificação - -O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. - -O programa requer dois parâmetros: O primeiro é o "servidor", que é o ponto de conexão TCP exposto pelo ``bitcoind``. O segundo é o "tópico", que atualmente é o ``zmqpubhashblock``,``zmqpubhashtx``, ``zmqpubrawblock`` ou ``zmqpubrawtx``. O tópico precisa ter suporte do ``bitcoin.conf`` e o endereço IP e a porta do servidor devem corresponder ao que está definido no arquivo de configuração. - -``` c -#include -int main(int argc, char ** argv) { - - char *zmqserver; - char *topic; - - if(argc < 3) { - printf("\nUSAGE:\nchainlistener \n\n"); - return 0; - } else { - zmqserver = argv[1]; - topic = argv[2]; - } -``` -Abriremos um soquete ZMQ para o servidor e para o tópico definido: -``` c - zsock_t *socket = zsock_new_sub(zmqserver, topic); - assert(socket); -``` -Depois, vamos esperar: -``` c - while(1) { - zmsg_t *msg; - int rc = zsock_recv(socket, "m", &msg); - assert(rc == 0); - - char *header = zmsg_popstr(msg); - zframe_t *zdata = zmsg_pop(msg); - unsigned int *no = (unsigned int*)zmsg_popstr(msg); - - char *data = zframe_strhex(zdata); - int len = zframe_size(zdata); - printf("Size: %d\n", len); - printf("Data: %s", data); - printf("\nNo: %d\n", *no); - - free(header); - free(data); - free(no); - free(zdata); - zmsg_destroy(&msg); - sleep(1); - } -``` -Enquanto esperamos, observamos as mensagens no soquete ZMQ. Sempre que recebermos uma mensagem, iremos retirá-la da pilha, relatando o número, comprimento e, o os dados que foram importante para nós. - -É isso! - -Claro, quando terminar o processo, precisamos limpar tudo: -``` c - zsock_destroy(&socket); - return 0; -} -``` - -### Testando o código de notificação - -O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: -``` -$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq -``` -Depois, podemos executá-lo com os tópicos e endereços que definimos no nosso ``bitcoin.conf``: -``` -$ ./chainlistener tcp://127.0.0.1:28333 rawtx -Size: 250 -Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 -No: 67 -Size: 249 -Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 -No: 68 -Size: 250 -Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 -No: 69 -Size: 250 -Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 -No: 70 -....... -``` - -### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ - -Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. - -> :fire: ***Qual é o poder das notificações?*** Com as notificações, não dependemos mais dos usuários para emitir os comandos. Ou seja, podemos criar programas que monitoram o blockchain do Bitcoin e tomar as ações apropriadas quando certas coisas ocorrem. Isso, por sua vez, pode ser utilizado juntamente com os comandos RPC que programamos nas seções anteriores. Este também é um grande passo além do que poderíamos fazer com os scripts shell: Certamente, podemos criar scripts shell que fica ouvindo infinitamente, mas existem outras linguagens de programação que possuem ferramentas melhores para isso. - -## O Que Vem Depois? - -Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file From 317ca7e1955f9f03aba7d42d15be5e225f5d6a17 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 11:05:33 -0300 Subject: [PATCH 078/155] Delete old chapter 15 --- pt/15_0_Talking_to_Bitcoind.md | 27 -- pt/15_1_Accessing_Bitcoind_with_C.md | 294 --------------- pt/15_2_Programming_Bitcoind_with_C.md | 354 ------------------ ...Receiving_Bitcoind_Notifications_with_C.md | 155 -------- 4 files changed, 830 deletions(-) delete mode 100644 pt/15_0_Talking_to_Bitcoind.md delete mode 100644 pt/15_1_Accessing_Bitcoind_with_C.md delete mode 100644 pt/15_2_Programming_Bitcoind_with_C.md delete mode 100644 pt/15_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/pt/15_0_Talking_to_Bitcoind.md b/pt/15_0_Talking_to_Bitcoind.md deleted file mode 100644 index 88bde29..0000000 --- a/pt/15_0_Talking_to_Bitcoind.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Capítulo 15: Conversando com Bitcoind usando C - -Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. - -Esta seção se concentra em três diferentes bibliotecas que podem ser usadas como base de programação C sofisticada: Uma biblioteca RPC e uma biblioteca JSON que juntas permitem recriar muito do que fazemos nos scripts de shell, porém, usando C; enquanto uma biblioteca ZMQ nos conecta a notificações, algo que não conseguiríamos acessar até agora. (O próximo capítulo cobrirá uma biblioteca ainda mais sofisticada chamada Libwally, para finalizar esta introdução à programação do Bitcoin com C). - -## Objetivos deste capítulo - -Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - - * Criar programas C que usam RPC para conversar com o Bitcoind; - * Criar programas C que usam ZMQ para conversar com o Bitcoind. - -Os objetivos secundários do capítulo incluem a capacidade de: - - * Entender como usar uma biblioteca RPC; - * Entender como usar uma biblioteca JSON; - * Compreender as capacidades do ZMQ; - * Entender como usar uma biblioteca ZMQ. - -## Tabela de conteúdo - - * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) - * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) - * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) - \ No newline at end of file diff --git a/pt/15_1_Accessing_Bitcoind_with_C.md b/pt/15_1_Accessing_Bitcoind_with_C.md deleted file mode 100644 index 2e97e1c..0000000 --- a/pt/15_1_Accessing_Bitcoind_with_C.md +++ /dev/null @@ -1,294 +0,0 @@ - -# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -Você já viu uma maneira alternativa de acessar as portas RPC do Bitcoind: Usando o ``curl``, que cobrimos no [Capítulo 4 Prefácio](04_4__interlude_using_curl.md). Interagir com o ``Bitcoind`` através de uma biblioteca de RPC usando C não é diferente do que já vimos, só precisamos de boas bibliotecas para nos auxiliar. Esta seção introduz um pacote chamado ``libbitcoinrpc``, que permite acessar a porta JSON-RPC do ``bitcoind``. Ele usa uma biblioteca ``curl`` para acessar os dados e usa a biblioteca ``jansson`` para codificar e decodificar o JSON. - -## Configurando o libbitcoinrpc - -Para usar o ``libbitcoinrpc``, precisaremos instalar uma configuração básica C e os pacotes dependentes, que são ``libcurl``, ``libjansson``, e ``libuuid``. Depois faremos isso no seu servidor Standup Bitcoin (ou em qualquer outro servidor Ubuntu). - -``` -$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev -Suggested packages: - libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev -The following NEW packages will be installed: - libcurl4-openssl-dev libjansson-dev uuid-dev -0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. -Need to get 358 kB of archives. -After this operation, 1.696 kB of additional disk space will be used. -Do you want to continue? [Y/n] y -``` -Agora, podemos baixar o [libbitcoinrpc no github](https://github.com/gitmarek/libbitcoinrpc/blob/master/readme.md). Vamos clonar ou pegar um arquivo zip, do jeito que preferir. - -``` -$ sudo apt-get install git -$ git clone https://github.com/gitmarek/libbitcoinrpc -``` - -> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. - -### Compilando o libbitcoinrpc. - -Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: -``` -$ PATH="/sbin:$PATH" -``` - -Para o Ubuntu, também precisaremos ajustar o ``install_libpath`` no ``makefile`` do ``libbitcoinrpc`` para instalar no ``/usr/lib`` ao invés do ``/usr/local/lib``: - -``` -$ emacs ~/libbitcoinrpc/Makefile -... -INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib -``` - -(Se preferir não usar o ``/usr/lib``, precisará alterar o ``etc/ld.so.conf`` ou os arquivos dependentes de maneira apropriada... Porém, para uma configuração de teste em uma máquina de teste, acredito que isso não seja um problema). - -Da mesma forma, vamos precisar ajustar o ``install_headerpath`` no ``Makefile`` do ``libbitcoinrpc`` para instalar no caminho ``/usr/include`` ao invés do ``/usr/local/inclusve``: - -``` -... -INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include -``` - -Agora, podemos compilar: -``` -$ cd libbitcoinrpc -~/libbitcoinrpc$ make - -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ -src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ --o .lib/libbitcoinrpc.so.0.2 \ --Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl -ldconfig -v -n .lib -.lib: - libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) -ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so -``` -Se tudo correr bem, podemos instalar o pacote: -``` -$ sudo make install -Installing to -install .lib/libbitcoinrpc.so.0.2 /usr/local/lib -ldconfig -n /usr/local/lib -ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so -install -m 644 src/bitcoinrpc.h /usr/local/include -Installing docs to /usr/share/doc/bitcoinrpc -mkdir -p /usr/share/doc/bitcoinrpc -install -m 644 doc/*.md /usr/share/doc/bitcoinrpc -install -m 644 CREDITS /usr/share/doc/bitcoinrpc -install -m 644 LICENSE /usr/share/doc/bitcoinrpc -install -m 644 Changelog.md /usr/share/doc/bitcoinrpc -Installing man pages -install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 -``` - -## Preparando o código - -``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. - -Para usar o ``libbitcoinrpc``, é importante certificar de que nossos arquivos do código incluam os cabeçalhos apropriados: -``` c -#include -#include -``` - -Precisaremos também vincular as bibliotecas apropriadas sempre que possamos compilar: - -``` -$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode -``` - -## Construindo a conexão - -Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. - -Primeiro, inicialize a biblioteca: -``` -bitcoinrpc_global_init(); -``` -Em seguida, vamos conectar ao ``Bitcoind`` com ``bitcoinrpc_cl_init_params``. Os quatro argumentos necessários para o ``bitcoinrpc_cl_init_params`` são o nome de usuário, a senha, o endereço IP e a porta. A esta altura, você deve saber todas essas informações, já que foram necessárias para realizar o trabalho com o [curl](04_4__interlude_using_curl.md). Apenas para recordar, o endereço de IP é 127.0.0.1 e a porta 18332 devem estar corretos para a configuração padrão da testenet descrita neste documento, enquanto podemos encontrar o usuário e a senha no arquivo ``~/.bitcoin/bitcoin.conf``. -``` -$ cat bitcoin.conf -server=1 -dbcache=1536 -par=1 -maxuploadtarget=137 -maxconnections=16 -rpcuser=StandUp -rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba -rpcallowip=127.0.0.1 -debug=tor -prune=550 -testnet=1 -[test] -rpcbind=127.0.0.1 -rpcport=18332 -[main] -rpcbind=127.0.0.1 -rpcport=8332 -[regtest] -rpcbind=127.0.0.1 -rpcport=18443 -``` -Com essas informações, vamos colocá-las no ``bitcoinrpc_cl_init_params``: -``` c -bitcoinrpc_cl_t *rpc_client; -rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); -``` - -> **MAINNET VS TESTNET:** A porta seria a 8332 caso estivéssemos usando a configuração da rede principal. - -Se o ``rpc_client`` for inicializado com sucesso, poderemos enviar os comandos do RPC. - -Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fechar da seguinte maneira: -``` c -bitcoinrpc_global_cleanup(); -``` - -### Testando o código de teste - -O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). - -Podemos compilar e executar o código da seguinte maneira: -``` -$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin -$ ./testbitcoin -Successfully connected to server! -``` - -> :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. - -## Fazendo uma chamada ao RPC - -Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). -``` c -bitcoinrpc_method_t *getmininginfo = NULL; -getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); -``` -Normalmente definiríamos os parâmetros em seguida, mas o ``GetMiningInfo`` não requer parâmetros, por isso podemos pular essa parte. - -Também devemos criar outros dois objetos, um "objeto de resposta" e um "objeto de erro". Eles podem ser inicializados da seguinte forma: -``` c -bitcoinrpc_resp_t *btcresponse = NULL; -btcresponse = bitcoinrpc_resp_init(); - -bitcoinrpc_err_t btcerror; -``` -Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos adicionar nosso método ``getmininginfo`` e os outros dois objetos: -``` c -bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); -``` - -### Mostrando o retorno da chamada - -Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: -``` c -json_t *jsonresponse = NULL; -jsonresponse = bitcoinrpc_resp_get(btcresponse); -``` -Se quisermos gerar os resultados completos da chamada RPC no JSON, podemos fazer com uma simples invocação do ``json_dumps``, da biblioteca ``jansson``: -``` c -printf("%s\n", json_dumps(j, JSON_INDENT(2))); -``` -No entanto, como agora estamos escrevendo programas completos, provavelmente iremos querer fazer um trabalho mais sutil, como retirar valores individuais do JSON para algum uso específico. A [Referência do Jansson](https6//jansson.readthedocs.Io/en/2.10/apiref.html) traz detalhes de como fazer. - -Assim como estávamos usando o [curl](04_4__interlude_using_curl.md), descobrimos que o RPC retorna um objeto JSON contendo um ``ID``, um ``error`` e, mais importante, um objeto JSON do tipo ``result``. - -A função ``json_object_get`` permite recuperar um valor (como o ``result``) de um objeto JSON usando chaves: -``` c -json_t *jsonresult = NULL; -jsonresult = json_object_get(jsonresponse,"result"); -printf("%s\n", json_dumps(jsonresult, JSON_INDENT(2))); -``` - -No entanto, provavelmente iremos querer analisar informações ainda mais profundas, para obter uma variável específica. Depois de recuperar o valor apropriado, precisaremos convertê-lo em um objeto C padrão usando a função ``JSON_*_value``. Por exemplo, para acessar um integer usamos o ``json_integer_value``: -``` c -json_t *jsonblocks = NULL; -jsonblocks = json_object_get(jsonresult,"blocks"); - -int blocks; -blocks = json_integer_value(jsonblocks); -printf("Block Count: %d\n",blocks); -``` - -> :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. - -### Testando o código de informação - -Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). -``` -$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo -$ ./getmininginfo -Full Response: { - "result": { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" - }, - "error": null, - "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" -} - -Just the Result: { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" -} - -Block Count: 1804406 -``` - -## Fazendo uma chamada RPC usando argumentos - -Mas e se a sua chamada RPC tiver argumentos? - -### Criando uma matriz JSON - -Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. - -Vamos criar a matriz JSON usando a função ``json_array do`` do ``jansson``: -``` c -json_t *params = NULL; -params = json_array(); -``` -Vamos fazer o processo inverso que fizemos para acessar valores do JSON: Vamos converter objetos no C para objetos no JSON usando as funções ``JSON_*``. Depois, vamos anexar tudo à matriz: -``` c -json_array_append_new(params,json_string(tx_rawhex)); -``` - -Observe que existem duas variantes para o comando de anexação: ``json_array_apend_new``, que acrescenta uma variável recém-criada, e ``json_array_apend``, que anexa uma variável existente. - -Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. - -### Atribuindo os parâmetros - -Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: -``` c -bitcoinrpc_method_set_params(rpc_method, params) -``` -Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. - -## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC - -Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. - -* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. - -## O Que Vem Depois? - -Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). diff --git a/pt/15_2_Programming_Bitcoind_with_C.md b/pt/15_2_Programming_Bitcoind_with_C.md deleted file mode 100644 index c1fdc38..0000000 --- a/pt/15_2_Programming_Bitcoind_with_C.md +++ /dev/null @@ -1,354 +0,0 @@ - -# 15.2: Programando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. - -## Planejando o código - -Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: - - 1. Solicitar um endereço e uma quantia; - 2. Definir uma taxa arbitrária; - 3. Preparar nosso RPC; - 4. Encontrar um UTXO que seja grande o suficiente para pagar o valor + a taxa; - 5. Criar uma mudança de endereço; - 6. Criar uma transação bruta que envie o UTXO para o endereço e altere o endereço; - 7. Assinar a transação; - 8. Enviar a transação. - -### Planejando para o futuro - -Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: - - 1. Testar e/ou higienizar as entradas; - 2. Calcular uma taxa automaticamente; - 3. Pensar logicamente sobre qual UTXO seria válido utilizar; - 4. Combinar vários UTXOs, caso seja necessário; - 5. Ficar atento a mais erros nos comandos ``libbitcoinrpc`` ou no ``jansson``; - 6. Observar se há erros nas respostas RPC. - -Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. - -## Escrevendo o sistema de transação - -Agora estamos prontos para realizar o passo a passo do nosso plano - -### Etapa 1: Solicitando um endereço e uma quantia - -Inserir as informações é bem simples se usarmos os argumentos na linha de comando: -``` c -if(argc != 3) { - - printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); - exit(-1); - -} - -char *tx_recipient = argv[1]; -float tx_amount = atof(argv[2]); - -printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); -``` - -> :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. - -### Etapa 2: Definindo uma taxa arbitrária - -Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: - -``` c -float tx_fee = 0.0005; -float tx_total = tx_amount + tx_fee; -``` - -> :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. - -### Etapa 3: Preparando nosso RPC - -Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: -``` c -bitcoinrpc_global_init(); -rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); -btcresponse = bitcoinrpc_resp_init(); -``` - -### Etapa 4: Encontrando um UTXO - -Para encontrar um UTXO, precisaremos chamar a função RPC ``listunspent``: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -``` - -No entanto, o verdadeiro trabalho consiste em decodificar a resposta. Na seção anterior vimos que a biblioteca ``jansson`` era "um tanto quanto desajeitada" e esta é a razão: Precisamos criar (e limpar) um conjunto muito grande de objetos ``json_t`` para descobrir o que queremos. - -Primeiro, precisamos nos recuperar o campo ``result`` do JSON: -``` c -json_t *lu_response = NULL; -json_t *lu_result = NULL; - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -``` - -> :warning: **ATENÇÃO:** Só obteremos um resultado se não houver nenhum erro. Aqui temos um momento para melhorar nossa verificação de erros no código que iremos colocar em produção. - -Em seguida, vamos fazer um laço, examinando cada transação que não foi gasta, que aparece como um elemento em sua matriz do resultado JSON: -``` c -int i; - -const char *tx_id = 0; -int tx_vout = 0; -double tx_value = 0.0; - -for(i = 0 ; i < json_array_size(lu_result) ; i++) { - - json_t *lu_data = NULL; - lu_data = json_array_get(lu_result, i); - - json_t *lu_value = NULL; - lu_value = json_object_get(lu_data,"amount"); - tx_value = json_real_value(lu_value); -``` - -O UTXO é grande o suficiente para pagar sua transação? Se sim, pegue-o! - -> :warning: **ATENÇÃO:** Um programa em produção pensaria com mais cuidado sobre qual UTXO utilizar, com base no tamanho e em outros fatores. Provavelmente não pegaria apenas o primeiro mais simples e pronto. - -``` c - if(tx_value > tx_total) { - - json_t *lu_txid = NULL; - lu_txid = json_object_get(lu_data,"txid"); - tx_id = strdup(json_string_value(lu_txid)); - - json_t *lu_vout = NULL; - lu_vout = json_object_get(lu_data,"vout"); - tx_vout = json_integer_value(lu_vout); - - json_decref(lu_value); - json_decref(lu_txid); - json_decref(lu_vout); - json_decref(lu_data); - break; - - } -``` -Você também deve limpar os principais elementos do JSON: -``` c -} - -json_decref(lu_result); -json_decref(lu_response); -``` - -> :warning: **ATENÇÃO:** Um programa em produção também se certificaria de que os UTXOs são passíveis de serem `gastos`. - -Se não encontramos nenhum UTXOs grande o suficiente, teremos que relatar este infortúnio ao usuário... E talvez, sugerir que ele deva usar um programa melhor, que irá mesclar os UTXOs de maneira correta. -``` c -if(!tx_id) { - - printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); - exit(-1); -} -``` - -> **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. - -### Etapa 5: Criando um endereço de troco - -Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); - -if(!rpc_method) { - - printf("ERROR: Unable to initialize listunspent method!\n"); - exit(-1); - -} - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -if(btcerror.code != BITCOINRPCE_OK) { - -printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); - - exit(-1); - -} - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -char *changeaddress = strdup(json_string_value(lu_result)); -``` -A única diferença é quais informações específicas são extraídas do objeto JSON. - -> :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. - -### Etapa 6: Criando uma transação bruta - -Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. - -Para criarmos esses parâmetros corretamente, precisaremos revisar o que o RPC ``createrawtransaction`` espera que passemos como argumento. Felizmente, isso é fácil de determinar usando a funcionalidade ``bitcoin-cli help``: -``` -$ bitcoin-cli help createrawtransaction -createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) -``` - -Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. - -#### Etapa 6.1: Criando os parâmetros de entrada - -Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): -``` c -json_t *inputtxid = NULL; -inputtxid = json_object(); - -json_object_set_new(inputtxid,"txid",json_string(tx_id)); -json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); -``` - -Pode-se notar que teremos que traduzir novamente cada tipo de variável C em um tipo de variável JSON usando a função apropriada, como ``json_string`` ou ``json_integer``. - -Para criar o array de entrada para todos os UTXOs, vamos usar o ``json_array`` e, em seguida, preenchê-lo com os objetos usando o ``json_array_append``: -``` c -json_t *inputparams = NULL; -inputparams = json_array(); -json_array_append(inputparams,inputtxid); -``` - -#### Etapa 6.2: Criando os parâmetros de saída - -Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: -``` c -json_t *outputparams = NULL; -outputparams = json_object(); - -char tx_amount_string[32]; -sprintf(tx_amount_string,"%.8f",tx_amount); -char tx_change_string[32]; -sprintf(tx_change_string,"%.8f",tx_value - tx_total); - -json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); -json_object_set(outputparams, changeaddress, json_string(tx_change_string)); -``` - -> :warning: **ATENÇÃO:** É possível pensar que teremos que inserir os valores do Bitcoin como sendo números, usando a função ``json_real``. Infelizmente, isso expõe um dos maiores problemas com a integração da biblioteca ``jansson`` e o Bitcoin. O Bitcoin só é válido até oito dígitos depois da casa decimal. Devemos nos lembrar que 0,00000001 BTC é um satoshi, e essa é a menor divisão possível de um Bitcoin. O tipo ``double`` no C oferecem mais dígitos do que precisamos, embora sejam frequentemente imprecisos depois das oito casas decimais. Se tentarmos convertê-los diretamente do nosso valor ``double`` no C (ou de um tipo ``float``, neste caso) para um valor Bitcoin, a imprecisão frequentemente criará um valor Bitcoin com mais de oito dígitos. Antes da versão Bitcoin Core 0.12, isso não era problema, e podíamos usar a função ``json_real``. Mas à partir dessa versão, se tentarmos usar a função ``createrawtransaction`` com mais do que oito dígitos, obteremos um erro e a transação não será criada. Como resultado, se o valor do Bitcoin _sempre_ se tornar um ``double`` ou ``float``, devemos deixar com apenas oito casas decimais antes de transformá-lo em uma ``string``. Obviamente, isso é um erro, portanto, certifique-se disso para que o código continue funcionando nas versões mais novas do Bitcoin Core. - -#### Etapa 6.3: Criando a Matriz de Parâmetros - -Para terminarmos de criar os parâmetros, só precisaremos agrupá-los em uma matriz JSON: -``` c -json_t *params = NULL; -params = json_array(); -json_array_append(params,inputparams); -json_array_append(params,outputparams); -``` - -#### Etapa 6.4: Fazendo a chamada ao RPC - -Vamos usar o método normal para criar uma chamada ao RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); -``` -Agora, porém, devemos adicionar os nossos parâmetros. Isso pode ser feito facilmente com a função ``bitcoinrpc_method_set_params``: -``` c -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for createrawtransaction"); - -} -``` -Depois, é só executar o RPC e obter os resultados: -``` c -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_rawhex = strdup(json_string_value(lu_result)); -``` -### Etapa 7. Assinando a transação - -É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_rawhex)); -``` -Por fim, vamos assinar a transação seguindo o rigamarole típico para criar uma chamada RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for signrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -``` -Novamente, usar a função ``jansson`` para acessar a saída pode ser complicado. Devemos lembrar que ``hex`` é parte de um objeto JSON, não um resultado independente, como era quando criamos a transação bruta. Claro, sempre podemos acessar essas informações a partir da ajuda da linha de comando: ``bitcoin-cli help signrawtransaction`` -``` c -lu_result = json_object_get(lu_response,"result"); -json_t *lu_signature = json_object_get(lu_result,"hex"); -char *tx_signrawhex = strdup(json_string_value(lu_signature)); -json_decref(lu_signature); -``` -> :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. - -### Etapa 8. Enviando a transação - -Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_signrawhex)); - -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); - -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for sendrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_newid = strdup(json_string_value(lu_result)); - -printf("Txid: %s\n",tx_newid); -``` - -O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. - -## Testando o código - -O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). - -Compile-o como de costume: -``` -$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress -``` -Agora, é possível utilizá-lo para enviar fundos para um endereço: - -``` -./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 -Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 -``` -Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). - -## Resumo do Programando o Bitcoind usando C com bibliotecas RPC - -Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. - -## O Que Vem Depois? - -Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md deleted file mode 100644 index fe166ac..0000000 --- a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md +++ /dev/null @@ -1,155 +0,0 @@ - -# 15.3 Recebendo notificações usando C com a biblioteca ZMQ - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. - -> :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). - -## Configurando o ZMQ - -Antes de podemos ouvir a blockchain, precisaremos configurar o ``bitcoind`` para permitir as notificações ZMQ. Por isso, precisamos instalar a biblioteca ZMQ para tirar proveito dessas notificações. - -### Configurando o ``bitcoind`` para usar o ZMQ - -O Bitcoin Core está pronto para ZMQ, mas devemos especificar os endpoints do ZMQ. O ZeroMQ publish-sockets prefixa cada item de dados com um prefixo de tópico arbitrário que permite aos clientes assinantes solicitarem apenas os itens com um prefixo correspondente. Existem atualmente quatro tópicos suportados pelo ``bitcoind``: -``` -$ bitcoind --help | grep zmq | grep address - -zmqpubhashblock=
- -zmqpubhashtx=
- -zmqpubrawblock=
- -zmqpubrawtx=
-``` - -Podemos executar o ``bitcoind`` com argumentos de linha de comando para endpoints ZMQ, como mostrado acima, mas também podemos criar um endpoint acessível adicionando linhas apropriadas ao nosso arquivo ``~/.bitcoin/bitcoin.conf`` e reiniciando o sistema. - -``` -zmqpubrawblock=tcp://127.0.0.1:28332 -zmqpubrawtx=tcp://127.0.0.1:28333 -``` -Podemos então testar se os nossos endpoints estão funcionando usando o RPC ``getzmqnotifications``: - -``` -$ bitcoin-cli getzmqnotifications -[ - { - "type": "pubrawblock", - "address": "tcp://127.0.0.1:28332", - "hwm": 1000 - }, - { - "type": "pubrawtx", - "address": "tcp://127.0.0.1:28333", - "hwm": 1000 - } -] -``` -Nosso ``bitcoind`` agora irá emitir as notificações ZMQ - -### Instalando o ZMQ - -Para aproveitar essas notificações, precisamos de uma biblioteca ZMQ para usar com o C, portanto, estaremos usando uma nova biblioteca ZMQ ao invés da biblioteca ``libbitcoinrpc`` nesta seção, mas no futuro, podemos combinar ambas. - -Felizmente, as bibliotecas ZMQ estão disponíveis por meio de pacotes Debian padrão: -``` -$ sudo apt-get install libzmq3-dev -$ sudo apt-get install libczmq-dev -``` -Agora estamos pronto para escrever o código! - -## Escrevendo o programa de notificação - -O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. - -O programa requer dois parâmetros: O primeiro é o "servidor", que é o ponto de conexão TCP exposto pelo ``bitcoind``. O segundo é o "tópico", que atualmente é o ``zmqpubhashblock``,``zmqpubhashtx``, ``zmqpubrawblock`` ou ``zmqpubrawtx``. O tópico precisa ter suporte do ``bitcoin.conf`` e o endereço IP e a porta do servidor devem corresponder ao que está definido no arquivo de configuração. - -``` c -#include -int main(int argc, char ** argv) { - - char *zmqserver; - char *topic; - - if(argc < 3) { - printf("\nUSAGE:\nchainlistener \n\n"); - return 0; - } else { - zmqserver = argv[1]; - topic = argv[2]; - } -``` -Abriremos um soquete ZMQ para o servidor e para o tópico definido: -``` c - zsock_t *socket = zsock_new_sub(zmqserver, topic); - assert(socket); -``` -Depois, vamos esperar: -``` c - while(1) { - zmsg_t *msg; - int rc = zsock_recv(socket, "m", &msg); - assert(rc == 0); - - char *header = zmsg_popstr(msg); - zframe_t *zdata = zmsg_pop(msg); - unsigned int *no = (unsigned int*)zmsg_popstr(msg); - - char *data = zframe_strhex(zdata); - int len = zframe_size(zdata); - printf("Size: %d\n", len); - printf("Data: %s", data); - printf("\nNo: %d\n", *no); - - free(header); - free(data); - free(no); - free(zdata); - zmsg_destroy(&msg); - sleep(1); - } -``` -Enquanto esperamos, observamos as mensagens no soquete ZMQ. Sempre que recebermos uma mensagem, iremos retirá-la da pilha, relatando o número, comprimento e, o os dados que foram importante para nós. - -É isso! - -Claro, quando terminar o processo, precisamos limpar tudo: -``` c - zsock_destroy(&socket); - return 0; -} -``` - -### Testando o código de notificação - -O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: -``` -$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq -``` -Depois, podemos executá-lo com os tópicos e endereços que definimos no nosso ``bitcoin.conf``: -``` -$ ./chainlistener tcp://127.0.0.1:28333 rawtx -Size: 250 -Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 -No: 67 -Size: 249 -Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 -No: 68 -Size: 250 -Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 -No: 69 -Size: 250 -Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 -No: 70 -....... -``` - -### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ - -Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. - -> :fire: ***Qual é o poder das notificações?*** Com as notificações, não dependemos mais dos usuários para emitir os comandos. Ou seja, podemos criar programas que monitoram o blockchain do Bitcoin e tomar as ações apropriadas quando certas coisas ocorrem. Isso, por sua vez, pode ser utilizado juntamente com os comandos RPC que programamos nas seções anteriores. Este também é um grande passo além do que poderíamos fazer com os scripts shell: Certamente, podemos criar scripts shell que fica ouvindo infinitamente, mas existem outras linguagens de programação que possuem ferramentas melhores para isso. - -## O Que Vem Depois? - -Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file From 8512f44de417a412b85440e4a0b54a749658d30c Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 11:11:25 -0300 Subject: [PATCH 079/155] Rename files chapter 16 to 17 --- ...ramming_with_Libwally.md => 17_0_Programming_with_Libwally.md} | 0 pt/{16_1_Setting_Up_Libwally.md => 17_1_Setting_Up_Libwally.md} | 0 ...Using_BIP39_in_Libwally.md => 17_2_Using_BIP39_in_Libwally.md} | 0 ...Using_BIP32_in_Libwally.md => 17_3_Using_BIP32_in_Libwally.md} | 0 ...Using_PSBTs_in_Libwally.md => 17_4_Using_PSBTs_in_Libwally.md} | 0 ...g_Scripts_in_Libwally.md => 17_5_Using_Scripts_in_Libwally.md} | 0 ...s_in_Libwally.md => 17_6_Using_Other_Functions_in_Libwally.md} | 0 ...itcoin-CLI.md => 17_7_Integrating_Libwally_and_Bitcoin-CLI.md} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename pt/{16_0_Programming_with_Libwally.md => 17_0_Programming_with_Libwally.md} (100%) rename pt/{16_1_Setting_Up_Libwally.md => 17_1_Setting_Up_Libwally.md} (100%) rename pt/{16_2_Using_BIP39_in_Libwally.md => 17_2_Using_BIP39_in_Libwally.md} (100%) rename pt/{16_3_Using_BIP32_in_Libwally.md => 17_3_Using_BIP32_in_Libwally.md} (100%) rename pt/{16_4_Using_PSBTs_in_Libwally.md => 17_4_Using_PSBTs_in_Libwally.md} (100%) rename pt/{16_5_Using_Scripts_in_Libwally.md => 17_5_Using_Scripts_in_Libwally.md} (100%) rename pt/{16_6_Using_Other_Functions_in_Libwally.md => 17_6_Using_Other_Functions_in_Libwally.md} (100%) rename pt/{16_7_Integrating_Libwally_and_Bitcoin-CLI.md => 17_7_Integrating_Libwally_and_Bitcoin-CLI.md} (100%) diff --git a/pt/16_0_Programming_with_Libwally.md b/pt/17_0_Programming_with_Libwally.md similarity index 100% rename from pt/16_0_Programming_with_Libwally.md rename to pt/17_0_Programming_with_Libwally.md diff --git a/pt/16_1_Setting_Up_Libwally.md b/pt/17_1_Setting_Up_Libwally.md similarity index 100% rename from pt/16_1_Setting_Up_Libwally.md rename to pt/17_1_Setting_Up_Libwally.md diff --git a/pt/16_2_Using_BIP39_in_Libwally.md b/pt/17_2_Using_BIP39_in_Libwally.md similarity index 100% rename from pt/16_2_Using_BIP39_in_Libwally.md rename to pt/17_2_Using_BIP39_in_Libwally.md diff --git a/pt/16_3_Using_BIP32_in_Libwally.md b/pt/17_3_Using_BIP32_in_Libwally.md similarity index 100% rename from pt/16_3_Using_BIP32_in_Libwally.md rename to pt/17_3_Using_BIP32_in_Libwally.md diff --git a/pt/16_4_Using_PSBTs_in_Libwally.md b/pt/17_4_Using_PSBTs_in_Libwally.md similarity index 100% rename from pt/16_4_Using_PSBTs_in_Libwally.md rename to pt/17_4_Using_PSBTs_in_Libwally.md diff --git a/pt/16_5_Using_Scripts_in_Libwally.md b/pt/17_5_Using_Scripts_in_Libwally.md similarity index 100% rename from pt/16_5_Using_Scripts_in_Libwally.md rename to pt/17_5_Using_Scripts_in_Libwally.md diff --git a/pt/16_6_Using_Other_Functions_in_Libwally.md b/pt/17_6_Using_Other_Functions_in_Libwally.md similarity index 100% rename from pt/16_6_Using_Other_Functions_in_Libwally.md rename to pt/17_6_Using_Other_Functions_in_Libwally.md diff --git a/pt/16_7_Integrating_Libwally_and_Bitcoin-CLI.md b/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md similarity index 100% rename from pt/16_7_Integrating_Libwally_and_Bitcoin-CLI.md rename to pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md From 2502bd075165bc836a740d57d266120f7815ae12 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 11:24:22 -0300 Subject: [PATCH 080/155] Update README --- pt/README.md | 56 ++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/pt/README.md b/pt/README.md index 2917302..0f155f5 100644 --- a/pt/README.md +++ b/pt/README.md @@ -105,40 +105,40 @@ Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuin **Estado:** Finalizado. -* [15.0: Conversando com o Bitcoind com C](15_0_Talking_to_Bitcoind.md) - * [15.1: Acessando o Bitcoind em C com Livrarias RPC](15_1_Accessing_Bitcoind_with_C.md) - * [15.2: Programando o Bitcoind em C com Livrarias RPC](15_2_Programming_Bitcoind_with_C.md) - * [15.3: Recebendo Notificações em C com Livrarias ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) -* [16.0: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md) - * [16.1: Configurando a Libwally](16_1_Setting_Up_Libwally.md) - * [16.2: Usando BIP39 na Libwally](16_2_Using_BIP39_in_Libwally.md) - * [16.3: Usando BIP32 na Libwally](16_3_Using_BIP32_in_Libwally.md) - * [16.4: Usando PSBTs na Libwally](16_4_Using_PSBTs_in_Libwally.md) - * [16.5: Usando Scripts na Libwally](16_5_Using_Scripts_in_Libwally.md) - * [16.6: Usando Outras Funções na Libwally](16_6_Using_Other_Functions_in_Libwally.md) - * [16.7: Integrando Libwally e Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md) -* [17.0: Conversando com o Bitcoind com Outras Linguagens](17_0_Talking_to_Bitcoind_Other.md) - * [17.1: Acessando o Bitcoind com Go](17_1_Accessing_Bitcoind_with_Go.md) - * [17.2: Acessando o Bitcoind com Java](17_2_Accessing_Bitcoind_with_Java.md) - * [17.3: Acessando o Bitcoind com Node JS](17_3_Accessing_Bitcoind_with_NodeJS.md) - * [17.4: Acessando o Bitcoind com Python](17_4_Accessing_Bitcoind_with_Python.md) - * [17.5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md) - * [17.6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md) +* [16.0: Conversando com o Bitcoind com C](15_0_Talking_to_Bitcoind.md) + * [16.1: Acessando o Bitcoind em C com Livrarias RPC](15_1_Accessing_Bitcoind_with_C.md) + * [16.2: Programando o Bitcoind em C com Livrarias RPC](15_2_Programming_Bitcoind_with_C.md) + * [16.3: Recebendo Notificações em C com Livrarias ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) +* [17.0: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md) + * [17.1: Configurando a Libwally](16_1_Setting_Up_Libwally.md) + * [17.2: Usando BIP39 na Libwally](16_2_Using_BIP39_in_Libwally.md) + * [17.3: Usando BIP32 na Libwally](16_3_Using_BIP32_in_Libwally.md) + * [17.4: Usando PSBTs na Libwally](16_4_Using_PSBTs_in_Libwally.md) + * [17.5: Usando Scripts na Libwally](16_5_Using_Scripts_in_Libwally.md) + * [17.6: Usando Outras Funções na Libwally](16_6_Using_Other_Functions_in_Libwally.md) + * [17.7: Integrando Libwally e Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md) +* [18.0: Conversando com o Bitcoind com Outras Linguagens](17_0_Talking_to_Bitcoind_Other.md) + * [18.1: Acessando o Bitcoind com Go](17_1_Accessing_Bitcoind_with_Go.md) + * [18.2: Acessando o Bitcoind com Java](17_2_Accessing_Bitcoind_with_Java.md) + * [18.3: Acessando o Bitcoind com Node JS](17_3_Accessing_Bitcoind_with_NodeJS.md) + * [18.4: Acessando o Bitcoind com Python](17_4_Accessing_Bitcoind_with_Python.md) + * [18.5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md) + * [18.6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md) ### PARTE SEIS: USANDO LIGHTNING-CLI **Estado:** Finalizado. -* [18.0: Compreendendo Sua Configuração Lightning](18_0_Understanding_Your_Lightning_Setup.md) - * [18.1: Verificando Sua Configuração c-lightning](18_1_Verifying_Your_Lightning_Setup.md) - * [18.2: Conhecendo Sua Configuração c-lightning](18_2_Knowing_Your_lightning_Setup.md) +* [19.0: Compreendendo Sua Configuração Lightning](18_0_Understanding_Your_Lightning_Setup.md) + * [19.1: Verificando Sua Configuração c-lightning](18_1_Verifying_Your_Lightning_Setup.md) + * [19.2: Conhecendo Sua Configuração c-lightning](18_2_Knowing_Your_lightning_Setup.md) * [Prefácio: Acessando um Segundo Node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md) - * [18.3: Criando um Canal Lightning](18_3_Setting_Up_a_Channel.md) -* [19.0: Usando Lightning](19_0_Using_Lightning.md) - * [19.1: Gerando um Pedido de Pagamento](19_1_Generate_a_Payment_Request.md) - * [19.2: Pagando uma Fatura](19_2_Paying_a_Invoice.md) - * [19.3: Fechando um Canal Lighnting]((19_3_Closing_a_Channel.md)) - * [19.4: Expandindo a Rede Lightning](19_4_Lightning_Network_Review.md) + * [19.3: Criando um Canal Lightning](18_3_Setting_Up_a_Channel.md) +* [20.0: Usando Lightning](19_0_Using_Lightning.md) + * [20.1: Gerando um Pedido de Pagamento](19_1_Generate_a_Payment_Request.md) + * [20.2: Pagando uma Fatura](19_2_Paying_a_Invoice.md) + * [20.3: Fechando um Canal Lighnting]((19_3_Closing_a_Channel.md)) + * [20.4: Expandindo a Rede Lightning](19_4_Lightning_Network_Review.md) ### APÊNDICES From c3578c8c1f2becd9e37aa3ad8d5ef18ddfb513df Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 11:26:45 -0300 Subject: [PATCH 081/155] Update README --- pt/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pt/README.md b/pt/README.md index 0f155f5..0086802 100644 --- a/pt/README.md +++ b/pt/README.md @@ -101,6 +101,9 @@ Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuin * [14.2: Mudando Seus Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) * [14.3: Adicionando SSH aos Seus Serviços Ocultos](14_3_Adding_SSH_Hidden_Services.md) +* [15.0: Usando i2p](15_0_Using_i2p.md) + * [15.1: Bitcoin Core como um Serviço I2P (Invisible Internet Project)](15_1_i2p_service.md) + ### PARTE CINCO: PROGRAMANDO COM RPC **Estado:** Finalizado. From cfee6bc11907ed55a22cde29af04b65972eb79fb Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 11:39:22 -0300 Subject: [PATCH 082/155] Review 17_0 --- pt/17_0_Programming_with_Libwally.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pt/17_0_Programming_with_Libwally.md b/pt/17_0_Programming_with_Libwally.md index 735b8ae..dab6205 100644 --- a/pt/17_0_Programming_with_Libwally.md +++ b/pt/17_0_Programming_with_Libwally.md @@ -1,14 +1,14 @@ -# Capítulo 16: Programando com Libwally +# Capítulo 17: Programando com Libwally -O capítulo anterior apresentou três bibliotecas C, para RPC, JSON e ZMQ, todas destinadas a interagir diretamente com o `bitcoind`, assim como você vem fazendo desde o início. Mas, às vezes você pode querer codificar sem acesso direto a um `bitcoind`. Isso pode ser devido a um cliente offline ou apenas porque você deseja manter algumas funcionalidades internas de seu programa C. Você também pode querer se aprofundar na funcionalidade da carteira, como criação de palavras mnemônicas ou derivação de endereços. É aí que entra Libwally: é uma biblioteca de carteira para C, C ++, Java, NodeJS ou Python, com wrappers também disponíveis para outras linguagens, como Swift. +O capítulo anterior apresentou três bibliotecas C, para RPC, JSON e ZMQ, todas destinadas a interagir diretamente com o `bitcoind`, assim como você vem fazendo desde o início. Mas às vezes você pode querer codificar sem acesso direto a um `bitcoind`. Isso pode ser devido a um cliente offline ou apenas porque você deseja manter algumas funcionalidades internas de seu programa C. Você também pode querer se aprofundar na funcionalidade da carteira, como criação de palavras mnemônicas ou derivação de endereços. É aí que entra Libwally: é uma biblioteca de carteira para C, C ++, Java, NodeJS ou Python, com wrappers também disponíveis para outras linguagens, como Swift. -Este capítulo aborda a funcionalidade possível dentro do Libwally, a maioria das quais complementa o trabalho que você fez através do acesso RPC ao `bitcoind`, mas algumas das quais o replicam. Ele também mostra como integrar esse trabalho com os clientes RPC com os quais você está mais familiarizado. No entanto, observe que esta é apenas uma introdução básica ao Libwally. Vários de seus conjuntos de funções mais importantes são destacados, mas nunca fazemos mais do que enfiar os pés no chão. Se você acha suas funções úteis ou intrigantes, então você precisará se aprofundar muito mais profundamente do que este curso pode cobrir. +Este capítulo aborda a funcionalidade possível dentro do Libwally, a maioria das quais complementa o trabalho que você fez através do acesso RPC ao `bitcoind`, mas algumas das quais o replicam. Ele também mostra como integrar esse trabalho com os clientes RPC com os quais você está mais familiarizado. No entanto, observe que esta é apenas uma introdução básica ao Libwally. Vários de seus conjuntos de funções mais importantes são destacados, mas nunca fazemos mais do que apresentar uma introdução. Se você acha suas funções úteis ou intrigantes, então você precisará se aprofundar muito mais do que este curso pode cobrir. -## Objetivos deste capítulo +## Objetivos Deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - * Usar as funções da carteira com o Libwally; + * Usar as funções de carteira com o Libwally; * Realizar manipulações de PSBTs e transações com o Libwally; * Implementar designs que combinem o Libwally e o RPC. @@ -20,10 +20,10 @@ Os objetivos secundários do capítulo incluem a capacidade de: ## Tabela de Conteúdo - * [Seção 1: Configurando o Libwally](16_1_Setting_Up_Libwally.md) - * [Seção 2: Usando o BIP39 no Libwally](16_2_Using_BIP39_in_Libwally.md) - * [Seção 3: Usando o BIP32 no Libwally](16_3_Using_BIP32_in_Libwally.md) - * [Seção 4: Usando o PSBTs no Libwally](16_4_Using_PSBTs_in_Libwally.md) - * [Seção 5: Usando Scripts no Libwally](16_5_Using_Scripts_in_Libwally.md) - * [Seção 6: Usando Outras Funções no Libwally](16_6_Using_Other_Functions_in_Libwally.md) - * [Seção 7: Integrando o Libwally ao Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md) \ No newline at end of file + * [Seção 1: Configurando o Libwally](17_1_Setting_Up_Libwally.md) + * [Seção 2: Usando o BIP39 no Libwally](17_2_Using_BIP39_in_Libwally.md) + * [Seção 3: Usando o BIP32 no Libwally](17_3_Using_BIP32_in_Libwally.md) + * [Seção 4: Usando os PSBTs no Libwally](17_4_Using_PSBTs_in_Libwally.md) + * [Seção 5: Usando Scripts no Libwally](17_5_Using_Scripts_in_Libwally.md) + * [Seção 6: Usando Outras Funções no Libwally](17_6_Using_Other_Functions_in_Libwally.md) + * [Seção 7: Integrando o Libwally ao Bitcoin-CLI](17_7_Integrating_Libwally_and_Bitcoin-CLI.md) \ No newline at end of file From dcb45e5ec76d3a03a1e3b29642490bec776ff026 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 11:41:06 -0300 Subject: [PATCH 083/155] Minor fixes on 17_0 --- pt/17_0_Programming_with_Libwally.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pt/17_0_Programming_with_Libwally.md b/pt/17_0_Programming_with_Libwally.md index dab6205..238269b 100644 --- a/pt/17_0_Programming_with_Libwally.md +++ b/pt/17_0_Programming_with_Libwally.md @@ -20,10 +20,10 @@ Os objetivos secundários do capítulo incluem a capacidade de: ## Tabela de Conteúdo - * [Seção 1: Configurando o Libwally](17_1_Setting_Up_Libwally.md) - * [Seção 2: Usando o BIP39 no Libwally](17_2_Using_BIP39_in_Libwally.md) - * [Seção 3: Usando o BIP32 no Libwally](17_3_Using_BIP32_in_Libwally.md) - * [Seção 4: Usando os PSBTs no Libwally](17_4_Using_PSBTs_in_Libwally.md) - * [Seção 5: Usando Scripts no Libwally](17_5_Using_Scripts_in_Libwally.md) - * [Seção 6: Usando Outras Funções no Libwally](17_6_Using_Other_Functions_in_Libwally.md) - * [Seção 7: Integrando o Libwally ao Bitcoin-CLI](17_7_Integrating_Libwally_and_Bitcoin-CLI.md) \ No newline at end of file + * [Seção 1: Configurando a Libwally](17_1_Setting_Up_Libwally.md) + * [Seção 2: Usando BIP39 na Libwally](17_2_Using_BIP39_in_Libwally.md) + * [Seção 3: Usando BIP32 na Libwally](17_3_Using_BIP32_in_Libwally.md) + * [Seção 4: Usando PSBTs na Libwally](17_4_Using_PSBTs_in_Libwally.md) + * [Seção 5: Usando Scripts na Libwally](17_5_Using_Scripts_in_Libwally.md) + * [Seção 6: Usando Outras Funções na Libwally](17_6_Using_Other_Functions_in_Libwally.md) + * [Seção 7: Integrando Libwally e Bitcoin-CLI](17_7_Integrating_Libwally_and_Bitcoin-CLI.md) \ No newline at end of file From acc04c5ec3650ab75024036de23e20e5b365c6c6 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 11:48:03 -0300 Subject: [PATCH 084/155] Review 17_1 --- pt/17_1_Setting_Up_Libwally.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/pt/17_1_Setting_Up_Libwally.md b/pt/17_1_Setting_Up_Libwally.md index 990b800..2e24409 100644 --- a/pt/17_1_Setting_Up_Libwally.md +++ b/pt/17_1_Setting_Up_Libwally.md @@ -4,9 +4,9 @@ Esta primeira seção explicará como fazer o download da Biblioteca Libwally C e como colocá-la em funcionamento. -> :book: ***O que é a Libwally?*** A Libwally é uma biblioteca de primitivas útil para a criação de carteiras que é totalmente multiplataforma, de modo que as mesmas funções possam ser usadas em qualquer lugar. Existem [documentação online](https://wally.readthedocs.io/en/latest/), caso esteja interessado. A Libwally está disponível como parte do [Elements Project](https://github.com/ElementsProject) da Blockstream. +> :book: ***O que é a Libwally?*** A Libwally é uma biblioteca de primitivas útil para a criação de carteiras que é totalmente multiplataforma, de modo que as mesmas funções possam ser usadas em qualquer lugar. Há uma [documentação online](https://wally.readthedocs.io/en/latest/), caso esteja interessado. A Libwally está disponível como parte do [Elements Project](https://github.com/ElementsProject) da Blockstream. -## Instalando o Libwally +## Instalando a Libwally Como de costume, precisaremos de alguns pacotes no nosso sistema: ``` @@ -17,7 +17,6 @@ Podemos então fazer o download do Libwally com base no seu repositório Git: ``` $ git clone https://github.com/ElementsProject/libwally-core ``` -Afterward, you can begin the configuration process: Depois, podemos começar com o processo de configuração. ``` $ ./tools/autogen.sh @@ -90,11 +89,11 @@ Finalmente, podemos instalar: $ sudo make install ``` -## Nos preparando para a Libwally +## Nos Preparando Para a Libwally -Então, como usamos a Libwally em nosso programa que estamos construindo? Como de costume, precisaremos incluir os arquivos e vincular as bibliotecas apropriadas em nosso código. +Então, como usamos a Libwally em um programa? Como de costume, precisaremos incluir os arquivos e vincular as bibliotecas apropriadas em nosso código. -### Incluindo os arquivos +### Incluindo os Arquivos Há um número considerável de arquivos que podemos incluir: @@ -106,7 +105,7 @@ $ ls /usr/include/wally* ``` Felizmente, os nomes dos arquivos correspondem amplamente às seções da [documentação](https://wally.readthedocs.io/en/latest/), então devemos ser capazes de incluir os arquivos corretos com base no que estamos fazendo, depois de incluir o onipresente `wally_core.h`. -### Vinculando as bibliotecas +### Vinculando as Bibliotecas Também precisaremos vincular as bibliotecas apropriadas: ``` @@ -116,7 +115,7 @@ $ ls /usr/lib/libsecp* /usr/lib/libwally* ``` Usaremos principalmente a `libwallycore`. -## Configurando um programa Libwally +## Configurando um Programa Libwally Comparado com algumas das bibliotecas anteriores, a Libwally é ridiculamente fácil de ser inicializada: ``` @@ -128,7 +127,7 @@ wally_cleanup(0); ``` Em ambos os casos, o argumento é para flags, mas atualmente está definido como `0`. -## Testando um programa de teste da Libwally +## Testando um Programa de Teste da Libwally O diretório src contém o arquivo [testwally.c](src / 16_1_testwally.c), que apenas mostra como funcionam as funções de inicialização e de limpeza. @@ -150,7 +149,7 @@ include/wally_core.h:#define WALLY_OK 0 /** Success */ Também precisamos instalar o Libsodium para obter acesso a um gerador de números aleatórios de alta qualidade para fins de teste. -> :warning: **AVISO:** A geração de números aleatórios pode ser um dos maiores pontos de vulnerabilidade em qualquer software do Bitcoin. Se fizermos isso de maneira errada, podemos export nossos usuários a ataques porque eles acabam tendo chaves privadas do Bitcoin inseguras, e isso não é um [problema teórico](https://github.com/BlockchainCommons/SmartCustodyBook/blob/master/manuscript/ 03-adversaries.md # adversary-systemic-key-compromise). A BlockchainInfo gerou incorretamente 0,0002% das suas chaves, o que resultou na perda temporária de 250 Bitcoins. Resumindo: Precisamos nos certificar de estar totalmente confortável com a geração de números aleatórios. Podemos usar o Libsodium ou qualquer outro método TRNG ainda mais robusto. +> :warning: **AVISO:** A geração de números aleatórios pode ser um dos maiores pontos de vulnerabilidade em qualquer software do Bitcoin. Se fizermos isso de maneira errada, podemos expor nossos usuários a ataques porque eles acabam tendo chaves privadas do Bitcoin inseguras, e isso não é um [problema teórico](https://github.com/BlockchainCommons/SmartCustodyBook/blob/master/manuscript/03-adversaries.md#adversary-systemic-key-compromise). A BlockchainInfo gerou incorretamente 0,0002% das suas chaves, o que resultou na perda temporária de 250 Bitcoins. Resumindo: precisamos nos certificar de estar totalmente confortável com a geração de números aleatórios. Podemos usar o Libsodium ou qualquer outro método TRNG ainda mais robusto. Podemos baixar um [Libsodium tarball](https://download.libsodium.org/libsodium/releases/) e seguir as instruções em [instalação do Libsodium](https://doc.libsodium.org/installation) para deixarmos tudo pronto em nosso computador. @@ -193,4 +192,4 @@ Então, o que exatamente podemos fazer agora? É para dar essa resposta que temo ## O Que Vem Depois? -Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.2: Usando o BIP39 no Libwally](16_2_Using_BIP39_in_Libwally.md). \ No newline at end of file +Vamos aprender mais sobre "Programando Bitcoin com Libwally" na seção [§16.2: Usando BIP39 na Libwally](16_2_Using_BIP39_in_Libwally.md). \ No newline at end of file From 8dbcbd76e245730a81b16f95425fc16ec1a89b71 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 23 Aug 2021 12:09:13 -0300 Subject: [PATCH 085/155] Review 17_2 --- pt/17_2_Using_BIP39_in_Libwally.md | 44 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/pt/17_2_Using_BIP39_in_Libwally.md b/pt/17_2_Using_BIP39_in_Libwally.md index 4669828..e8ab746 100644 --- a/pt/17_2_Using_BIP39_in_Libwally.md +++ b/pt/17_2_Using_BIP39_in_Libwally.md @@ -1,20 +1,20 @@ -# 16.2: Usando o BIP39 no Libwally +# 16.2: Usando BIP39 na Libwally > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Um dos maiores poderes de Libwally é que ele pode revelar o trabalho oculto da geração de seeds, chaves privadas e, também, de endereços. Para começar, ele suporta o [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki), que é o BIP que define códigos mnemônicos para o Bitcoin, algo que é totalmente incompatível, na época, com o Bitcoin Core. +Um dos maiores poderes da Libwally é que ela pode revelar o trabalho oculto da geração de seeds, chaves privadas e, também, de endereços. Para começar, ela suporta o [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki), que é o BIP que define códigos mnemônicos para o Bitcoin, algo que era totalmente incompatível, na época, com o Bitcoin Core. -> :book: ***O que é um código mnemônico?*** Os endereços de Bitcoin (e suas chaves privadas correspondentes e as suas seeds) são listas longas e ininteligíveis de caracteres e números, que não são apenas impossíveis de serem lembrados, mas também fáceis de serem digitados erroneamente. Os códigos mnemônicos são uma solução para isso que permitem aos usuários gravar 12 (ou 24) palavras em inglês, algo que é muito menos sujeito a erros. Esses códigos podem ser usados para restaurar totalmente uma seed BIP32 que é a base de uma carteira Determinística Hierárquica. +> :book: ***O que é um código mnemônico?*** Os endereços de Bitcoin (e suas chaves privadas correspondentes e as suas seeds) são listas longas e ininteligíveis de caracteres e números que não apenas são impossíveis de serem lembrados, mas também fáceis de serem digitados erroneamente. Os códigos mnemônicos são uma solução para isso que permitem aos usuários gravar 12 (ou 24) palavras em inglês, algo que é muito menos sujeito a erros. Esses códigos podem ser usados para restaurar totalmente uma seed BIP32 que é a base de uma carteira Determinística Hierárquica (HD). -> :book: ***O que é uma seed?*** Nós falamos brevemente das seeds na seção [§3.5: Compreendendo o descritor](03_5_Understanding_the_Descriptor.md). É o número aleatório usado para gerar uma sequência inteira de chaves privadas (e, portanto, endereços) em uma carteira Determinística Hierárquica. Voltaremos às seeds na próxima seção, onde falaremos sobre as carteiras Determinísticas Hierárquicas e a Libwally. Por enquanto, apenas é necessário saber que um código mnemônico BIP39 corresponde à seed para uma carteira determinística hierárquica do BIP32. +> :book: ***O que é uma seed?*** Nós falamos brevemente das seeds na seção [§3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md). É o número aleatório usado para gerar uma sequência inteira de chaves privadas (e, portanto, endereços) em uma carteira HD. Voltaremos às seeds na próxima seção, onde falaremos sobre as carteiras HD e a Libwally. Por enquanto, apenas é necessário saber que um código mnemônico BIP39 corresponde à seed para uma carteira HD do BIP32. ## Criando Códigos Mnemônicos -Todas as chaves Bitcoin começam com a entropia. Este primeiro uso de Libwally, e os mnemônicos BIP39, mostram como gerar entropia e obter um código mnemônico a partir disso. +Todas as chaves Bitcoin começam com a entropia. Este primeiro uso da Libwally, e os mnemônicos BIP39, mostram como gerar entropia e obter um código mnemônico a partir disso. -> :book: ***O que é entropia?*** Entropia é uma maneira sofisticada de dizer aleatoriedade, mas é uma aleatoriedade medida cuidadosamente que é usada como a base de um número aleatório gerado verdadeiramente (no inglês, true-random-number generated, TRG). É medido em "bits", com mais bits de entropia resultando em mais aleatoriedade (e, portanto, mais proteção para o que está sendo gerado). Para o Bitcoin, a entropia é a base de nossa seed, que em uma carteira Determinística Hierárquica que gera todos os seus endereços. +> :book: ***O que é entropia?*** Entropia é uma maneira sofisticada de dizer aleatoriedade, mas é uma aleatoriedade medida cuidadosamente que é usada como a base de um número aleatório gerado verdadeiramente (no inglês, true-random-number generated, TRG). É medido em "bits", com mais bits de entropia resultando em mais aleatoriedade (e, portanto, mais proteção para o que está sendo gerado). Para o Bitcoin, a entropia é a base de nossa seed, que em uma carteira HD gera todos os seus endereços. -Sempre começaremos a trabalhar com a Libwally inicializando a biblioteca e testando os resultados, conforme demonstrado pela primeira vez na seção [§16.1](16_1_Setting_Up_Libwally.md): +Sempre começaremos a trabalhar com a Libwally inicializando a biblioteca e testando os resultados, conforme demonstrado pela primeira vez na seção [§17.1](17_1_Setting_Up_Libwally.md): ``` int lw_response; @@ -29,9 +29,9 @@ Sempre começaremos a trabalhar com a Libwally inicializando a biblioteca e test ``` Agora estamos prontos para a entropia. -### Criando a Entropia +### Criando Entropia -Usando o `libsodium`, podemos criar a entropia com o comando `randombytes_buf`: +Usando o `libsodium`, podemos criar entropia com o comando `randombytes_buf`: ``` unsigned char entropy[16]; randombytes_buf(entropy, 16); @@ -40,26 +40,26 @@ Este exemplo, que será a única maneira de usarmos a biblioteca `libsodium`, cr > :warning: **AVISO:** Mais uma vez, certifique-se de estar muito confortável com o método de geração de entropia antes de usá-lo em um programa do mundo real. -### Traduzindo para um mnemônico +### Traduzindo para um Mnemônico 16 bytes de entropia são suficientes para criar um código Mnemônico de 12 caracteres, que é feito com a função `bip39_mnemonic_from_bytes` da Libwally: ``` char *mnem = NULL; lw_response = bip39_mnemonic_from_bytes(NULL,entropy,16,&mnem); ``` -Observe que temos que passar o tamanho do byte, então se quiser aumentar o tamanho da entropia, para gerar uma frase mnemônica mais longa, também precisaria aumentar o valor nesta função. +Observe que temos que passar o tamanho do byte, então se quisermos aumentar o tamanho da entropia, para gerar uma frase mnemônica mais longa, também precisaríamos aumentar o valor nesta função. > **NOTA:** Existem listas de palavras mnemônicas para diferentes idiomas! O padrão é usar a lista do idioma inglês, que é a variável `NULL` nesses comandos mnemônicos da Libwally, mas podemos, alternativamente, solicitar um idioma diferente! É isso! Nós criamos uma frase mnemônica! -> :book: ***Como a frase mnemônica é criada?*** Podemos aprender mais sobre isso no [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki), mas se preferir, Greg Walker tem um [excelente exemplo](https://learnmeabitcoin.com/technical/mnemonic): De maneira geral, adicionamos uma soma de verificação e convertemos cada conjunto de 11 bits em uma palavra da lista de palavras. Podemos fazer isso com os comandos `bip39_get_wordlist` e `bip39_get_word` se não confiarmos no comando `bip39_mnemonic_from_bytes`. +> :book: ***Como a frase mnemônica é criada?*** Podemos aprender mais sobre isso no [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki), mas, se preferir, Greg Walker tem um [excelente exemplo](https://learnmeabitcoin.com/technical/mnemonic): de maneira geral, adicionamos um checksum e convertemos cada conjunto de 11 bits em uma palavra da lista de palavras. Podemos fazer isso com os comandos `bip39_get_wordlist` e `bip39_get_word` se não confiarmos no comando `bip39_mnemonic_from_bytes`. -### Traduzindo para uma seed +### Traduzindo para uma Seed -Existem algumas funções, como o `bip32_key_from_seed` (que veremos na próxima seção) que requerem que tenhamos os bits ao invés do Mnemônico. As duas coisas são funcionalmente idênticas, se temos a seed, pode gerar o mnemônico e vice-versa. +Existem algumas funções, como o `bip32_key_from_seed` (que veremos na próxima seção) que requerem que tenhamos os bits ao invés do Mnemônico. As duas coisas são funcionalmente idênticas: se temos a seed, podemos gerar o mnemônico e vice-versa. -Se você precisarmos gerar a seed a partir do nosso mnemônico, basta usar o comando `bip39_mnemonic_to_seed`: +Se precisarmos gerar a seed a partir do nosso mnemônico, basta usar o comando `bip39_mnemonic_to_seed`: ``` unsigned char seed[BIP39_SEED_LEN_512]; size_t seed_len; @@ -68,9 +68,9 @@ Se você precisarmos gerar a seed a partir do nosso mnemônico, basta usar o com ``` Observe que todas as seeds do BIP39 têm 512 bytes; no entanto, devemos definir o tamanho de nossa variável apropriadamente e passar o tamanho para o `bip39_mnemonic_to_seed`. -### Mostrando na Tela a Nossa Seed +### Vendo a Nossa Seed -Se quisermos ver como nossa semente se parece em hexadecimal, podemos usar a função `wally_hex_from_bytes` para transformar nossa seed em um código hexadecimal legível (mas isso não é muito bom para pessoas): +Se quisermos ver como nossa seed é em hexadecimal, podemos usar a função `wally_hex_from_bytes` para transformar nossa seed em um código hexadecimal legível (mas isso não é muito bom para pessoas): ``` char *seed_hex; wally_hex_from_bytes(seed,sizeof(seed),&seed_hex); @@ -82,7 +82,7 @@ Se dizermos tudo certo, devemos obter uma seed de 64 bytes. (Essa é a variável ## Testando o Código Mnemônico -O código completo para gerar entropia, gerar um mnemônico BIP39, validar o mnemônico e gerar uma seed pode ser encontrado no [diretório src/](src/16_2_genmnemonic.c). Podemos fazer o download e compilar: +O código completo para gerar entropia, gerar um mnemônico BIP39, validar o mnemônico e gerar uma seed pode ser encontrado no [diretório src/](src/17_2_genmnemonic.c). Podemos fazer o download e compilar: ``` $ cc genmnemonic.c -lwallycore -lsodium -o genmnemonic ``` @@ -93,14 +93,14 @@ Mnemonic validated! Seed: 47b04cfb5d8fd43d371497f8555a27a25ca0a04aafeb6859dd4cbf37f6664b0600c4685c1efac29c082b1df29081f7a46f94a26f618fc6fd38d8bc7b6cd344c7 ``` -## Resumo: Usando o BIP39 no Libwally +## Resumo: Usando BIP39 na Libwally -O BIP39 permite que possamos gerar um conjunto de 12-24 palavras Mnemônicas a partir de uma seed e a biblioteca Libwally também permite que a validemos! +O BIP39 nos permite gerar um conjunto de 12-24 palavras Mnemônicas a partir de uma seed (e a biblioteca Libwally também permite que a validemos!). > :fire: ***Qual é o poder do BIP39?*** Seeds de Bitcoin e chaves privadas estão sujeitas a todos os tipos de perda. Se digitarmos errado um único dígito, nosso dinheiro será perdido para sempre. Palavras mnemônicas são uma forma muito mais amigável de representar os mesmos dados, mas como são palavras no idioma de escolha do usuário, são menos sujeitas a erros. O poder do BIP39 é, portanto, melhorar a acessibilidade, usabilidade e segurança do Bitcoin. -> :fire: ***Qual é o poder do BIP39 na Libwally?*** O Bitcoind atualmente não suporta palavras mnemônicas, então usar a Libwally pode permitir que geremos palavras mnemônicas em conjunto com endereços mantidos no `bitcoind`, embora como veremos na seção §16.7, é necessário um pouco de gambiarra para importar suas chaves para o Bitcoin Core. +> :fire: ***Qual é o poder do BIP39 na Libwally?*** O Bitcoind atualmente não suporta palavras mnemônicas, então usar a Libwally pode permitir que geremos palavras mnemônicas em conjunto com endereços mantidos no `bitcoind`, embora como veremos na seção §17.7, é necessário um pouco de gambiarra para importar suas chaves para o Bitcoin Core. ## O Que Vem Depois? -Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.3: Usando o BIP32 no Libwally](16_3_Using_BIP32_in_Libwally.md). \ No newline at end of file +Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§17.3: Usando o BIP32 no Libwally](16_3_Using_BIP32_in_Libwally.md). \ No newline at end of file From b139a7611e40e5f5fe3432c946a59eec2a18e6d4 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 08:11:44 -0300 Subject: [PATCH 086/155] Review 17_3 --- pt/17_3_Using_BIP32_in_Libwally.md | 38 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/pt/17_3_Using_BIP32_in_Libwally.md b/pt/17_3_Using_BIP32_in_Libwally.md index 040cae3..46749c8 100644 --- a/pt/17_3_Using_BIP32_in_Libwally.md +++ b/pt/17_3_Using_BIP32_in_Libwally.md @@ -1,14 +1,14 @@ -# 16.3: Usando o BIP32 no Libwally +# 17.3: Usando o BIP32 na Libwally > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Na seção [§16.2](16_2_Using_BIP39_in_Libwally.md), fomos capazes de usar a entropia para gerar uma semente e nosso mnemônico relacionado. Como devemos nos lembrar da seção [§3.5: Compreendendo o descritor](03_5_Understanding_the_Descriptor.md), uma seed é a base de uma Carteira Determinística Hierárquica (no inglês Hierchical Deterministic, HD), onde aquela única seed pode ser usada para gerar muitos endereços. Então, como passamos da seed para os endereços reais? É aí que entra o [BIP32](https://en.bitcoin.it/wiki/BIP_0032). +Na seção [§17.2](17_2_Using_BIP39_in_Libwally.md), fomos capazes de usar entropia para gerar uma semente e nosso mnemônico relacionado. Como devemos nos lembrar da seção [§3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md), uma seed é a base de uma Carteira Determinística Hierárquica (no inglês Hierchical Deterministic, HD), onde aquela única seed pode ser usada para gerar muitos endereços. Então, como passamos da seed para os endereços reais? É aí que entra o [BIP32](https://en.bitcoin.it/wiki/BIP_0032). -## Criando uma raiz HD +## Criando uma Raiz HD Para criar um endereço HD, é necessário começar com uma seed e, em seguida, descer na hierarquia até o ponto em que criamos os endereços. -Isso começa com bastante facilidade, conosco gerando uma seed, o que já fizemos na seção anterior: +Isso começa com bastante facilidade, gerando uma seed, o que já fizemos na seção anterior: ``` unsigned char entropy[16]; randombytes_buf(entropy, 16); @@ -20,7 +20,7 @@ Isso começa com bastante facilidade, conosco gerando uma seed, o que já fizemo size_t seed_len; lw_response = bip39_mnemonic_to_seed(mnem,NULL,seed,BIP39_SEED_LEN_512,&seed_len); ``` -### Gerando uma chave raiz +### Gerando uma Chave Raiz Com uma seed em mãos, podemos gerar uma chave mestra estendida com a função `bip32_key_from_seed_alloc` (ou, alternativamente, com o comando `bip32_key_from_seed`, que não faz o `alloc`): ``` @@ -42,15 +42,15 @@ Sempre que tivermos uma chave em mãos, podemos transformá-la em chaves xpub ou lw_response = bip32_key_to_base58(key_root, BIP32_FLAG_KEY_PUBLIC, &xpub); ``` -## Compreendendo a hierarquia +## Compreendendo a Hierarquia -Antes de prosseguir, precisamos entender como funciona a hierarquia de uma carteira HD. Conforme discutido na seção [§3.5](03_5_Understanding_the_Descriptor.md), um caminho de derivação descreve a árvore que seguimos para obter uma chave hierárquica, então `[0/1/0]` é o 0º filho do 1º filho do 0º filho de uma chave raiz. Às vezes, parte dessa derivação é marcada com `'` s ou `h`s para mostrar derivações endurecidas, que aumentam a segurança: `[0'/1'/0']`. +Antes de prosseguir, precisamos entender como funciona a hierarquia de uma carteira HD. Conforme discutido na seção [§3.5](03_5_Understanding_the_Descriptor.md), um caminho de derivação descreve a árvore que seguimos para obter uma chave hierárquica, então `[0/1/0]` é o 0º filho do 1º filho do 0º filho de uma chave raiz. Às vezes, parte dessa derivação é marcada com `'`s ou `h`s para mostrar derivações endurecidas, que aumentam a segurança: `[0'/1'/0']`. No entanto, para carteiras HD, cada um desses níveis da hierarquia é usado de uma forma muito específica. Isso foi definido originalmente no [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) e foi atualizado posteriormente para o Segwit no [BIP84](https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki). Ao todo, um caminho de derivação BIP32 é definido para ter cinco níveis: -1. **Objetivo.** Isso geralmente é definido como `44'` ou `84'`, dependendo do BIP que estamos seguindo; +1. **Propósito.** Isso geralmente é definido como `44'` ou `84'`, dependendo do BIP que estamos seguindo; 2. **Moeda.** Para bitcoins Mainnet, é `0'`, para testnet é `1'`; 3. **Conta.** Uma carteira pode conter várias contas discretas, começando com `0'`; 4. **Troco.** Os endereços externos (para distribuição) são definidos como `0`, enquanto os endereços internos (para troco) são definidos como `1`; @@ -62,13 +62,13 @@ Então, na testnet, o endereço zero para um endereço externo para a conta zero ### Entendendo a Hierarquia no Bitcoin Core -Estaremos usando a hierarquia acima para todas as chaves de HD na Libwally, mas observe que este padrão não é usado no `bitcoin-cli` do Bitcoin Core, que ao invés disso usa `[m/0'/0'/0']` para o enésimo endereço externo e `[m/0'/1'/0']` para o enésimo endereço de troco. +Estaremos usando a hierarquia acima para todas as chaves HD na Libwally, mas observe que este padrão não é usado no `bitcoin-cli` do Bitcoin Core, que ao invés disso usa `[m/0'/0'/0']` para o enésimo endereço externo e `[m/0'/1'/0']` para o enésimo endereço de troco. -## Gerando um endereço +## Gerando um Endereço Para gerar um endereço, devemos explorar toda a hierarquia. -### Gerando uma chave da conta +### Gerando uma Chave de Conta Uma maneira de fazer isso é usar a função `bip32_key_from_parent_path_alloc` para descer vários níveis de uma hierarquia. Podemos incorporar os níveis em uma matriz: ``` @@ -87,7 +87,7 @@ Sempre que tiviermos uma nova chave, poderemos usá-la para gerar novas chaves x lw_response = bip32_key_to_base58(key_account, BIP32_FLAG_KEY_PUBLIC, &a_xpub); ``` -### Gerando uma chave de endereço +### Gerando uma Chave de Endereço Alternativamente, podemos usar a função `bip32_key_from_parent_alloc`, que apenas desce um nível da hierarquia por vez. O exemplo a seguir desce para o enésimo filho da chave da conta (que é o endereço externo) e, em seguida, o enésimo filho dessa chave. Isso seria útil porque poderíamos continuar gerando o primeiro endereço, o segundo endereço e assim por diante a partir dessa chave externa: ``` @@ -99,9 +99,9 @@ Alternativamente, podemos usar a função `bip32_key_from_parent_alloc`, que ape ``` > :warning: **AVISO:** Em algum ponto desta hierarquia, podemos decidir gerar o `BIP32_FLAG_KEY_PUBLIC` ao invés do `BIP32_FLAG_KEY_PRIVATE`. Obviamente, essa decisão será baseada na nossa segurança e nas nossas necessidades, mas precisamos lembrar de que só precisamos de uma chave pública para gerar o endereço real. -### Gerando um endereço +### Gerando um Endereço -Finalmente, estamos pronto para gerar um endereço a partir de sua chave final. Tudo que fazemos é executar `wally_bip32_to_addr_segwit` usando nossa chave final e uma descrição de que tipo de endereço é este. +Finalmente, estamos prontos para gerar um endereço a partir de sua chave final. Tudo que fazemos é executar `wally_bip32_to_addr_segwit` usando nossa chave final e uma descrição de que tipo de endereço é este. ``` char *segwit; lw_response = wally_bip32_key_to_addr_segwit(key_address,"tb",0,&segwit); @@ -115,7 +115,7 @@ Há também uma função `wally_bip32_key_to_address`, que pode ser usada para g ## Testando o Código HD -O código para esses exemplos de HD pode, como de costume, ser encontrado no [diretório src/](src / 16_3_genhd.c). +O código para esses exemplos HD pode, como de costume, ser encontrado no [diretório src/](src/17_3_genhd.c). Podemos compilá-lo e testá-lo: ``` @@ -129,14 +129,14 @@ Account xpub key: tpubDWFQG78gYHzCkACXxkeh2LwWo8MVLm3YkTGd85LJwtpBB6xp4KwseGTEvx [m/84'/1'/0'/0/0]: tb1q0knqq26ek59pfl7nukzqr28m2zl5wn2f0ldvwu ``` -## Resumo: Usando o BIP32 no Libwally +## Resumo: Usando o BIP32 na Libwally -Uma carteira HD permite gerar um grande número de chaves a partir de uma única seed. Agora sabemos como essas chaves são organizadas no BIP44, BIP84 e no Bitcoin Core e, como derivá-las, começando com uma seed ou palavras mnemônicas. +Uma carteira HD permite gerar um grande número de chaves a partir de uma única seed. Agora sabemos como essas chaves são organizadas no BIP44, BIP84 e no Bitcoin Core, além de como derivá-las, começando com uma seed ou palavras mnemônicas. > :fire: ***Qual é o poder do BIP32?*** As chaves são o elemento mais difícil (e mais perigoso) da maioria das operações criptográficas. Se as perdermos, perderemos tudo o que a chave protegeu. O BIP32 garante que só precisamos conhecer uma chave, a semente, ao invés de um grande número de chaves diferentes para endereços diferentes. -> :fire: ***Qual é o poder do BIP32 na Libwally?*** O Bitcoind já faz a criação de endereços baseada em HD para nós, o que significa que normalmente não precisamos nos preocupar em derivar endereços dessa maneira. No entanto, usar as funções BIP32 da Libwally pode ser muito útil se estivermos uma máquina offline onde precisamos derivar endereços, possivelmente com base em uma semente passada do `bitcoind` para nosso dispositivo offline (ou vice-versa). +> :fire: ***Qual é o poder do BIP32 na Libwally?*** O Bitcoind já faz a criação de endereços baseada em HD para nós, o que significa que normalmente não precisamos nos preocupar em derivar endereços dessa maneira. No entanto, usar as funções BIP32 da Libwally pode ser muito útil se tivermos uma máquina offline onde precisamos derivar endereços, possivelmente com base em uma semente passada do `bitcoind` para nosso dispositivo offline (ou vice-versa). ## O Que Vem Depois? -Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.4: Usando o PSBTs no Libwally](16_4_Using_PSBTs_in_Libwally.md). \ No newline at end of file +Vamos aprender mais sobre "Programando Bitcoin com Libwally" na seção [§17.4: Usando PSBTs na Libwally](16_4_Using_PSBTs_in_Libwally.md). \ No newline at end of file From 30e32c9449808434b9e6b6d66243f75284d98100 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 08:30:52 -0300 Subject: [PATCH 087/155] Review 17_4 --- pt/17_4_Using_PSBTs_in_Libwally.md | 42 ++++++++++++++---------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/pt/17_4_Using_PSBTs_in_Libwally.md b/pt/17_4_Using_PSBTs_in_Libwally.md index efc9b3b..4bff407 100644 --- a/pt/17_4_Using_PSBTs_in_Libwally.md +++ b/pt/17_4_Using_PSBTs_in_Libwally.md @@ -1,10 +1,10 @@ -# 16.4: Usando o PSBTs na Libwally +# 17.4: Usando PSBTs na Libwally > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Nós aprendemos tudo sobre as transações do Bitcoin parcialmente assinadas (PSBTs) na seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) e na [§7.2](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md), e como vimos na [§7.3: Integrando com Hardware Wallets](/github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_3_Integrating_with_Hardware_Wallets.md), uma das nossas principais vantagens é a capacidade de integração com nodes offline, como Hardware Wallets. O HWI permitiu que passassemos comandos para uma carteira de hardware, mas o que a própria carteira usa para gerenciar os PSBTs? Por acaso, podemos usar algo na Libwally, como esta seção irá demonstrar. +Nós aprendemos tudo sobre as transações parcialmente assinadas no Bitcoin (PSBTs) na seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) e na [§7.2](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md), e como vimos na [§7.3: Integrando com Hardware Wallets](/github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_3_Integrating_with_Hardware_Wallets.md), uma das nossas principais vantagens é a capacidade de integração com nodes offline, como Hardware Wallets. O HWI permitiu que passássemos comandos para uma carteira de hardware, mas o que a própria carteira usa para gerenciar os PSBTs? Por acaso, podemos usar algo na Libwally, como esta seção irá demonstrar. -Basicamente, a Libwally tem todas as funcionalidades PSBT, então se há algo que podemos fazer com o `bitcoind`, também podemos fazer usando a Libwally, mesmo se nosso dispositivo estiver offline. O que se iremos fazer agora, é a introdução a um tópico bem complexo. +Basicamente, a Libwally tem todas as funcionalidades PSBT, então se há algo que podemos fazer com o `bitcoind`, também podemos fazer usando a Libwally, mesmo se nosso dispositivo estiver offline. O que segue é uma introdução básica a um tópico bem complexo. ## Convertendo um PSBT @@ -14,7 +14,6 @@ Converter um PSBT na estrutura interna da Libwally é incrivelmente fácil, bast No entanto, é um pouco mais difícil de lidar com o resultado, porque a Libwally o converte em uma estrutura `wally_psbt` muito complexa. -Here's how it's defined in `/usr/include/wally_psbt.h`: Veja como é definido no arquivo `/usr/include/wally_psbt.h`: ``` struct wally_psbt { @@ -77,9 +76,9 @@ struct wally_tx_output { ``` Tem muita coisa aí! Embora muito disso deva ser familiar dos capítulos anteriores, é um pouco intimidador ver tudo disposto em estruturas C. -## Lendo um PSBT convertido +## Lendo um PSBT Convertido -Obviamente, podemos ler qualquer coisa de uma estrutura PSBT chamando os elementos individuais das várias subestruturas. A seguir, uma breve visão geral que mostra como captar alguns dos elementos. +Obviamente, podemos ler qualquer coisa de uma estrutura PSBT chamando os elementos individuais das várias subestruturas. A seguir, veja uma breve visão geral que mostra como captar alguns dos elementos. Aqui está um exemplo de recuperação dos valores e os `scriptPubKeys` das entradas: ``` @@ -111,13 +110,13 @@ Aqui está um exemplo semelhante para as saídas: wally_free_string(pubkey_hex); } ``` -Obviamente, há muito mais coisas que poderemos observar nos PSBTs. Na verdade, olhar é o ponto principal de um PSBT: Podemos verificar entradas e saídas de um computador offline. +Obviamente, há muito mais coisas que poderemos observar nos PSBTs. Na verdade, olhar é o ponto principal de um PSBT: podemos verificar entradas e saídas de um computador offline. -> :warning: **AVISO:** Estas funções de leitura são _muito_ rudimentares e não funcionarão corretamente para situações extremamente normais como uma entrada ou saída que ainda está vazia ou que inclui um `non_witness_utxo`. Eles darão um segfault se não forem entregues um PSBT precisamente esperado. Um verdadeiro leitor precisaria ser consideravelmente mais robusto, para cobrir todas as situações possíveis, mas vamos deixar isso para o leitor. +> :warning: **AVISO:** Estas funções de leitura são _muito_ rudimentares e não funcionarão corretamente para situações extremamente normais como uma entrada ou saída que ainda está vazia ou que inclui um `non_witness_utxo`. Elas darão um segfault se não forem entregues um PSBT precisamente esperado. Um leitor de verdade precisaria ser consideravelmente mais robusto, para cobrir todas as situações possíveis, mas vamos deixar isso como um exercício para o leitor. -### Testando nosso leitor PSBT +### Testando Nosso Leitor PSBT -Novamente, o código para este leitor PSBT (extremamente rudimentar e específico) está no [diretório src/](src/16_4_examinepsbt.c). +Novamente, o código para este leitor PSBT (extremamente rudimentar e específico) está no [diretório src/](src/17_4_examinepsbt.c). Podemos compilá-lo normalmente: ``` @@ -146,8 +145,7 @@ scriptPubKey: 0014c772d6f95542e11ef11e8efc7c7a69830ad38a05 INPUT #1 scriptPubKey: 0014f4e8dde5db370898b57c84566e3f76098850817d ``` -And of course, you can check this with the `decodepsbt` RPC command for `bitcoin-cli`: -E, claro, você pode verificar isso com o comando RPC `decodepsbt` para` bitcoin-cli`: +E, claro, você pode verificar tudo isso com o comando RPC `decodepsbt` para` bitcoin-cli`: ``` $ bitcoin-cli decodepsbt $psbt { @@ -264,17 +262,17 @@ $ bitcoin-cli decodepsbt $psbt "fee": 0.00000209 } ``` -Podemos ver a entrada de satoshis e o `scriptPubKey` claramente listadas nos `inputs` e a nova `scriptPubKey` no `vout` do `tx`. +Podemos ver a entrada de satoshis e o `scriptPubKey` claramente listadOs nos `inputs` e a nova `scriptPubKey` no `vout` do `tx`. Então, está tudo lá para utilizarmos! ## Criando um PSBT -Conforme observado no início desta seção, todas as funções necessárias para criar e processar os PSBTs estão disponíveis em Libwally. Na verdade, percorrer todo o processo para fazer isso é complexo o suficiente para estar além do escopo desta seção, mas aqui está um resumo rápido das funções necessárias. Observe que a [documentação](https://wally.readthedocs.io/en/latest/psbt/) está desatualizada para os PSBTs, portanto, precisaremos consultar o `/usr/include/wally_psbt.h` para obter as informações completas. +Conforme observado no início desta seção, todas as funções necessárias para criar e processar os PSBTs estão disponíveis na Libwally. Na verdade, percorrer todo o processo para fazer isso é tão complexo que foge do escopo desta seção, mas aqui está um resumo rápido das funções necessárias. Observe que a [documentação](https://wally.readthedocs.io/en/latest/psbt/) está desatualizada para os PSBTs, portanto, precisaremos consultar o `/usr/include/wally_psbt.h` para obter as informações completas. -Conforme discutido na seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md), existem várias funções envolvidas na criação dos PSBTs. +Conforme discutido na seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md), existem várias funções envolvidas na criação de PSBTs. -### Assumindo o papel de criador +### Assumindo o Papel de Criador A função de criador tem a tarefa de criar um PSBT com pelo menos uma entrada. @@ -289,9 +287,9 @@ Mas o que temos ainda não é um PSBT legal, por falta de entradas. Podemos cri lw_response = wally_tx_init_alloc(0,0,1,1,>x); lw_response = wally_psbt_set_global_tx(psbt,gtx); ``` -### Testando nosso PSBT criado +### Testando nosso PSBT Criado -Neste ponto, devemos ter um PSBT vazio, mas funcionando, que pode ser visto compilando e executando [o programa](src/16_4_createemptypsbt.c). +Neste ponto, devemos ter um PSBT vazio, mas funcionando, que pode ser visto compilando e executando [o programa](src/17_4_createemptypsbt.c). ``` $ cc createemptypsbt.c -lwallycore -o createemptypsbt $ ./createemptypsbt @@ -324,7 +322,7 @@ $ bitcoin-cli decodepsbt $psbt "fee": 0.00000000 } ``` -## Assumindo as demais das funções +## Assumindo as Demais Funções Assim como na leitura de PSBT, estamos introduzindo o conceito de criação do PSBT e, em seguida, deixando o resto como um exercício para o leitor. @@ -367,12 +365,12 @@ A seguir está uma lista aproximada de funções para cada papel. Mais funções * wally_psbt_extract -## Resumo: Usando o PSBTs na Libwally +## Resumo: Usando PSBTs na Libwally Esta seção poderia ser um capítulo inteiro, já que trabalhar com os PSBTs em um nível baixo é um trabalho muito intenso que requer uma manipulação muito mais intensiva de entradas e saídas como foi o caso do [Capítulo 7](07_0_Expanding_Bitcoin_Transactions_PSBTs.md). Ao invés disso, esta seção mostra o básico: como extrair informações de um PSBT e como começar a criar um. -> :fire: ***Qual é o poder dos PSBTs na Libwally?*** Obviamente, já podemos fazer tudo isso nos `bitcoin-cli`, e é mais simples porque o Bitcoin Core gerencia muito do penoso trabalho. A vantagem de usar o Libwally é que ele pode ser executado offline, então pode ser a Libwally que está do outro lado de um dispositivo de hardware com o qual nosso `bitcoin-cli` está se comunicando com o HWI. Este é, de fato, um dos principais pontos dos PSBTs: ser capaz de manipular transações parcialmente assinadas sem a necessidade de um node completo. A Libwally permite isso. +> :fire: ***Qual é o poder dos PSBTs na Libwally?*** Obviamente, já podemos fazer tudo isso nos `bitcoin-cli`, e é mais simples porque o Bitcoin Core gerencia muito do trabalho penoso. A vantagem de usar a Libwally é que ela pode ser executada offline, então pode ser a Libwally que está do outro lado de um dispositivo de hardware com o qual nosso `bitcoin-cli` está se comunicando com o HWI. Este é, de fato, um dos principais pontos dos PSBTs: ser capaz de manipular transações parcialmente assinadas sem a necessidade de um node completo. A Libwally permite isso. ## O Que Vem Depois? -Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.5: Usando Scripts no Libwally](16_5_Using_Scripts_in_Libwally.md). \ No newline at end of file +Vamos aprender mais sobre "Programando Bitcoin com Libwally" na seção [§17.5: Usando Scripts na Libwally](17_5_Using_Scripts_in_Libwally.md). \ No newline at end of file From 7876104d0decbf4184d9a2c2bad9a4e372d2abb4 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 08:45:08 -0300 Subject: [PATCH 088/155] Review 17_5 --- pt/17_5_Using_Scripts_in_Libwally.md | 44 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/pt/17_5_Using_Scripts_in_Libwally.md b/pt/17_5_Using_Scripts_in_Libwally.md index 5afb79e..2fb7458 100644 --- a/pt/17_5_Using_Scripts_in_Libwally.md +++ b/pt/17_5_Using_Scripts_in_Libwally.md @@ -1,16 +1,16 @@ -# 16.5: Usando Scripts na Libwally +# 17.5: Usando Scripts na Libwally > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Na seção 3 deste capítulo, ao apresentar os scripts, dissemos que era provável que criássemos transações usando scripts com uma API e dissemos que este era um tópico para o futuro. Bem, o futuro já chegou. +Na seção 3 deste capítulo, ao apresentar os scripts, dissemos que era provável que criássemos transações usando scripts com uma API e dissemos que este era um tópico para o futuro. Bem, agora o futuro chegou. ## Criando o Script -Criar o script é a coisa mais _fácil_ de se fazer na Libwally. Veja o exemplo a seguir, um simples [Puzzle Script](13_1_Writing_Puzzle_Scripts.md) ao qual retornamos de vez em quando: +Criar o script é a coisa _mais fácil_ de se fazer na Libwally. Veja o exemplo a seguir, um simples [Script Quebra-Cabeça](13_1_Writing_Puzzle_Scripts.md) ao qual retornamos de vez em quando: ``` OP_ADD 99 OP_EQUAL ``` -Usando o `btcc`, podemos serializar isso. +Usando o `btcc`, podemos serializar isto. ``` $ btcc OP_ADD 99 OP_EQUAL warning: ambiguous input 99 is interpreted as a numeric value; use 0x99 to force into hexadecimal interpretation @@ -25,7 +25,7 @@ Primeiro, a Libwally precisa converter o hex em bytes, uma vez que os bytes são lw_response = wally_hex_to_bytes(script,bscript,script_length,&written); ``` -Então, executamos o comando `wally_scriptpubkey_p2sh_from_bytes` com os bytes, dizendo a Libwally para também fazer o `HASH160` para nós: +Então, executamos o comando `wally_scriptpubkey_p2sh_from_bytes` com os bytes, dizendo à Libwally para também fazer o `HASH160` para nós: ``` unsigned char p2sh[WALLY_SCRIPTPUBKEY_P2SH_LEN]; @@ -35,11 +35,11 @@ Se olharmos os resultados do `p2sh`, veremos o seguinte: ``` a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87 ``` -Que [devemos nos lembrar](10_2_Building_the_Structure_of_P2SH.md) de divide em: +Que [devemos nos lembrar](10_2_Building_the_Structure_of_P2SH.md) se divide em: ``` a9 / 14 / 3f58b4f7b14847a9083694b9b3b52a4cea2569ed / 87 ``` -Esse é nosso velho amigo `OP_HASH160 3f58b4f7b14847a9083694b9b3b52a4cea2569ed OP_EQUAL`. +Este é o nosso velho amigo `OP_HASH160 3f58b4f7b14847a9083694b9b3b52a4cea2569ed OP_EQUAL`. Basicamente, a Libwally pegou nosso script de resgate serializado, fez o hash para nós com SHA-256 e RIPEMD-160 e aplicou o enquadramento padrão para transformá-lo em um P2SH adequado. Fizemos um trabalho semelhante ao feito na seção [§10.2](10_2_Building_the_Structure_of_P2SH.md), mas com um excesso de comandos shell. @@ -50,9 +50,9 @@ $ echo -n $redeemScript | xxd -r -p | openssl dgst -sha256 -binary | openssl dgs (stdin)= 3f58b4f7b14847a9083694b9b3b52a4cea2569ed ``` -## Criando uma transação +## Criando uma Transação -A fim de fazer uso do `pubScriptKey` que acabamos de criar, precisamos criar uma transação e incorporar o `pubScriptKey` dentro, e esta é a grande mudança para o `bitcoin-cli`. Podemos criar manualmente uma transação com um script P2SH. +A fim de fazer uso do `pubScriptKey` que acabamos de criar, precisamos criar uma transação e incorporar o `pubScriptKey` dentro dela (e esta é a grande mudança do `bitcoin-cli`: podemos criar manualmente uma transação com um script P2SH). O processo de criação de uma transação na Libwally é muito intenso, assim como o processo de criação de um PSBT, portanto, vamos apenas esboçá-lo, pegando um atalho e, em seguida, deixando um método sem atalhos para investigação futura. @@ -63,7 +63,7 @@ Criar uma transação em si é fácil, só precisamos dizer ao comando `wally_tx ``` Preencher essas entradas e saídas é onde as coisas ficam complicadas! -### Criando uma saída na transação +### Criando uma Saída de Transação Para criar uma saída, dizemos a `wally_tx_output_init_alloc` quantos satoshis estamos gastando, além de entregar o script de bloqueio: ``` @@ -77,9 +77,9 @@ Mais um comando o adiciona à nossa transação: lw_response = wally_tx_add_output(tx,tx_output); ``` -### Criando uma entrada na transação +### Criando uma Entrada de Transação -Criar a entrada é muito mais difícil porque temos que empilhar informações nas rotinas de criação, nem todas as quais são intuitivamente acessíveis quando usamos a Libwally. Então, ao invés de ir mergulhar fundo nessa biblioteca, é neste momento que pegamos nosso atalho. Escrevemos o código de forma que seja passado o código hexadecimal para uma transação que já foi criada e, em seguida, apenas reutilizamos a entrada. +Criar a entrada é muito mais difícil porque temos que empilhar informações nas rotinas de criação, nem todas as quais são intuitivamente acessíveis quando usamos a Libwally. Então, ao invés de mergulharmos fundo nessa biblioteca, é neste momento que pegamos nosso atalho. Escrevemos o código de forma que seja passado o código hexadecimal para uma transação que já foi criada e, em seguida, apenas reutilizamos a entrada. A conversão do código hexadecimal é feita com `wally_tx_from_hex`: ``` @@ -92,27 +92,27 @@ Então podemos roubar as entradas de nosso código hexadecimal para criar uma en lw_response = wally_tx_input_init_alloc(utxo->inputs[0].txhash,sizeof(utxo->inputs[0].txhash),utxo->inputs[0].index,0,utxo->inputs[0].script,utxo->inputs[0].script_len,utxo->inputs[0].witness,&tx_input); assert(lw_response == WALLY_OK); ``` -Como seria de esperar, adicionamos essa entrada à nossa transação: +Como seria de se esperar, adicionamos essa entrada à nossa transação: ``` lw_response = wally_tx_add_input(tx,tx_input); ``` -> **NOTA:** Obviamente, iremos querer criar nossas próprias entradas se estivermos usando Libwally aplicativos reais, mas isso é uma primeira etapa. E, na verdade, pode ser útil para integração com o `bitcoin-cli`, como veremos na seção [§16.7](16_7_Integrating_Libwally_and_Bitcoin-CLI.md). +> **NOTA:** Obviamente, iremos querer criar nossas próprias entradas se estivermos usando Libwally para aplicações reais, mas isso é uma primeira etapa. E, na verdade, pode ser útil para integração com o `bitcoin-cli`, como veremos na seção [§17.7](17_7_Integrating_Libwally_and_Bitcoin-CLI.md). -### Mostrando na tela uma transação +### Vendo uma Transação -Teoricamente, poderíamos assinar e enviar esta transação para nosso programa C construído na Libwally, mas mantendo a ideia de que estamos apenas usando um programa C simples para substituir um P2SH, vamos imprimir o novo hex. Isso é feito com a ajuda de `wally_tx_to_hex`: +Teoricamente, poderíamos assinar e enviar esta transação para nosso programa C construído na Libwally, mas mantendo a ideia de que estamos apenas usando um programa C simples para substituir um P2SH, vamos imprimir o novo hex. Isto é feito com a ajuda de `wally_tx_to_hex`: ``` char *tx_hex; lw_response = wally_tx_to_hex(tx,0, &tx_hex); printf("%s\n",tx_hex); ``` -Mostraremos como fazer uso disso na seção §16.7. +Mostraremos como fazer uso disso na seção §17.7. -## Testando nosso script de substituição +## Testando Nosso Script de Substituição -Podemos pegar o código de teste do [diretório src/](src/16_5_replacewithscript.c) e compilá-lo: +Podemos pegar o código de teste do [diretório src/](src/17_5_replacewithscript.c) e compilá-lo: ``` $ cc replacewithscript.c -lwallycore -o replacewithscript ``` @@ -170,10 +170,10 @@ O `vin` deve apenas corresponder à entrada que substituímos, mas é o `vout` q ## Resumo: Usando Scripts na Libwally -A criação de transações na Libwally é outro tópico que pode ocupar um capítulo inteiro, mas o melhor é que, uma vez que demos esse salto, pode introduzir um P2SH `scriptPubKey`, e só essa parte é muito fácil. Embora a metodologia detalhada neste capítulo exija que já tenhamos um hex de transação em mãos (provavelmente criado com o `bitcoin-cli`) se nos aprofundarmos na Libwally, podemos fazer tudo sozinho. +A criação de transações na Libwally é outro tópico que pode ocupar um capítulo inteiro, mas o melhor é que uma vez que demos esse salto, podemos introduzir um P2SH `scriptPubKey`, e só essa parte é muito fácil. Embora a metodologia detalhada neste capítulo exija que já tenhamos um hex de transação em mãos (provavelmente criado com o `bitcoin-cli`), se nos aprofundarmos na Libwally, podemos fazer tudo sozinhos. -> :fire: ***Qual é o poder dos scripts no Libwally?*** De maneira bem simples, podemos fazer algo que não podíamos antes. Criar uma transação bloqueada com um P2SH arbitrário. +> :fire: ***Qual é o poder dos scripts na Libwally?*** De maneira bem simples, podemos fazer algo que não podíamos antes. Criar uma transação bloqueada com um P2SH arbitrário. ## O Que Vem Depois? -Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.6: Usando Outras Funções no Libwally](16_6_Using_Other_Functions_in_Libwally.md). \ No newline at end of file +Vamos aprender mais sobre "Programando Bitcoin com Libwally" na seção [§17.6: Usando Outras Funções na Libwally](17_6_Using_Other_Functions_in_Libwally.md). \ No newline at end of file From f54d67c5a78aac2157457ec224f976a912cb5acd Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 08:54:47 -0300 Subject: [PATCH 089/155] Review 17_6 --- pt/17_6_Using_Other_Functions_in_Libwally.md | 59 ++++++++++---------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/pt/17_6_Using_Other_Functions_in_Libwally.md b/pt/17_6_Using_Other_Functions_in_Libwally.md index f198be2..b6f9efe 100644 --- a/pt/17_6_Using_Other_Functions_in_Libwally.md +++ b/pt/17_6_Using_Other_Functions_in_Libwally.md @@ -1,10 +1,10 @@ -# 16.6: Usando Outras Funções no Libwally +# 17.6: Usando Outras Funções na Libwally > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -A Libwally é uma extensa biblioteca que fornece uma quantidade considerável de funcionalidades relacionadas à carteira, muitas delas não disponíveis por meio do `bitcoin-cli`. A seguir, está uma visão geral de algumas funcionalidades não abordadas anteriormente neste capítulo. +A Libwally é uma biblioteca extensa que fornece uma quantidade considerável de funcionalidades relacionadas a carteiras, muitas delas não disponíveis por meio do `bitcoin-cli`. A seguir, está uma visão geral de algumas funcionalidades não abordadas anteriormente neste capítulo. -## Usando funções criptográficas +## Usando Funções Criptográficas Diversas funções criptográficas podem ser acessadas diretamente na Libwally: @@ -14,7 +14,7 @@ Diversas funções criptográficas podem ser acessadas diretamente na Libwally: * `wally_scrypt` - Usa derivação de chave Scrypt; * `wally_sha256` - Usa hash SHA256; * `wally_sha256_midstate` - Usa SHA256 para fazer hash apenas do primeiro bloco de dados; - * `wally_sha256d` - Conduza um hash duplo SHA256; + * `wally_sha256d` - Conduz um hash duplo SHA256; * `wally_sha512` - Usa hash SHA512. Existem também funções HMAC para os dois hashes SHA, que são usados ​​para gerar códigos de autenticação de mensagem com base nos hashes. Eles são usados no [BIP32](https://en.bitcoin.it/wiki/BIP_0032), entre outros lugares. @@ -22,30 +22,30 @@ Existem também funções HMAC para os dois hashes SHA, que são usados ​​pa * `wally_hmac_sha256` * `wally_hmac_sha512` -Funções adicionais cobrem derivação chave PBKDF2 e matemática de curva elíptica. +Funções adicionais cobrem derivação de chave PBKDF2 e matemática de curva elíptica. -## Usando funções de endereço +## Usando Funções de Endereço A Libwally contém várias funções que podem ser usadas para importar, exportar e traduzir endereços de Bitcoin. Alguns convertem entre endereços e bytes `scriptPubKey`: - * `wally_addr_segwit_from_bytes` - Converta um programa witness (em bytes) em um endereço Segwit; - * `wally_addr_segwit_to_bytes` - Converta um endereço Segwit em um `scriptPubKey` (em bytes); - * `wally_address_to_scriptpubkey` - Converta um endereço legado em um `scriptPubKey` (em bytes); - * `wally_scriptpubkey_to_address` - Converta um `scriptPubKey` (em bytes) em um endereço legado. + * `wally_addr_segwit_from_bytes` - Converte um programa witness (em bytes) em um endereço Segwit; + * `wally_addr_segwit_to_bytes` - Converte um endereço Segwit em um `scriptPubKey` (em bytes); + * `wally_address_to_scriptpubkey` - Converte um endereço legado em um `scriptPubKey` (em bytes); + * `wally_scriptpubkey_to_address` - Converte um `scriptPubKey` (em bytes) em um endereço legado. Alguns estão relacionados ao formato de importação de carteira (WIF): - * `wally_wif_from_bytes` - Converta uma chave privada (em bytes) para um WIF; + * `wally_wif_from_bytes` - Converte uma chave privada (em bytes) para um WIF; * `wally_wif_is_uncompressed` - Determina se um WIF está descompactado; * `wally_wif_to_address` - Deriva um endereço P2PKH de um WIF; - * `wally_wif_to_bytes` - Converta um WIF em uma chave privada (em bytes); + * `wally_wif_to_bytes` - Converte um WIF em uma chave privada (em bytes); * `wally_wif_to_public_key` - Deriva uma chave pública (em bytes) de um WIF. -## Usando funções BIP32 +## Usando Funções do BIP32 -Existem funções adicionais de carteira HD BIP32, além do que foi abordado na seção [§16.3: Usando o BIP32 no Libwally](16_3_Using_BIP32_in_Libwally.md). +Existem funções adicionais de carteira HD do BIP32, além do que foi abordado na seção [§17.3: Usando o BIP32 na Libwally](17_3_Using_BIP32_in_Libwally.md). * `bip32_key_get_fingerprint` - Gera uma impressão digital BIP32 para uma chave estendida; * `bip32_key_serialize` - Transforma uma chave estendida em bytes serializados; @@ -54,37 +54,36 @@ Existem funções adicionais de carteira HD BIP32, além do que foi abordado na Existem também vários outros comandos, dependendo se desejamos alocar memória ou fazer com que a Libwally faça o `_alloc` para nós. -## Usando funções BIP38 +## Usando Funções do BIP38 -O [BIP38](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki) permite a criação de uma chave privada protegida por senha. Não ensinamos porque consideramos perigoso inserir esse tipo de fator humano no gerenciamento de chaves. Se duvida disso, consulte [#SmartCustody](https://www.smartcustody.com/index.html). +O [BIP38](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki) permite a criação de uma chave privada protegida por senha. Não o ensinamos porque consideramos perigoso inserir este tipo de fator humano no gerenciamento de chaves. Se duvida disso, consulte [#SmartCustody](https://www.smartcustody.com/index.html). As principais funções são: * `bip38_from_private_key` - Codifica uma chave privada usando BIP38; * `bip38_to_private_key` - Decodifica uma chave privada usando BIP38. -## Usando funções BIP39 +## Usando Funções do BIP39 -Algumas funções de palavras mnemônicas do BIP39 foram resumidas recentemente na seção [§16.2: Usando o BIP39 no Libwally](16_2_Using_BIP39_in_Libwally.md): +Algumas funções de palavras mnemônicas do BIP39 foram resumidas recentemente na seção [§17.2: Usando o BIP39 na Libwally](17_2_Using_BIP39_in_Libwally.md): * `bip39_get_languages` - Veja a lista de idiomas suportados; * `bit39_get_word` - Recupera uma palavra específica da lista de palavras de um idioma; * `bip39_get_wordlist` - Veja uma lista de palavras para um idioma. -## Usando funções PSBT +## Usando Funções de PSBT -As listas da maioria das funções PSBT podem ser encontradas na seção [16.4: Usando o PSBTs no Libwally](16_4_Using_PSBTs_in_Libwally.md). +As listas da maioria das funções de PSBT podem ser encontradas na seção [17.4: Usando PSBTs na Libwally](17_4_Using_PSBTs_in_Libwally.md). -## Usando funções de script +## Usando Funções de Script -A seção [§16.5: Usando Scripts no Libwally](16_5_Using_Scripts_in_Libwally.md) apenas tocou nas funções de scripts da Libwally. +A seção [§17.5: Usando Scripts na Libwally](17_5_Using_Scripts_in_Libwally.md) apenas tocou nas funções de scripts da Libwally. Há outra função que permite determinar o tipo de script encontrado em uma transação: - * `wally_scriptpubkey_get_type` — Determina a transaction's script type; * `wally_scriptpubkey_get_type` - Determina o tipo de script de uma transação. -Depois, há uma série de funções que criam `scriptPubKey` a partir de bytes, o `scriptSig` a partir de assinaturas e witness a partir de bytes ou assinaturas. +Depois, há uma série de funções que criam `scriptPubKey` a partir de bytes, `scriptSig` a partir de assinaturas e Witness a partir de bytes ou assinaturas. * `wally_script_push_from_bytes` * `wally_scriptpubkey_csv_2of2_then_1_from_bytes` @@ -103,7 +102,7 @@ Depois, há uma série de funções que criam `scriptPubKey` a partir de bytes, ## Usando Funções de Transação -Também mal tocamos nas funções que podem ser usadas para criar e converter funções na seção [§16.5](16_5_Using_Scripts_in_Libwally.md). +Também mal tocamos nas funções que podem ser usadas para criar e converter funções na seção [§17.5](17_5_Using_Scripts_in_Libwally.md). Existem inúmeras funções informativas, algumas das mais interessantes são: @@ -113,14 +112,14 @@ Existem inúmeras funções informativas, algumas das mais interessantes são: Também existem funções que afetam um `wally_tx`, um `wally_tx_input`, um `wally_tx_output`, ou um `wally_tx_witness_stack` e que criam assinaturas. -## Usando funções de elementos +## Usando Funções do Elements -A Libwally pode ser compilada para ser usada com os Elementos do Blockstream, que inclui acesso às funções dos ativos. +A Libwally pode ser compilada para ser usada com os Elements da Blockstream, que inclui acesso às funções dos ativos. -## Resumo: Usando Outras Funções no Libwally +## Resumo: Usando Outras Funções na Libwally -Há muito mais coisas que podemos fazer com a Libwally, mais do que podemos abordar neste capítulo ou mesmo listar nesta seção. Notavelmente, podemos executar funções criptográficas, codificar chaves privadas, criar transações completas e usar elementos. A [documentação da Libwally](https://wally.readthedocs.io/en/latest/) é o lugar onde podemos obter mais informações, embora, no momento da criação deste livro, a documentação esteja limitada e desatualizada. Os arquivos de cabeçalho da Libwally são um backup se os documentos estiverem incompletos ou incorretos. +Há muito mais coisas que podemos fazer com a Libwally, mais do que podemos abordar neste capítulo ou mesmo listar nesta seção. Notavelmente, podemos executar funções criptográficas, codificar chaves privadas, criar transações completas e usar Elements. A [documentação da Libwally](https://wally.readthedocs.io/en/latest/) é o lugar onde podemos obter mais informações, embora, no momento da criação deste livro, a documentação esteja limitada e desatualizada. Os cabeçalhos dos arquivos da Libwally são um backup se os documentos estiverem incompletos ou incorretos. ## O Que Vem Depois? -Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§16.7: Integrando o Libwally ao Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md). \ No newline at end of file +Vamos aprender mais sobre "Programando Bitcoin com Libwally" na seção [§17.7: Integrando Libwally e Bitcoin-CLI](17_7_Integrating_Libwally_and_Bitcoin-CLI.md). \ No newline at end of file From 44c594dbdd79b324fb32e98ba115041fd09e0d46 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 09:20:05 -0300 Subject: [PATCH 090/155] Review 17_7 --- ..._7_Integrating_Libwally_and_Bitcoin-CLI.md | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md b/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md index b93d537..91c267c 100644 --- a/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md +++ b/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md @@ -1,14 +1,14 @@ -# 16.7: Integrando o Libwally ao Bitcoin-CLI +# 17.7: Integranda Libwally e Bitcoin-CLI > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -A Libwally é limitado. Trata-se de manipular seeds, chaves, endereços e outros elementos de carteiras, com algumas funções adicionais relacionadas a transações e PSBTs que podem ser úteis para serviços que não estão conectados a nodes completos na Internet. No final das contas, no entanto, precisaremos de serviços de nodes completos para aproveitar as vantagens da Libwally. +A Libwally é limitada. Trata-se de manipular seeds, chaves, endereços e outros elementos de carteiras, com algumas funções adicionais relacionadas a transações e PSBTs que podem ser úteis para serviços que não estão conectados a nodes completos na Internet. No final das contas, no entanto, precisaremos de serviços de nodes completos para aproveitar as vantagens da Libwally. -Esta última seção oferecerá alguns exemplos de uso de programas Libwally para complementar um ambiente `bitcoin-cli`. Embora esses exemplos impliquem que esses serviços estão todos na mesma máquina, eles podem se tornar ainda mais poderosos se o serviço `bitcoin-cli` estiver diretamente conectado à internet e o serviço Libwally não. +Esta última seção oferecerá alguns exemplos de uso de programas Libwally para complementar um ambiente `bitcoin-cli`. Embora esses exemplos impliquem que esses serviços estão todos na mesma máquina, eles podem se tornar ainda mais poderosos se o serviço `bitcoin-cli` estiver diretamente conectado à internet e o serviça Libwally não. -## Compartilhando uma transação +## Compartilhando uma Transação -Na seção [§16.5: Usando Scripts no Libwally](16_5_Using_Scripts_in_Libwally.md) detalhamos como a Libwally poderia ser usada para reescrever uma transação existente, para fazer algo que o `bitcoin-cli` não pode, ou seja, produzir uma transação que contém um P2SH único. Obviamente, este é um bloco de construção, se decidirmos nos aprofundar no Libwally, criaremos transações inteiras por conta própria. Mas, esta metodologia abreviada também tem seu próprio uso, mostrar como as transações podem ser passadas de um lado para outro entre `bitcoin-cli` e Libwally, demonstrando um primeiro exemplo de como usá-los de forma complementar. +Na seção [§17.5: Usando Scripts na Libwally](17_5_Using_Scripts_in_Libwally.md) detalhamos como a Libwally poderia ser usada para reescrever uma transação existente, para fazer algo que o `bitcoin-cli` não pode, ou seja, produzir uma transação que contém um P2SH único. Obviamente, esta é uma parte essencial, mas não o todo; se você decidir se aprofundar na Libwally, poderá criar transações inteiras por conta própria. Mas esta metodologia abreviada também tem seu próprio uso, mostrar como as transações podem ser passadas de um lado para outro entre `bitcoin-cli` e Libwally, demonstrando um primeiro exemplo de como usá-los de forma complementar. Para demonstrar totalmente essa metodologia, criaremos uma transação com o `bitcoin-cli`, usando este UTXO: ``` @@ -33,7 +33,7 @@ $ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') $ recipient=tb1qycsmq3jas5wkhf8xrfn8k7438cm5pc8h9ae2k0 $ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.0009 }''') ``` -Embora tenhamos colocado um destinatário e uma quantia na saída, é irrelevante, porque nós o reescreveremos. Um código mais elaborado poderia ler as informações `vout` existentes antes de reescrever, mas estamos mantendo as coisas muito próximas do nosso [código original](src/16_5_replacewithscript.c). +Embora tenhamos colocado um destinatário e uma quantia na saída, isto é irrelevante, porque nós o reescreveremos. Um código mais elaborado poderia ler as informações `vout` existentes antes de reescrever, mas estamos mantendo as coisas muito próximas do nosso [código original](src/17_5_replacewithscript.c). Aqui está a única alteração necessária, para permitir que especifiquemos os satoshis no `vout`, sem ter que codificá-lo, como no original: ``` @@ -129,7 +129,7 @@ Depois, podemos assiná-la normalmente com o `bitcoin-cli`: ``` $ signedtx=$(bitcoin-cli signrawtransactionwithwallet $newtxhex | jq -r '.hex') ``` -E como podemos ver, o resultado é uma transação legítima pronta para ir para a rede Bitcoin: +E, como podemos ver, o resultado é uma transação legítima pronta para ir para a rede Bitcoin: ``` $ bitcoin-cli decoderawtransaction $signedtx { @@ -170,21 +170,21 @@ $ bitcoin-cli decoderawtransaction $signedtx ``` Pronto! Esse é o poder da Libwally com o `bitcoin-cli`. -Obviamente, também pode passar um PSBT usando as funções descritas na seção [§16.4](16_4_Using_PSBTs_in_Libwally.md) e essa é uma metodologia mais atualizada para o uso moderno do Bitcoin, mas em qualquer um dos exemplos, o conceito de passar transações do `bitcoin-cli` para código Libwally e vice-versa deve ser semelhante. +Obviamente, também podemos passar um PSBT usando as funções descritas na seção [§17.4](17_4_Using_PSBTs_in_Libwally.md) e esta é uma metodologia mais atualizada para o uso moderno do Bitcoin; mas em qualquer um dos exemplos, o conceito de passar transações do `bitcoin-cli` para códiga Libwally e vice-versa deve ser semelhante. -## Importando e exportando seeds BIP39 +## Importando e Exportando Seeds BIP39 -Infelizmente, nem todas as interações entre a Libwally e o `bitcoin-cli` são fáceis. Por exemplo, seria bom se pudessemos exportar uma seed HD do `bitcoin-cli`, para gerar a frase mnemônica com a Libwally, ou gerar uma seed de uma frase mnemônica usando a Libwally e depois importá-la para o `bitcoin-cli `. Infelizmente, nada disso é possível neste momento. Uma frase mneômica é traduzida em uma seed usando HMAC-SHA512, o que significa que o resultado é 512 bits. No entanto, o `bitcoin-cli` exporta seeds HD (usando `dumpwallet`) e importa sementes HD (usando `sethdseed`) com um comprimento de 256 bits. Até que isso seja mudado, não podemos fazer nada sobre isso. +Infelizmente, nem todas as interações entre a Libwally e o `bitcoin-cli` são fáceis. Por exemplo, seria bom se pudéssemos exportar uma seed HD do `bitcoin-cli` para gerar a frase mnemônica com a Libwally, ou gerar uma seed de uma frase mnemônica usando a Libwally e depois importá-la para o `bitcoin-cli `. Infelizmente, nada disso é possível neste momento. Uma frase mneômica é traduzida em uma seed usando HMAC-SHA512, o que significa que o resultado é 512 bits. No entanto, o `bitcoin-cli` exporta seeds HD (usando `dumpwallet`) e importa seeds HD (usando `sethdseed`) com um comprimento de 256 bits. Até que isso seja mudado, não há nada que possamos fazer. -> :book: ***Qual é a diferença entre entropia e uma seed?*** A Libwally diz que criamos nossas frases mnemônicas a partir da entropia. Isso é essencialmente a mesma coisa que uma seed, pois ambos são números grandes e aleatórios. Portanto, se o `bitcoin-cli` fosse compatível com as sementes de frase mnemônica de 512 bits, poderíamos usar uma para gerar as frases mnemônicas e obter os resultados esperados. +> :book: ***Qual é a diferença entre entropia e uma seed?*** A Libwally diz que criamos nossas frases mnemônicas a partir de entropia. Isso é essencialmente a mesma coisa que uma seed, pois ambos são números grandes e aleatórios. Portanto, se o `bitcoin-cli` fosse compatível com as seeds de frase mnemônica de 512 bits, poderíamos usar uma para gerar as frases mnemônicas e obter os resultados esperados. -> :book: ***Qual é a diferença entre entropia e entropia bruta?*** Nem toda entropia é a mesma. Quando inserimos entropia em um comando que cria uma seed mnemônica, ela tem um comprimento específico e bem conhecido. Mudar a entropia bruta em uma entropia requer alterar a entropia bruta até que tenha o comprimento e o formato corretos, e nesse ponto podemos reutilizar essa entropia (não bruta) para sempre recriar os mesmos mnemônicos (razão pela qual a entropia é efetivamente a mesma coisa que um seed naquele ponto, mas a entropia bruta não). +> :book: ***Qual é a diferença entre entropia e entropia bruta?*** Nem toda entropia é a mesma. Quando inserimos entropia em um comando que cria uma seed mnemônica, ela tem um comprimento específico e bem conhecido. Mudar de entropia bruta para entropia requer alterar a entropia bruta até que se tenha o comprimento e o formato corretos, e nesse ponto podemos reutilizar essa entropia (não bruta) para sempre recriar os mesmos mnemônicos (razão pela qual a entropia é efetivamente a mesma coisa que uma seed naquele ponto, mas a entropia bruta não). -## Importando chaves privadas +## Importando Chaves Privadas -Felizmente, podemos fazer quase a mesma coisa importando uma chave privada gerada na Libwally. Dê uma olhada no [genhd-for-import.c](src/16_7_genhd_for_import.c), uma versão simplificada do programa `genhd` da seção [§16.3](16_3_Using_BIP32_in_Libwally.md) que também usa a biblioteca `jansson` da seção [ §15.1](15_1_Accessing_Bitcoind_with_C.md) para saída regularizada. +Felizmente, podemos fazer quase a mesma coisa importando uma chave privada gerada na Libwally. Dê uma olhada no [genhd-for-import.c](src/17_7_genhd_for_import.c), uma versão simplificada do programa `genhd` da seção [§17.3](17_3_Using_BIP32_in_Libwally.md) que também usa a biblioteca `jansson` da seção [§16.1](16_1_Accessing_Bitcoind_with_C.md) para saída regularizada. -O código atualizado também contém uma alteração importante, pois ele solicita uma impressão digital da Libwally para que possa criar um caminho de derivação de maneira adequada: +O código atualizado também contém uma alteração importante, pois ele solicita uma impressão digital da Libwally para que se possa criar um caminho de derivação de maneira adequada: ``` char account_fingerprint[BIP32_KEY_FINGERPRINT_LEN]; lw_response = bip32_key_get_fingerprint(key_account,account_fingerprint,BIP32_KEY_FINGERPRINT_LEN); @@ -193,13 +193,13 @@ O código atualizado também contém uma alteração importante, pois ele solici lw_response = wally_hex_from_bytes(account_fingerprint,BIP32_KEY_FINGERPRINT_LEN,&fp_hex); ``` -> :aviso: **AVISO:** Lembre-se de que a impressão digital nos caminhos de derivação é arbitrária. Como o Libwally fornece um, nós o estamos usando, mas se não tivermos um, poderemos adicionar um código hexadecimal arbitrário de 4 bytes como uma impressão digital em nosso caminho de derivação. +> :aviso: **AVISO:** Lembre-se de que a impressão digital nos caminhos de derivação é arbitrária. Como a Libwally fornece um, nós o estamos usando, mas se não tivéssemos um, poderíamos adicionar um código hexadecimal arbitrário de 4 bytes como uma impressão digital em nosso caminho de derivação. -Certifique-se de compilar o novo código com a biblioteca `jansson`, após instalá-lo (se necessário) de acordo com a seção [§15.1](15_1_Accessing_Bitcoind_with_C.md). +Certifique-se de compilar o novo código com a biblioteca `jansson`, após instalá-lo (se necessário) de acordo com a seção [§16.1](16_1_Accessing_Bitcoind_with_C.md). ``` $ cc genhd-for-import.c -lwallycore -lsodium -ljansson -o genhd-for-import ``` -Quando executamos o novo programa, ele nos dará uma lista de saída com todas as informações: +Quando executarmos o novo programa, ele nos dará uma lista de saída com todas as informações: ``` $ ./genhd-for-import { @@ -209,11 +209,11 @@ $ ./genhd-for-import "derivation": "[d1280779/84h/1h/0h]" } ``` -Temos o `mnemônico` que podemos recuperar, um `account-xprv` que podemos importar, uma `derivação` para usar para a importação e um `address` de amostra, que podemos usar para testar a importação. +Temos o `mnemonic` que podemos recuperar, um `account-xprv` que podemos importar, uma `derivation` para usar para a importação e um `address` de amostra, que podemos usar para testar a importação. Agora podemos recorrer às lições aprendidas na seção [§3.5](03_5_Understanding_the_Descriptor.md) sobre como transformar esse xprv em um descritor e importá-lo. -Primeiro, precisamos descobrir a soma de verificação: +Primeiro, precisamos descobrir o checksum: ``` $ xprv=tprv8yxn8iFNgsLktEPkWKQpMqb7bcx5ViFQEbJMtqrGi8LEgvy8es6YeJvyJKrbYEPKMw8JbU3RFhNRQ4F2pataAtTNokS1JXBZVg62xfd5HCn $ dp=[d1280779/84h/1h/0h] @@ -229,7 +229,7 @@ $ bitcoin-cli getdescriptorinfo "wpkh($dp$xprv/0/*)" Há três coisas a serem observadas aqui: -1. Usamos o `wpkh` como a função em nosso caminho de derivação. Isso porque queremos gerar endereços Segwit modernos, não endereços legados. Isso corresponde ao uso na Libwally da função `wally_bip32_key_to_addr_segwit`. A coisa mais importante, entretanto, é ter as mesmas expectativas com a Libwally e o `bitcoin-cli` (e nosso descritor) de que tipo de endereço estamos gerando, para que tudo sê certo; +1. Usamos o `wpkh` como a função em nosso caminho de derivação. Isso porque queremos gerar endereços Segwit modernos, não endereços legados. Isso corresponde ao uso na Libwally da função `wally_bip32_key_to_addr_segwit`. A coisa mais importante, entretanto, é ter as mesmas expectativas com a Libwally e o `bitcoin-cli` (e nosso descritor) de que tipo de endereço estamos gerando, para que tudo dê certo; 2. Usamos o caminho `/0/*` porque queríamos os endereços externos para esta conta. Se, em vez disso, quiséssemos alterar os endereços, usaríamos `/1/*`; 3. Não vamos usar a linha `descriptor` que foi retornada, pois é para um endereço `xpub`. Ao invés disso, aplicaremos o `checksum` retornado ao `xprv` que já temos. ``` @@ -247,7 +247,7 @@ $ bitcoin-cli importmulti '''[{ "desc": "wpkh('$dp''$xprv'/0/*)#'$cs'", "timesta ``` Aqui, importamos/geramos os primeiros dez endereços para a chave privada. -Vamos examinar o novo rótulo `LibwallyImported`: +Vamos examinar o novo rótulo `LibwallyImports`: ``` $ bitcoin-cli getaddressesbylabel "LibwallyImports" { @@ -289,15 +289,15 @@ $ bitcoin-cli getaddressesbylabel "LibwallyImports" ``` O segundo em nossa lista realmente corresponde ao que temos de amostra (`tb1q9lhru6k0ymwrtr5w98w35n3lz22upml23h753n`). A importação desta chave privada e a derivação de dez endereços foram bem-sucedidas. -Se olharmos agora para trás na seção [§7.3](07_3_Integrating_with_Hardware_Wallets.md), veremos que esta era a mesma metodologia que usamos para importar endereços de uma carteira física (embora desta vez também importamos a chave privada como prova de conceito). A maior diferença é que anteriormente a informação era criada por uma caixa preta (literalmente, pois era um dispositivo Ledger), e desta vez nós mesmos criamos a informação usando a Libwally, mostrando como podemos fazer esse tipo de trabalho de maneira airgaped ou em outro dispositivo remoto e, em seguida, levá-lo ao `bitcoin-cli`. +Se olharmos agora para trás na seção [§7.3](07_3_Integrating_with_Hardware_Wallets.md), veremos que esta era a mesma metodologia que usamos para importar endereços de uma hardware wallet (embora desta vez também importamos a chave privada como prova de conceito). A maior diferença é que anteriormente a informação era criada por uma caixa preta (literalmente: era um dispositivo Ledger), e desta vez nós mesmos criamos a informação usando a Libwally, mostrando como podemos fazer esse tipo de trabalho de maneira airgaped ou em outro dispositivo remoto e, em seguida, levá-lo ao `bitcoin-cli`. -## Importando endereços +## Importando Endereços Obviamente, se podemos importar chaves privadas, também podemos importar endereços, o que geralmente significa importar endereços somente para observação _sem_ as chaves privadas. -Uma maneira do fazer isso é utilizar a metodologia `importmulti` acima, mas neste caso, usamos o endereço fornecido XPUB (`wpkh([d1280779/84'/1'/0']tpubDWepH8HcqF2RmhRYPy5QmFFEAeU1f3SJotu9BMta8Q8dXRDuHFv8poYqUUtEiWftBjtKn1aNhi9Qg2P4NdzF66dShYvB92z78WJbYeHTLTz/0/*)#f8rmqc0z`) ao invés do xprv original. Essa é a melhor maneira de importar uma sequência inteira de endereços somente para observação. +Uma maneira de fazer isso é utilizar a metodologia `importmulti` acima, mas neste caso, usamos o endereço xpub fornecido (`wpkh([d1280779/84'/1'/0']tpubDWepH8HcqF2RmhRYPy5QmFFEAeU1f3SJotu9BMta8Q8dXRDuHFv8poYqUUtEiWftBjtKn1aNhi9Qg2P4NdzF66dShYvB92z78WJbYeHTLTz/0/*)#f8rmqc0z`) ao invés do xprv original. Essa é a melhor maneira de importar uma sequência inteira de endereços somente para observação. -Como alternativa, podemos importar endereços individuais. Por exemplo, considere o único endereço de amostra retornado pelo programa `genhd-for-import`: +Como alternativa, podemos importar endereços individuais. Por exemplo, considere o único endereço de amostra retornado pelo programa `genhd-for-import`: ``` $ ./genhd-for-import { @@ -319,12 +319,12 @@ $ bitcoin-cli getaddressesbylabel "LibwallyWO" } ``` -## Resumo: Integrando o Libwally ao Bitcoin-CLI +## Resumo: Integrando Libwally e Bitcoin-CLI -Com um conhecimento básico de Libwally, agora podemos complementar todo o trabalho das lições anteriores. A transferência de endereços, chaves, transações e PSBTs são apenas algumas das maneiras pelas quais podemos usar esses dois poderosos métodos de programação do Bitcoin juntos. Também há muito mais profundidade potencial se quisermos nos aprofundar na extensa biblioteca de funções do Libwally. +Com um conhecimento básico de Libwally, agora podemos complementar todo o trabalho das lições anteriores. A transferência de endereços, chaves, transações e PSBTs são apenas algumas das maneiras pelas quais podemos usar esses dois poderosos métodos de programação do Bitcoin juntos. Também há muito mais profundidade potencial se quisermos nos aprofundar na extensa biblioteca de funções da Libwally. -> :fire: ***Qual é o poder de integrar Libwally e Bitcoin-CLI?*** Uma das maiores vantagens do Libwally é que ele tem muitas funções que podem ser usadas offline. Em comparação, o Bitcoin Core é um programa em rede. Isso pode ajudá-lo a aumentar a segurança fazendo com que o `bitcoin-cli` passe chaves, endereços, transações ou PSBTs para uma fonte offline (que estaria executando programas Libwally). Além disso, o Libwally pode fazer coisas que o Bitcoin Core não pode, como gerar uma seed a partir de um mnemônico BIP39 (e mesmo se não pudermos importá-la para o Bitcoin Core, _podemos_ importar a chave mestra, conforme mostrado aqui). +> :fire: ***Qual é o poder de integrar Libwally e Bitcoin-CLI?*** Uma das maiores vantagens da Libwally é que ela tem muitas funções que podem ser usadas offline. Em comparação, o Bitcoin Core é um programa em rede. Isso pode ajudá-lo a aumentar a segurança fazendo com que o `bitcoin-cli` passe chaves, endereços, transações ou PSBTs para uma fonte offline (que estaria executando programas Libwally). Além disso, a Libwally pode fazer coisas que o Bitcoin Core não pode, como gerar uma seed a partir de um mnemônico BIP39 (e mesmo se não pudermos importá-la para o Bitcoin Core, _podemos_ importar a chave mestra, conforme mostrado aqui). ## O Que Vem Depois? -Saiba mais sobre outras linguagens de programação no [Capítulo 17: Conversando com o Bitcoind com Outras Linguagens](17_0_Talking_to_Bitcoind_Other.md). \ No newline at end of file +Saiba mais sobre outras linguagens de programação no [Capítulo 18: Conversando com o Bitcoind com Outras Linguagens](18_0_Talking_to_Bitcoind_Other.md). \ No newline at end of file From dd5dd5d82354a75d537e5abdd65e91480b75308b Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 09:52:51 -0300 Subject: [PATCH 091/155] Delete old 15 files --- pt/15_0_Talking_to_Bitcoind.md | 27 -- pt/15_1_Accessing_Bitcoind_with_C.md | 294 --------------- pt/15_2_Programming_Bitcoind_with_C.md | 354 ------------------ ...Receiving_Bitcoind_Notifications_with_C.md | 155 -------- 4 files changed, 830 deletions(-) delete mode 100644 pt/15_0_Talking_to_Bitcoind.md delete mode 100644 pt/15_1_Accessing_Bitcoind_with_C.md delete mode 100644 pt/15_2_Programming_Bitcoind_with_C.md delete mode 100644 pt/15_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/pt/15_0_Talking_to_Bitcoind.md b/pt/15_0_Talking_to_Bitcoind.md deleted file mode 100644 index 88bde29..0000000 --- a/pt/15_0_Talking_to_Bitcoind.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Capítulo 15: Conversando com Bitcoind usando C - -Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. - -Esta seção se concentra em três diferentes bibliotecas que podem ser usadas como base de programação C sofisticada: Uma biblioteca RPC e uma biblioteca JSON que juntas permitem recriar muito do que fazemos nos scripts de shell, porém, usando C; enquanto uma biblioteca ZMQ nos conecta a notificações, algo que não conseguiríamos acessar até agora. (O próximo capítulo cobrirá uma biblioteca ainda mais sofisticada chamada Libwally, para finalizar esta introdução à programação do Bitcoin com C). - -## Objetivos deste capítulo - -Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - - * Criar programas C que usam RPC para conversar com o Bitcoind; - * Criar programas C que usam ZMQ para conversar com o Bitcoind. - -Os objetivos secundários do capítulo incluem a capacidade de: - - * Entender como usar uma biblioteca RPC; - * Entender como usar uma biblioteca JSON; - * Compreender as capacidades do ZMQ; - * Entender como usar uma biblioteca ZMQ. - -## Tabela de conteúdo - - * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) - * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) - * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) - \ No newline at end of file diff --git a/pt/15_1_Accessing_Bitcoind_with_C.md b/pt/15_1_Accessing_Bitcoind_with_C.md deleted file mode 100644 index 2e97e1c..0000000 --- a/pt/15_1_Accessing_Bitcoind_with_C.md +++ /dev/null @@ -1,294 +0,0 @@ - -# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -Você já viu uma maneira alternativa de acessar as portas RPC do Bitcoind: Usando o ``curl``, que cobrimos no [Capítulo 4 Prefácio](04_4__interlude_using_curl.md). Interagir com o ``Bitcoind`` através de uma biblioteca de RPC usando C não é diferente do que já vimos, só precisamos de boas bibliotecas para nos auxiliar. Esta seção introduz um pacote chamado ``libbitcoinrpc``, que permite acessar a porta JSON-RPC do ``bitcoind``. Ele usa uma biblioteca ``curl`` para acessar os dados e usa a biblioteca ``jansson`` para codificar e decodificar o JSON. - -## Configurando o libbitcoinrpc - -Para usar o ``libbitcoinrpc``, precisaremos instalar uma configuração básica C e os pacotes dependentes, que são ``libcurl``, ``libjansson``, e ``libuuid``. Depois faremos isso no seu servidor Standup Bitcoin (ou em qualquer outro servidor Ubuntu). - -``` -$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev -Suggested packages: - libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev -The following NEW packages will be installed: - libcurl4-openssl-dev libjansson-dev uuid-dev -0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. -Need to get 358 kB of archives. -After this operation, 1.696 kB of additional disk space will be used. -Do you want to continue? [Y/n] y -``` -Agora, podemos baixar o [libbitcoinrpc no github](https://github.com/gitmarek/libbitcoinrpc/blob/master/readme.md). Vamos clonar ou pegar um arquivo zip, do jeito que preferir. - -``` -$ sudo apt-get install git -$ git clone https://github.com/gitmarek/libbitcoinrpc -``` - -> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. - -### Compilando o libbitcoinrpc. - -Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: -``` -$ PATH="/sbin:$PATH" -``` - -Para o Ubuntu, também precisaremos ajustar o ``install_libpath`` no ``makefile`` do ``libbitcoinrpc`` para instalar no ``/usr/lib`` ao invés do ``/usr/local/lib``: - -``` -$ emacs ~/libbitcoinrpc/Makefile -... -INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib -``` - -(Se preferir não usar o ``/usr/lib``, precisará alterar o ``etc/ld.so.conf`` ou os arquivos dependentes de maneira apropriada... Porém, para uma configuração de teste em uma máquina de teste, acredito que isso não seja um problema). - -Da mesma forma, vamos precisar ajustar o ``install_headerpath`` no ``Makefile`` do ``libbitcoinrpc`` para instalar no caminho ``/usr/include`` ao invés do ``/usr/local/inclusve``: - -``` -... -INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include -``` - -Agora, podemos compilar: -``` -$ cd libbitcoinrpc -~/libbitcoinrpc$ make - -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ -src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ --o .lib/libbitcoinrpc.so.0.2 \ --Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl -ldconfig -v -n .lib -.lib: - libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) -ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so -``` -Se tudo correr bem, podemos instalar o pacote: -``` -$ sudo make install -Installing to -install .lib/libbitcoinrpc.so.0.2 /usr/local/lib -ldconfig -n /usr/local/lib -ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so -install -m 644 src/bitcoinrpc.h /usr/local/include -Installing docs to /usr/share/doc/bitcoinrpc -mkdir -p /usr/share/doc/bitcoinrpc -install -m 644 doc/*.md /usr/share/doc/bitcoinrpc -install -m 644 CREDITS /usr/share/doc/bitcoinrpc -install -m 644 LICENSE /usr/share/doc/bitcoinrpc -install -m 644 Changelog.md /usr/share/doc/bitcoinrpc -Installing man pages -install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 -``` - -## Preparando o código - -``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. - -Para usar o ``libbitcoinrpc``, é importante certificar de que nossos arquivos do código incluam os cabeçalhos apropriados: -``` c -#include -#include -``` - -Precisaremos também vincular as bibliotecas apropriadas sempre que possamos compilar: - -``` -$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode -``` - -## Construindo a conexão - -Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. - -Primeiro, inicialize a biblioteca: -``` -bitcoinrpc_global_init(); -``` -Em seguida, vamos conectar ao ``Bitcoind`` com ``bitcoinrpc_cl_init_params``. Os quatro argumentos necessários para o ``bitcoinrpc_cl_init_params`` são o nome de usuário, a senha, o endereço IP e a porta. A esta altura, você deve saber todas essas informações, já que foram necessárias para realizar o trabalho com o [curl](04_4__interlude_using_curl.md). Apenas para recordar, o endereço de IP é 127.0.0.1 e a porta 18332 devem estar corretos para a configuração padrão da testenet descrita neste documento, enquanto podemos encontrar o usuário e a senha no arquivo ``~/.bitcoin/bitcoin.conf``. -``` -$ cat bitcoin.conf -server=1 -dbcache=1536 -par=1 -maxuploadtarget=137 -maxconnections=16 -rpcuser=StandUp -rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba -rpcallowip=127.0.0.1 -debug=tor -prune=550 -testnet=1 -[test] -rpcbind=127.0.0.1 -rpcport=18332 -[main] -rpcbind=127.0.0.1 -rpcport=8332 -[regtest] -rpcbind=127.0.0.1 -rpcport=18443 -``` -Com essas informações, vamos colocá-las no ``bitcoinrpc_cl_init_params``: -``` c -bitcoinrpc_cl_t *rpc_client; -rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); -``` - -> **MAINNET VS TESTNET:** A porta seria a 8332 caso estivéssemos usando a configuração da rede principal. - -Se o ``rpc_client`` for inicializado com sucesso, poderemos enviar os comandos do RPC. - -Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fechar da seguinte maneira: -``` c -bitcoinrpc_global_cleanup(); -``` - -### Testando o código de teste - -O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). - -Podemos compilar e executar o código da seguinte maneira: -``` -$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin -$ ./testbitcoin -Successfully connected to server! -``` - -> :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. - -## Fazendo uma chamada ao RPC - -Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). -``` c -bitcoinrpc_method_t *getmininginfo = NULL; -getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); -``` -Normalmente definiríamos os parâmetros em seguida, mas o ``GetMiningInfo`` não requer parâmetros, por isso podemos pular essa parte. - -Também devemos criar outros dois objetos, um "objeto de resposta" e um "objeto de erro". Eles podem ser inicializados da seguinte forma: -``` c -bitcoinrpc_resp_t *btcresponse = NULL; -btcresponse = bitcoinrpc_resp_init(); - -bitcoinrpc_err_t btcerror; -``` -Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos adicionar nosso método ``getmininginfo`` e os outros dois objetos: -``` c -bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); -``` - -### Mostrando o retorno da chamada - -Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: -``` c -json_t *jsonresponse = NULL; -jsonresponse = bitcoinrpc_resp_get(btcresponse); -``` -Se quisermos gerar os resultados completos da chamada RPC no JSON, podemos fazer com uma simples invocação do ``json_dumps``, da biblioteca ``jansson``: -``` c -printf("%s\n", json_dumps(j, JSON_INDENT(2))); -``` -No entanto, como agora estamos escrevendo programas completos, provavelmente iremos querer fazer um trabalho mais sutil, como retirar valores individuais do JSON para algum uso específico. A [Referência do Jansson](https6//jansson.readthedocs.Io/en/2.10/apiref.html) traz detalhes de como fazer. - -Assim como estávamos usando o [curl](04_4__interlude_using_curl.md), descobrimos que o RPC retorna um objeto JSON contendo um ``ID``, um ``error`` e, mais importante, um objeto JSON do tipo ``result``. - -A função ``json_object_get`` permite recuperar um valor (como o ``result``) de um objeto JSON usando chaves: -``` c -json_t *jsonresult = NULL; -jsonresult = json_object_get(jsonresponse,"result"); -printf("%s\n", json_dumps(jsonresult, JSON_INDENT(2))); -``` - -No entanto, provavelmente iremos querer analisar informações ainda mais profundas, para obter uma variável específica. Depois de recuperar o valor apropriado, precisaremos convertê-lo em um objeto C padrão usando a função ``JSON_*_value``. Por exemplo, para acessar um integer usamos o ``json_integer_value``: -``` c -json_t *jsonblocks = NULL; -jsonblocks = json_object_get(jsonresult,"blocks"); - -int blocks; -blocks = json_integer_value(jsonblocks); -printf("Block Count: %d\n",blocks); -``` - -> :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. - -### Testando o código de informação - -Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). -``` -$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo -$ ./getmininginfo -Full Response: { - "result": { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" - }, - "error": null, - "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" -} - -Just the Result: { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" -} - -Block Count: 1804406 -``` - -## Fazendo uma chamada RPC usando argumentos - -Mas e se a sua chamada RPC tiver argumentos? - -### Criando uma matriz JSON - -Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. - -Vamos criar a matriz JSON usando a função ``json_array do`` do ``jansson``: -``` c -json_t *params = NULL; -params = json_array(); -``` -Vamos fazer o processo inverso que fizemos para acessar valores do JSON: Vamos converter objetos no C para objetos no JSON usando as funções ``JSON_*``. Depois, vamos anexar tudo à matriz: -``` c -json_array_append_new(params,json_string(tx_rawhex)); -``` - -Observe que existem duas variantes para o comando de anexação: ``json_array_apend_new``, que acrescenta uma variável recém-criada, e ``json_array_apend``, que anexa uma variável existente. - -Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. - -### Atribuindo os parâmetros - -Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: -``` c -bitcoinrpc_method_set_params(rpc_method, params) -``` -Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. - -## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC - -Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. - -* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. - -## O Que Vem Depois? - -Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). diff --git a/pt/15_2_Programming_Bitcoind_with_C.md b/pt/15_2_Programming_Bitcoind_with_C.md deleted file mode 100644 index c1fdc38..0000000 --- a/pt/15_2_Programming_Bitcoind_with_C.md +++ /dev/null @@ -1,354 +0,0 @@ - -# 15.2: Programando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. - -## Planejando o código - -Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: - - 1. Solicitar um endereço e uma quantia; - 2. Definir uma taxa arbitrária; - 3. Preparar nosso RPC; - 4. Encontrar um UTXO que seja grande o suficiente para pagar o valor + a taxa; - 5. Criar uma mudança de endereço; - 6. Criar uma transação bruta que envie o UTXO para o endereço e altere o endereço; - 7. Assinar a transação; - 8. Enviar a transação. - -### Planejando para o futuro - -Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: - - 1. Testar e/ou higienizar as entradas; - 2. Calcular uma taxa automaticamente; - 3. Pensar logicamente sobre qual UTXO seria válido utilizar; - 4. Combinar vários UTXOs, caso seja necessário; - 5. Ficar atento a mais erros nos comandos ``libbitcoinrpc`` ou no ``jansson``; - 6. Observar se há erros nas respostas RPC. - -Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. - -## Escrevendo o sistema de transação - -Agora estamos prontos para realizar o passo a passo do nosso plano - -### Etapa 1: Solicitando um endereço e uma quantia - -Inserir as informações é bem simples se usarmos os argumentos na linha de comando: -``` c -if(argc != 3) { - - printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); - exit(-1); - -} - -char *tx_recipient = argv[1]; -float tx_amount = atof(argv[2]); - -printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); -``` - -> :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. - -### Etapa 2: Definindo uma taxa arbitrária - -Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: - -``` c -float tx_fee = 0.0005; -float tx_total = tx_amount + tx_fee; -``` - -> :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. - -### Etapa 3: Preparando nosso RPC - -Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: -``` c -bitcoinrpc_global_init(); -rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); -btcresponse = bitcoinrpc_resp_init(); -``` - -### Etapa 4: Encontrando um UTXO - -Para encontrar um UTXO, precisaremos chamar a função RPC ``listunspent``: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -``` - -No entanto, o verdadeiro trabalho consiste em decodificar a resposta. Na seção anterior vimos que a biblioteca ``jansson`` era "um tanto quanto desajeitada" e esta é a razão: Precisamos criar (e limpar) um conjunto muito grande de objetos ``json_t`` para descobrir o que queremos. - -Primeiro, precisamos nos recuperar o campo ``result`` do JSON: -``` c -json_t *lu_response = NULL; -json_t *lu_result = NULL; - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -``` - -> :warning: **ATENÇÃO:** Só obteremos um resultado se não houver nenhum erro. Aqui temos um momento para melhorar nossa verificação de erros no código que iremos colocar em produção. - -Em seguida, vamos fazer um laço, examinando cada transação que não foi gasta, que aparece como um elemento em sua matriz do resultado JSON: -``` c -int i; - -const char *tx_id = 0; -int tx_vout = 0; -double tx_value = 0.0; - -for(i = 0 ; i < json_array_size(lu_result) ; i++) { - - json_t *lu_data = NULL; - lu_data = json_array_get(lu_result, i); - - json_t *lu_value = NULL; - lu_value = json_object_get(lu_data,"amount"); - tx_value = json_real_value(lu_value); -``` - -O UTXO é grande o suficiente para pagar sua transação? Se sim, pegue-o! - -> :warning: **ATENÇÃO:** Um programa em produção pensaria com mais cuidado sobre qual UTXO utilizar, com base no tamanho e em outros fatores. Provavelmente não pegaria apenas o primeiro mais simples e pronto. - -``` c - if(tx_value > tx_total) { - - json_t *lu_txid = NULL; - lu_txid = json_object_get(lu_data,"txid"); - tx_id = strdup(json_string_value(lu_txid)); - - json_t *lu_vout = NULL; - lu_vout = json_object_get(lu_data,"vout"); - tx_vout = json_integer_value(lu_vout); - - json_decref(lu_value); - json_decref(lu_txid); - json_decref(lu_vout); - json_decref(lu_data); - break; - - } -``` -Você também deve limpar os principais elementos do JSON: -``` c -} - -json_decref(lu_result); -json_decref(lu_response); -``` - -> :warning: **ATENÇÃO:** Um programa em produção também se certificaria de que os UTXOs são passíveis de serem `gastos`. - -Se não encontramos nenhum UTXOs grande o suficiente, teremos que relatar este infortúnio ao usuário... E talvez, sugerir que ele deva usar um programa melhor, que irá mesclar os UTXOs de maneira correta. -``` c -if(!tx_id) { - - printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); - exit(-1); -} -``` - -> **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. - -### Etapa 5: Criando um endereço de troco - -Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); - -if(!rpc_method) { - - printf("ERROR: Unable to initialize listunspent method!\n"); - exit(-1); - -} - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -if(btcerror.code != BITCOINRPCE_OK) { - -printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); - - exit(-1); - -} - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -char *changeaddress = strdup(json_string_value(lu_result)); -``` -A única diferença é quais informações específicas são extraídas do objeto JSON. - -> :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. - -### Etapa 6: Criando uma transação bruta - -Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. - -Para criarmos esses parâmetros corretamente, precisaremos revisar o que o RPC ``createrawtransaction`` espera que passemos como argumento. Felizmente, isso é fácil de determinar usando a funcionalidade ``bitcoin-cli help``: -``` -$ bitcoin-cli help createrawtransaction -createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) -``` - -Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. - -#### Etapa 6.1: Criando os parâmetros de entrada - -Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): -``` c -json_t *inputtxid = NULL; -inputtxid = json_object(); - -json_object_set_new(inputtxid,"txid",json_string(tx_id)); -json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); -``` - -Pode-se notar que teremos que traduzir novamente cada tipo de variável C em um tipo de variável JSON usando a função apropriada, como ``json_string`` ou ``json_integer``. - -Para criar o array de entrada para todos os UTXOs, vamos usar o ``json_array`` e, em seguida, preenchê-lo com os objetos usando o ``json_array_append``: -``` c -json_t *inputparams = NULL; -inputparams = json_array(); -json_array_append(inputparams,inputtxid); -``` - -#### Etapa 6.2: Criando os parâmetros de saída - -Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: -``` c -json_t *outputparams = NULL; -outputparams = json_object(); - -char tx_amount_string[32]; -sprintf(tx_amount_string,"%.8f",tx_amount); -char tx_change_string[32]; -sprintf(tx_change_string,"%.8f",tx_value - tx_total); - -json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); -json_object_set(outputparams, changeaddress, json_string(tx_change_string)); -``` - -> :warning: **ATENÇÃO:** É possível pensar que teremos que inserir os valores do Bitcoin como sendo números, usando a função ``json_real``. Infelizmente, isso expõe um dos maiores problemas com a integração da biblioteca ``jansson`` e o Bitcoin. O Bitcoin só é válido até oito dígitos depois da casa decimal. Devemos nos lembrar que 0,00000001 BTC é um satoshi, e essa é a menor divisão possível de um Bitcoin. O tipo ``double`` no C oferecem mais dígitos do que precisamos, embora sejam frequentemente imprecisos depois das oito casas decimais. Se tentarmos convertê-los diretamente do nosso valor ``double`` no C (ou de um tipo ``float``, neste caso) para um valor Bitcoin, a imprecisão frequentemente criará um valor Bitcoin com mais de oito dígitos. Antes da versão Bitcoin Core 0.12, isso não era problema, e podíamos usar a função ``json_real``. Mas à partir dessa versão, se tentarmos usar a função ``createrawtransaction`` com mais do que oito dígitos, obteremos um erro e a transação não será criada. Como resultado, se o valor do Bitcoin _sempre_ se tornar um ``double`` ou ``float``, devemos deixar com apenas oito casas decimais antes de transformá-lo em uma ``string``. Obviamente, isso é um erro, portanto, certifique-se disso para que o código continue funcionando nas versões mais novas do Bitcoin Core. - -#### Etapa 6.3: Criando a Matriz de Parâmetros - -Para terminarmos de criar os parâmetros, só precisaremos agrupá-los em uma matriz JSON: -``` c -json_t *params = NULL; -params = json_array(); -json_array_append(params,inputparams); -json_array_append(params,outputparams); -``` - -#### Etapa 6.4: Fazendo a chamada ao RPC - -Vamos usar o método normal para criar uma chamada ao RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); -``` -Agora, porém, devemos adicionar os nossos parâmetros. Isso pode ser feito facilmente com a função ``bitcoinrpc_method_set_params``: -``` c -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for createrawtransaction"); - -} -``` -Depois, é só executar o RPC e obter os resultados: -``` c -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_rawhex = strdup(json_string_value(lu_result)); -``` -### Etapa 7. Assinando a transação - -É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_rawhex)); -``` -Por fim, vamos assinar a transação seguindo o rigamarole típico para criar uma chamada RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for signrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -``` -Novamente, usar a função ``jansson`` para acessar a saída pode ser complicado. Devemos lembrar que ``hex`` é parte de um objeto JSON, não um resultado independente, como era quando criamos a transação bruta. Claro, sempre podemos acessar essas informações a partir da ajuda da linha de comando: ``bitcoin-cli help signrawtransaction`` -``` c -lu_result = json_object_get(lu_response,"result"); -json_t *lu_signature = json_object_get(lu_result,"hex"); -char *tx_signrawhex = strdup(json_string_value(lu_signature)); -json_decref(lu_signature); -``` -> :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. - -### Etapa 8. Enviando a transação - -Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_signrawhex)); - -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); - -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for sendrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_newid = strdup(json_string_value(lu_result)); - -printf("Txid: %s\n",tx_newid); -``` - -O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. - -## Testando o código - -O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). - -Compile-o como de costume: -``` -$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress -``` -Agora, é possível utilizá-lo para enviar fundos para um endereço: - -``` -./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 -Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 -``` -Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). - -## Resumo do Programando o Bitcoind usando C com bibliotecas RPC - -Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. - -## O Que Vem Depois? - -Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md deleted file mode 100644 index fe166ac..0000000 --- a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md +++ /dev/null @@ -1,155 +0,0 @@ - -# 15.3 Recebendo notificações usando C com a biblioteca ZMQ - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. - -> :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). - -## Configurando o ZMQ - -Antes de podemos ouvir a blockchain, precisaremos configurar o ``bitcoind`` para permitir as notificações ZMQ. Por isso, precisamos instalar a biblioteca ZMQ para tirar proveito dessas notificações. - -### Configurando o ``bitcoind`` para usar o ZMQ - -O Bitcoin Core está pronto para ZMQ, mas devemos especificar os endpoints do ZMQ. O ZeroMQ publish-sockets prefixa cada item de dados com um prefixo de tópico arbitrário que permite aos clientes assinantes solicitarem apenas os itens com um prefixo correspondente. Existem atualmente quatro tópicos suportados pelo ``bitcoind``: -``` -$ bitcoind --help | grep zmq | grep address - -zmqpubhashblock=
- -zmqpubhashtx=
- -zmqpubrawblock=
- -zmqpubrawtx=
-``` - -Podemos executar o ``bitcoind`` com argumentos de linha de comando para endpoints ZMQ, como mostrado acima, mas também podemos criar um endpoint acessível adicionando linhas apropriadas ao nosso arquivo ``~/.bitcoin/bitcoin.conf`` e reiniciando o sistema. - -``` -zmqpubrawblock=tcp://127.0.0.1:28332 -zmqpubrawtx=tcp://127.0.0.1:28333 -``` -Podemos então testar se os nossos endpoints estão funcionando usando o RPC ``getzmqnotifications``: - -``` -$ bitcoin-cli getzmqnotifications -[ - { - "type": "pubrawblock", - "address": "tcp://127.0.0.1:28332", - "hwm": 1000 - }, - { - "type": "pubrawtx", - "address": "tcp://127.0.0.1:28333", - "hwm": 1000 - } -] -``` -Nosso ``bitcoind`` agora irá emitir as notificações ZMQ - -### Instalando o ZMQ - -Para aproveitar essas notificações, precisamos de uma biblioteca ZMQ para usar com o C, portanto, estaremos usando uma nova biblioteca ZMQ ao invés da biblioteca ``libbitcoinrpc`` nesta seção, mas no futuro, podemos combinar ambas. - -Felizmente, as bibliotecas ZMQ estão disponíveis por meio de pacotes Debian padrão: -``` -$ sudo apt-get install libzmq3-dev -$ sudo apt-get install libczmq-dev -``` -Agora estamos pronto para escrever o código! - -## Escrevendo o programa de notificação - -O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. - -O programa requer dois parâmetros: O primeiro é o "servidor", que é o ponto de conexão TCP exposto pelo ``bitcoind``. O segundo é o "tópico", que atualmente é o ``zmqpubhashblock``,``zmqpubhashtx``, ``zmqpubrawblock`` ou ``zmqpubrawtx``. O tópico precisa ter suporte do ``bitcoin.conf`` e o endereço IP e a porta do servidor devem corresponder ao que está definido no arquivo de configuração. - -``` c -#include -int main(int argc, char ** argv) { - - char *zmqserver; - char *topic; - - if(argc < 3) { - printf("\nUSAGE:\nchainlistener \n\n"); - return 0; - } else { - zmqserver = argv[1]; - topic = argv[2]; - } -``` -Abriremos um soquete ZMQ para o servidor e para o tópico definido: -``` c - zsock_t *socket = zsock_new_sub(zmqserver, topic); - assert(socket); -``` -Depois, vamos esperar: -``` c - while(1) { - zmsg_t *msg; - int rc = zsock_recv(socket, "m", &msg); - assert(rc == 0); - - char *header = zmsg_popstr(msg); - zframe_t *zdata = zmsg_pop(msg); - unsigned int *no = (unsigned int*)zmsg_popstr(msg); - - char *data = zframe_strhex(zdata); - int len = zframe_size(zdata); - printf("Size: %d\n", len); - printf("Data: %s", data); - printf("\nNo: %d\n", *no); - - free(header); - free(data); - free(no); - free(zdata); - zmsg_destroy(&msg); - sleep(1); - } -``` -Enquanto esperamos, observamos as mensagens no soquete ZMQ. Sempre que recebermos uma mensagem, iremos retirá-la da pilha, relatando o número, comprimento e, o os dados que foram importante para nós. - -É isso! - -Claro, quando terminar o processo, precisamos limpar tudo: -``` c - zsock_destroy(&socket); - return 0; -} -``` - -### Testando o código de notificação - -O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: -``` -$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq -``` -Depois, podemos executá-lo com os tópicos e endereços que definimos no nosso ``bitcoin.conf``: -``` -$ ./chainlistener tcp://127.0.0.1:28333 rawtx -Size: 250 -Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 -No: 67 -Size: 249 -Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 -No: 68 -Size: 250 -Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 -No: 69 -Size: 250 -Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 -No: 70 -....... -``` - -### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ - -Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. - -> :fire: ***Qual é o poder das notificações?*** Com as notificações, não dependemos mais dos usuários para emitir os comandos. Ou seja, podemos criar programas que monitoram o blockchain do Bitcoin e tomar as ações apropriadas quando certas coisas ocorrem. Isso, por sua vez, pode ser utilizado juntamente com os comandos RPC que programamos nas seções anteriores. Este também é um grande passo além do que poderíamos fazer com os scripts shell: Certamente, podemos criar scripts shell que fica ouvindo infinitamente, mas existem outras linguagens de programação que possuem ferramentas melhores para isso. - -## O Que Vem Depois? - -Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file From 46d385810e3fb9f8efec9f457963623b48b269b3 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 09:55:33 -0300 Subject: [PATCH 092/155] Rename files chapter 17 to 18 --- ...ing_to_Bitcoind_Other.md => 18_0_Talking_to_Bitcoind_Other.md} | 0 ...ing_Bitcoind_with_Go.md => 18_1_Accessing_Bitcoind_with_Go.md} | 0 ...Bitcoind_with_Java.md => 18_2_Accessing_Bitcoind_with_Java.md} | 0 ...oind_with_NodeJS.md => 18_3_Accessing_Bitcoind_with_NodeJS.md} | 0 ...oind_with_Python.md => 18_4_Accessing_Bitcoind_with_Python.md} | 0 ...Bitcoind_with_Rust.md => 18_5_Accessing_Bitcoind_with_Rust.md} | 0 ...tcoind_with_Swift.md => 18_6_Accessing_Bitcoind_with_Swift.md} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename pt/{17_0_Talking_to_Bitcoind_Other.md => 18_0_Talking_to_Bitcoind_Other.md} (100%) rename pt/{17_1_Accessing_Bitcoind_with_Go.md => 18_1_Accessing_Bitcoind_with_Go.md} (100%) rename pt/{17_2_Accessing_Bitcoind_with_Java.md => 18_2_Accessing_Bitcoind_with_Java.md} (100%) rename pt/{17_3_Accessing_Bitcoind_with_NodeJS.md => 18_3_Accessing_Bitcoind_with_NodeJS.md} (100%) rename pt/{17_4_Accessing_Bitcoind_with_Python.md => 18_4_Accessing_Bitcoind_with_Python.md} (100%) rename pt/{17_5_Accessing_Bitcoind_with_Rust.md => 18_5_Accessing_Bitcoind_with_Rust.md} (100%) rename pt/{17_6_Accessing_Bitcoind_with_Swift.md => 18_6_Accessing_Bitcoind_with_Swift.md} (100%) diff --git a/pt/17_0_Talking_to_Bitcoind_Other.md b/pt/18_0_Talking_to_Bitcoind_Other.md similarity index 100% rename from pt/17_0_Talking_to_Bitcoind_Other.md rename to pt/18_0_Talking_to_Bitcoind_Other.md diff --git a/pt/17_1_Accessing_Bitcoind_with_Go.md b/pt/18_1_Accessing_Bitcoind_with_Go.md similarity index 100% rename from pt/17_1_Accessing_Bitcoind_with_Go.md rename to pt/18_1_Accessing_Bitcoind_with_Go.md diff --git a/pt/17_2_Accessing_Bitcoind_with_Java.md b/pt/18_2_Accessing_Bitcoind_with_Java.md similarity index 100% rename from pt/17_2_Accessing_Bitcoind_with_Java.md rename to pt/18_2_Accessing_Bitcoind_with_Java.md diff --git a/pt/17_3_Accessing_Bitcoind_with_NodeJS.md b/pt/18_3_Accessing_Bitcoind_with_NodeJS.md similarity index 100% rename from pt/17_3_Accessing_Bitcoind_with_NodeJS.md rename to pt/18_3_Accessing_Bitcoind_with_NodeJS.md diff --git a/pt/17_4_Accessing_Bitcoind_with_Python.md b/pt/18_4_Accessing_Bitcoind_with_Python.md similarity index 100% rename from pt/17_4_Accessing_Bitcoind_with_Python.md rename to pt/18_4_Accessing_Bitcoind_with_Python.md diff --git a/pt/17_5_Accessing_Bitcoind_with_Rust.md b/pt/18_5_Accessing_Bitcoind_with_Rust.md similarity index 100% rename from pt/17_5_Accessing_Bitcoind_with_Rust.md rename to pt/18_5_Accessing_Bitcoind_with_Rust.md diff --git a/pt/17_6_Accessing_Bitcoind_with_Swift.md b/pt/18_6_Accessing_Bitcoind_with_Swift.md similarity index 100% rename from pt/17_6_Accessing_Bitcoind_with_Swift.md rename to pt/18_6_Accessing_Bitcoind_with_Swift.md From 4df18c9aa169155bf5ac8c8b55e475c7a4b0ab41 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 09:59:45 -0300 Subject: [PATCH 093/155] Review 18_0 --- pt/18_0_Talking_to_Bitcoind_Other.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pt/18_0_Talking_to_Bitcoind_Other.md b/pt/18_0_Talking_to_Bitcoind_Other.md index 60de440..5e09e8f 100644 --- a/pt/18_0_Talking_to_Bitcoind_Other.md +++ b/pt/18_0_Talking_to_Bitcoind_Other.md @@ -1,26 +1,26 @@ -# Capítulo 17: Conversando com o Bitcoind com Outras Linguagens +# Capítulo 18: Conversando com o Bitcoind com Outras Linguagens -Agora devemos ter uma base sólida para trabalhar com Bitcoin usando a linguagem C, não apenas usando as bibliotecas RPC, JSON e ZMQ para interagir diretamente com o `bitcoind`, mas também, utilizando as bibliotecas Libwally para complementar esse trabalho. O C é uma ótima linguagem para prototipagem e abstração, porém provavelmente não é o que estamos usando para programar. Este capítulo, portanto, faz uma apresentação rápida por seis outras linguagens de programação, demonstrando a funcionalidade mais básica do Bitcoin em cada uma, permitindo que possamos expandir as lições da linha de comando e do C para a linguagem de programação que desejarmos escolha. +Agora devemos ter uma base sólida para trabalhar com Bitcoin usando a linguagem C, não apenas usando as bibliotecas RPC, JSON e ZMQ para interagir diretamente com o `bitcoind`, mas também, utilizando as bibliotecas Libwally para complementar esse trabalho. O C é uma ótima linguagem para prototipagem e abstração, porém provavelmente não é o que estamos usando para programar. Este capítulo, portanto, faz uma apresentação rápida de seis outras linguagens de programação, demonstrando a funcionalidade mais básica do Bitcoin em cada uma, permitindo que possamos expandir as lições da linha de comando e do C para a linguagem de programação que desejarmos. -Cada uma das seções contém aproximadamente as mesmas informações, o foco será: Criar uma conexão RPC, examinar a carteira, criando um novo endereço e criar uma transação. No entanto, há alguma mudança entre as linguagens, mostrando diferentes aspectos dos comandos RPC do Bitcoin em diferentes exemplos. Em particular, algumas linguagens usam a metodologia fácil do `sendtoaddress`, enquanto outras usam uma metodologia mais difícil para a criação de uma transação bruta do zero. +Cada uma das seções contém aproximadamente as mesmas informações, o foco será: criar uma conexão RPC, examinar a carteira, criar um novo endereço e criar uma transação. No entanto, há alguma mudança entre as linguagens, mostrando diferentes aspectos dos comandos RPC do Bitcoin em diferentes exemplos. Em particular, algumas linguagens usam a metodologia fácil do `sendtoaddress`, enquanto outras usam uma metodologia mais difícil para a criação de uma transação bruta do zero. -## Objetivos deste capítulo +## Objetivos Deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: * Preparar ambientes de desenvolvimento para o Bitcoin para uma variedade de linguagens; - * Usar as funções da carteira em várias linguagens; + * Usar as funções de carteira em várias linguagens; * Usar funções de transação em uma variedade de linguagens. Os objetivos secundários do capítulo incluem a capacidade de: - * Saiber mais sobre o Bitcoin RPC por meio de interações com uma variedade de linguagens. + * Saber mais sobre o Bitcoin RPC por meio de interações com uma variedade de linguagens. ## Tabela de Conteúdo - * [Seção 1: Acessando o Bitcoind com Go](17_1_Accessing_Bitcoind_with_Go.md) - * [Seção 2: Acessando o Bitcoind com Java](17_2_Accessing_Bitcoind_with_Java.md) - * [Seção 3: Acessando o Bitcoind com NodeJS](17_3_Accessing_Bitcoind_with_NodeJS.md) - * [Seção 4: Acessando o Bitcoind com Python](17_4_Accessing_Bitcoind_with_Python.md) - * [Seção 5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md) - * [Seção 6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md) \ No newline at end of file + * [Seção 1: Acessando o Bitcoind com Go](18_1_Accessing_Bitcoind_with_Go.md) + * [Seção 2: Acessando o Bitcoind com Java](18_2_Accessing_Bitcoind_with_Java.md) + * [Seção 3: Acessando o Bitcoind com NodeJS](18_3_Accessing_Bitcoind_with_NodeJS.md) + * [Seção 4: Acessando o Bitcoind com Python](18_4_Accessing_Bitcoind_with_Python.md) + * [Seção 5: Acessando o Bitcoind com Rust](18_5_Accessing_Bitcoind_with_Rust.md) + * [Seção 6: Acessando o Bitcoind com Swift](18_6_Accessing_Bitcoind_with_Swift.md) \ No newline at end of file From 1be8fd84535577e30e6ceaa6f3ae110d4058606b Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 10:14:29 -0300 Subject: [PATCH 094/155] Review 18_1 --- pt/18_1_Accessing_Bitcoind_with_Go.md | 71 +++++++++++++-------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/pt/18_1_Accessing_Bitcoind_with_Go.md b/pt/18_1_Accessing_Bitcoind_with_Go.md index d42f925..76d5f64 100644 --- a/pt/18_1_Accessing_Bitcoind_with_Go.md +++ b/pt/18_1_Accessing_Bitcoind_with_Go.md @@ -1,4 +1,4 @@ -# 17.1: Acessando o Bitcoind com Go +# 18.1: Acessando o Bitcoind com Go > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -12,7 +12,7 @@ Para nos preparamos para o uso do Go em nossa máquina UNIX, primeiro precisamos $ sudo apt install curl ``` -Então, vamos ler a [página de downloads do Go](https://golang.org/dl/), para obtermos o link para o download mais recente e posteriormente fazer o download usando `curl`. Para uma configuração Debian, vamos querer usar a versão `linux-amd64`: +Então, vamos ler a [página de downloads do Go](https://golang.org/dl/) para obtermos o link para o download mais recente e posteriormente fazer o download usando `curl`. Para uma configuração Debian, vamos querer usar a versão `linux-amd64`: ``` $ curl -O https://dl.google.com/go/go1.15.1.linux-amd64.tar.gz @@ -31,7 +31,7 @@ $ sudo chown -R root:root ./go $ sudo mv go /usr/local ``` -Agora precisamos criar um caminho no Go para especificar nosso ambiente. Abra o arquivo `~ / .profile` com o editor de texto mais utilizado por nós e vamos escolher e adicionar o seguinte ao final dele: +Agora precisamos criar um caminho no Go para especificar nosso ambiente. Abra o arquivo `~ / .profile` com o editor de texto de sua escolha e adicione o seguinte ao final dele: ``` export GOPATH=$HOME/work @@ -86,7 +86,7 @@ Devemos ver a contagem de blocos impressa: 2020/09/01 11:41:24 Block count: 1830861 ``` -### Criando um projeto `rpcclient` +### Criando um Projeto `rpcclient` Normalmente, iríamos criar projetos no diretório `~/work/src/myproject/bitcoin`: ``` @@ -101,13 +101,13 @@ import ( "github.com/btcsuite/btcd/rpcclient" ) ``` -Esta declaração `import` permite que importemos bibliotecas relevantes. Para cada exemplo aqui, precisaremos importar `"log","fmt"` e `"github.com/btcsuite/btcd/rpcclient"`. Podemos precisar importar bibliotecas adicionais em alguns exemplos. +Esta declaração `import` permite que importemos bibliotecas relevantes. Para cada exemplo aqui, precisaremos importar `"log", "fmt"` e `"github.com/btcsuite/btcd/rpcclient"`. Podemos precisar importar bibliotecas adicionais em alguns exemplos. * O `log` é usado para mostrar mensagens de erro na tela. Após cada vez que o node Bitcoin for chamado, uma instrução `if` irá verificar se há algum erro. Se houver erros, o `log` é usado para imprimi-los; * O `fmt` é usado para imprimir a saída; * O `rpcclient` é obviamente a biblioteca do `rpcclient`; -## Construindo nossa conexão +## Construindo Nossa Conexão Cada função do `bitcoind` no Go começa com a criação da conexão RPC, usando a função `ConnConfig`: ``` @@ -126,15 +126,15 @@ Cada função do `bitcoind` no Go começa com a criação da conexão RPC, usand ``` Os parâmetros da `connCfg` permitem que escolhamos a porta Bitcoin RPC, nome de usuário, senha e se estamos usando a testnet ou mainnet. -> **NOTA:** Novamente, precisamos nos certificar de substituir o `User` e o `Pass` com aquele encontrado no nosso `~/.bitcoin/bitcon.conf`. +> **NOTA:** Novamente, precisamos nos certificar de substituir o `User` e o `Pass` com aqueles encontrados no nosso `~/.bitcoin/bitcon.conf`. -A função `rpcclient.New(connCfg, nil)` configura o`client` para nos conectarmos ao nosso node de Bitcoin. +A função `rpcclient.New(connCfg, nil)` configura o`client` para nos conectarmos ao nosso node Bitcoin. -A linha `defer client.Shutdown()` é para desconectar do nosso node Bitcoin, uma vez que a função `main()` termina de ser executada. Após a linha `defer client.Shutdown()` é onde as coisas interessantes acontecem, e será muito fácil de utilizar. Isso porque o `rpcclient` ajuda a transformar os comandos `bitcoin-cli` em funções, usando PascalCase. Por exemplo, `bitcoin-cli getblockcount` se transformará em `client.GetBlockCount` no Go. +A linha `defer client.Shutdown()` é para desconectar do nosso node Bitcoin, uma vez que a função `main()` termina de ser executada. Após a linha `defer client.Shutdown()` é onde as coisas interessantes acontecem –– e será muito fácil de utilizar. Isso porque o `rpcclient` ajuda a transformar os comandos `bitcoin-cli` em funções, usando PascalCase. Por exemplo, `bitcoin-cli getblockcount` se transformará em `client.GetBlockCount` no Go. -### Fazendo uma chamada RPC +### Fazendo uma Chamada RPC -Agora, tudo o que é necessário é fazer uma chamada informativa como `GetBlockCount` ou` GetBlockHash` usando nosso `client`: +Agora, tudo o que precisamos fazer é uma chamada informativa como `GetBlockCount` ou` GetBlockHash` usando nosso `client`: ``` blockCount, err := client.GetBlockCount() if err != nil { @@ -149,7 +149,7 @@ Agora, tudo o que é necessário é fazer uma chamada informativa como `GetBlock fmt.Printf("%s\n", blockHash.String()) ``` -### Fazendo uma chamada RPC com argumentos +### Fazendo uma Chamada RPC com Argumentos As funções `rpcclient` também podem receber entradas, por exemplo, `client.GetBlockHash(blockCount)` recebe a contagem de blocos como uma entrada. O `client.GetBlockHash (blockCount)` de cima seria parecido com um comando `bitcoin-cli`: ``` @@ -158,9 +158,9 @@ $ bitcoin-cli getblockhash 1830868 ``` No entanto, uma peculiaridade com hashes no `rpcclient` é que normalmente eles irão ser mostrados em uma codificação diferente se imprimirmos normalmente com o ` blockHash`. Para imprimi-los como uma string, precisamos usar o `blockHash.String()`. -### Executando nosso código +### Executando Nosso Código -Podemos baixar o código completo do [diretório src](src / 17_1_blockinfo.go). +Podemos baixar o código completo do [diretório src](src/18_1_blockinfo.go). Podemos então, executar: ``` @@ -169,11 +169,11 @@ $ go run blockinfo.go 00000000000002d53b6b9bba4d4e7dc44a79cebd1024d1bcfb9b3cc07d6cad9c ``` -O último número do bloco junto com nosso hash deve ser impresso. +O último número do bloco, junto com nosso hash, devem ser impressos. -## Pesquisando os fundos +## Procurando por Fundos -Devido às limitações do `btcd` no `rpcclient`, não pode fazer o uso da função `getwalletinfo`. No entanto, podemos usar o RPC `getbalance`: +Devido às limitações do `btcd` no `rpcclient`, não podemos fazer uso da função `getwalletinfo`. No entanto, podemos usar o RPC `getbalance`: ``` wallet, err := client.GetBalance("*") @@ -183,22 +183,21 @@ Devido às limitações do `btcd` no `rpcclient`, não pode fazer o uso da funç fmt.Println(wallet) ``` -O `client.GetBalance("*")` requer a entrada `"*"`, devido a uma peculiaridade do `btcd`. O asterisco significa que desejamos obter o saldo de todas as nossas carteiras. +O `client.GetBalance("*")` requer a entrada `"*"` devido a uma peculiaridade do `btcd`. O asterisco significa que desejamos obter o saldo de todas as nossas carteiras. -Se executarmos [o código src](src / 17_1_getbalance.go), deveremos obter uma saída semelhante a esta: +Se executarmos [o código src](src/18_1_getbalance.go), deveremos obter uma saída semelhante a esta: ``` $ go run getbalance.go 0.000689 BTC ``` -## Criando um endereço +## Criando um Endereço Podemos gerar endereços em Go, mas não podemos especificar o tipo do endereço: Isso requer o uso de uma função especial `chaincfg`, para especificar para qual rede os endereços estão sendo criados. Esta especificação é necessária apenas durante a geração do endereço, por isso é usada apenas neste exemplo. Também podemos incluir isso nos demais exemplos, mas não é necessário. -Be sure to import ```"github.com/btcsuite/btcd/chaincfg"```: -Vamos nos certificar de importar o `"github.com/btcsuite/btcd/chaincfg"`: +Certifique-se de importar o `"github.com/btcsuite/btcd/chaincfg"`: ``` import ( "log" @@ -235,20 +234,20 @@ Podemos então criar nosso endereço: ``` Uma peculiaridade com o `client.GetNewAddress("")` é que uma string vazia precisa ser incluída para que tudo funcione perfeitamente. -Executando o [the source](17_1_getaddress.go) teremos os seguintes resultados: +Executando o [código fonte](18_1_getaddress.go) teremos os seguintes resultados: ``` $ go run getaddress.go tb1qutkcj34pw0aq7n9wgp3ktmz780szlycwddfmza ``` -### Decodificando um endereço +### Decodificando um Endereço -Criando um endereço exigia um trabalho extra, ao especificar a blockchain correta. Usar um endereço também funcionará, porque teremos que decodificá-lo antes de usá-lo. +Criar um endereço exigia um trabalho extra, em especificar a blockchain correta. Usar um endereço também exigirá, porque teremos que decodificá-lo antes de usá-lo. Isso significa que teremos que importar as bibliotecas `"github.com/btcsuite/btcutil"` e `"github.com/btcsuite/btcd/chaincfg"`. * O `btcutil` permite que um endereço Bitcoin seja decodificado de uma forma que o `rpcclient` possa entender. Isso é necessário ao trabalhar com endereços no `rpcclient`; - * O `chaincfg` é (novamente) usado para configurar nossa cadeia como a cadeia Testnet. Isso é necessário para a decodificação de endereços, pois os endereços usados na Mainnet e na Testnet são diferentes. + * O `chaincfg` é (novamente) usado para configurar nossa chain como a chain Testnet. Isso é necessário para a decodificação de endereços, pois os endereços usados na Mainnet e na Testnet são diferentes. ``` import ( @@ -259,7 +258,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" ) ``` -A variável defaultNet agora é usada para especificar se nosso node do Bitcoin que está na Testnet ou na Mainnet. Essa informação (e o objeto `btcutil`) é então usado para decodificar o endereço. +A variável defaultNet agora é usada para especificar se nosso node Bitcoin está na Testnet ou na Mainnet. Essa informação (e o objeto `btcutil`) é então usada para decodificar o endereço. > **MAINNET VS TESTNET:** `&chaincfg.TestNet3Params` deve ser `& chaincfg.MainNetParams` na Mainnet. @@ -271,9 +270,9 @@ A variável defaultNet agora é usada para especificar se nosso node do Bitcoin } ``` -> **NOTA:** Precisamos alterar o endereço (`mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha`) para um que seja da nossa carteira. Podemos usar o `bitcoin-cli listunspent` para encontrar alguns endereços com fundos para o teste. Se quisermos ser realmente sofisticados, podemos modificar o código Go para obter um argumento e, em seguida, escrever um script que executa o `listunspent`, para depois salvarmos a informação em uma variável e executar o código Go nela. +> **NOTA:** Precisamos alterar o endereço (`mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha`) para um que seja da nossa carteira. Podemos usar o `bitcoin-cli listunspent` para encontrar alguns endereços com fundos para teste. Se quisermos ser realmente sofisticados, podemos modificar o código Go para obter um argumento e, em seguida, escrever um script que executa o `listunspent`, para depois salvarmos a informação em uma variável e executar o código Go nela. -Só depois disso usamos o RPC `getreceivedbyaddress`, no nosso endereço decodificado: +Só depois disso usamos o RPC `getreceivedbyaddress` no nosso endereço decodificado: ``` wallet, err := client.GetReceivedByAddress(addr) if err != nil { @@ -282,20 +281,20 @@ Só depois disso usamos o RPC `getreceivedbyaddress`, no nosso endereço decodif fmt.Println(wallet) ``` -Ao executar [o código](src/17_1_getamountreceived.go), devemos obter uma saída semelhante a esta: +Ao executar [o código](src/18_1_getamountreceived.go), devemos obter uma saída semelhante a esta: ``` $ go run getamountreceived.go 0.0085 BTC ``` -## Enviando uma transação +## Enviando uma Transação Agora temos todas as peças do quebra-cabeça no lugar para enviar uma transação. Vamos querer: 1. Importar as bibliotecas corretas, incluindo a `chaincfg` para especificar uma rede e o `btcutil` para decodificar um endereço; 2. Escolher um endereço para enviar; 3. Decodificar esse endereço; -4. Executar o `sendtoaddress` para enviar fundos da maneira mais fácil. +4. Executar o `sendtoaddress` para enviar fundos da maneira fácil. ``` package main @@ -334,14 +333,14 @@ func main() { fmt.Println(sent) } ``` -Quando executamos [o código](src/17_1_sendtransaction.go), o txid da transação nos será retornado: +Quando executamos [o código](src/18_1_sendtransaction.go), o txid da transação nos será retornado: ``` $ go run sendtransaction.go 9aa4cd6559e0d69059eae142c35bfe78b71a8084e1fcc2c74e2a9675e9e7489d ``` -### Pesquisando uma transação +### Consultando uma Transação Para consultar uma transação, como a que acabamos de enviar, precisaremos fazer mais uma vez algumas conversões, desta vez do txid. O `"github.com/btcsuite/btcd/chaincfg/chainhash"` é importado para permitir que os hashes sejam armazenados no código Go. O `chainhash.NewHashFromStr("hash")` converte um hash em uma string para um formato que funciona com o rpcclient. @@ -383,7 +382,7 @@ func main() { ``` > **NOTA:** Novamente, vamos querer trocar o txid por um que realmente será reconhecido pelo nosso sistema. -Ao executar [o código](src/17_1_lookuptransaction.go), ele imprimirá os detalhes associados a uma transação, como nosso valor e quantas vezes foi confirmado: +Ao executar [o código](src/18_1_lookuptransaction.go), ele imprimirá os detalhes associados a uma transação, como seu valor e quantas vezes foi confirmada: ``` $ go run lookuptransaction.go @@ -418,4 +417,4 @@ Embora o `btcd` e o `rpcclient` tenham alguns limites, ainda podemos executar os ## O Que Vem Depois? -Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.2: Acessando Bitcoin com Java](17_2_Accessing_Bitcoind_with_Java.md). \ No newline at end of file +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§18.2: Acessando Bitcoin com Java](18_2_Accessing_Bitcoind_with_Java.md). \ No newline at end of file From 7ab1c58a0a89bbf852befc4ea1752142278be82e Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 10:29:17 -0300 Subject: [PATCH 095/155] Review 18_2 --- pt/18_2_Accessing_Bitcoind_with_Java.md | 58 ++++++++++++------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/pt/18_2_Accessing_Bitcoind_with_Java.md b/pt/18_2_Accessing_Bitcoind_with_Java.md index 87e0c2e..7b01aad 100644 --- a/pt/18_2_Accessing_Bitcoind_with_Java.md +++ b/pt/18_2_Accessing_Bitcoind_with_Java.md @@ -1,4 +1,4 @@ -# 17.2: Acessando o Bitcoind com Java +# 18.2: Acessando o Bitcoind com Java > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -19,7 +19,7 @@ OpenJDK Runtime Environment (build 11.0.8+10-post-Debian-1deb10u1) OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Debian-1deb10u1, mixed mode, sharing) ``` -### Criando um projeto Maven +### Criando um Projeto Maven Para programar o Bitcoin usando o java, criaremos um projeto Maven: ``` @@ -57,7 +57,7 @@ Para incluir o `JavaBitcoindRpcClient`, devemos adicionar nossa dependência a ` 1.2.1 ``` -Também precisa adicionar propriedades do compilador para indicar qual versão do JDK compilará o código-fonte. +Também precisamos adicionar propriedades do compilador para indicar qual versão do JDK compilará o código-fonte. ``` @@ -68,7 +68,7 @@ Também precisa adicionar propriedades do compilador para indicar qual versão d ``` -Sempre que adicionarmos um código-fonte às nossas aulas, poderemos testá-lo com: +Sempre que adicionarmos um código-fonte às nossas classes, poderemos testá-lo com: ``` $ mvn compile ``` @@ -79,16 +79,16 @@ $ mvn exec:java -Dexec.mainClass=com.blockchaincommons.lbtc.App ### Criando Projetos Alternativos -Se usamos o [Gradle](https://gradle.org/releases/), podemos executar o seguinte comando: +Se usarmos o [Gradle](https://gradle.org/releases/), poderemos executar o seguinte comando: ```groovy compile 'wf.bitcoin:JavaBitcoindRpcClient:1.2.1' ``` -Se quisermos um projeto de amostra e algumas instruções sobre como executá-lo no servidor que acabamos de criar, podemos consultar o [Projeto de amostra do Bitcoind Java](https://github.com/brunocvcunha/bitcoind-java-client- amostra/). Também pode navegar por todo o código de origem do [bitcoin-rpc-client](https://github.com/Polve/bitcoin-rpc-client). +Se quisermos um projeto de amostra e algumas instruções sobre como executá-lo no servidor que acabamos de criar, podemos consultar o [Projeto de amostra do Bitcoind Java](https://github.com/bvolpato/bitcoind-java-client-sample). Também podemos navegar por todo o código de origem do [bitcoin-rpc-client](https://github.com/Polve/bitcoin-rpc-client). -## Construindo nossa conexão +## Construindo Nossa Conexão -Para usar o `JavaBitcoindRpcClient`, precisamos criar uma instância `BitcoindRpcClient`. Fazemos isso criando um URL com argumentos de nome de usuário, senha, endereço IP e porta. Como devemos nos lembrar, o endereço IP é `127.0.0.1` e a porta `18332` devem estar corretos para a configuração testnet padrão descrita neste curso, enquanto podemos extrair o usuário e a senha abrindo o arquivo `~/.bitcoin/bitcoin.conf`. +Para usar o `JavaBitcoindRpcClient`, precisamos criar uma instância `BitcoindRpcClient`. Fazemos isso criando um URL com argumentos de nome de usuário, senha, endereço IP e porta. Como devemos nos lembrar, o endereço IP `127.0.0.1` e a porta `18332` devem estar corretos para a configuração testnet padrão descrita neste curso, enquanto podemos extrair o usuário e a senha abrindo o arquivo `~/.bitcoin/bitcoin.conf`. ```java BitcoindRpcClient rpcClient = new BitcoinJSONRPCClient("http://StandUp:6305f1b2dbb3bc5a16cd0f4aac7e1eba@localhost:18332"); @@ -101,14 +101,14 @@ import wf.bitcoin.javabitcoindrpcclient.BitcoindRpcClient; > **MAINNET VS TESTNET:** A porta seria 8332 para uma configuração da mainnet. -Se o `rpcClient` for inicializado com sucesso, podemos enviar comandos RPC. +Se o `rpcClient` for inicializado com sucesso, poderemos enviar comandos RPC. -Mais tarde, quando terminarmos nossa conexão `bitcoind`, precisamos fechá-la: +Mais tarde, quando terminarmos nossa conexão `bitcoind`, precisaremos fechá-la: ``` rpcClient.stop(); ``` -### Fazendo uma chamada RPC +### Fazendo uma Chamada RPC Você verá que o `BitcoindRpcClient` fornece a maioria das funcionalidades que podem ser acessadas através do `bitcoin-cli` ou outros métodos RPC, usando o mesmo método que o nome, mas em camelCase. @@ -131,7 +131,7 @@ Blocks.....: 1830905 Difficulty.: 4194304 Hash Power.: 40367401348837.41 ``` -### Fazendo uma chamada RPC usando argumentos +### Fazendo uma Chamada RPC com Argumentos Podemos procurar os endereços em nossa carteira passando o endereço como um argumento para o comando `getAddressInfo`: @@ -152,9 +152,9 @@ HdKeyPath: m/0'/0'/5' PubKey: 0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65 ``` -### Executando nosso código +### Executando Nosso Código -O código para esses exemplos pode ser encontrado no [diretório src/](src/17_2_App-getinfo.java) e deve ser instalado na estrutura de diretório padrão criada neste caso como `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. Ele pode então ser compilado e executado. +O código para esses exemplos pode ser encontrado no [diretório src/](src/18_2_App-getinfo.java) e deve ser instalado na estrutura de diretório padrão criada neste caso como `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. Ele pode então ser compilado e executado. ``` $ mvn compile @@ -170,14 +170,14 @@ PubKey: 0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65 ``` Você também verá muito mais informações sobre a compilação, é claro. -## Pesquisando os fundos +## Consultando Fundos -Recuperando o saldo de uma conta inteira é tão fácil quanto: +Recuperar o saldo de uma conta inteira é tão fácil quanto: ``` System.out.println("Balance: " + rpcClient.getBalance()); ``` -## Criando um endereço +## Criando um Endereço Podemos criar um novo endereço em nossa carteira, anexando um rótulo específico a ela e até mesmo descartando nossa chave privada. @@ -194,11 +194,11 @@ New Address: mpsFtZ8qTJPRGZy1gaaUw37fHeUSPLkzzs Priv Key: cTy2AnmAALsHokYzJzTdsUBSqBtypmWfmSNYgG6qQH43euUZgqic ``` -## Enviando uma transação +## Enviando uma Transação A biblioteca `JavaBitcoindRpcClient` possui algumas ferramentas interessantes que facilitam a criação de uma transação desde o início. -### Criando uma transação +### Criando uma Transação Podemos criar uma transação bruta usando o método `createRawTransaction`, passando como argumentos dois objetos ArrayList contendo entradas e saídas a serem utilizadas. @@ -253,7 +253,7 @@ Agora estamos prontos para realmente criar a transação: System.out.println("Created unsignedRawTx from addr1 to addr2: " + unsignedRawTxHex); ``` -### Assinando uma transação +### Assinando uma Transação Agora podemos assinar a transação com o método `signRawTransactionWithKey`. Este método recebe como parâmetros uma transação de string bruta não assinada, a chave privada do endereço de envio e o objeto TxInput. @@ -267,7 +267,7 @@ Agora podemos assinar a transação com o método `signRawTransactionWithKey`. E System.out.println("signedRawTx complete: " + srTx.complete()); ``` -### Enviando uma transação +### Enviando uma Transação Finalmente, o envio requer o comando `sendRawTransaction`: ```java @@ -275,9 +275,9 @@ String sentRawTransactionID = rpcClient.sendRawTransaction(srTx.hex()); System.out.println("Sent signedRawTx (txID): " + sentRawTransactionID); ``` -### Executando nosso código +### Executando Nosso Código -Agora podemos executar [o código da transação](src/17_2_App-sendtx.java) como `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. +Agora podemos executar [o código da transação](src/18_2_App-sendtx.java) como `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. ``` $ mvn compile @@ -293,11 +293,11 @@ signedRawTx complete: true Sent signedRawTx (txID): 82032c07e0ed91780c3369a1943ea8abf49c9e11855ffedd935374ecbc789c45 ``` -## Ouvindo as transações ou blocos +## Escutando Transações ou Blocos -Tal como acontece com [C e nas nossas bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md), existem maneiras fáceis de usar o Java para ouvir a blockchain, além de executar o código específico quando algo acontece, como uma transação que envolve um endereço em nossa carteira, ou até a geração de um novo bloco na rede. +Tal como acontece com [C e suas bibliotecas ZMQ](16_3_Receiving_Bitcoind_Notifications_with_C.md), existem maneiras fáceis de usar o Java para escutar a blockchain, além de executar o código específico quando algo acontece, como uma transação que envolve um endereço em nossa carteira, ou até a geração de um novo bloco na rede. -Para fazer isso, podemos usar a classe `BitcoinAcceptor` do `JavaBitcoindRpcClient`, que permite anexar _listerners_ na rede. +Para fazer isso, podemos usar a classe `BitcoinAcceptor` do `JavaBitcoindRpcClient`, que nos permite anexar "ouvintes" à rede. ```java String blockHash = rpcClient.getBestBlockHash(); @@ -316,7 +316,7 @@ Para fazer isso, podemos usar a classe `BitcoinAcceptor` do `JavaBitcoindRpcClie acceptor.run(); ``` -Veja [o diretório src/](src / 17_2_App-listen.java) para o código completo. Cada vez que uma transação é enviada ou um novo bloco é gerado, devemos ver a saída em nosso console: +Veja [o diretório src/](src/18_2_App-listen.java) para o código completo. Cada vez que uma transação é enviada ou um novo bloco é gerado, devemos ver a saída em nosso console: ``` Transaction: {account=Tests, address=mhopuJzgmTwhGfpNLCJ9CRknugY691oXp1, category=receive, amount=5.0E-4, label=Tests, vout=1, confirmations=0, trusted=false, txid=361e8fcff243b74ebf396e595a007636654f67c3c7b55fd2860a3d37772155eb, walletconflicts=[], time=1513132887, timereceived=1513132887, bip125-replaceable=unknown} @@ -325,8 +325,8 @@ Block: 000000004564adfee3738314549f7ca35d96c4da0afc6b232183917086b6d971 ### Resumo: Acessando o Bitcoind com Java -Usando a biblioteca `javabitcoinrpc`, podemos acessar facilmente o `bitcoind` por meio de chamadas RPC no Java. Também teremos acesso a recursos adicionais interessantes, como o serviço de escuta usando o comando `bitcoinAcceptor`. +Usando a biblioteca `javabitcoinrpc`, podemos acessar facilmente o `bitcoind` por meio de chamadas RPC com Java. Também teremos acesso a recursos adicionais interessantes, como o serviço de escuta usando o comando `bitcoinAcceptor`. ## O Que Vem Depois? -Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.3: Acessando o Bitcoind com NodeJS](17_2_Accessing_Bitcoind_with_Java.md). \ No newline at end of file +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§18.3: Acessando o Bitcoind com NodeJS](18_3_Accessing_Bitcoind_with_NodeJS.md). \ No newline at end of file From 9cbc5e18e65fc4cef0707825894e7c8c15210f1b Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 10:48:09 -0300 Subject: [PATCH 096/155] Review 18_3 --- pt/18_3_Accessing_Bitcoind_with_NodeJS.md | 39 +++++++++++------------ 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/pt/18_3_Accessing_Bitcoind_with_NodeJS.md b/pt/18_3_Accessing_Bitcoind_with_NodeJS.md index 4ebf78a..152ea62 100644 --- a/pt/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/pt/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -1,10 +1,9 @@ -# 17.3: Acessando o Bitcoind com NodeJS +# 18.3: Acessando o Bitcoind com NodeJS > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Esta seção explica como interagir com o `bitcoind` usando a linguagem de programação NodeJS e o [pacote BCRPC](https://github.com/dgarage/bcrpc). -## Set Up Node.js ## Configurando o Node.js O BCRPC é construído em node.js. Portanto, primeiro precisamos instalar os pacotes `node.js` e o `npm` (o gerenciador de pacotes do node) em nosso sistema. @@ -27,7 +26,7 @@ $ cd bcrpc $ npm install ``` -Para testar o pacote BCRPC, devemos primeiro definir as variáveis ​​ambientais para o rpcuser e rpcpassword. Como de costume, eles vêm do `~/.bitcoin/bitcoin.conf`. Também devemos definir a porta RPC como sendo 18332, que deve ser a correta para a configuração Testnet padrão descrita nos documentos. +Para testar o pacote BCRPC, devemos primeiro definir as variáveis de ambiente para o rpcuser e rpcpassword. Como de costume, elas vêm do `~/.bitcoin/bitcoin.conf`. Também devemos definir a porta RPC como sendo 18332, que deve ser a correta para a configuração Testnet padrão descrita nos documentos. ``` $ export BITCOIND_USER=StandUp @@ -35,7 +34,7 @@ $ export BITCOIND_PASS=d8340efbcd34e312044c8431c59c792c $ export BITCOIND_PORT=18332 ``` -> :warning: **AVISO:** Obviamente, nunca colocaria nossa senha definida em uma variável de ambiente em um ambiente de produção. +> :warning: **AVISO:** Obviamente, você nunca colocaria sua senha em uma variável de ambiente em um ambiente de produção. > :link: **MAINNET VS TESTNET:** A porta seria 8332 para uma configuração na Mainnet. @@ -55,7 +54,7 @@ $ npm test 2 passing (36ms) ``` -Parabéns, agora temos um wrapper RPC pronto para usar o Bitcoin com o Node.js que está funcionando com nossa configuração do Bitcoin. +Parabéns, agora temos um wrapper RPC pronto para ser usado no Bitcoin com o Node.js e que está funcionando com as nossas configurações do Bitcoin. ### Criando um Projeto BCRPC @@ -69,7 +68,7 @@ $ npm init [continue with default options] $ npm install bcrpc ``` -## Construindo nossa conexão +## Construindo Nossa Conexão Em nosso diretório `myproject`, criamos um arquivo `.js` onde nosso código JavaScript será executado. @@ -78,7 +77,7 @@ Podemos iniciar uma conexão RPC criando um `RpcAgent`: const RpcAgent = require('bcrpc'); agent = new RpcAgent({port: 18332, user: 'StandUp', pass: 'd8340efbcd34e312044c8431c59c792c'}); ``` -Obviamente, nosso `user` e `pass` devem coincidir novamente com o que está em nosso `~/.bitcoin/bitcoin.conf`, e usamos a `porta 18332` se estivermos na Testnet. +Obviamente, nosso `user` e `pass` devem coincidir novamente com o que está em nosso `~/.bitcoin/bitcoin.conf`, e usamos a `port 18332` se estivermos na Testnet. ### Fazendo uma chamada RPC @@ -108,15 +107,15 @@ As funções BCRPC podem aceitar argumentos. Por exemplo, o `getBlockHash` receb O resultado das funções BCRPC é um objeto JSON contendo informações sobre quaisquer erros e o id da solicitação. Ao acessar nosso resultado, adicionamos o `.result` no final dele para especificar que estamos interessados no resultado real, não em informações sobre os erros. -### Executando nosso código +### Executando Nosso Código -Podemos encontrar o código `getinfo` no [diretório src/](src / 17_3_getinfo.js). +Podemos encontrar o código `getinfo` no [diretório src/](src/18_3_getinfo.js). ``` $ node getinfo.js 1831094 00000000000002bf8b522a830180ad3a93b8eed33121f54b3842d8838580a53c ``` -Isto é o que a saída do exemplo acima pareceria se substituíssemos o `console.log(blockCount.result);` e o `console.log(hash.result);` por `console.log(blockCount);` e `console.log (hash);`, respectivamente: +Isso é com o que a saída do exemplo acima se pareceria se substituíssemos o `console.log(blockCount.result);` e o `console.log(hash.result);` por `console.log(blockCount);` e `console.log (hash);`, respectivamente: ``` { result: 1774686, error: null, id: null } @@ -127,9 +126,9 @@ Isto é o que a saída do exemplo acima pareceria se substituíssemos o `console } ``` -## Pesquisando os fundos +## Pesquisando por Fundos -É útil ao aceitar Bitcoin verificar os Bitcoin recebidos em um endereço específico em nossa carteira. Por exemplo, se administrássemos uma loja online que aceita Bitcoin, para cada pagamento de um cliente, geraríamos um novo endereço, mostraríamos esse endereço ao cliente e, em seguida, verificaríamos o saldo do endereço após algum tempo, para certificar-se de que o montante foi recebido: +É útil, ao aceitar Bitcoin, verificar o Bitcoin recebido em um endereço específico em nossa carteira. Por exemplo, se administrássemos uma loja online que aceita Bitcoin, para cada pagamento de um cliente, geraríamos um novo endereço, mostraríamos esse endereço ao cliente e, em seguida, verificaríamos o saldo do endereço após algum tempo, para certificar-se de que o montante foi recebido: ``` agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', function (err, addressInfo) { @@ -151,7 +150,7 @@ agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', 6, function (er }); ``` -### Pesquisando informações da carteira +### Pesquisando Informações da Carteira Também podemos procurar informações adicionais sobre nossa carteira e visualizar nosso saldo, contagem de transações etc. @@ -163,7 +162,7 @@ agent.getWalletInfo(function (err, walletInfo) { }); ``` -O código está disponível como [walletinfo.js](src/17_3_walletinfo.js). +O código está disponível como [walletinfo.js](src/18_3_walletinfo.js). ``` $ node walletinfo.js 0.008498 @@ -184,9 +183,9 @@ $ node walletinfo.js scanning: false } ``` -Ao invés de imprimir todos os detalhes associados à nossa carteira, podemos imprimir informações específicas, como nosso saldo. Como um objeto JSON está sendo acessado, podemos fazer isso alterando a linha `console.log(walletInfo.result);` para `console.log(walletInfo.result.balance);`: +Ao invés de imprimirmos todos os detalhes associados à nossa carteira, podemos imprimir informações específicas, como nosso saldo. Como um objeto JSON está sendo acessado, podemos fazer isso alterando a linha `console.log(walletInfo.result);` para `console.log(walletInfo.result.balance);`: -## Criando um endereço +## Criando um Endereço Também podemos passar argumentos adicionais para os comandos RPC. Por exemplo, o seguinte gera um novo endereço legado, com o sinalizador `-addresstype`. @@ -205,7 +204,7 @@ mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ No BCRPC, geralmente podemos usar os mesmos sinalizadores que no `bitcoin-cli` no BCRPC. Embora usamos o camelCase (`getNewAddress`) para os métodos, os sinalizadores, que normalmente são separados por espaços na linha de comando, são colocados em strings e separados por vírgulas. -## Enviando uma transação +## Enviando uma Transação Podemos enviar saldos para um endereço muito facilmente, usando a função `sendToAddress`: @@ -223,7 +222,7 @@ Isso deve retornar o txid da transação: 1679bee019c61608340b79810377be2798efd4d2ec3ace0f00a1967af70666b9 ``` -### Pesquisando uma transação +### Pesquisando uma Transação Agora podemos desejar visualizar uma transação, como a que acabamos de enviar. ``` @@ -261,7 +260,7 @@ Devemos obter uma saída semelhante a esta: } ``` -O código completo está disponível no [sendtx.js](src/17_3_sendtx.js). +O código completo está disponível no [sendtx.js](src/18_3_sendtx.js). ## Resumo: Acessando o Bitcoind com NodeJS @@ -271,4 +270,4 @@ Com base nesses exemplos, devemos ser capazes de incorporar Bitcoin em um projet ## O Que Vem Depois? -Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.4: Acessando o Bitcoind com Python](17_2_Accessing_Bitcoind_with_Java.md). \ No newline at end of file +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§18.4: Acessando o Bitcoind com Python](18_4_Accessing_Bitcoind_with_Python.md). \ No newline at end of file From 73e1a65e35f9205cbd43f8e7528ac80b9b85ab57 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 11:05:59 -0300 Subject: [PATCH 097/155] Review 18_4 --- pt/18_4_Accessing_Bitcoind_with_Python.md | 72 +++++++++++------------ 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/pt/18_4_Accessing_Bitcoind_with_Python.md b/pt/18_4_Accessing_Bitcoind_with_Python.md index 22066f1..f343cc9 100644 --- a/pt/18_4_Accessing_Bitcoind_with_Python.md +++ b/pt/18_4_Accessing_Bitcoind_with_Python.md @@ -1,4 +1,4 @@ -# 17.4: Acessando o Bitcoind com Python +# 18.4: Acessando o Bitcoind com Python > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -13,7 +13,7 @@ Podemos verificar isso executando: Se ele retornar um número de versão (por exemplo, `3.7.3` ou `3.8.3`), então temos o python3 instalado. -No entanto, se não tivermos o Python instalado, precisaremos compilá-lo a partir do código-fonte. Podemos consultar como fazer isso, como mostrado no ["Construindo Python a partir da fonte"](17_4_Accessing_Bitcoind_with_Python.md # variant-build-python-from-source) antes de continuarmos. +No entanto, se não tivermos o Python instalado, precisaremos compilá-lo a partir do código-fonte. Devemos consultar como fazer isso em ["Construindo Python da Fonte"](18_4_Accessing_Bitcoind_with_Python.md#variant-build-python-from-source) antes de continuarmos. ### Configurando o BitcoinRPC @@ -22,13 +22,13 @@ Quer tenhamos usado um Python existente ou compilado a partir da fonte, agora es ``` $ pip3 install python-bitcoinrpc ``` -Se você não instalamos o `pip`, precisaremos executar o seguinte: +Se não instalamos o `pip`, precisaremos executar o seguinte: ``` $ sudo apt install python3-pip ``` Em seguida, vamos repetir o comando `pip3 install python-bitcoinrpc`. -### Criar um projeto BitcoinRPC +### Criando um Projeto BitcoinRPC Geralmente, precisaremos incluir declarações apropriadas do `bitcoinrpc` em nosso projetos Bitcoin usando o Python. O seguinte fornecerá acesso aos comandos baseados em RPC: ```py @@ -43,14 +43,14 @@ O `pprint` irá imprimir a resposta `json` do `bitcoind`. O `logging` irá imprimir a chamada que fizemos para o respose do `bitcoind` e o próprio `bitcoind`, o que é útil quando fazemos um monte de chamadas juntas. Se não quisermos um retorno muito grande no terminal, podemos comentar o bloco `logging`. -## Construindo a nossa conexão +## Construindo a Nossa Conexão Agora estamos prontos para começar a interagir com o `bitcoind` estabelecendo uma conexão. Vamos criar um arquivo chamado `btcrpc.py` e digitar o seguinte: ```py logging.basicConfig() logging.getLogger("BitcoinRPC").setLevel(logging.DEBUG) -# rpc_user and rpc_password are set in the bitcoin.conf file +# rpc_user e rpc_password estão configurados no arquivo bitcoin.conf rpc_user = "StandUp" rpc_pass = "6305f1b2dbb3bc5a16cd0f4aac7e1eba" rpc_host = "127.0.0.1" @@ -59,9 +59,9 @@ rpc_client = AuthServiceProxy(f"http://{rpc_user}:{rpc_pass}@{rpc_host}:18332", Os argumentos na URL são `:@:`. Como de costume, o `user` e o `pass` são encontrados no arquivo `~/.bitcoin/bitcoin.conf`, enquanto o `host` é o nosso localhost, e a porta é `18332` para Testnet. O argumento `timeout` é especificado desde o tempo limite dos sockets sob grande demanda na rede principal. Se obtivermos a resposta `socket.timeout: timed out`, precisamos ser pacientes e aumentar o` timeout`. -> :link: ** MAINNET VS TESTNET: ** A porta seria 8332 para uma configuração na Mainnet. +> :link: **MAINNET VS TESTNET:** A porta seria 8332 para uma configuração na Mainnet. -### Fazendo uma chamada RPC +### Fazendo uma Chamada RPC Se o `rpc_client` for inicializado com sucesso, seremos capazes de enviar comandos RPC para o nosso node do Bitcoin. @@ -87,7 +87,7 @@ Block Count: 1773020 --------------------------------------------------------------- ``` -### Fazendo uma chamada RPC enviando argumentos +### Fazendo uma Chamada RPC com Argumentos Podemos usar esse blockcount como um argumento para recuperar o blockhash de um bloco e também para recuperar os detalhes do bloco. @@ -128,7 +128,7 @@ print("---------------------------------------------------------------\n") ### Executando nosso código -Podemos usar [o código que está no src/](src/17_4_getinfo.py) e executá-lo com `python3`: +Podemos usar [o código que está no src/](src/18_4_getinfo.py) e executá-lo com `python3`: ``` $ python3 getinfo.py @@ -160,7 +160,7 @@ First 10 transactions: --------------------------------------------------------------- ``` -## Pesquisando fundos +## Pesquisando Fundos Da mesma forma, podemos recuperar as informações da nossa carteira com o RPC `getwalletinfo`: @@ -244,7 +244,7 @@ pprint(utxo_tx_details) print("---------------------------------------------------------------\n") ``` -Este código está disponível no arquivo [walletinfo.py](src/17_4_walletinfo.py). +Este código está disponível no arquivo [walletinfo.py](src/18_4_walletinfo.py). ``` $ python3 walletinfo.py --------------------------------------------------------------- @@ -338,16 +338,16 @@ UTXO Details: --------------------------------------------------------------- ``` -## Crindo um endereço +## Crindo um Endereço Criar um novo endereço com Python 3 requer apenas o uso de um RPC como `getnewaddress` ou `getrawchangeaddress`. ``` new_address = rpc_client.getnewaddress("Learning-Bitcoin-from-the-Command-Line") new_change_address = rpc_client.getrawchangeaddress() ``` -Neste exemplo, usamos comando `getnewaddress` junto com um argumento: o rótulo `Learning-Bitcoin-from-the-Command-Line`. +Neste exemplo, usamos o comando `getnewaddress` junto com um argumento: o rótulo `Learning-Bitcoin-from-the-Command-Line`. -## Enviando uma transação +## Enviando uma Transação A criação de uma transação no Python 3 requer a combinação de alguns dos exemplos anteriores, de criação de endereços e de recuperação de UTXOs, com alguns comandos novos do RPC para criar, assinar e enviar uma transação, da mesma forma que fizemos anteriormente na linha de comando. @@ -359,13 +359,13 @@ Existem cinco etapas: 3. Assinar a transação bruta com a chave privada do UTXO; 4. Transmitir a transação na Testnet do bitcoin. -### 1. Selecionando o UTXO e definindo os detalhes da transação +### 1. Selecionando o UTXO e Definindo os Detalhes da Transação No trecho de código a seguir, primeiro selecionaremos o UTXO que gostaríamos de gastar. Em seguida, iremos obter o endereço, id da transação e o índice vetorial da saída. ```py utxos = rpc_client.listunspent() -selected_utxo = utxos[0] # again, selecting the first utxo here +selected_utxo = utxos[0] # novamente, selecionando o primeiro utxo aqui utxo_address = selected_utxo['address'] utxo_txid = selected_utxo['txid'] utxo_vout = selected_utxo['vout'] @@ -375,17 +375,17 @@ Em seguida, também recuperamos o endereço do destinatário para o qual desejam ```py recipient_address = new_address -recipient_amt = utxo_amt / 2 # sending half coins to recipient -miner_fee = 0.00000300 # choose appropriate fee based on your tx size +recipient_amt = utxo_amt / 2 # enviando metade das moedas para o recebedor +miner_fee = 0.00000300 # escolha uma taxa apropriada baseada no tamanho da sua transação change_address = new_change_address change_amt = float('%.8f'%((utxo_amt - recipient_amt) - miner_fee)) ``` -> :warning: **AVISO:** Obviamente, um programa real faria escolhas mais sofisticadas sobre qual UTXO usar, o que fazer com os fundos e que taxa de mineração pagar. +> :warning: **AVISO:** Obviamente, um programa real faria escolhas mais sofisticadas sobre qual UTXO usar, o que fazer com os fundos e qual taxa de mineração pagar. -### 2. Criando uma transação bruta +### 2. Criando uma Transação Bruta -Agora temos todas as informações para enviar uma transação, mas antes de enviá-la, devemos criar uma transação. +Agora temos todas as informações para enviar uma transação, mas antes de enviá-la, devemos criá-la. ```py txids_vouts = [{"txid": utxo_txid, "vout": utxo_vout}] @@ -396,13 +396,13 @@ Lembre-se de que o formato do comando `createrawtransaction` é: ```$ bitcoin-cli createrawtransaction '[{"txid": , "vout": }]' '{"
": }'``` -O `txids_vouts` é, portanto, uma lista e o `address_amts` é um dicionário python, para combinar com o formato de `createrawtransaction`. +O `txids_vouts` é, portanto, uma lista, e o `address_amts` é um dicionário python, para combinar com o formato de `createrawtransaction`. Se quisermos ver mais sobre os detalhes da transação que criamos, podemos usar `decoderawtransaction`, tanto no Python 3 quanto com `bitcoin-cli`. -### 3. Assinar transação bruta +### 3. Assinar Transação Bruta -Assinar uma transação geralmente é a parte mais complicada do envio de uma transação, quando olhamos a parte de programação. Aqui recuperamos uma chave privada de um endereço com `dumpprivkey` e a coloca em uma matriz: +Assinar uma transação geralmente é a parte mais complicada do envio de uma transação, quando olhamos a parte de programação. Aqui recuperamos uma chave privada de um endereço com `dumpprivkey` e a colocamos em uma matriz: ```py address_priv_key = [] # list of priv keys of each utxo address_priv_key.append(rpc_client.dumpprivkey(utxo_address)) @@ -411,7 +411,7 @@ Depois, usamos esse array, que deve conter as chaves privadas de cada UTXO que e ```py signed_tx = rpc_client.signrawtransactionwithkey(unsigned_tx_hex, address_priv_key) ``` -Isso retornará um objeto JSON com o hex da transação assinada e, se foi assinado completamente ou não: +Isso retornará um objeto JSON com o hex da transação assinada e se foi assinado completamente ou não: ### 4. Transmitindo a Transação @@ -420,9 +420,9 @@ Finalmente, estamos prontos para transmitir a transação assinada na rede Bitco ```py send_tx = rpc_client.sendrawtransaction(signed_tx['hex']) ``` -### Executando nosso código +### Executando Nosso Código -[Este código](src/17_4_sendtx.py) está cheio de instruções com `print` para demonstrar todos os dados disponíveis em cada momento: +[Este código](src/18_4_sendtx.py) está cheio de instruções com `print` para demonstrar todos os dados disponíveis a cada momento: ``` $ python3 sendtx.py Creating a Transaction @@ -457,34 +457,34 @@ TXID of sent transaction: 187f8baa222f9f37841d966b6bad59b8131cfacca861cbe9bfc86 ## Resumo: Acessando o Bitcoind com Python -Acessar Bitcoind com Python é muito fácil usando uma biblioteca `python-bitcoinrpc`. A primeira coisa a se fazer, é estabelecer uma conexão com nossa instância `bitcoind`, então podemos fazer todas as chamadas API bitcoin conforme descrito nos documentos do Bitcoin Core. Isso torna mais fácil criar programas pequenos ou grandes para gerenciar nosso próprio node, verificando saldos ou criando aplicações interessantes, conforme acessamos todo o poder do `bitcoin-cli`. +Acessar Bitcoind com Python é muito fácil usando a biblioteca `python-bitcoinrpc`. A primeira coisa a se fazer é estabelecer uma conexão com nossa instância `bitcoind`, então podemos fazer todas as chamadas da API do Bitcoin conforme descrito nos documentos do Bitcoin Core. Isso torna mais fácil criar programas pequenos ou grandes para gerenciar nosso próprio node, verificando saldos ou criando aplicações interessantes, conforme acessamos todo o poder do `bitcoin-cli`. ## O Que Vem Depois? -Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md). +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§18.5: Acessando o Bitcoind com Rust](18_5_Accessing_Bitcoind_with_Rust.md). -## Variante: Construindo o Python a partir do código-fonte +## Variante: Construindo Python da Fonte -Se precisarmos instalar o Python 3 a partir do código-fonte, precisaremos seguir estas instruções e continuar da parte ["Criando um projeto BitcoinRPC"](17_4_Accessing_Bitcoind_with_Python.md#Creating-a-bitcoinrpc-project). +Se precisarmos instalar o Python 3 a partir do código-fonte, precisaremos seguir estas instruções, e então continuar com ["Criando um projeto BitcoinRPC"](18_4_Accessing_Bitcoind_with_Python.md#creating-a-bitcoinrpc-project). -### 1. Instalando as dependências +### 1. Instalando as Dependências ```sh $ sudo apt-get install build-essential checkinstall $ sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev ``` -### 2. Baixando e extraindo o Python +### 2. Baixando e Extraindo o Python ```sh $ wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz $ tar -xzf Python-3.8.3.tgz ``` -### 3. Compilando o código-fonte Python e verificando a instalação: +### 3. Compilando o Código-Fonte Python e Verificando a Instalação: ```sh $ cd Python-3.8.3 $ sudo ./configure --enable-optimizations -$ sudo make -j 8 # enter the number of cores of your system you want to use to speed up the build process. +$ sudo make -j 8 # coloque o número de núcleos que você quer usar do seu sistema para acelerar o processo $ sudo make altinstall $ python3.8 --version ``` From cb8b8deadb798c8131d8571ce0e25e251db1cc10 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 11:17:55 -0300 Subject: [PATCH 098/155] Review 18_5 --- pt/18_5_Accessing_Bitcoind_with_Rust.md | 66 ++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/pt/18_5_Accessing_Bitcoind_with_Rust.md b/pt/18_5_Accessing_Bitcoind_with_Rust.md index f3133d8..20b4d37 100644 --- a/pt/18_5_Accessing_Bitcoind_with_Rust.md +++ b/pt/18_5_Accessing_Bitcoind_with_Rust.md @@ -1,4 +1,4 @@ -# 17.5: Acessando o Bitcoind com Rust +# 18.5: Acessando o Bitcoind com Rust > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -23,9 +23,9 @@ $ source $HOME/.cargo/env ### Configurando o `bitcoincore-rpc` -Para a maioria das linguagens de programação, precisamos instalar uma biblioteca Bitcoin RPC antes de criar nosso primeiro projeto, mas aqui iremos fazer como parte da criação do nosso projeto. +Para a maioria das linguagens de programação, precisamos instalar uma biblioteca Bitcoin RPC antes de criar nosso primeiro projeto, mas aqui iremos fazê-lo como parte da criação do nosso projeto. -### Criando um projeto `bitcoincore-rpc` +### Criando um Projeto `bitcoincore-rpc` Podemos criar um novo projeto usando `cargo new btc_test`: @@ -49,7 +49,7 @@ Hello, world! > :information_source: **NOTA:** se encontrarmos o erro `linker‘ cc ’not found`, teremos que instalar um Compilador C. Se estivermos no Linux, podemos instalar com as [ferramentas de desenvolvimento](https://www.ostechnix.com/install-development-tools-linux/). -Para acessar o crate (biblioteca) `bitcoincore-rpc`, devemos adicioná-la ao nosso arquivo `Cargo.toml` na seção `dependencies`: +Para acessar o crate (biblioteca) `bitcoincore-rpc`, devemos adicioná-lo ao nosso arquivo `Cargo.toml` na seção `dependencies`: ```rust [dependencies] @@ -70,12 +70,12 @@ $ cargo run Hello, world! ``` -Quando estiver usando o `bitcoin-rpc`, normalmente precisaremos incluir o seguinte: +Quando estivermos usando o `bitcoin-rpc`, normalmente precisaremos incluir o seguinte: ``` use bitcoincore_rpc::{Auth, Client, RpcApi}; ``` -## Construindo nossa conexão +## Construindo Nossa Conexão Para criarmos um `RPC client` do Bitcoin, vamos modificar o `src/main.rs`: @@ -94,16 +94,16 @@ fn main() { Como de costume, vamos nos certificar de inserir nosso nome de usuário e senha corretos no `~/.bitcoin/bitcoin.conf`. Aqui, eles serão usados ​​como argumentos para `Auth :: UserPass`. -> :link: **TESTNET vs MAINNET:** E, como de costume, vamos usar a porta 8332 para a Mainnet. +> :link: **TESTNET vs MAINNET:** E, como de costume, use a porta 8332 para a Mainnet. -Quando terminar, também deve fechar nossa conexão: +Quando terminarmos, também devemos fechar nossa conexão: ```rust let _ = rpc.stop().unwrap(); ``` O `cargo run` deve compilar e executar o exemplo com sucesso com um aviso `warning: unused variable: rpc` -### Fazendo uma chamada RPC +### Fazendo uma Chamada RPC As chamadas RPC são feitas usando o `rpc Client` que criamos: @@ -113,7 +113,7 @@ println!("{:#?}", mining_info); ``` Geralmente, as palavras na chamada RPC são separadas por `_`s. Uma lista completa está disponível na [documentação do crate](https://crates.io/crates/bitcoincore-rpc). -### Fazendo uma chamada RPC com argumentos +### Fazendo uma Chamada RPC com Argumentos O envio de uma chamada RPC com argumentos usando Rust requer apenas o conhecimento de como a função é apresentada. Por exemplo, a função `get_block` é definida da seguinte forma na [documentação](https://docs.rs/bitcoincore-rpc/0.11.0/bitcoincore_rpc/trait.RpcApi.html#method.get_block): @@ -130,11 +130,11 @@ Aqui está o código completo para recuperar um hash de bloco, transformando-o e println!("{:?}", block); ``` -> **NOTA:** Outra chamada possível que consideramos para esta seção é a `get_address_info`, mas, infelizmente, no momento em que este livro foi escrito, a função `bitcoincore-rpc` não funciona com versões recentes do Bitcoin Core devido ao crate não abordar as mais recentes mudanças de API no Bitcoin Core. Esperamos que isso seja resolvido no próximo lançamento do crate, mas enquanto isso, damos essa atenção ao programador. +> **NOTA:** Outra chamada possível que consideramos para esta seção é a `get_address_info`, mas, infelizmente, no momento de escrita, a função `bitcoincore-rpc` não funciona com versões recentes do Bitcoin Core devido ao crate não abordar as mais recentes mudanças de API no Bitcoin Core. Esperamos que isso seja resolvido no próximo lançamento do crate, mas, enquanto isso programador, _cuidado_. -### Executando nosso código +### Executando Nosso Código -Podemos acessar o [código src](src/17_5_main-getinfo.rs) e executá-lo. Infelizmente, a informação do "Block" sairá um pouco feia porque este exemplo não inclui uma biblioteca para embelezá-la. +Podemos acessar o [código src](src/18_5_main-getinfo.rs) e executá-lo. Infelizmente, a informação do "Block" sairá um pouco feia porque este exemplo não inclui uma biblioteca para embelezá-la. ``` $ cargo run @@ -154,7 +154,7 @@ GetMiningInfoResult { Block { header: BlockHeader { version: 541065216, prev_blockhash: 000000000000027715981d5a3047daf6819ea3b8390b73832587594a2074cbf5, merkle_root: 4b2e2c2754b6ed9cf5c857a66ed4c8642b6f6b33b42a4859423e4c3dca462d0c, time: 1599602277, bits: 436469756, nonce: 218614401 }, txdata: [Transaction { version: 1, lock_time: 0, input: [TxIn { previous_output: OutPoint { txid: 0000000000000000000000000000000000000000000000000000000000000000, vout: 4294967295 }, script_sig: Script(OP_PUSHBYTES_3 8ff51b OP_PUSHBYTES_22 315448617368263538434f494e1d00010320a48db852 OP_PUSHBYTES_32 ), sequence: 4294967295, witness: [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] }], output: [TxOut { value: 19721777, script_pubkey: Script(OP_HASH160 OP_PUSHBYTES_20 011beb6fb8499e075a57027fb0a58384f2d3f784 OP_EQUAL) }, TxOut { value: 0, script_pubkey: Script(OP_RETURN OP_PUSHBYTES_36 aa21a9ed63363f3620ab5e38b8860a50c84050e5ec31af3636bbd73f01ba9f14103100ee) }] }, Transaction { version: 2, lock_time: 1832282, input: [TxIn { previous_output: OutPoint { txid: cbf880f73d421baf0aa4f0d28e63ba00e5bc6bd934b91eb0641354ce5ca42f7e, vout: 0 }, script_sig: Script(OP_PUSHBYTES_22 00146b8dbd32e5deb90d22934e1513bae6e70156cd50), sequence: 4294967294, witness: [[48, 68, 2, 32, 13, 89, 205, 30, 67, 24, 196, 83, 65, 224, 44, 138, 98, 58, 81, 135, 132, 209, 23, 166, 23, 44, 3, 228, 95, 102, 166, 214, 62, 38, 155, 147, 2, 32, 119, 2, 34, 246, 148, 255, 166, 10, 90, 52, 242, 32, 74, 241, 123, 148, 89, 199, 197, 3, 152, 134, 242, 215, 109, 61, 241, 241, 13, 70, 86, 207, 1], [2, 192, 145, 170, 206, 55, 4, 36, 138, 145, 217, 50, 19, 73, 130, 136, 245, 131, 184, 142, 239, 75, 13, 67, 17, 177, 57, 86, 151, 139, 89, 35, 109]] }], output: [TxOut { value: 1667908, script_pubkey: Script(OP_HASH160 OP_PUSHBYTES_20 908ca2b8b49ccf53efa2226afa85f6cc58dfd7e7 OP_EQUAL) }, TxOut { value: 9093, script_pubkey: Script(OP_DUP OP_HASH160 OP_PUSHBYTES_20 42ee67664ce16edefc68ad0e4c5b7ce2fc2ccc18 OP_EQUALVERIFY OP_CHECKSIG) }] }, ...] } ``` -## Pesquisando os fundos +## Procurando por Fundos Podemos procurar fundos sem argumentos opcionais usando a função `get_balance`: @@ -167,12 +167,12 @@ Conforme mostrado, a função `as_btc()` ajuda a gerar o saldo em um formato leg Balance: 3433.71692741 BTC ``` -## Criando um endereço +## Criando um Endereço A criação de um endereço demonstra como fazer uma chamada RPC com vários argumentos opcionais especificados (por exemplo, um rótulo e um tipo de endereço). ```rust -// Generate a new address +// Gerar um novo endereço let myaddress = rpc .get_new_address(Option::Some("BlockchainCommons"), Option::Some(json::AddressType::Bech32)) .unwrap(); @@ -183,7 +183,7 @@ Isso também exigirá que tragamos a definição `json` para o escopo: use bitcoincore_rpc::{json, Auth, Client, RpcApi}; ``` -## Enviando uma transação +## Enviando uma Transação Agora temos tudo de que precisamos para criar uma transação, o que será feito em cinco partes: @@ -193,9 +193,9 @@ Agora temos tudo de que precisamos para criar uma transação, o que será feito 4. Assinar transação; 5. Enviar transação. -### 1. Listando o UTXOs +### 1. Listando os UTXOs -Para iniciar a criação de uma transação, primeiro encontramos um UTXO para usar. O seguinte leva o primeiro UTXO com pelo menos 0,01 BTC: +Para iniciar a criação de uma transação, primeiro encontramos um UTXO para usar. O seguinte pega o primeiro UTXO com pelo menos 0,01 BTC: ```rust @@ -218,7 +218,7 @@ let selected_tx = &unspent[0]; println!("selected unspent transaction: {:#?}", selected_tx); ``` -Isso exigirá trazer mais estruturas para o escopo: +Isso nos exigirá trazer mais estruturas para o escopo: ```rust use bitcoincore_rpc::bitcoin::{Address, Amount}; @@ -226,7 +226,7 @@ use bitcoincore_rpc::bitcoin::{Address, Amount}; Podemos observar que estamos passando cinco variáveis ​​ao comando `list_unspent`. Os primeiros quatro (`minconf`,` maxconf`, `address` e `include_unsafe`) não são usados ​​aqui. O quinto é o `query_options`, que não usamos antes, mas temos algumas opções de filtragem poderosas, incluindo a capacidade de olhar apenas para os UTXOs com um certo valor, mínimo ou máximo. -### 2. Preenchendo as variáveis +### 2. Preenchendo as Variáveis Para começar a preencher as variáveis ​​que precisaremos para criar uma nova transação, criamos a entrada do `txid` e do `vout` ao UTXO que selecionamos: ```rust @@ -237,35 +237,35 @@ let selected_utxos = json::CreateRawTransactionInput { }; ``` Em seguida, podemos calcular a quantia que vamos gastar subtraindo uma taxa de mineração dos fundos no UTXO: -``` -// send all bitcoin in the UTXO except a minor value which will be paid to miners +```rust +// enviar todo o bitcoin no UTXO exceto um valor pequeno que será pago aos mineradores let unspent_amount = selected_tx.amount; let amount = unspent_amount - Amount::from_btc(0.00001).unwrap(); ``` Por fim, podemos criar um mapa do hash do endereço e da quantidade para formar a saída: -``` +```rust let mut output = HashMap::new(); output.insert( myaddress.to_string(), amount, ); ``` -Outra característica é necessária para a variável de saída: O `HashMap`. Ele permite que armazenemos +Outra característica é necessária para a variável de saída: o `HashMap`. Ele nos permite armazenar valores por chave, que iremos precisar para representar a informação `{address: amount}`. ```rust use std::collections::HashMap; ``` -### 3. Criando a transação bruta +### 3. Criando a Transação Bruta -Agora, estamos prontos para criar uma transação bruta: +Agora estamos prontos para criar uma transação bruta: ```rust let unsigned_tx = rpc .create_raw_transaction(&[selected_utxos], &output, None, None) .unwrap(); ``` -### 4. Assinando a transação +### 4. Assinando a Transação A assinatura da transação pode ser feita com um simples uso do `sign_raw_transaction_with_wallet`: ```rust @@ -276,7 +276,7 @@ let signed_tx = rpc println!("signed tx {:?}", signed_tx.transaction().unwrap()); ``` -### 5. Enviando a transação +### 5. Enviando a Transação Finalmente, podemos transmitir a transação: ```rust @@ -287,9 +287,9 @@ let txid_sent = rpc println!("{:?}", txid_sent); ``` -### Executando nosso código +### Executando Nosso Código -Agora podemos executar o código completo do [src](src/17_5_main-sendtx.rs). +Agora podemos executar o código completo do [src](src/18_5_main-sendtx.rs). ``` @@ -355,8 +355,8 @@ b0eda3517e6fac69e58ae315d7fe7a1981e3a858996cc1e3135618cac9b79d1a ## Resumo: Acessando o Bitcoind com Rust -O `bitcoincore-rpc` é um crate simples e robusto que permitirá que possamos interagir com o Bitcoin RPC usando Rust. No entanto, no momento em que este livro foi escrito, ele ficou para trás no Bitcoin Core, o que pode causar alguns problemas de uso. +O `bitcoincore-rpc` é um crate simples e robusto que nos permitirá interagir com o Bitcoin RPC usando Rust. No entanto, no momento em que este livro foi escrito, ele ficou para trás no Bitcoin Core, o que pode causar alguns problemas de uso. ## O Que Vem Depois? -Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md). \ No newline at end of file +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§18.6: Acessando o Bitcoind com Swift](18_6_Accessing_Bitcoind_with_Swift.md). \ No newline at end of file From 0ae39490657562ea8f4838d919c36bde863fe2e7 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 24 Aug 2021 11:34:46 -0300 Subject: [PATCH 099/155] Review 18_6 --- pt/18_6_Accessing_Bitcoind_with_Swift.md | 84 ++++++++++++------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/pt/18_6_Accessing_Bitcoind_with_Swift.md b/pt/18_6_Accessing_Bitcoind_with_Swift.md index 4716dee..27a4cd3 100644 --- a/pt/18_6_Accessing_Bitcoind_with_Swift.md +++ b/pt/18_6_Accessing_Bitcoind_with_Swift.md @@ -1,4 +1,4 @@ -# 17.6: Acessando o Bitcoind com Swift +# 18.6: Acessando o Bitcoind com Swift > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -12,29 +12,29 @@ Ao invés disso, sugerimos a criação de um ambiente Swift ideal em um Mac. Exi ### 1. Instalando o Xcode -Vamos precisar do `Xcode`, o ambiente de desenvolvimento integrado para o Swift e para o Objective-C. Isso pode ser facilmente instalado acessando a Mac App Store e o `Get` Xcode. +Vamos precisar do `Xcode`, o ambiente de desenvolvimento integrado para o Swift e para o Objective-C. Isso pode ser facilmente instalado acessando a Mac App Store e baixando o Xcode. -#### Alternativa: Instalando manualmente +#### Alternativa: Instalando Manualmente -Algumas pessoas desaconselham a instalação da App Store porque é tudo ou nada. Também não funcionará se estivermos usando o Mojave, pois iremos querer evitar as incompatibilidades da Catalina. Nesse caso, podemos fazer o download diretamente da [Área do desenvolvedor](https://developer.apple.com/download/more/) na Apple. +Algumas pessoas desaconselham a instalação da App Store porque é tudo ou nada. Também não funcionará se estivermos usando o Mojave, pois desejaremos evitar as incompatibilidades do Catalina. Nesse caso, podemos fazer o download diretamente da [Área do desenvolvedor](https://developer.apple.com/download/more/) na Apple. Se estivermos usando o Mojave, precisaremos do arquivo `xip` para o Xcode 10.3.1. Caso contrário, podemos utilizar o mais recente. -Depois de baixado, podemos clicar no `xip` para extraí-lo e mover o aplicativo Xcode para a pasta Aplicativos. +Depois de baixado, podemos clicar no `xip` para extraí-lo e mover o aplicativo Xcode para a pasta de Aplicativos. -De qualquer forma, devemos ter o Xcode instalado na pasta Aplicativos no final desta etapa. +De qualquer forma, devemos ter o Xcode instalado na pasta de Aplicativos no final desta etapa. -### 2. Instalando o servidor Gordian +### 2. Instalando o Servidor Gordian Também vamos precisar de um node Bitcoin em nosso Mac, para que possamos nos comunicar com ele. Tecnicamente, poderíamos usar um node remoto e acessá-lo com o login e senha RPC pela rede. No entanto, sugerimos a instalação do full node diretamente no Mac, porque essa é a configuração mais segura e limpa, garantindo que nenhuma das comunicações saia de nossa máquina. -Para instalar facilmente um full node em nosso Mac, podemos usar Blockchain Commons '[GordianServer for MacOS](https://github.com/BlockchainCommons/GordianServer-macOS). Podemos seguir as [instruções de instalação](https://github.com/BlockchainCommons/GordianServer-macOS#installation-instructions) no README, mas geralmente tudo que precisamos fazer é baixar o arquivo `dmg` atual, abri-lo e instalar a aplicação em nosso diretório de aplicações. +Para instalar facilmente um full node em nosso Mac, podemos usar o [GordianServer for MacOS](https://github.com/BlockchainCommons/GordianServer-macOS) da Blockchain Commons. Podemos seguir as [instruções de instalação](https://github.com/BlockchainCommons/GordianServer-macOS#installation-instructions) no README, mas geralmente tudo que precisamos fazer é baixar o arquivo `dmg` atual, abri-lo e instalar a aplicação em nosso diretório de aplicações. -Depois, vamos executar o aplicativo GordianServer e dizer a ele para `Start` a Testnet. +Depois, vamos executar o aplicativo GordianServer e dizer a ele para `Start` na Testnet. > :link: **TESTNET vs. MAINNET:** Ou `Start` na Mainnet. -#### 3. Tornando nosso bitcoin-cli Gordian acessível +#### 3. Tornando Nosso bitcoin-cli Gordian Acessível Quando desejarmos acessar o `bitcoin-cli` criado pelo GordianServer em nosso Mac local, podemos encontrá-lo em `~/.standup/BitcoinCore/bitcoin-0.20.1/bin/bitcoin-cli`. @@ -43,9 +43,9 @@ Podemos criar um alias para isso: alias bitcoin-cli="~/.standup/BitcoinCore/bitcoin-0.20.1/bin/bitcoin-cli -testnet" ``` -> :link: **TESTNET vs. MAINNET:** Obviamente, o parâmetro `-testnet` só é necessário se estivermos executando a testnet. +> :link: **TESTNET vs. MAINNET:** Obviamente, o parâmetro `-testnet` só é necessário se estivermos rodando na testnet. -### 4. Encontrando nossas informações do GordianServer +### 4. Encontrando Nossas Informações do GordianServer Finalmente, precisaremos de nossas informações de `rpcuser` e `rpcpassword`. Essas informações estarão em `~/Library/Application Support/Bitcoin/bitcoin.conf` por padrão no Gordian. ``` @@ -54,9 +54,9 @@ rpcuser=oIjA53JC2u rpcpassword=ebVCeSyyM0LurvgQyi0exWTqm4oU0rZU ... ``` -## Construindo nossa conexão manualmente +## Construindo Nossa Conexão Manualmente -No momento em que este artigo foi escrito, não havia uma biblioteca Bitcoin RPC atualizada e simples de ser usada, que fosse específica para Swift, algo que pudesse entrar e começar a usar imediatamente. Portanto, faremos algo que nunca fizemos antes: Construir uma conexão RPC manualmente. +No momento em que este artigo foi escrito, não havia uma biblioteca Bitcoin RPC atualizada e simples de ser usada, que fosse específica para Swift, algo que pudéssemos baixar e começar a usar imediatamente. Portanto, faremos algo que nunca fizemos antes: construir uma conexão RPC manualmente. ### Grave o Transmissor RPC @@ -65,9 +65,9 @@ Isso requer apenas a escrita de uma função que passe os comandos RPC para o `b func makeCommand(method: String, param: Any, completionHandler: @escaping (Any?) -> Void) -> Void { ``` -As conexões RPC para o `bitcoind` usam o protocolo HTML, o que significa que precisamos fazer três coisas: Criar uma URL, fazer um URLRequest e, iniciar uma URLSession. +As conexões RPC para o `bitcoind` usam o protocolo HTML, o que significa que precisamos fazer três coisas: Criar uma URL, fazer um URLRequest e iniciar uma URLSession. -#### 1. Criando um URL +#### 1. Criando uma URL Dentro da função, precisamos criar uma URL a partir do nosso IP, porta, `rpcuser`, `rpcpassword` e wallet: ``` @@ -77,7 +77,7 @@ Dentro da função, precisamos criar uma URL a partir do nosso IP, porta, `rpcus let rpcpassword = "ebVCeSyyM0LurvgQyi0exWTqm4oU0rZU" let walletName = "" ``` -A conexão RPC real com o Bitcoin Core é construída usando um URL no formato "http://rpcusername:rpcpassword@nodeIp/walletName": +A conexão RPC real com o Bitcoin Core é construída usando uma URL no formato "http://rpcusername:rpcpassword@nodeIp/walletName": ``` let walletUrl = "http://\(rpcusername):\(rpcpassword)@\(nodeIp)/\(walletName)" @@ -154,9 +154,9 @@ Claro que eventualmente teremos que dizer à `task` para que ela seja iniciada: ``` E isso é "tudo" o que precisamos fazer nessa interação RPC manual, usando uma linguagem de programação como o Swift. -> :pray: **AGRADECIMENTOS:** Obrigado a @Fonta1n3 que forneceu o [código principal](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues/137) para nosso Transmissor RPC. +> :pray: **AGRADECIMENTO:** Obrigado @Fonta1n3, que forneceu o [código principal](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues/137) para nosso Transmissor RPC. -### Fazendo uma chamada RPC +### Fazendo uma Chamada RPC Tendo escrito a função RPC `makeCommand`, podemos enviar uma chamada RPC executando-a. Aqui está `getblockchaininfo`: ``` @@ -169,7 +169,7 @@ makeCommand(method: method,param: param) { result in } ``` -### Fazendo uma chamada RPC com argumentos +### Fazendo uma Chamada RPC com Argumentos Poderíamos da mesma forma obter a contagem de bloco atual a partir dessa informação e usá-la de modo redundante para obter o hash do bloco atual, usando o parâmetro `param`: ``` @@ -189,9 +189,9 @@ makeCommand(method: method,param: param) { result in } ``` -### Executando nosso código +### Executando Nosso Código -O código completo está disponível no [diretório src/](src / 17_6_getinfo.playground). Carregue-o no playground Xcode e, em seguida, "Editor -> Executar Playground" e devemos obter resultados como: +O código completo está disponível no [diretório src/](src/18_6_getinfo.playground). Carregue-o no playground Xcode e, em seguida, "Editor -> Executar Playground" e devemos obter resultados como: ``` { bestblockhash = 00000000000000069725608ebc5b59e520572a8088cbc57ffa5ba87b7f300ac7; @@ -236,7 +236,7 @@ O código completo está disponível no [diretório src/](src / 17_6_getinfo.pla } Blockhash for 1836745 is 00000000000000069725608ebc5b59e520572a8088cbc57ffa5ba87b7f300ac7 ``` -## Pesquisando fundos +## Procurando por Fundos Com nosso novo `makeCommand` para funções RPC, podemos executar um comando como `getwalletinfo` ou `getbalance`: ``` @@ -277,11 +277,11 @@ Balance is 0.01 walletversion = 169900; } ``` -## Criando um endereço +## Criando um Endereço Criar um endereço é bastante simples, mas que tal criar um endereço legado com um rótulo específico? Isso requer dois parâmetros na nossa chamada RPC. -Uma vez que a simples função `makeCommand` desta seção apenas passa nossos `param`s como as entranhas de um objeto JSON, tudo o que precisamos fazer é formatar corretamente essas entranhas. Esta é uma maneira para fazermos isso: +Uma vez que a simples função `makeCommand` desta seção apenas passa nossos `param`s como as entranhas de um objeto JSON, tudo o que precisamos fazer é formatar corretamente essas entranhas. Aqui está uma maneira para fazermos isso: ``` method = "getnewaddress" param = "\"learning-bitcoin\", \"legacy\"" @@ -296,7 +296,7 @@ Executá-lo no playground do Xcode produz o seguinte resultado: ``` mt3ZRsmXHVMMqYQPJ8M74QjF78bmqrdHZF ``` -Esse resultado é obviamente um endereço legado, op rótulo pode então ser verificado na linha de comando: +Esse resultado é obviamente um endereço legado; seu rótulo pode então ser verificado na linha de comando: ``` $ bitcoin-cli getaddressesbylabel "learning-bitcoin" { @@ -309,11 +309,11 @@ Sucesso! > :information_source: **NOTA:** Como costumamos dizer nesses exemplos de programação, um programa do mundo real seria muito mais sofisticado. Em particular, gostaríamos de poder enviar um objeto JSON real como um parâmetro e, em seguida, ter no nosso programa um `makeCommand` analisando-o e inserindo-o na URLSession de forma adequada. O que temos aqui maximiza a legibilidade e a simplicidade sem enfocar na facilidade de uso. -## Enviando uma transação +## Enviando uma Transação Como de costume, o envio de uma transação (da maneira mais difícil) é um processo de várias etapas: -0. Gerar ou recebar um endereço de recebimento; +0. Gerar ou receber um endereço de recebimento; 1. Encontrar um UTXO não gasto; 2. Criar uma transação bruta; 3. Assinar a transação bruta; @@ -321,7 +321,7 @@ Como de costume, o envio de uma transação (da maneira mais difícil) é um pro Usando o `address` gerado na etapa anterior como nosso destinatário. -### 1. Encontrando um UTXO não gasto +### 1. Encontrando um UTXO Não Gasto O RPC `listunspent` permite que encontremos nosso UTXO: ``` @@ -338,11 +338,11 @@ O RPC `listunspent` permite que encontremos nosso UTXO: let amount = utxo["amount"] as! NSNumber let new_amount = amount.floatValue - 0.0001 ``` -Como em outros exemplos, vamos arbitrariamente pegar o enésimo UTXO e pegar o `txid`,`vout` e `amount` dele. +Como em outros exemplos, vamos arbitrariamente pegar o enésimo UTXO e pegar o `txid`, `vout` e `amount` dele. > :information_source **NOTA:** Mais uma vez, um programa real seria muito mais sofisticado. -### 2. Criando uma transação bruta +### 2. Criando uma Transação Bruta Criar uma transação bruta é a coisa mais complicada, porque precisamos acertar todos os nossos objetos JSON, arrays e aspas. Veja como fazer isso no Swift, usando a formatação `param` muito básica do transmissor: ``` @@ -352,7 +352,7 @@ Criar uma transação bruta é a coisa mais complicada, porque precisamos acerta let hex = result as! NSString ``` -### 3. Assinando a transação bruta +### 3. Assinando a Transação Bruta Assinar nossa transação requer apenas que executemos o RPC `signrawtransactionwithwallet`, usando nosso novo `hex`: ``` @@ -365,7 +365,7 @@ Assinar nossa transação requer apenas que executemos o RPC `signrawtransactio let signedhex = signedhexinfo["hex"] as! NSString ``` -### 4. Enviando a transação bruta +### 4. Enviando a Transação Bruta Enviar nossa transação é igualmente simples: ``` @@ -384,26 +384,26 @@ Enviar nossa transação é igualmente simples: } ``` -O código para este remetente de transação pode ser encontrado no [diretório src/](src/17_6_sendtx.playground). +O código para este remetente de transação pode ser encontrado no [diretório src/](src/18_6_sendtx.playground). -## Usando o Swift de outras maneiras +## Usando o Swift de Outras Maneiras Isso cobre nossas discussões habituais sobre a programação do Bitcoin RPC usando uma linguagem, mas o Swift é uma linguagem particularmente importante, pois pode ser implantada em dispositivos móveis, um dos principais locais para nossas carteiras. Como tal, podemos querer considerar algumas outras bibliotecas: -* O Blockchain Commons [ios-Bitcoin framework](https://github.com/BlockchainCommons/iOS-Bitcoin) converte a biblioteca Libbitcoin de C++ para Swift; +* O [framework ios-Bitcoin](https://github.com/BlockchainCommons/iOS-Bitcoin) da Blockchain Commons converte a biblioteca Libbitcoin de C++ para Swift; * [Libwally Swift](https://github.com/blockchain/libwally-swift) é um wrapper Swift para a Libwally. ## Resumo: Acessando o Bitcoind com Swift -O Swift é uma linguagem de programação robusta e moderna que infelizmente ainda não tem nenhuma biblioteca RPC fácil de ser utilizada... O que apenas nos deu a oportunidade de escrever uma função de acesso ao RPC. Com isso em mãos, podemos interagir com o `bitcoind` em um Mac ou criar aplicativos complementares em um iPhone, o que é uma combinação perfeita para usar o Bitcoin com airgap. +O Swift é uma linguagem de programação robusta e moderna que infelizmente ainda não tem nenhuma biblioteca RPC fácil de ser utilizada... o que acabou de nos dar a oportunidade de escrever uma função de acesso ao RPC. Com isso em mãos, podemos interagir com o `bitcoind` em um Mac ou criar aplicativos complementares em um iPhone, o que é uma combinação perfeita para usar o Bitcoin com airgap. ## O Que Vem Depois? -Aprenda sobre o Lightning em [Capítulo 18: Compreendendo a configuração da Lightning](18_0_Understanding_Your_Lightning_Setup.md). +Aprenda sobre o Lightning em [Capítulo 19: Compreendendo Sua Configuração da Lightning](19_0_Understanding_Your_Lightning_Setup.md). -## Variante: implantando o Swift no Ubuntu +## Variante: Implantando o Swift no Ubuntu -Se preferirmos implantar o Swift no Ubuntu, pode fazê-lo, embora a funcionalidade não seja a mesma. Parte do código neste capítulo provavelmente gerará erros que precisaremos resolver e também precisaremos trabalhar mais para vincular as bibliotecas C. +Se preferirmos implantar o Swift no Ubuntu, podemos fazê-lo, embora a funcionalidade não seja a mesma. Parte do código neste capítulo provavelmente gerará erros que precisaremos resolver e também precisaremos trabalhar mais para vincular as bibliotecas C. Para começar, vamos instalar algumas bibliotecas Debian necessárias: ``` @@ -432,7 +432,7 @@ Swift version 5.1.3 (swift-5.1.3-RELEASE) Target: x86_64-unknown-linux-gnu ``` -### Criando um projeto +### Criando um Projeto Depois de instalar o Swift em nossa máquina Ubuntu, podemos criar projetos com o comando `package init`: ``` $ mkdir swift-project @@ -450,7 +450,7 @@ Creating Tests/swift-projectTests/ Creating Tests/swift-projectTests/swift_projectTests.swift Creating Tests/swift-projectTests/XCTestManifests.swift ``` -Também editaremos o `Sources/.../main.swift` e quando estivermos pronto para compilar, podemos usar o comando `build`: +Também editaremos o `Sources/.../main.swift` e, quando estivermos pronto para compilar, podemos usar o comando `build`: ``` $ swift build [4/4] Linking swift-project From c3113187016cf2adec6aa5fb97c148936838d680 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 25 Aug 2021 16:14:11 -0300 Subject: [PATCH 100/155] Delete old files --- pt/15_0_Talking_to_Bitcoind.md | 27 -- pt/15_1_Accessing_Bitcoind_with_C.md | 294 --------------- pt/15_2_Programming_Bitcoind_with_C.md | 354 ------------------ ...Receiving_Bitcoind_Notifications_with_C.md | 155 -------- 4 files changed, 830 deletions(-) delete mode 100644 pt/15_0_Talking_to_Bitcoind.md delete mode 100644 pt/15_1_Accessing_Bitcoind_with_C.md delete mode 100644 pt/15_2_Programming_Bitcoind_with_C.md delete mode 100644 pt/15_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/pt/15_0_Talking_to_Bitcoind.md b/pt/15_0_Talking_to_Bitcoind.md deleted file mode 100644 index 88bde29..0000000 --- a/pt/15_0_Talking_to_Bitcoind.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Capítulo 15: Conversando com Bitcoind usando C - -Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. - -Esta seção se concentra em três diferentes bibliotecas que podem ser usadas como base de programação C sofisticada: Uma biblioteca RPC e uma biblioteca JSON que juntas permitem recriar muito do que fazemos nos scripts de shell, porém, usando C; enquanto uma biblioteca ZMQ nos conecta a notificações, algo que não conseguiríamos acessar até agora. (O próximo capítulo cobrirá uma biblioteca ainda mais sofisticada chamada Libwally, para finalizar esta introdução à programação do Bitcoin com C). - -## Objetivos deste capítulo - -Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - - * Criar programas C que usam RPC para conversar com o Bitcoind; - * Criar programas C que usam ZMQ para conversar com o Bitcoind. - -Os objetivos secundários do capítulo incluem a capacidade de: - - * Entender como usar uma biblioteca RPC; - * Entender como usar uma biblioteca JSON; - * Compreender as capacidades do ZMQ; - * Entender como usar uma biblioteca ZMQ. - -## Tabela de conteúdo - - * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) - * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) - * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) - \ No newline at end of file diff --git a/pt/15_1_Accessing_Bitcoind_with_C.md b/pt/15_1_Accessing_Bitcoind_with_C.md deleted file mode 100644 index 2e97e1c..0000000 --- a/pt/15_1_Accessing_Bitcoind_with_C.md +++ /dev/null @@ -1,294 +0,0 @@ - -# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -Você já viu uma maneira alternativa de acessar as portas RPC do Bitcoind: Usando o ``curl``, que cobrimos no [Capítulo 4 Prefácio](04_4__interlude_using_curl.md). Interagir com o ``Bitcoind`` através de uma biblioteca de RPC usando C não é diferente do que já vimos, só precisamos de boas bibliotecas para nos auxiliar. Esta seção introduz um pacote chamado ``libbitcoinrpc``, que permite acessar a porta JSON-RPC do ``bitcoind``. Ele usa uma biblioteca ``curl`` para acessar os dados e usa a biblioteca ``jansson`` para codificar e decodificar o JSON. - -## Configurando o libbitcoinrpc - -Para usar o ``libbitcoinrpc``, precisaremos instalar uma configuração básica C e os pacotes dependentes, que são ``libcurl``, ``libjansson``, e ``libuuid``. Depois faremos isso no seu servidor Standup Bitcoin (ou em qualquer outro servidor Ubuntu). - -``` -$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev -Suggested packages: - libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev -The following NEW packages will be installed: - libcurl4-openssl-dev libjansson-dev uuid-dev -0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. -Need to get 358 kB of archives. -After this operation, 1.696 kB of additional disk space will be used. -Do you want to continue? [Y/n] y -``` -Agora, podemos baixar o [libbitcoinrpc no github](https://github.com/gitmarek/libbitcoinrpc/blob/master/readme.md). Vamos clonar ou pegar um arquivo zip, do jeito que preferir. - -``` -$ sudo apt-get install git -$ git clone https://github.com/gitmarek/libbitcoinrpc -``` - -> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. - -### Compilando o libbitcoinrpc. - -Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: -``` -$ PATH="/sbin:$PATH" -``` - -Para o Ubuntu, também precisaremos ajustar o ``install_libpath`` no ``makefile`` do ``libbitcoinrpc`` para instalar no ``/usr/lib`` ao invés do ``/usr/local/lib``: - -``` -$ emacs ~/libbitcoinrpc/Makefile -... -INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib -``` - -(Se preferir não usar o ``/usr/lib``, precisará alterar o ``etc/ld.so.conf`` ou os arquivos dependentes de maneira apropriada... Porém, para uma configuração de teste em uma máquina de teste, acredito que isso não seja um problema). - -Da mesma forma, vamos precisar ajustar o ``install_headerpath`` no ``Makefile`` do ``libbitcoinrpc`` para instalar no caminho ``/usr/include`` ao invés do ``/usr/local/inclusve``: - -``` -... -INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include -``` - -Agora, podemos compilar: -``` -$ cd libbitcoinrpc -~/libbitcoinrpc$ make - -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ -src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ --o .lib/libbitcoinrpc.so.0.2 \ --Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl -ldconfig -v -n .lib -.lib: - libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) -ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so -``` -Se tudo correr bem, podemos instalar o pacote: -``` -$ sudo make install -Installing to -install .lib/libbitcoinrpc.so.0.2 /usr/local/lib -ldconfig -n /usr/local/lib -ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so -install -m 644 src/bitcoinrpc.h /usr/local/include -Installing docs to /usr/share/doc/bitcoinrpc -mkdir -p /usr/share/doc/bitcoinrpc -install -m 644 doc/*.md /usr/share/doc/bitcoinrpc -install -m 644 CREDITS /usr/share/doc/bitcoinrpc -install -m 644 LICENSE /usr/share/doc/bitcoinrpc -install -m 644 Changelog.md /usr/share/doc/bitcoinrpc -Installing man pages -install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 -``` - -## Preparando o código - -``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. - -Para usar o ``libbitcoinrpc``, é importante certificar de que nossos arquivos do código incluam os cabeçalhos apropriados: -``` c -#include -#include -``` - -Precisaremos também vincular as bibliotecas apropriadas sempre que possamos compilar: - -``` -$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode -``` - -## Construindo a conexão - -Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. - -Primeiro, inicialize a biblioteca: -``` -bitcoinrpc_global_init(); -``` -Em seguida, vamos conectar ao ``Bitcoind`` com ``bitcoinrpc_cl_init_params``. Os quatro argumentos necessários para o ``bitcoinrpc_cl_init_params`` são o nome de usuário, a senha, o endereço IP e a porta. A esta altura, você deve saber todas essas informações, já que foram necessárias para realizar o trabalho com o [curl](04_4__interlude_using_curl.md). Apenas para recordar, o endereço de IP é 127.0.0.1 e a porta 18332 devem estar corretos para a configuração padrão da testenet descrita neste documento, enquanto podemos encontrar o usuário e a senha no arquivo ``~/.bitcoin/bitcoin.conf``. -``` -$ cat bitcoin.conf -server=1 -dbcache=1536 -par=1 -maxuploadtarget=137 -maxconnections=16 -rpcuser=StandUp -rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba -rpcallowip=127.0.0.1 -debug=tor -prune=550 -testnet=1 -[test] -rpcbind=127.0.0.1 -rpcport=18332 -[main] -rpcbind=127.0.0.1 -rpcport=8332 -[regtest] -rpcbind=127.0.0.1 -rpcport=18443 -``` -Com essas informações, vamos colocá-las no ``bitcoinrpc_cl_init_params``: -``` c -bitcoinrpc_cl_t *rpc_client; -rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); -``` - -> **MAINNET VS TESTNET:** A porta seria a 8332 caso estivéssemos usando a configuração da rede principal. - -Se o ``rpc_client`` for inicializado com sucesso, poderemos enviar os comandos do RPC. - -Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fechar da seguinte maneira: -``` c -bitcoinrpc_global_cleanup(); -``` - -### Testando o código de teste - -O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). - -Podemos compilar e executar o código da seguinte maneira: -``` -$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin -$ ./testbitcoin -Successfully connected to server! -``` - -> :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. - -## Fazendo uma chamada ao RPC - -Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). -``` c -bitcoinrpc_method_t *getmininginfo = NULL; -getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); -``` -Normalmente definiríamos os parâmetros em seguida, mas o ``GetMiningInfo`` não requer parâmetros, por isso podemos pular essa parte. - -Também devemos criar outros dois objetos, um "objeto de resposta" e um "objeto de erro". Eles podem ser inicializados da seguinte forma: -``` c -bitcoinrpc_resp_t *btcresponse = NULL; -btcresponse = bitcoinrpc_resp_init(); - -bitcoinrpc_err_t btcerror; -``` -Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos adicionar nosso método ``getmininginfo`` e os outros dois objetos: -``` c -bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); -``` - -### Mostrando o retorno da chamada - -Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: -``` c -json_t *jsonresponse = NULL; -jsonresponse = bitcoinrpc_resp_get(btcresponse); -``` -Se quisermos gerar os resultados completos da chamada RPC no JSON, podemos fazer com uma simples invocação do ``json_dumps``, da biblioteca ``jansson``: -``` c -printf("%s\n", json_dumps(j, JSON_INDENT(2))); -``` -No entanto, como agora estamos escrevendo programas completos, provavelmente iremos querer fazer um trabalho mais sutil, como retirar valores individuais do JSON para algum uso específico. A [Referência do Jansson](https6//jansson.readthedocs.Io/en/2.10/apiref.html) traz detalhes de como fazer. - -Assim como estávamos usando o [curl](04_4__interlude_using_curl.md), descobrimos que o RPC retorna um objeto JSON contendo um ``ID``, um ``error`` e, mais importante, um objeto JSON do tipo ``result``. - -A função ``json_object_get`` permite recuperar um valor (como o ``result``) de um objeto JSON usando chaves: -``` c -json_t *jsonresult = NULL; -jsonresult = json_object_get(jsonresponse,"result"); -printf("%s\n", json_dumps(jsonresult, JSON_INDENT(2))); -``` - -No entanto, provavelmente iremos querer analisar informações ainda mais profundas, para obter uma variável específica. Depois de recuperar o valor apropriado, precisaremos convertê-lo em um objeto C padrão usando a função ``JSON_*_value``. Por exemplo, para acessar um integer usamos o ``json_integer_value``: -``` c -json_t *jsonblocks = NULL; -jsonblocks = json_object_get(jsonresult,"blocks"); - -int blocks; -blocks = json_integer_value(jsonblocks); -printf("Block Count: %d\n",blocks); -``` - -> :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. - -### Testando o código de informação - -Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). -``` -$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo -$ ./getmininginfo -Full Response: { - "result": { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" - }, - "error": null, - "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" -} - -Just the Result: { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" -} - -Block Count: 1804406 -``` - -## Fazendo uma chamada RPC usando argumentos - -Mas e se a sua chamada RPC tiver argumentos? - -### Criando uma matriz JSON - -Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. - -Vamos criar a matriz JSON usando a função ``json_array do`` do ``jansson``: -``` c -json_t *params = NULL; -params = json_array(); -``` -Vamos fazer o processo inverso que fizemos para acessar valores do JSON: Vamos converter objetos no C para objetos no JSON usando as funções ``JSON_*``. Depois, vamos anexar tudo à matriz: -``` c -json_array_append_new(params,json_string(tx_rawhex)); -``` - -Observe que existem duas variantes para o comando de anexação: ``json_array_apend_new``, que acrescenta uma variável recém-criada, e ``json_array_apend``, que anexa uma variável existente. - -Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. - -### Atribuindo os parâmetros - -Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: -``` c -bitcoinrpc_method_set_params(rpc_method, params) -``` -Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. - -## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC - -Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. - -* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. - -## O Que Vem Depois? - -Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). diff --git a/pt/15_2_Programming_Bitcoind_with_C.md b/pt/15_2_Programming_Bitcoind_with_C.md deleted file mode 100644 index c1fdc38..0000000 --- a/pt/15_2_Programming_Bitcoind_with_C.md +++ /dev/null @@ -1,354 +0,0 @@ - -# 15.2: Programando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. - -## Planejando o código - -Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: - - 1. Solicitar um endereço e uma quantia; - 2. Definir uma taxa arbitrária; - 3. Preparar nosso RPC; - 4. Encontrar um UTXO que seja grande o suficiente para pagar o valor + a taxa; - 5. Criar uma mudança de endereço; - 6. Criar uma transação bruta que envie o UTXO para o endereço e altere o endereço; - 7. Assinar a transação; - 8. Enviar a transação. - -### Planejando para o futuro - -Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: - - 1. Testar e/ou higienizar as entradas; - 2. Calcular uma taxa automaticamente; - 3. Pensar logicamente sobre qual UTXO seria válido utilizar; - 4. Combinar vários UTXOs, caso seja necessário; - 5. Ficar atento a mais erros nos comandos ``libbitcoinrpc`` ou no ``jansson``; - 6. Observar se há erros nas respostas RPC. - -Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. - -## Escrevendo o sistema de transação - -Agora estamos prontos para realizar o passo a passo do nosso plano - -### Etapa 1: Solicitando um endereço e uma quantia - -Inserir as informações é bem simples se usarmos os argumentos na linha de comando: -``` c -if(argc != 3) { - - printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); - exit(-1); - -} - -char *tx_recipient = argv[1]; -float tx_amount = atof(argv[2]); - -printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); -``` - -> :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. - -### Etapa 2: Definindo uma taxa arbitrária - -Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: - -``` c -float tx_fee = 0.0005; -float tx_total = tx_amount + tx_fee; -``` - -> :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. - -### Etapa 3: Preparando nosso RPC - -Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: -``` c -bitcoinrpc_global_init(); -rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); -btcresponse = bitcoinrpc_resp_init(); -``` - -### Etapa 4: Encontrando um UTXO - -Para encontrar um UTXO, precisaremos chamar a função RPC ``listunspent``: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -``` - -No entanto, o verdadeiro trabalho consiste em decodificar a resposta. Na seção anterior vimos que a biblioteca ``jansson`` era "um tanto quanto desajeitada" e esta é a razão: Precisamos criar (e limpar) um conjunto muito grande de objetos ``json_t`` para descobrir o que queremos. - -Primeiro, precisamos nos recuperar o campo ``result`` do JSON: -``` c -json_t *lu_response = NULL; -json_t *lu_result = NULL; - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -``` - -> :warning: **ATENÇÃO:** Só obteremos um resultado se não houver nenhum erro. Aqui temos um momento para melhorar nossa verificação de erros no código que iremos colocar em produção. - -Em seguida, vamos fazer um laço, examinando cada transação que não foi gasta, que aparece como um elemento em sua matriz do resultado JSON: -``` c -int i; - -const char *tx_id = 0; -int tx_vout = 0; -double tx_value = 0.0; - -for(i = 0 ; i < json_array_size(lu_result) ; i++) { - - json_t *lu_data = NULL; - lu_data = json_array_get(lu_result, i); - - json_t *lu_value = NULL; - lu_value = json_object_get(lu_data,"amount"); - tx_value = json_real_value(lu_value); -``` - -O UTXO é grande o suficiente para pagar sua transação? Se sim, pegue-o! - -> :warning: **ATENÇÃO:** Um programa em produção pensaria com mais cuidado sobre qual UTXO utilizar, com base no tamanho e em outros fatores. Provavelmente não pegaria apenas o primeiro mais simples e pronto. - -``` c - if(tx_value > tx_total) { - - json_t *lu_txid = NULL; - lu_txid = json_object_get(lu_data,"txid"); - tx_id = strdup(json_string_value(lu_txid)); - - json_t *lu_vout = NULL; - lu_vout = json_object_get(lu_data,"vout"); - tx_vout = json_integer_value(lu_vout); - - json_decref(lu_value); - json_decref(lu_txid); - json_decref(lu_vout); - json_decref(lu_data); - break; - - } -``` -Você também deve limpar os principais elementos do JSON: -``` c -} - -json_decref(lu_result); -json_decref(lu_response); -``` - -> :warning: **ATENÇÃO:** Um programa em produção também se certificaria de que os UTXOs são passíveis de serem `gastos`. - -Se não encontramos nenhum UTXOs grande o suficiente, teremos que relatar este infortúnio ao usuário... E talvez, sugerir que ele deva usar um programa melhor, que irá mesclar os UTXOs de maneira correta. -``` c -if(!tx_id) { - - printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); - exit(-1); -} -``` - -> **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. - -### Etapa 5: Criando um endereço de troco - -Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); - -if(!rpc_method) { - - printf("ERROR: Unable to initialize listunspent method!\n"); - exit(-1); - -} - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -if(btcerror.code != BITCOINRPCE_OK) { - -printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); - - exit(-1); - -} - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -char *changeaddress = strdup(json_string_value(lu_result)); -``` -A única diferença é quais informações específicas são extraídas do objeto JSON. - -> :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. - -### Etapa 6: Criando uma transação bruta - -Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. - -Para criarmos esses parâmetros corretamente, precisaremos revisar o que o RPC ``createrawtransaction`` espera que passemos como argumento. Felizmente, isso é fácil de determinar usando a funcionalidade ``bitcoin-cli help``: -``` -$ bitcoin-cli help createrawtransaction -createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) -``` - -Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. - -#### Etapa 6.1: Criando os parâmetros de entrada - -Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): -``` c -json_t *inputtxid = NULL; -inputtxid = json_object(); - -json_object_set_new(inputtxid,"txid",json_string(tx_id)); -json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); -``` - -Pode-se notar que teremos que traduzir novamente cada tipo de variável C em um tipo de variável JSON usando a função apropriada, como ``json_string`` ou ``json_integer``. - -Para criar o array de entrada para todos os UTXOs, vamos usar o ``json_array`` e, em seguida, preenchê-lo com os objetos usando o ``json_array_append``: -``` c -json_t *inputparams = NULL; -inputparams = json_array(); -json_array_append(inputparams,inputtxid); -``` - -#### Etapa 6.2: Criando os parâmetros de saída - -Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: -``` c -json_t *outputparams = NULL; -outputparams = json_object(); - -char tx_amount_string[32]; -sprintf(tx_amount_string,"%.8f",tx_amount); -char tx_change_string[32]; -sprintf(tx_change_string,"%.8f",tx_value - tx_total); - -json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); -json_object_set(outputparams, changeaddress, json_string(tx_change_string)); -``` - -> :warning: **ATENÇÃO:** É possível pensar que teremos que inserir os valores do Bitcoin como sendo números, usando a função ``json_real``. Infelizmente, isso expõe um dos maiores problemas com a integração da biblioteca ``jansson`` e o Bitcoin. O Bitcoin só é válido até oito dígitos depois da casa decimal. Devemos nos lembrar que 0,00000001 BTC é um satoshi, e essa é a menor divisão possível de um Bitcoin. O tipo ``double`` no C oferecem mais dígitos do que precisamos, embora sejam frequentemente imprecisos depois das oito casas decimais. Se tentarmos convertê-los diretamente do nosso valor ``double`` no C (ou de um tipo ``float``, neste caso) para um valor Bitcoin, a imprecisão frequentemente criará um valor Bitcoin com mais de oito dígitos. Antes da versão Bitcoin Core 0.12, isso não era problema, e podíamos usar a função ``json_real``. Mas à partir dessa versão, se tentarmos usar a função ``createrawtransaction`` com mais do que oito dígitos, obteremos um erro e a transação não será criada. Como resultado, se o valor do Bitcoin _sempre_ se tornar um ``double`` ou ``float``, devemos deixar com apenas oito casas decimais antes de transformá-lo em uma ``string``. Obviamente, isso é um erro, portanto, certifique-se disso para que o código continue funcionando nas versões mais novas do Bitcoin Core. - -#### Etapa 6.3: Criando a Matriz de Parâmetros - -Para terminarmos de criar os parâmetros, só precisaremos agrupá-los em uma matriz JSON: -``` c -json_t *params = NULL; -params = json_array(); -json_array_append(params,inputparams); -json_array_append(params,outputparams); -``` - -#### Etapa 6.4: Fazendo a chamada ao RPC - -Vamos usar o método normal para criar uma chamada ao RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); -``` -Agora, porém, devemos adicionar os nossos parâmetros. Isso pode ser feito facilmente com a função ``bitcoinrpc_method_set_params``: -``` c -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for createrawtransaction"); - -} -``` -Depois, é só executar o RPC e obter os resultados: -``` c -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_rawhex = strdup(json_string_value(lu_result)); -``` -### Etapa 7. Assinando a transação - -É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_rawhex)); -``` -Por fim, vamos assinar a transação seguindo o rigamarole típico para criar uma chamada RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for signrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -``` -Novamente, usar a função ``jansson`` para acessar a saída pode ser complicado. Devemos lembrar que ``hex`` é parte de um objeto JSON, não um resultado independente, como era quando criamos a transação bruta. Claro, sempre podemos acessar essas informações a partir da ajuda da linha de comando: ``bitcoin-cli help signrawtransaction`` -``` c -lu_result = json_object_get(lu_response,"result"); -json_t *lu_signature = json_object_get(lu_result,"hex"); -char *tx_signrawhex = strdup(json_string_value(lu_signature)); -json_decref(lu_signature); -``` -> :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. - -### Etapa 8. Enviando a transação - -Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_signrawhex)); - -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); - -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for sendrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_newid = strdup(json_string_value(lu_result)); - -printf("Txid: %s\n",tx_newid); -``` - -O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. - -## Testando o código - -O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). - -Compile-o como de costume: -``` -$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress -``` -Agora, é possível utilizá-lo para enviar fundos para um endereço: - -``` -./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 -Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 -``` -Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). - -## Resumo do Programando o Bitcoind usando C com bibliotecas RPC - -Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. - -## O Que Vem Depois? - -Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md deleted file mode 100644 index fe166ac..0000000 --- a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md +++ /dev/null @@ -1,155 +0,0 @@ - -# 15.3 Recebendo notificações usando C com a biblioteca ZMQ - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. - -> :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). - -## Configurando o ZMQ - -Antes de podemos ouvir a blockchain, precisaremos configurar o ``bitcoind`` para permitir as notificações ZMQ. Por isso, precisamos instalar a biblioteca ZMQ para tirar proveito dessas notificações. - -### Configurando o ``bitcoind`` para usar o ZMQ - -O Bitcoin Core está pronto para ZMQ, mas devemos especificar os endpoints do ZMQ. O ZeroMQ publish-sockets prefixa cada item de dados com um prefixo de tópico arbitrário que permite aos clientes assinantes solicitarem apenas os itens com um prefixo correspondente. Existem atualmente quatro tópicos suportados pelo ``bitcoind``: -``` -$ bitcoind --help | grep zmq | grep address - -zmqpubhashblock=
- -zmqpubhashtx=
- -zmqpubrawblock=
- -zmqpubrawtx=
-``` - -Podemos executar o ``bitcoind`` com argumentos de linha de comando para endpoints ZMQ, como mostrado acima, mas também podemos criar um endpoint acessível adicionando linhas apropriadas ao nosso arquivo ``~/.bitcoin/bitcoin.conf`` e reiniciando o sistema. - -``` -zmqpubrawblock=tcp://127.0.0.1:28332 -zmqpubrawtx=tcp://127.0.0.1:28333 -``` -Podemos então testar se os nossos endpoints estão funcionando usando o RPC ``getzmqnotifications``: - -``` -$ bitcoin-cli getzmqnotifications -[ - { - "type": "pubrawblock", - "address": "tcp://127.0.0.1:28332", - "hwm": 1000 - }, - { - "type": "pubrawtx", - "address": "tcp://127.0.0.1:28333", - "hwm": 1000 - } -] -``` -Nosso ``bitcoind`` agora irá emitir as notificações ZMQ - -### Instalando o ZMQ - -Para aproveitar essas notificações, precisamos de uma biblioteca ZMQ para usar com o C, portanto, estaremos usando uma nova biblioteca ZMQ ao invés da biblioteca ``libbitcoinrpc`` nesta seção, mas no futuro, podemos combinar ambas. - -Felizmente, as bibliotecas ZMQ estão disponíveis por meio de pacotes Debian padrão: -``` -$ sudo apt-get install libzmq3-dev -$ sudo apt-get install libczmq-dev -``` -Agora estamos pronto para escrever o código! - -## Escrevendo o programa de notificação - -O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. - -O programa requer dois parâmetros: O primeiro é o "servidor", que é o ponto de conexão TCP exposto pelo ``bitcoind``. O segundo é o "tópico", que atualmente é o ``zmqpubhashblock``,``zmqpubhashtx``, ``zmqpubrawblock`` ou ``zmqpubrawtx``. O tópico precisa ter suporte do ``bitcoin.conf`` e o endereço IP e a porta do servidor devem corresponder ao que está definido no arquivo de configuração. - -``` c -#include -int main(int argc, char ** argv) { - - char *zmqserver; - char *topic; - - if(argc < 3) { - printf("\nUSAGE:\nchainlistener \n\n"); - return 0; - } else { - zmqserver = argv[1]; - topic = argv[2]; - } -``` -Abriremos um soquete ZMQ para o servidor e para o tópico definido: -``` c - zsock_t *socket = zsock_new_sub(zmqserver, topic); - assert(socket); -``` -Depois, vamos esperar: -``` c - while(1) { - zmsg_t *msg; - int rc = zsock_recv(socket, "m", &msg); - assert(rc == 0); - - char *header = zmsg_popstr(msg); - zframe_t *zdata = zmsg_pop(msg); - unsigned int *no = (unsigned int*)zmsg_popstr(msg); - - char *data = zframe_strhex(zdata); - int len = zframe_size(zdata); - printf("Size: %d\n", len); - printf("Data: %s", data); - printf("\nNo: %d\n", *no); - - free(header); - free(data); - free(no); - free(zdata); - zmsg_destroy(&msg); - sleep(1); - } -``` -Enquanto esperamos, observamos as mensagens no soquete ZMQ. Sempre que recebermos uma mensagem, iremos retirá-la da pilha, relatando o número, comprimento e, o os dados que foram importante para nós. - -É isso! - -Claro, quando terminar o processo, precisamos limpar tudo: -``` c - zsock_destroy(&socket); - return 0; -} -``` - -### Testando o código de notificação - -O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: -``` -$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq -``` -Depois, podemos executá-lo com os tópicos e endereços que definimos no nosso ``bitcoin.conf``: -``` -$ ./chainlistener tcp://127.0.0.1:28333 rawtx -Size: 250 -Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 -No: 67 -Size: 249 -Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 -No: 68 -Size: 250 -Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 -No: 69 -Size: 250 -Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 -No: 70 -....... -``` - -### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ - -Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. - -> :fire: ***Qual é o poder das notificações?*** Com as notificações, não dependemos mais dos usuários para emitir os comandos. Ou seja, podemos criar programas que monitoram o blockchain do Bitcoin e tomar as ações apropriadas quando certas coisas ocorrem. Isso, por sua vez, pode ser utilizado juntamente com os comandos RPC que programamos nas seções anteriores. Este também é um grande passo além do que poderíamos fazer com os scripts shell: Certamente, podemos criar scripts shell que fica ouvindo infinitamente, mas existem outras linguagens de programação que possuem ferramentas melhores para isso. - -## O Que Vem Depois? - -Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file From cfa1479e00bfdf82cfd237f32f26670f7786636a Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 25 Aug 2021 16:16:57 -0300 Subject: [PATCH 101/155] Rename chapter 18 to 19 files --- ...htning_Setup.md => 19_0_Understanding_Your_Lightning_Setup.md} | 0 ..._Lightning_Setup.md => 19_1_Verifying_Your_Lightning_Setup.md} | 0 ...ur_lightning_Setup.md => 19_2_Knowing_Your_lightning_Setup.md} | 0 ...de.md => 19_2__Interlude_Accessing_a_Second_Lightning_Node.md} | 0 pt/{18_3_Setting_Up_a_Channel.md => 19_3_Setting_Up_a_Channel.md} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename pt/{18_0_Understanding_Your_Lightning_Setup.md => 19_0_Understanding_Your_Lightning_Setup.md} (100%) rename pt/{18_1_Verifying_Your_Lightning_Setup.md => 19_1_Verifying_Your_Lightning_Setup.md} (100%) rename pt/{18_2_Knowing_Your_lightning_Setup.md => 19_2_Knowing_Your_lightning_Setup.md} (100%) rename pt/{18_2__Interlude_Accessing_a_Second_Lightning_Node.md => 19_2__Interlude_Accessing_a_Second_Lightning_Node.md} (100%) rename pt/{18_3_Setting_Up_a_Channel.md => 19_3_Setting_Up_a_Channel.md} (100%) diff --git a/pt/18_0_Understanding_Your_Lightning_Setup.md b/pt/19_0_Understanding_Your_Lightning_Setup.md similarity index 100% rename from pt/18_0_Understanding_Your_Lightning_Setup.md rename to pt/19_0_Understanding_Your_Lightning_Setup.md diff --git a/pt/18_1_Verifying_Your_Lightning_Setup.md b/pt/19_1_Verifying_Your_Lightning_Setup.md similarity index 100% rename from pt/18_1_Verifying_Your_Lightning_Setup.md rename to pt/19_1_Verifying_Your_Lightning_Setup.md diff --git a/pt/18_2_Knowing_Your_lightning_Setup.md b/pt/19_2_Knowing_Your_lightning_Setup.md similarity index 100% rename from pt/18_2_Knowing_Your_lightning_Setup.md rename to pt/19_2_Knowing_Your_lightning_Setup.md diff --git a/pt/18_2__Interlude_Accessing_a_Second_Lightning_Node.md b/pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md similarity index 100% rename from pt/18_2__Interlude_Accessing_a_Second_Lightning_Node.md rename to pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md diff --git a/pt/18_3_Setting_Up_a_Channel.md b/pt/19_3_Setting_Up_a_Channel.md similarity index 100% rename from pt/18_3_Setting_Up_a_Channel.md rename to pt/19_3_Setting_Up_a_Channel.md From 485176ee596bd4087ad990db1a3862d9f7e7ce4b Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 25 Aug 2021 16:24:10 -0300 Subject: [PATCH 102/155] Review 19_0 --- pt/19_0_Understanding_Your_Lightning_Setup.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pt/19_0_Understanding_Your_Lightning_Setup.md b/pt/19_0_Understanding_Your_Lightning_Setup.md index 3a3a6bf..e02d6f6 100644 --- a/pt/19_0_Understanding_Your_Lightning_Setup.md +++ b/pt/19_0_Understanding_Your_Lightning_Setup.md @@ -1,15 +1,15 @@ -# Capítulo 18: Compreendendo a configuração da Lightning +# Capítulo 19: Compreendendo a Configuração da Lightning > :information_source: **NOTA:** Este é um rascunho que está em andamento. Seu objetivo é que possa obter alguns comentários dos revisores iniciais. Ainda não está pronto para ser produzido. O capítulo anterior concluiu nosso trabalho com o Bitcoin propriamente dito, por meio do CLI, scripts e linguagens de programação. No entanto, existem muitos outros utilitários dentro do ecossistema Bitcoin. Neste capítulo e no próximo, iremos cobrir o que pode ser o maior e mais importante deles, a Lightning Network. Aqui, começaremos a trabalhar com a interface de linha de comando `lightning-cli`, entendendo a configuração do c-lightning e dos seus recursos, incluindo alguns exemplos e configuração básica. -## Objetivos deste capítulo +## Objetivos Deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: * Avaliar se um node c-lightning está instalado e atualizado; - * Executar comandos básicos de uma carteira Lightning ; + * Executar comandos básicos de uma carteira Lightning; * Criar um canal na Lightning. Os objetivos secundários do capítulo incluem a capacidade de: @@ -20,7 +20,7 @@ Os objetivos secundários do capítulo incluem a capacidade de: ## Tabela de Conteúdo -* [Seção 1: Verificando a configuração do c-lightning](18_1_Verifying_Your_Lightning_Setup.md) -* [Seção 2: Conhecendo a configuração do c-lightning](18_2_Knowing_Your_lightning_Setup.md) - * [Adendo: Acessando um segundo node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md) -* [Seção 3: Criando um canal na Lightning](18_3_Setting_Up_a_Channel.md) \ No newline at end of file +* [Seção 1: Verificando a Configuração do c-lightning](19_1_Verifying_Your_Lightning_Setup.md) +* [Seção 2: Conhecendo a Configuração do c-lightning](19_2_Knowing_Your_lightning_Setup.md) + * [Adendo: Acessando um Segundo Node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md) +* [Seção 3: Criando um Canal na Lightning](19_3_Setting_Up_a_Channel.md) \ No newline at end of file From 851d2a74d492883b64d393ab4dbaca1427e98329 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 25 Aug 2021 16:49:07 -0300 Subject: [PATCH 103/155] Review 19_1 --- pt/19_0_Understanding_Your_Lightning_Setup.md | 4 +- pt/19_1_Verifying_Your_Lightning_Setup.md | 72 +++++++++---------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/pt/19_0_Understanding_Your_Lightning_Setup.md b/pt/19_0_Understanding_Your_Lightning_Setup.md index e02d6f6..279604f 100644 --- a/pt/19_0_Understanding_Your_Lightning_Setup.md +++ b/pt/19_0_Understanding_Your_Lightning_Setup.md @@ -20,7 +20,7 @@ Os objetivos secundários do capítulo incluem a capacidade de: ## Tabela de Conteúdo -* [Seção 1: Verificando a Configuração do c-lightning](19_1_Verifying_Your_Lightning_Setup.md) -* [Seção 2: Conhecendo a Configuração do c-lightning](19_2_Knowing_Your_lightning_Setup.md) +* [Seção 1: Verificando a Configuração da c-lightning](19_1_Verifying_Your_Lightning_Setup.md) +* [Seção 2: Conhecendo a Configuração da c-lightning](19_2_Knowing_Your_lightning_Setup.md) * [Adendo: Acessando um Segundo Node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md) * [Seção 3: Criando um Canal na Lightning](19_3_Setting_Up_a_Channel.md) \ No newline at end of file diff --git a/pt/19_1_Verifying_Your_Lightning_Setup.md b/pt/19_1_Verifying_Your_Lightning_Setup.md index 5d3cb0c..cbf3844 100644 --- a/pt/19_1_Verifying_Your_Lightning_Setup.md +++ b/pt/19_1_Verifying_Your_Lightning_Setup.md @@ -1,16 +1,16 @@ -# 18.1: Verificando a configuração do c-lightning +# 19.1: Verificando a Configuração da c-lightning ->: information_source: ** NOTA: ** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. +>: information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Nesta seção, instalaremos e verificaremos o c-lightning, nosso utilitário para acessar a Lightning Network. +Nesta seção, instalaremos e verificaremos a c-lightning, nosso utilitário para acessar a Lightning Network. -> :book: ***O que é a Lightning Network?*** A Rede Lightning é uma rede descentralizada que usa a funcionalidade de contrato inteligente da blockchain do Bitcoin para permitir pagamentos instantâneos em uma rede de participantes. A Lightning é construída como um protocolo de segunda camada que interage com o Bitcoin para permitir que os usuários troquem seus bitcoins "fora da blockchain (ou como muitos falam, offchain)". +> :book: ***O que é a Lightning Network?*** A Rede Lightning é uma rede descentralizada que usa a funcionalidade de contrato inteligente da blockchain do Bitcoin para permitir pagamentos instantâneos em uma rede de participantes. A Lightning é construída como um protocolo de segunda camada que interage com o Bitcoin para permitir que os usuários troquem seus bitcoins "fora da blockchain" (ou o jargão em inglês, "off-chain"). -> :book: ***O que é um protocolo de segunda camada?*** A segunda camada refere-se a um protocolo secundário criado em cima do sistema de blockchain do Bitcoin. O objetivo principal desses protocolos é resolver a velocidade de transação e as dificuldades de escala que estão presentes no Bitcoin. O Bitcoin não é capaz de processar milhares de transações por segundo (TPS), então protocolos de segunda camada foram criados para resolver o problema de escalabilidade da blockchain . Essas soluções também são conhecidas como soluções de dimensionamento "offchain". +> :book: ***O que é um protocolo de segunda camada?*** A segunda camada refere-se a um protocolo secundário criado em cima do sistema de blockchain do Bitcoin. O objetivo principal desses protocolos é resolver a velocidade de transação e as dificuldades de escala que estão presentes no Bitcoin. O Bitcoin não é capaz de processar milhares de transações por segundo (TPS), então protocolos de segunda camada foram criados para resolver o problema de escalabilidade da blockchain. Essas soluções também são conhecidas como soluções de dimensionamento "off-chain". -## Instalando o C-Lightning +## Instalando a c-lightning -Se já usamos os [Bitcoin Standup Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts), talvez já o tenhamos instalado no início deste curso. Podemos testar isso verificando se o `lightningd` está em execução: +Se já usamos os [Bitcoin Standup Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts), talvez já o tenhamos instalado no início deste curso. Podemos testar isto verificando se o `lightningd` está em execução: ``` $ ps auxww | grep -i lightning standup 31213 0.0 0.2 24144 10424 pts/0 S 15:38 0:00 lightningd --testnet @@ -25,17 +25,17 @@ standup 31228 0.0 0.2 23044 8192 pts/0 S 15:38 0:00 /usr/local/libe standup 31229 0.0 0.1 22860 7556 pts/0 S 15:38 0:00 /usr/local/libexec/c-lightning/lightning_gossipd standup 32072 0.0 0.0 6208 888 pts/0 S+ 15:50 0:00 grep -i lightning ``` -Caso contrário, precisaremos instalá-lo agora. Infelizmente, se estivermos usando o Debian, precisaremos instalá-lo manualmente, compilando o código-fonte, mas ainda assim deve ser muito simples se seguirmos estas instruções. Se acontecer de estarmos em um sistema Ubuntu padrão, podemos tentar [Instalar a partir do Ubuntu ppa](#variant-install-from-ubuntu-ppa), e sempre pode tentar [Instalar os binários pré-compilados](#variant-install- binários pré-compilados). +Caso contrário, precisaremos instalá-lo agora. Infelizmente, se estivermos usando o Debian, precisaremos instalá-lo manualmente, compilando o código-fonte, mas ainda assim deve ser muito simples se seguirmos estas instruções. Se acontecer de estarmos em um sistema Ubuntu padrão, podemos tentar [Instalar a partir do Ubuntu ppa](#variant-install-from-ubuntu-ppa), e sempre podemos tentar [Instalar os binários pré-compilados](#variant-install-pre-compiled-binaries). -> :book: ***O que é a c-lightning?*** Existem três implementações diferentes da Lightning no momento: C-lightning, LND e Eclair. Todos devem ser funcionalmente compatíveis, com base nas mesmas [RFCs do BOLT](https://github.com/lightningnetwork/lightning-rfc/blob/master/00-introduction.md), mas os detalhes de implementação podem ser diferentes. Escolhemos a c-lightning como base do curso porque ela também faz parte do mesmo [Elements Project](https://github.com/ElementsProject) que também contém a Libwally. +> :book: ***O que é a c-lightning?*** Existem três implementações diferentes da Lightning no momento: C-lightning, LND e Eclair. Todos devem ser funcionalmente compatíveis, com base nas mesmas [RFCs do BOLT](https://github.com/lightningnetwork/lightning-rfc/blob/master/00-introduction.md), mas os detalhes de implementação podem ser diferentes. Escolhemos a c-lightning como base do curso porque ela também faz parte do [projeto Elements](https://github.com/ElementsProject), que contém a Libwally. -### Compilando o código-fonte da c-lightning +### Compilando o Código-Fonte da c-lightning A instalação da Lightning a partir do código-fonte deve ser bem simples se seguirmos estas instruções. -_Provavelmente_ desejaremos fazer isso em um node não prunado, pois trabalhar com nodes prunados na Lightning pode causar problemas de instalação e uso. Se configuramos nosso node no início deste curso para ser prunado, podemos querer substituí-lo por um full node agora. Se estivermos usando a testnet, devemos conseguir usar o mesmo tipo de máquina que usamos para o node prunado. +_Provavelmente_ desejaremos fazer isso em um node não prunado, pois trabalhar com nodes prunados na Lightning pode causar problemas de instalação e uso. Se, no início deste curso, configuramos nosso node para ser prunado, podemos querer substituí-lo por um full node agora. Se estivermos usando a testnet, provavelmente conseguiremos usar o mesmo tipo de máquina que usamos para o node prunado. -> :warning: **AVISO:** Realmente podemos executar o c-lightning em um node prunado. No entanto, conforme observamos no [repositório Lightning](https://github.com/ElementsProject/lightning#pruning), pode haver uma série de problemas. Para fazer isso funcionar, devemos garantir que o node da Lightning sempre tente atualizar informações sobre os blocos que o node do Bitcoin não excluiu. Para fazermos isso, devemos nos certificar de (1) que nosso node de Bitcoin está totalmente atualizado antes de iniciar nosso node da Lightning pela primeira vez e; (2) que nosso node Lightning nunca fique defasado do node do Bitcoin (para um node prunado em 550 blocos padrão, ele nunca pode ser desligado por 4 dias ou mais). Portanto, podemos usar o node assim, mas apresenta algum perigo, o que não é uma boa ideia se estivermos executando um serviço em produção. +> :warning: **AVISO:** Realmente podemos executar a c-lightning em um node prunado. No entanto, conforme observamos no [repositório Lightning](https://github.com/ElementsProject/lightning#pruning), pode haver uma série de problemas. Para fazer isso funcionar, devemos garantir que o node da Lightning sempre tente atualizar informações sobre os blocos que o node do Bitcoin não excluiu. Para fazermos isso, devemos nos certificar de que (1) nosso node de Bitcoin está totalmente atualizado antes de iniciar nosso node da Lightning pela primeira vez e; (2) nosso node Lightning nunca fique defasado do node do Bitcoin (para um node prunado em 550 blocos padrão, ele nunca pode ser desligado por 4 dias ou mais). Portanto, podemos usar o node assim, mas apresenta algum perigo, o que não é uma boa ideia se estivermos executando um serviço em produção. Dito isso, estamos prontos para instalar a Lightning: @@ -69,9 +69,9 @@ Depois disso, o que precisamos fazer é instalar: $ sudo make install ``` -## Verificando nossa instalação +## Verificando Nossa Instalação -Podemos confirmar que tudo foi instalado o lightningd corretamente usando o parâmetro `help`: +Podemos confirmar que o lightningd foi instalado corretamente usando o parâmetro `help`: ``` $ lightningd --help @@ -90,11 +90,11 @@ A bitcoin lightning daemon (default values shown for network: testnet). --mainnet Alias for --network=bitcoin ``` -## Executar a Lightningd +## Executando lightningd Começaremos a explorar a Lightning Network com o comando `lightning-cli`. No entanto, `lightningd` _deve_ estar rodando para podermos usar o `lightning-cli`, já que `lightning-cli` envia comandos JSON-RPC para o `lightningd` (tudo exatamente como o `bitcoin-cli` e o `bitcoind`). -Se instalamos o `c-lightning` manualmente, precisaremos iniciá-lo: +Se instalamos a `c-lightning` manualmente, precisaremos iniciá-la: ``` $ nohup lightningd --testnet & ``` @@ -151,7 +151,7 @@ $ sudo systemctl enable lightningd.service $ sudo systemctl start lightningd.service ``` -### Habilitando as conexões remotas +### Habilitando Conexões Remotas Se tivermos algum tipo de firewall, precisaremos abrir a porta 9735 para permitir que outros nodes da Lightning interajam conosco. @@ -160,9 +160,9 @@ Se usarmos o `ufw` do Bitcoin Standup, podemos fazer da seguinte maneira: $ sudo ufw allow 9735 ``` -## Verificando o nosso node +## Verificando o Nosso Node -Podemos verificar se o nosso node Lightning está pronto para funcionar comparando a saída de `bitcoin-cli getblockcount` com o resultado de do `blockheight` do `lightning-cli getinfo`. +Podemos verificar se o nosso node Lightning está pronto para funcionar comparando a saída de `bitcoin-cli getblockcount` com o resultado de `blockheight` do `lightning-cli getinfo`. ``` $ bitcoin-cli -testnet getblockcount @@ -220,14 +220,14 @@ Se o nosso node Lightning não estiver atualizado, receberemos uma mensagem como ``` "warning_lightningd_sync": "Still loading latest blocks from bitcoind." ``` -Se tentarmos executar em uma blockchain prunada em que o node Bitcoin não estava atualizado quando iniciamos o node Lightning, receberemos as mensagens de erro em nosso log, parecidas como esta: +Se tentarmos executar em uma blockchain prunada cujo node Bitcoin não estava atualizado quando iniciamos o node Lightning, receberemos mensagens de erro em nosso log parecidas com esta: ``` bitcoin-cli -testnet getblock 0000000000000559febee77ab6e0be1b8d0bef0f971c7a4bee9785393ecef451 0 exited with status 1 ``` -## Criando aliases +## Criando Aliases -Sugerimos a criação de alguns aliases para facilitar o uso do c-lightning. +Sugerimos a criação de alguns aliases (apelidos de comandos) para facilitar o uso da c-lightning. Podemos fazer isso colocando-os em nosso arquivo `.bash_profile`. ``` @@ -238,37 +238,37 @@ alias lnd="lightningd" alias lninfo='lightning-cli getinfo' EOF ``` -Depois de inserir esses alias, podemos executar o comando `source~/.bash_profile` para inseri-los ou apenas efetuar logout e login novamente. +Depois de inserir esses aliases, podemos executar o comando `source ~/.bash_profile` para inseri-los, ou apenas efetuar logout e login novamente. -Podemos observar que esses alias incluem atalhos para executar o `lightning-cli`, para executar o `lightningd` e para ir para o diretório c-lightning. Esses alias têm como objetivo principal tornar nossa vida mais fácil. Sugerimos criar outros apelidos para facilitar o uso de comandos frequentes (e dos argumentos) e para minimizar erros. Os aliases desse tipo podem ser ainda mais úteis se tivermos uma configuração complexa onde regularmente executamos comandos associados a Mainnet, com Testnet, _e_ com a Regtest, conforme explicado mais adiante. +Podemos observar que esses aliases incluem atalhos para executar o `lightning-cli`, para executar o `lightningd` e para ir para o diretório c-lightning. Esses aliases têm como objetivo principal tornar nossa vida mais fácil. Sugerimos criar outros apelidos para facilitar o uso de comandos frequentes (e seus argumentos) e para minimizar erros. Os aliases desse tipo podem ser ainda mais úteis se tivermos uma configuração complexa onde regularmente executamos comandos associados a Mainnet, com Testnet _e_ com a Regtest, conforme explicado mais adiante. Dito isso, o uso desses aliases _neste_ livro pode acidentalmente obscurecer as lições principais que estão sendo ensinadas sobre a c-lightning, portanto, continuaremos a mostrar os comandos completos. Podemos ajustá-los para nosso próprio uso conforme apropriado. -## Opcional: Modificando nossos tipos de servidor +## Opcional: Modificando Nossos Tipos de Servidor -> :link: **TESTNET vs MAINNET:** Ao configurar nosso node, escolhemos criá-lo como um node Mainnet, Testnet ou Regtest. Embora este documento presuma uma configuração no Testenet, vale a pena entender como podemos acessar e usar os outros tipos de configuração, mesmo todos estando na mesma máquina! Mas, se formos um usuário iniciante, podemos pular esta parte, pois não é necessário para uma configuração básica. +> :link: **TESTNET vs MAINNET:** Ao configurar nosso node, escolhemos criá-lo como um node Mainnet, Testnet ou Regtest. Embora este documento presuma uma configuração no Testenet, vale a pena entender como podemos acessar e usar os outros tipos de configuração, mesmo todos estando na mesma máquina! Mas, se você for um usuário iniciante, pode pular esta parte, pois não é necessária para uma configuração básica. -Quando o lightningd é inicializado, geralmente ele lê um arquivo de configuração cuja localização depende da rede que estamos usando (O padrão é: `~/.lightning/testnet/config`). Isso pode ser alterado com os sinalizadores `–conf` e `–lightning-dir`. +Quando o lightningd é inicializado, geralmente ele lê um arquivo de configuração cuja localização depende da rede que estamos usando (o padrão é `~/.lightning/testnet/config`). Isso pode ser alterado com os sinalizadores `–conf` e `–lightning-dir`. ``` ~/.lightning/testnet$ ls -la config -rw-rw-r-- 1 user user 267 jul 12 17:08 config ``` -Também existe um arquivo de configuração geral (O padrão é: `~/.lightning/config`). Se desejarmos executar vários tipos diferentes de nodes simultaneamente. Devemos deixar o sinalizador testnet (ou regtest) fora deste arquivo de configuração. Devemos então escolher se estamos usando a mainnet, a testnet ou a regtest toda vez que executarmos o `lightningd` ou o `lightning-cli`. +Também existe um arquivo de configuração geral (o padrão é `~/.lightning/config`). Se desejarmos executar vários tipos diferentes de nodes simultaneamente, devemos deixar o sinalizador testnet (ou regtest) fora deste arquivo de configuração. Devemos então escolher se estamos usando a mainnet, a testnet ou a regtest toda vez que executarmos o `lightningd` ou o `lightning-cli`. -Nossa configuração pode não ter nenhum arquivo de configuração. O c-lightning será executado com uma boa configuração padrão, sem eles. +Nossa configuração pode não ter nenhum arquivo de configuração: a c-lightning será executada com uma boa configuração padrão, sem eles. -## Resumo: Verificando a configuração do c-lightning +## Resumo: Verificando a Configuração da c-lightning -Antes de começar a brincar com o lightning, devemos nos certificar de que nossos aliases estão configurados, nosso `lightningd` está rodando e nosso node está sincronizado. Também podemos querer configurar algum acesso a configurações alternativas da Lightning, em outras redes. +Antes de começar a brincar com a lightning, devemos nos certificar de que nossos aliases estão configurados, nosso `lightningd` está rodando e nosso node está sincronizado. Também podemos querer configurar algum acesso a configurações alternativas da Lightning, em outras redes. ## O Que Vem Depois? -Vamos continuar "Compreendendo a configuração da Lightning" na seção [§18.2: Conhecendo a configuração do c-lightning](18_2_Knowing_Your_lightning_Setup.md). +Vamos continuar "Compreendendo a Configuração da Lightning" na seção [§19.2: Conhecendo a Configuração da c-lightning](19_2_Knowing_Your_lightning_Setup.md). -## Variante: Instalando no Ubuntu ppa +## Variante: Instalando do Ubuntu ppa -Se estivermos usando uma versão do Ubuntu diferente do Debian, podemos instalar o c-lightning usando [Ubuntu ppa](https://launchpad.net/~lightningnetwork/+archive/ubuntu/ppa): +Se estivermos usando uma versão do Ubuntu diferente do Debian, podemos instalar a c-lightning usando [Ubuntu ppa](https://launchpad.net/~lightningnetwork/+archive/ubuntu/ppa): ``` $ sudo apt-get install -y software-properties-common @@ -276,9 +276,9 @@ $ sudo add-apt-repository -u ppa:lightningnetwork/ppa $ sudo apt-get install lightningd ``` -## Variante: Instale binários pré-compilados +## Variante: Instalando Binários Pré-Compilados -Outro método para instalar a Lightning é usar os binários pré-compilados no [repositório Github](https://github.com/ElementsProject/lightning/releases). Vamos escolher o tarball mais recente, como `clightning-v0.9.1-Ubuntu-20.04.tar.xz`. +Outro método para instalar a Lightning é usar os binários pré-compilados no [repositório Github](https://github.com/ElementsProject/lightning/releases). Vamos escolher o arquivo mais recente, como `clightning-v0.9.1-Ubuntu-20.04.tar.xz`. Depois de baixá-lo, precisaremos ir para o diretório raiz e descompactá-lo: ``` From 1b36e74550e3ed2203304b59ff441aede7c21b66 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 25 Aug 2021 16:55:38 -0300 Subject: [PATCH 104/155] Review 19_2 --- pt/19_2_Knowing_Your_lightning_Setup.md | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pt/19_2_Knowing_Your_lightning_Setup.md b/pt/19_2_Knowing_Your_lightning_Setup.md index edb617c..18c2aa0 100644 --- a/pt/19_2_Knowing_Your_lightning_Setup.md +++ b/pt/19_2_Knowing_Your_lightning_Setup.md @@ -1,29 +1,29 @@ -# 18.2: Conhecendo a configuração do c-lightning +# 19.2: Conhecendo a Configuração da c-lightning > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Antes de começar a acessar a Lightning Network, devemos compreender melhor nossa configuração. +Antes de começar a acessar a Lightning Network, devemos compreender melhor a nossa configuração. -## Conhecendo o diretório da c-lightning +## Conhecendo o Diretório da c-lightning -Ao usar o c-lightning, tudo será mantindo dentro do diretório `~/.lightning`. +Ao usar a c-lightning, tudo será mantindo dentro do diretório `~/.lightning`. O diretório principal contém apenas os diretórios para as redes configuradas, neste caso da Testnet: ``` $ ls ~/.lightning testnet ``` -O diretório `~/.lightning/testnet` irá então conter a essência de nossa configuração: +O diretório `~/.lightning/testnet` irá então conter a essência da nossa configuração: ``` $ ls ~/.lightning/testnet3 config gossip_store hsm_secret lightningd.sqlite3 lightningd.sqlite3-journal lightning-rpc ``` -> :link: **TESTNET vs MAINNET:** Se estivermos usando a Mainnet, então _tudo_ será colocado no diretório principal `~/.lightning/bitcoin`. Essas várias configurações _empilham-se_ elegantemente, então se estivermos usando a Mainnet, Testnet e Regtest, descobriremos que `~/.lightning/bitcoin` contém os arquivos de configuração e os dados de mainnet, o diretório `~/.lightning/testnet` contém os dados da Testnet, e o diretório `~/.lightning/regtest` contém os dados Regtest. +> :link: **TESTNET vs MAINNET:** Se estivermos usando a Mainnet, então _tudo_ será colocado no diretório principal `~/.lightning/bitcoin`. Essas várias configurações _empilham-se_ elegantemente, então se estivermos usando a Mainnet, Testnet e Regtest, descobriremos que `~/.lightning/bitcoin` contém os arquivos de configuração e os dados da Mainnet, o diretório `~/.lightning/testnet` contém os dados da Testnet, e o diretório `~/.lightning/regtest` contém os dados Regtest. -## Conhecendo os comandos lightning-cli +## Conhecendo os Comandos lightning-cli -A maior parte do nosso trabalho inicial será feito com o comando `lightning-cli`, que oferece uma interface fácil para a `lightningd`, assim como o `bitcoin-cli`. +A maior parte do nosso trabalho inicial será feito com o comando `lightning-cli`, que oferece uma interface fácil para o `lightningd`, assim como o `bitcoin-cli`. Já vimos que o comando `help` nos dará uma lista de outros comandos: @@ -228,7 +228,7 @@ dev-rescan-outputs run `lightning-cli help ` for more information on a specific command ``` -## Conhecendo as informações de Lightning +## Conhecendo Informações da Lightning Uma variedade de comandos `lightning-cli` podem fornecer informações adicionais sobre nosso node Lightning. Os mais comuns são: ``` @@ -329,12 +329,12 @@ c$ lightning-cli --testnet listconfigs } ``` -## Resumo: Conhecendo a configuração do c-lightning +## Resumo: Conhecendo a Configuração da c-lightning -O diretório `~/.lightning` contém todos os arquivos, enquanto o comando `lightning-cli help` mostra uma variedade de informações dos comandos que podem ser usados para obter mais informações sobre nossa configuração e funcionamento da Lightning Network. +O diretório `~/.lightning` contém todos os arquivos, enquanto o comando `lightning-cli help` mostra uma variedade de informações dos comandos que podem ser usados para obter mais informações sobre a configuração e o funcionamento da Lightning Network. ## O Que Vem Depois? -Precisaremos de um segundo node para testar o pagamento dos invoices. Se precisaremos de suporte para configurar um, podemos ler o [Adendo: Acessando um segundo node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md). +Precisaremos de um segundo node para testar o pagamento dos invoices. Se precisarmos de suporte para configurar um, podemos ler o [Adendo: Acessando um segundo node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md). -Caso contrário, vamos continuar "Compreendendo sua configuração do Lightning" na seção [§18.3: Criando um canal na Lightning](18_3_Setting_Up_a_Channel.md). \ No newline at end of file +Caso contrário, vamos continuar "Compreendendo a Configuração da Lightning" na seção [§19.3: Criando um Canal na Lightning](19_3_Setting_Up_a_Channel.md). \ No newline at end of file From e54c2dafa3cbb3cbc3d3dcd23a750c41f34fa225 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 25 Aug 2021 17:13:57 -0300 Subject: [PATCH 105/155] Review 19_2__Interlude --- pt/19_2_Knowing_Your_lightning_Setup.md | 2 +- ...rlude_Accessing_a_Second_Lightning_Node.md | 72 +++++++++---------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/pt/19_2_Knowing_Your_lightning_Setup.md b/pt/19_2_Knowing_Your_lightning_Setup.md index 18c2aa0..044cf8c 100644 --- a/pt/19_2_Knowing_Your_lightning_Setup.md +++ b/pt/19_2_Knowing_Your_lightning_Setup.md @@ -335,6 +335,6 @@ O diretório `~/.lightning` contém todos os arquivos, enquanto o comando `light ## O Que Vem Depois? -Precisaremos de um segundo node para testar o pagamento dos invoices. Se precisarmos de suporte para configurar um, podemos ler o [Adendo: Acessando um segundo node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md). +Precisaremos de um segundo node para testar o pagamento dos invoices. Se precisarmos de suporte para configurar um, podemos ler o [Adendo: Acessando um Segundo Node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md). Caso contrário, vamos continuar "Compreendendo a Configuração da Lightning" na seção [§19.3: Criando um Canal na Lightning](19_3_Setting_Up_a_Channel.md). \ No newline at end of file diff --git a/pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md b/pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md index cccd6ea..33f330d 100644 --- a/pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md +++ b/pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md @@ -1,16 +1,16 @@ -# Adendo: Acessando um segundo node Lightning +# Adendo: Acessando um Segundo Node Lightning -> :information_source: ** NOTA: ** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Quando estávamos brincando com o Bitcoin, estávamos acessando uma rede existente, e isso torna tudo relativamente fácil para se trabalhar. Apenas ligávamos o `bitcoind` e estávamos imediatamente interagindo com a rede. Agora, é assim que a Lightning funciona: É fundamentalmente uma rede ponto a ponto, construída a partir das conexões entre dois nodes individuais. Em outras palavras, para interagir com a Lightning Network, precisaremos primeiro encontrar um node ao qual podemos nos conectar. +Quando estávamos brincando com o Bitcoin, estávamos acessando uma rede existente, e isso torna tudo relativamente fácil para se trabalhar. Apenas ligávamos o `bitcoind` e estávamos imediatamente interagindo com a rede. Agora, a Lightning funciona da seguinte maneira: é fundamentalmente uma rede ponto a ponto, construída a partir das conexões entre dois nodes individuais. Em outras palavras, para interagir com a Lightning Network, precisaremos primeiro encontrar um node ao qual podemos nos conectar. -Existem quatro maneiras de fazermos isso, as três primeiras são possíveis para a nossa primeira conexão: +Existem quatro maneiras de fazermos isso (das quais as três primeiras são possíveis para a nossa primeira conexão): -## Pedindo informações sobre um node +## Pedindo Informações Sobre um Node Se outra pessoa já tiver um node da Lightning Network na rede que escolhemos, podemos pedir o ID dele. -Se estiverem executando o c-lightning, eles só precisam usar o comando `getinfo`: +Se estiverem executando a c-lightning, eles só precisam usar o comando `getinfo`: ``` $ lightning-cli getinfo lightning-cli: WARNING: default network changing in 2020: please set network=testnet in config! @@ -48,23 +48,23 @@ lightning-cli: WARNING: default network changing in 2020: please set network=tes "lightning-dir": "/home/standup/.lightning/testnet" } ``` -Eles podem então poderão nos dizer o `ID` (`03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687`). Eles também precisarão informar o endereço IP (`74.207.240.32`) e porta (`9735`). +Eles poderão então nos dizer o `ID` deles (`03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687`). Eles também precisarão informar o endereço IP (`74.207.240.32`) e porta (`9735`). -## Criando um novo node c-lightning +## Criando um Novo Node c-lightning -No entanto, para fins de teste, provavelmente iremos desejar ter um segundo node sob nosso próprio controle. A maneira mais fácil de fazer isso é criar um segundo node c-lightning em uma nova máquina, usando Bitcoin Standup, de acordo com a seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) ou compilando-o manualmente, de acordo com a seção [§18.1](18_1_Verifying_Your_Lightning_Setup .md). +No entanto, para fins de teste, provavelmente iremos desejar ter um segundo node sob nosso próprio controle. A maneira mais fácil de fazer isso é criar um segundo node c-lightning em uma nova máquina, usando Bitcoin Standup, de acordo com a seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) ou compilando-o manualmente, de acordo com a seção [§19.1](19_1_Verifying_Your_Lightning_Setup.md). Depois de ter nosso node em execução, podemos executar o `getinfo` para recuperar nossas informações, como mostrado acima. -## Criando um novo node LND +## Criando um Novo Node LND -No entanto, para nossos exemplos no próximo capítulo, vamos criar um node LND. Isso nos permitirá demonstrar um pouco da profundidade do ecossistema Lightning, mostrando como comandos semelhantes funcionam nas duas plataformas diferentes. +No entanto, para os exemplos do próximo capítulo, vamos criar um node LND. Isso nos permitirá demonstrar um pouco da profundidade do ecossistema Lightning, mostrando como comandos semelhantes funcionam nas duas plataformas diferentes. Uma maneira de criar um node LND é executar os scripts Bitcoin Standup novamente em uma nova máquina, mas desta vez escolher a LND, de acordo com a seção [§2.1](2_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md). Outra forma é compilar o LND a partir do código-fonte em uma máquina em que já estejamos executando um node Bitcoin, como falaremos abaixo. -### Compilando o código-fonte LND +### Compilando o Código-Fonte do LND Primeiro, precisaremos baixar e instalar o Go: ``` @@ -72,9 +72,9 @@ $ wget --progress=bar:force https://dl.google.com/go/"go1.14.4"."linux"-"amd64". $ /bin/tar xzf ~standup/"go1.14.4"."linux"-"amd64".tar.gz -C ~standup $ sudo mv ~standup/go /usr/local ``` -Depois, precisamos nos certificar de que a versão Go é a mais atualizada (atualmente é a `go1.14.4`), e a plataforma e arquitetura são adequadas para nossa máquina. O item acima funcionará para o Debian. +Depois, precisamos nos certificar de que a versão Go é a mais atualizada (atualmente é a `go1.14.4`), e que a plataforma e arquitetura são adequadas para nossa máquina. O item acima funcionará para o Debian. -Vamos atulizar o caminho: +Vamos atualizar nosso PATH: ``` $ export GOPATH=~standup/gocode $ export PATH="$PATH":/usr/local/go/bin:"$GOPATH"/bin @@ -89,7 +89,7 @@ Também precisaremos do `git` e do `make`: $ sudo apt-get install git $ sudo apt-get install build-essential ``` -Agora estamos pronto para recuperar o LND. Certifique-se de obter a versão atual (no momento, é a `v0.11.0-beta.rc4`). +Agora estamos prontos para recuperar o LND. Certifique-se de obter a versão atual (no momento, é a `v0.11.0-beta.rc4`). ``` $ go get -d github.com/lightningnetwork/lnd ``` @@ -107,21 +107,21 @@ Devemos alterá-la para os diretórios globais: $ sudo cp $GOPATH/bin/lnd $GOPATH/bin/lncli /usr/bin ``` -### Criando um arquivo de configuração LND +### Criando um Arquivo de Configuração do LND -Ao contrário do c-lightning, precisaremos criar um arquivo de configuração padrão para o LND. +Ao contrário da c-lightning, precisaremos criar um arquivo de configuração padrão para o LND. -No entanto, primeiro, iremos precisar habilitar o ZMQ em nosso Bitcoind, se ainda não o fizemos na seção [§15.3](15_3_Receiving_Bitcoind_Notifications_with_C.md). +No entanto, primeiro, iremos precisar habilitar o ZMQ em nosso Bitcoind, se ainda não o fizemos na seção [§16.3](16_3_Receiving_Bitcoind_Notifications_with_C.md). -Isso requer adicionar o seguinte ao nosso arquivo `~/.bitcoin/bitcoin.conf` se ainda não estiver lá: +Isso requer adicionar o seguinte ao nosso arquivo `~/.bitcoin/bitcoin.conf`, se ainda não estiver lá: ``` zmqpubrawblock=tcp://127.0.0.1:28332 zmqpubrawtx=tcp://127.0.0.1:28333 ``` -Se estivermos usando um arquivo de configuração Bitcoin do Standup ou algum outro `conf` especializado, precisamos nos certificar de colocar nossos novos comandos na seção correta. Idealmente, devemos chegar perto do topo do arquivo, caso contrário, na seção `[test]` (assumindo, como de costume, que estamos testando na testnet). +Se estivermos usando um arquivo de configuração Bitcoin do Standup ou algum outro `conf` especializado, precisamos nos certificar de colocar nossos novos comandos na seção correta. Idealmente, devemos chegar perto do topo do arquivo, caso contrário, na seção `[test]` (assumindo, como de costume, que estamos usando a testnet). -Devemos então, reiniciar o bitcoin (ou apenas reiniciar nossa máquina). Podemos testar se está tudo funcionando da seguinte maneira: +Devemos então reiniciar o Bitcoin (ou apenas reiniciar nossa máquina). Podemos testar se está tudo funcionando da seguinte maneira: ``` $ bitcoin-cli getzmqnotifications [ @@ -139,7 +139,7 @@ $ bitcoin-cli getzmqnotifications ``` Agora estamos prontos para criar um arquivo de configuração. -Primeiro, precisamos recuperar nosso rpcuser e rpcpassword. Esta é uma maneira automatizada de fazer isso: +Primeiro, precisamos recuperar nosso rpcuser e rpcpassword. A seguinte é uma maneira automatizada de fazer isso: ``` $ BITCOINRPC_USER=$(cat ~standup/.bitcoin/bitcoin.conf | grep rpcuser | awk -F = '{print $2}') $ BITCOINRPC_PASS=$(cat ~standup/.bitcoin/bitcoin.conf | grep rpcpassword | awk -F = '{print $2}') @@ -171,7 +171,7 @@ bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 EOF ``` -### Criando um serviço LND +### Criando um Serviço LND Finalmente, podemos criar um serviço LND para executar automaticamente o `lnd`: ``` @@ -203,22 +203,22 @@ RestartSec=60 WantedBy=multi-user.target EOF ``` -Em seguida, precisaremos instalar isso e iniciar as coisas: +Em seguida, precisaremos instalar aquilo e iniciar as coisas: ``` $ sudo cp ~/lnd.service /etc/systemd/system $ sudo systemctl enable lnd $ sudo systemctl start lnd ``` -É esperado que a primeira vez demore um tempo para a inicialização. +(É esperado que a primeira vez leve um certo tempo.) -### Habilitando as conexões remotas +### Habilitando Conexões Remotas -Assim como com o c-lightning, precisaremos tornar o LND acessível a outros nodes. Veja como fazer isso se usarmos o `ufw`, de acordo com as configurações do Bitcoin Standup: +Assim como na c-lightning, precisaremos tornar o LND acessível a outros nodes. Veja como fazer isso se usarmos o `ufw`, de acordo com as configurações do Bitcoin Standup: ``` $ sudo ufw allow 9735 ``` -### Criando uma carteira +### Criando uma Carteira Na primeira vez que executamos o LND, devemos criar uma carteira: ``` @@ -292,11 +292,11 @@ $ lncli --network=testnet getinfo } } ``` -O ID deste node é `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543`. Embora este comando não mostre o endereço IP e a porta, eles devem ser o endereço IP da nossa máquina e a porta `9735`. +O ID deste node é `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543`. Embora este comando não nos mostre o endereço IP e a porta, eles devem ser o endereço IP da nossa máquina e a porta `9735`. -## Ouvindo a Lightning +## Escute a Fofoca -Se já estivermos conectados à Lightning Network, nosso node já deve estar "fofocando" com seus pares, também já pode ser capaz de encontrar informações sobre os pares automaticamente, por meio do comando `listpeers`: +Se já estivéssemos conectados à Lightning Network, e nosso node já estivesse "fofocando" com seus pares, também poderíamos ser capazes de encontrar informações sobre os pares automaticamente, por meio do comando `listpeers`: ``` c$ lightning-cli --network=testnet listpeers { @@ -313,14 +313,14 @@ c$ lightning-cli --network=testnet listpeers ] } ``` -No entanto, esse definitivamente não será o caso da nossa primeira interação com a Lightning Network. +No entanto, este definitivamente não será o caso na nossa primeira interação com a Lightning Network. -## Resumo: Adendo: Acessando um segundo node Lightning +## Resumo: Adendo: Acessando um Segundo Node Lightning -Sempre precisaremos de dois nodes Lightning para formar um canal. Se não tivermos outra pessoa que está testando as coisas conosco, precisaremos criar um segundo node, usando c-lightning ou (como faremos em nossos exemplos) usando a LND. +Sempre precisaremos de dois nodes Lightning para formar um canal. Se não tivermos outra pessoa que está testando as coisas conosco, precisaremos criar um segundo node, usanda c-lightning ou (como faremos em nossos exemplos) usando a LND. ## O Que Vem Depois? -Embora possivelmente tenhamos criado um LND, o c-lightning permanecerá o coração dos nossos exemplos até que precisemos começar a usar os dois, no [Capítulo 19](19_0_Understanding_Your_Lightning_Setup.md). +Embora possivelmente tenhamos criado um LND, a c-lightning permanecerá no centro dos nossos exemplos até que precisemos começar a usar os dois, no [Capítulo 19](19_0_Understanding_Your_Lightning_Setup.md). -Vamos continuar "Compreendendo a configuração da Lightning" na seção [§18.3: Criando um canal na Lightning](18_3_Setting_Up_a_Channel.md). +Vamos continuar "Compreendendo a Configuração da Lightning" na seção [§19.3: Criando um Canal na Lightning](19_3_Setting_Up_a_Channel.md). From b804f5147b545b3b1c66f0d124005031fb92a0ea Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 25 Aug 2021 17:43:27 -0300 Subject: [PATCH 106/155] Review 19_3 --- pt/19_3_Setting_Up_a_Channel.md | 40 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pt/19_3_Setting_Up_a_Channel.md b/pt/19_3_Setting_Up_a_Channel.md index b193b06..386c43e 100644 --- a/pt/19_3_Setting_Up_a_Channel.md +++ b/pt/19_3_Setting_Up_a_Channel.md @@ -1,30 +1,30 @@ -# 18.3: Criando um canal na Lightning +# 19.3: Criando um Canal na Lightning > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Agora que entendemos o básico da configuração da Lightning e, com sorte, já criamos ou recebemos informações sobre um segundo node Lightning. Estamos prontos para criar nosso primeiro canal na Lightning Network. Claro, precisaremos entender o que é e como é criado usando o c-lightning. +Agora que entendemos o básico da configuração da Lightning e, com sorte, já criamos ou recebemos informações sobre um segundo node Lightning, estamos prontos para criar nosso primeiro canal na Lightning Network. Claro, precisaremos entender o que ele é e como é criado usando a c-lightning. -> :book: ***O que é um canal Lightning?*** De maneira simples, um canal Lightning é um tubo de dinheiro que permite transferências rápidas, baratas e privadas sem enviar transações para a blockchain. Mais tecnicamente, um canal é uma transação de Bitcoin em cadeia com várias assinaturas 2 de 2 que estabelece um relacionamento financeiro sem confiança entre duas pessoas ou dois agentes. Uma certa quantia de dinheiro é depositada no canal, quando então se mantém um banco de dados local com saldo em bitcoins para ambas as partes, mantendo o registro de qual é o saldo de cada parte. Os dois usuários podem então trocar bitcoins por meio do canal Lightning sem nunca escrever na blockchain do Bitcoin. Somente quando desejam fechar o canal, eles liquidam os bitcoins na blockchain, com base no saldo final das moedas. +> :book: ***O que é um canal Lightning?*** De maneira simples, um canal Lightning é um tubo de dinheiro que permite transferências rápidas, baratas e privadas sem enviar transações para a blockchain. Mais tecnicamente, um canal é uma transação multisig 2-de-2 no Bitcoin que estabelece um relacionamento financeiro sem confiança entre duas pessoas ou dois agentes. Uma certa quantia de dinheiro é depositada no canal, quando então se mantém um banco de dados local com saldo em bitcoins para ambas as partes, mantendo o registro de qual é o saldo de cada parte. Os dois usuários podem então trocar bitcoins por meio do canal Lightning sem nunca escrever na blockchain do Bitcoin. Somente quando desejam fechar o canal é que eles dividem os bitcoins na blockchain, com base na divisão final das moedas para cada um. > :book: ***Como os canais Lightning criam uma rede Lightning?*** Embora um canal Lightning só permita o pagamento entre dois usuários, os canais podem ser conectados para formar uma rede que permite pagamentos entre membros que não têm um canal direto entre eles. Isso cria uma rede entre várias pessoas, construída a partir de conexões em pares. -Nesta seção, continuaremos usando nossa configuração c-lightning como nosso node principal. +Nesta seção, continuaremos usando nossa configuraçãa c-lightning como nosso node principal. -## Criando um canal +## Criando um Canal A criação de um canal Lightning requer as seguintes etapas: * Financiar nossa carteira c-lightning com alguns satoshis; -* Conectar-se a um nó remoto como um par; +* Conectar-se a um node remoto como um par; * Abrir um canal. -### Financiando nossa carteira c-lightning +### Financiando Nossa Carteira c-lightning Para mover fundos para um canal Lightning, primeiro é necessário financiar nossa carteira c-lightning. -> :book: ***O que é uma carteira c-lightning?*** A implementação padrão a c-lightning vem com uma carteira Bitcoin integrada que permite enviar e receber transações bitcoin na blockchain. Esta carteira será usada para criar novos canais. +> :book: ***O que é uma carteira c-lightning?*** A implementação padrão da c-lightning vem com uma carteira Bitcoin integrada que permite enviar e receber transações de bitcoin na blockchain. Esta carteira será usada para criar novos canais. -A primeira coisa que precisamos fazer é enviar alguns satoshis para nossa carteira c-lightning. Podemos criar um novo endereço usando o comando `lightning-cli newaddr`. Isso gera um novo endereço que pode ser subsequentemente usado para financiar canais gerenciados pelo node c-lightning. Podemos especificar o tipo de endereço desejado. Se não for especificado, o endereço gerado será um bech32. +A primeira coisa que precisamos fazer é enviar alguns satoshis para nossa carteira c-lightning. Podemos criar um novo endereço usando o comando `lightning-cli newaddr`. Isto gera um novo endereço que pode ser subsequentemente usado para financiar canais gerenciados pelo node c-lightning. Podemos especificar o tipo de endereço desejado; se não for especificado, o endereço gerado será um bech32. ``` $ lightning-cli --testnet newaddr @@ -37,7 +37,7 @@ Podemos então enviar fundos para este endereço usando `bitcoin-cli sendtoaddre Esta transação é chamada de [transação de financiamento](https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#funding-transaction-output) e precisa ser confirmada antes que os fundos possam ser utilizados. -> :book: ***O que é uma transação de financiamento?*** Uma transação de financiamento é uma transação de Bitcoin que coloca dinheiro em um canal Lightning. Pode ser de financiamento único (por um participante) ou de financiamento duplo (por ambos). A partir daí, as transações da Lightning tratam de realocar a propriedade da transação de financiamento, mas só se ajustam na blockchain quando o canal é fechado. +> :book: ***O que é uma transação de financiamento?*** Uma transação de financiamento é uma transação de bitcoin que coloca dinheiro em um canal Lightning. Pode ser de financiamento único (por um participante) ou de financiamento duplo (por ambos). A partir daí, as transações da Lightning tratam de realocar a propriedade da transação de financiamento, mas só se ajustam na blockchain quando o canal é fechado. Para verificar nosso saldo local, devemos usar o comando `lightning-cli listfunds`: @@ -76,11 +76,11 @@ Observe que o valor está listado em satoshis ou microsatoshis, não em Bitcoin! Agora que financiamos nossa carteira c-lightning, precisaremos de informações sobre um node remoto para começar a criar o processo do canal. -### Conectando a um node Remoto +### Conectando a um Node Remoto A próxima coisa que precisaremos fazer é conectar nosso node a um par. Isso é feito com o comando `lightning-cli connect`. Lembre-se que se quisermos mais informações sobre este comando, devemos digitar `lightning-cli help connect`. -Para conectar nosso nodes a um par remoto, precisaremos do nosso id, que representa a chave pública do node de destino. Por conveniência, o `ID` pode ter a forma `id@host` ou `id@host:port`. Podemos ter recuperado isso com o `lightning-cli getinfo` (no c-lightning) ou `lncli --network=testnet getinfo` (no LND) conforme discutido no [adendo anterior](18_2__Interlude_Accessing_a_Second_Lightning_Node.md). +Para conectar nosso node a um par remoto, precisaremos do nosso id, que representa a chave pública do node de destino. Por conveniência, o `ID` pode ter a forma `id@host` ou `id@host:port`. Podemos já ter pego esta informação com o `lightning-cli getinfo` (na c-lightning) ou `lncli --network=testnet getinfo` (no LND) conforme discutido no [adendo anterior](19_2__Interlude_Accessing_a_Second_Lightning_Node.md). Selecionamos o node LND, `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543`, que está localizado no endereço IP `45.33.35.151`, ao qual vamos nos conectar a partir de nosso node c-lightning: @@ -92,15 +92,15 @@ $ lightning-cli --network=testnet connect 032a7572dc013b6382cde391d79f292ced2730 } ``` -### Abrindo um canal +### Abrindo um Canal -O comando fundchannel do RPC abre um canal de pagamento com um par ao comprometer uma transação de financiamento para o blockchain. Devemos usar o comando `lightning-cli fundchannel` para fazer isso, com os seguintes parâmetros: +O comando fundchannel do RPC abre um canal de pagamento com um par ao comprometer uma transação de financiamento para a blockchain. Devemos usar o comando `lightning-cli fundchannel` para fazer isso, com os seguintes parâmetros: * **id** é o retorno do id do peer da conexão; * **amount** é o valor em satoshis retirado da carteira interna para financiar o canal. O valor não pode ser inferior ao limite mínimo, atualmente definido como 546 satoshis, nem superior a 16.777.215 satoshis (a menos que grandes canais tenham sido negociados com o par). * **feerate** é o feerate opcional usado para a transação de abertura e como feerate inicial para transações de confirmação e HTLC. * **announce** é um sinalizador opcional que aciona o anúncio deste canal ou não. O padrão é verdadeiro. Se desejarmos criar um canal privado, precisamos definí-lo como falso. -* **minconf** especifica o número mínimo de confirmações que devem ter saídas usadas no processo de abertura de canal. O padrão é 1. +* **minconf** especifica o número mínimo de confirmações que saídas usadas no processo de abertura do canal devem ter. O padrão é 1. * **utxos** especifica os utxos a serem usados ​​para financiar o canal, como uma matriz de “txid:vout”. Agora podemos abrir o canal assim: @@ -158,11 +158,11 @@ c$ lightning-cli --testnet listfunds } ``` -Embora este novo canal com 100.000 satoshis não esteja confirmado, nosso estado será `CHANNELD_AWAITING_LOCKIN`. Observe que a alteração não confirmada de satoshis `99847` também está aparecendo como uma nova transação na carteira. Depois que todas as seis confirmações forem concluídas, o canal mudará para o estado `CHANNELD_NORMAL`, que será o estado permanente. Nesse momento, um `short_channel_id` também aparecerá, como: +Embora este novo canal com 100.000 satoshis não esteja confirmado, nosso estado será `CHANNELD_AWAITING_LOCKIN`. Observe que a alteração não confirmada de `99847` satoshis também está aparecendo como uma nova transação na carteira. Depois que todas as seis confirmações forem concluídas, o canal mudará para o estado `CHANNELD_NORMAL`, que será o estado permanente. Nesse momento, um `short_channel_id` também aparecerá, por exemplo: ``` "short_channel_id": "1862856x29x0", ``` -Esses valores indicam onde a transação de financiamento pode ser encontrada na blockchain. Ele aparece na forma `bloco x txid x vout`. +Esses valores indicam onde a transação de financiamento pode ser encontrada na blockchain. Ela aparece na forma `bloco x txid x vout`. Neste caso, `1862856x29x0` significa: @@ -174,12 +174,12 @@ Podemos precisar usar este `short_channel_id` para certos comandos na Lightning. Esta transação de financiamento também pode ser encontrada onchain pelo TXID [66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d] (https://mempool.space/pt/testnet/tx/66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d) -> :book: ***O que é a capacidade do canal?*** Em um canal Lightning, ambos os lados do canal possuem uma parte da capacidade. O valor do lado do canal é chamado de *saldo local (local balance)* e o valor do outro lado é chamado de *saldo remoto (remote balance)*. Ambos os saldos podem ser atualizados muitas vezes sem fechar o canal (quando o saldo final é enviado para a blockchain), mas a capacidade do canal não pode mudar sem fechá-lo. A capacidade total de um canal é a soma do saldo de cada participante do canal. +> :book: ***O que é a capacidade do canal?*** Em um canal Lightning, ambos os lados do canal possuem uma parte da capacidade. O valor do seu lado do canal é chamado de *saldo local (local balance)* e o valor do outro lado é chamado de *saldo remoto (remote balance)*. Ambos os saldos podem ser atualizados muitas vezes sem fechar o canal (quando o saldo final é enviado para a blockchain), mas a capacidade do canal não pode mudar sem fechá-lo. A capacidade total de um canal é a soma do saldo de cada participante do canal. -## Resumo: Criando um canal na Lightning +## Resumo: Criando um Canal na Lightning Precisaremos criar um canal com um node remoto para poder receber e enviar dinheiro pela Lightning Network. ## O Que Vem Depois? -Você está pronto para passar para o [Capítulo 19: Usando Lightning](19_0_Using_Lightning.md). \ No newline at end of file +Você está pronto para passar para o [Capítulo 20: Usando Lightning](20_0_Using_Lightning.md). \ No newline at end of file From cca0ae27050e3c86988a042b3c3f7febea737224 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 30 Aug 2021 12:23:12 -0300 Subject: [PATCH 107/155] Translate 02_1 --- ..._Up_a_Bitcoin-Core_VPS_with_StackScript.md | 256 ++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md diff --git a/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md b/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md new file mode 100644 index 0000000..bc3d35f --- /dev/null +++ b/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md @@ -0,0 +1,256 @@ +# 2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup + +Este documento explica como configurar um VPS (Servidor Privado Virtual, ou no inglês, Virtual Private Server) para rodar um node do Bitcoin em Linode.com, instalado usando um StackScript automatizado do [projeto Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Você apenas precisa copiar e colar alguns comandos e inicializar o seu VPS. Quase que imediatamente após a inicialização, você encontrará o seu novo node do Bitcoin alegremente baixando blocos. + + +> :warning: **AVISO:** Não use o VPS para uma carteira de bitcoin com fundos reais significativos; veja http://blog.thestateofme.com/2012/03/03/lessons-to-be-learned-from-the-linode-bitcoin-incident/ . Ele é muito bom para poder experimentar com transações de bitcoin reais em um node online sem atar um servidor auto-hospedado na sua rede local. Ele também é útil para poder usar um iPhone ou iPad para comunicar via SSH com o seu VPS para fazer algumas tarefas Bitcoin simples. Mas um nível mais alto de segurança é preciso para fundos significantes. + +* Se você quiser saber o que essa configuração faz, leia o [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md) enquanto o instala. +* Se, ao invés disso, você quiser configurá-lo em outra máquina que não seja um VPS na Linode, como uma máquina na AWS ou um Mac, vá para [§2.2: Configurando um Bitcoin-Core de Outras Maneiras](02_2_Setting_Up_Bitcoin_Core_Other.md) +* Se você já tem um node do Bitcoin rodando, vá para [Capítulo Três: Compreendendo a Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). + +## Começando com a Linode + +A Linode é um serviço de hospedagem na nuvem que oferece servidores rápidos e baratos com armazenamento SSD. Nós a utilizamos neste tutorial principalmente porque os seus StackScripts feitos para BASH oferecem uma maneira fácil de automaticamente configurar um node Bitcoin sem confusão e bagunça. + +### Configure uma Conta na Linode + +Você pode criar uma conta na Linode por aqui: + +``` +https://www.linode.com +``` + +Se preferir, o seguinte código de indicação te dará dois meses de uso grátis (até U$100), ótimo para aprender sobre Bitcoin: + +[https://www.linode.com/?r=3c7fa15a78407c9a3d4aefb027539db2557b3765](https://www.linode.com/?r=3c7fa15a78407c9a3d4aefb027539db2557b3765) + +Você precisará prover um endereço de email e depois pré-carregar dinheiro de um cartão de crédito ou do PayPal para eventuais custos futuros. + +Quando estiver terminado, você deve cair em [https://cloud.linode.com/dashboard](https://cloud.linode.com/dashboard). + +### Considere Autenticação de Dois Fatores + +A segurança do seu servidor não estará completa se pessoas possam invadir a sua conta da Linode, então considere ativar a Autenticação de Dois Fatores para ele. Você pode encontrar essa configuração na [página Minha Conta: Senha e Autenticação](https://manager.linode.com/profile/auth). Se você não fizer isso agora, anote como tarefa para voltar e fazê-lo depois. + +## Criando a Imagem Linode usando um StackScript + +### Load the StackScript + +Faça o download do [Linode Standup Script](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) pelo [repositório do Bitcoin Standup Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Este script basicamente automatiza todas as instruções de configuração do VPS Bitcoin. Se você quiser ser particularmente prudente, leia-o com atenção. Se estiver satisfeito, pode copiar o StackScript para sua conta Linode e selecionar [Criar Novo StackScript](https://cloud.linode.com/stackscripts/create). Dê a ele um bom nome (nós usamos `Bitcoin Standup`), então copie e cole o script. Escolha Debian 10 para sua imagem alvo e clique em "Salvar". + +### Faça a Configuração Inicial + +Agora você está pronto para criar um node baseado no StackScript. + +1. Na [página de StackScripts](https://cloud.linode.com/stackscripts?type=account), clique em "..." à esquerda do seu novo script e escolha "Deploy New Linode". +2. Coloque um hostname curto e qualificado por completo + * **Hostname Curto.** Escolha um nome para o seu VPS. Por exemplo, "meutestebtc". + * **Hostname Qualificado por Completo.** Se você for incluir este VPS como parte de uma rede com recordes DNS completos, escreva o hostname com seu domínio. Por exemplo, "meutestebtc.meudominio.com". Caso contrário, apenas repita o hostname curto e adicione ".local", por exemplo "meutestebtc.local". +3. Coloque a senha do usuário "standup". +4. Escolha um Tipo de Instalação nas opções avançadas. + * **Tipo de Instalação.** Provavelmente isto será "Mainnet" ou "Mainnet Prunado" se você estiver configurando um node para uso e "Testnet" ou "Testnet Prunado" se você estiver apenas testando. A maior parte deste tutorial irá assumir que você tenha escolhido "Testnet Prunado", mas você deve conseguir segui-lo mesmo com os outros tipos. Veja a [Sinopse](#synopsis-bitcoin-installation-types) para maiores informações sobre essas opções. (Perceba que se você estiver planejando a tentar os capítulos de Lightning, você provavelmente se dará melhor com um node não prunado, pois trabalhar com nodes prunados na Lightning é experimental. Refira à seção [§19.1](19_1_Verifying_Your_Lightning_Setup.md#compiling-the-source-code) para maiores informações.) +5. Preencha quaisquer outras opções avançadas aplicáveis. + * **Chave Pública X25519.** Esta é a chave pública para adicionar à lista de clientes autorizados do Tor. Se você não a utilizar, qualquer pessoa que obtiver acesso ao QR code do seu node poderá acessá-lo. Você receberá esta chave pública do cliente que você estiver utilizando para acessar o seu node. Por exemplo, se você estiver utilizando a [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2), você pode ir às configurações e clicar em "Export Tor V3 Authentication Public Key" para usá-la aqui. + * **Chave SSH.** Copie a chave SSH do seu computador local para este campo; isto permite que você possa fazer login automaticamente à conta standup via SSH. Se você ainda não configurou uma chave SSH no seu computador local, o [Github](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/) contém boas instruções para isto. Você provavelmente também irá querer adicionar sua chave SSH ao seu LISH (Linode Interactive Shell) através da sua "Linode Home Page / My Preferences / LISH Settings / LISH Keys". Usar SSH te proporcionará uma maneira mais fácil e simples de fazer login no seu servidor. + * **IPs Permitidos para SSH.** Esta é uma lista de endereços IP separados por vírgula que serão autorizados a se conectarem via SSH ao seu VPS. Por exemplo "192.168.1.15,192.168.1.16". Se você não adicionar nenhum IP, _o seu VPS não estará muito seguro_. Ele será bombardeado constantemente por hackers tentando encontrar uma forma de adentrá-lo, e podem conseguir. +4. Selecione uma Imagem + * **Imagem Alvo.** Se você seguiu as instruções, isto apenas irá deixá-lo selecionar "Debian 10" (apesar de que "Debian 9" tem funcionado com versões posteriores deste StackScript e pode ser que ainda funcione). +5. Escolha uma região para onde o Linode ficará hospedado. + +*Todas as questões remanescentes têm a ver com as mecânicas de implantar o VPS e devem ser deixadas como estão, com uma exceção: aumente o Swap Disk de 256MB para 512MB, para se assegurar de que você terá memória suficiente para baixar a blockchain._ + +Finalmente, você deverâ preencher a senha root, que será a senha usada para a conta root. + +### Escolha Outras Opções Standup + +A Blockchain Commons ainda está no processo de expandir seus Bitcoin Standup Scripts com opções para a instalação da Lightning e outras aplicações notáveis de Bitcoin. Dê uma olhada nas opções extras e veja se elas são coisas com as quais você gostaria de brincar. Em particular, se Lightning for uma opção, nós sugerimos que a instale, porque facilitará bastante os capítulos [19](19_0_Understanding_Your_Lightning_Setup.md) e [20](20_0_Using_Lightning.md). + +### Escolha um Plano da Linode + +Em seguida, você escolherá um plano da Linode. + +Um Linode de 4GB será suficiente para a maioria das configurações, incluindo: Mainnet Prunado, Testnet Prunado, e até Testnet não prunado. Todos estes usam menos de 50GB de armazenamento e 4GB é uma quantidade confortável de memória. Este é o plano que recomendamos. Ele gasta 20 dólares por mês. + +Se, ao invés disso, você quiser ter um node Mainnet não prunado em um VPS, você precisará instalar um Linode em um disco com mais de 280GB(!), que no momento é o Linode 16GB, que tem 320GB de armazenamento e 16GB de memória, custando aproximadamente 80 dólares por mês. Nós _não_ recomendamos este plano. + +A tabela à seguir mostra os requisitos mínimos + +| Configuração | Memória | Armazenamento | Linode | +|-------|--------|---------|---------| +| Mainnet | 2G | 280G | Linode 16GB | +| Mainnet Prunado | 2G | ~5G | Linode 4GB | +| Testnet | 2G | ~15G | Linode 4GB | +| Testnet Prunado | 2G | ~5G | Linode 4GB | +| Regtest | 2G | ~ | Linode 4GB | + +Mas saiba que possam existir maneiras de reduzir custos. + +* Para as máquinas que sugerimos o **Linode 4GB**, você pode conseguir reduzí-las para um Linode 2GB. Algumas versões do Bitcoin Core têm funcionado bem com este tamanho, outras têm esgotado a memória de vez em quando e depois recuperado, e outras têm esgotado a memória continuamente. Lembre-se de aumentar o Swap Disk para maximizar as chances disto funcionar. Use por sua conta própria e risco. +* Para o Mainnet Não Prunado, que suregimos como um **Linode 16GB**, você provavelmente conseguirá utilizar um Linode 4GB, mas adicione [Block Storage](https://cloud.linode.com/volumes) suficiente para armazenar a blockchain. Esta é com certeza uma solução melhor para o longo prazo porque os requisitos de armazenamento da blockchain do Bitcoin aumentam continuamente se você não pruná-la, enquanto os requisitos de CPU não aumentam (ou pelo menos não nas mesmas proporções). Um armazenamento GibiByte de 320GB custaria U$32 por mês, que combinado com um Linode 4GB custa U$52 por mês, ao invés de U$80, e mais importante, você pode continuar crescendo-o. Nós não documentamos esta configuração por completo por duas razões: (1) nós não sugerimos a configuração mainnet não prunada, então suspeitamos ser uma configuração incomum; e (2) nós não testamos como volumes Linode comparam com seus SSDs intrínsecos em performance e uso. Mas existe uma documentação completa na página Block Storage. Você precisaria configurar o Linode, executar seu stackscript, e então interrompê-lo para mover o armazenamento da blockchain para um volume comissionado antes de continuar. + +### Faça a Configuração Final + +A última coisa que você precisa fazer é colocar a senha root. (Se você tiver se esquecido de algo, você será informado agora!) + +Clique em "Deploy" para iniciallizar seus discos e preparar seu VPS. A fila inteira deve executar em menos de um minuto. Quando estiver pronto você verá, na "Host Job Queue", botões verdes de "Success" dizendo "Disk Create from StackScript - Setting password for root... done." e "Create Filesystem - 256MB Swap Image". + +Agora você pode querer alterar o nome do seu VPS Linode do padrão `linodexxxxxxxx`. Vá para a aba de configurações e altere o rótulo para algo mais útil, como o hostname curto do seu VPS. Por exemplo, você pode chamá-lo de `bitcoin-testnet-prunado` para diferenciá-lo de outros VPSs em sua conta. + +## Faça Login no Seu VPS + +Se você olhar o painel de controle do seu Linode, você deve ver o novo computador se iniciar. Quando o serviço atingir 100%, você poderá fazer login. + +Primeiramente, você precisará do endereço de IP. Clique na aba "Linodes" e uma lista dos seus VPSs deve aparecer, além do fato de que ele está rodando, o seu "plano", endereço de IP, e outras informações. + +Vá para o seu console local e faça login na conta `standup` usando aquele endereço: + +``` +ssh standup@[IP-ADDRESS] +``` + +Por exemplo: + +``` +ssh standup@192.168.33.11 +``` + +Se você configurou o seu VPS para usar uma chave SSH, o login deve ser automático (possivelmente requisitando sua senha SSH para desbloquear sua chave). Se você não tiver configurado uma chave SSH, então precisará escrever a senha do user1. + +### Espere Alguns Instantes + +Aqui vai uma pequena sacada: _o seu StackScript está executando agora_. O script BASH é executado na primeira vex que o VPS é ligado. O que significa que o seu VPS ainda não está pronto. + +O tempo total de execução é por volta de 10 minutos. Então, tire um intervalo, vá buscar um café, ou apenas relaxe por alguns instantes. Há duas partes do script que demoram um pouco: a atualização de todos os pacotes do Debian e o download do código do Bitcoin. Eles devem demorar não mais do que 5 minutos cada, o que significa que se você voltar em uns 10 minutos, provavelmente tudo estará pronto. + +Se você estiver impaciente, pode pular e fazer `sudo tail -f /standup.log`, que mostrará o progresso da instalação, como descrito na próxima seção. + +## Verifique Sua Instalação + +Você saberâ que o stackscript terminou quando a `tail` do `standup.log` disser algo como o seguinte: +``` +/root/StackScript - Bitcoin is setup as a service and will automatically start if your VPS reboots and so is Tor +/root/StackScript - You can manually stop Bitcoin with: sudo systemctl stop bitcoind.service +/root/StackScript - You can manually start Bitcoin with: sudo systemctl start bitcoind.service +``` +Naquele momento, seu diretório home se parecerá com isso: + +``` +$ ls +bitcoin-0.20.0-x86_64-linux-gnu.tar.gz laanwj-releases.asc SHA256SUMS.asc +``` + +Essas são os vários arquivos que foram usados para instalar o Bitcoin no seu VPS. _Nenhum_ deles é necessário. Nós apenas os deixamos lá caso você queira fazer qualquer verificacão adicional. Caso contrário, você pode deletá-los: + +``` +$ rm * +``` + +### Verifique a Configuração do Bitcoin + +Para ter certeza de que o Bitcoin baixado é válido, o StackScript checa a assinatura e o checksum SHA. Você deve verificar que ambos estes testes foram bem sucedidos: + +``` +$ sudo grep VERIFICATION /standup.log +``` + +Se você ver algo como o seguinte, tudo deve estar OK: + +``` +/root/StackScript - VERIFICATION SUCCESS / SIG: gpg: Good signature from "Wladimir J. van der Laan (Bitcoin Core binary release signing key) " [unknown] +/root/StackScript - VERIFICATION SUCCESS / SHA: 35ec10f87b6bc1e44fd9cd1157e5dfa4``` +``` +However, if either of those two checks instead reads "VERIFICATION ERROR", then there's a problem. Since this is all scripted, it's possible that there's just been a minor change that has caused the script's checks not to work right. (This has happened a few times over the existence of the script that became Standup.) But, it's also possible that someone is trying to encourage you to run a fake copy of the Bitcoin daemon. So, _be very sure you know what happened before you make use of Bitcoin!_ + +Entretanto, se qualquer um desses dois cheques disser "VERIFICATION ERROR", então temos um problema. Como tudo isso é programado, é possível que tenha ocorrido apenas uma mudança pequena que causou erros nos cheques do script. (Isto aconteceu poucas vezes durante a existência do script que virou o Standup.) Mas, também é possível que alguém esteja tentando te empurrar uma cópia falsa do daemon do Bitcoin. Então, _tenha absoluta que você saiba o que de fato aconteceu antes de usar o Bitcoin!_ + +### Leia os Logs + +Você também pode querer ler todos os logs dos arquivos de configuração para se assegurar de que nada imprevisível aconteceu durante a instalação. + +É melhor olhar o arquivo de log padrão do StackScript, que tem todas as saídas, incluindo erros: + +`$ sudo more /standup.log` + +Observe que é totalmente normal ver _alguns_ erros, particularmente quando executando o software gpg e quando várias coisas tentam accessar o dispositivo `/dev/tty` inexistente. + +Se, ao invés disso, você quiser olhar para um conjunto menor de informação, todos os erros devem estar em: + +`$ sudo more /standup.err` + +Ele ainda contém uma certa quantidade de informação além de erros, mas é uma leitura mais rápida. + +Se tudo estiver OK, parabéns, você tem um node Bitcoin funcionando usando a Linode! + +## O Que Nós Temos Feito + +Apesar de a imagem padrão do Debian 10 que estamos usando para o VPS ter sido modificada pela Linode para ser razoavelmente segura, o seu node Bitcoin instalado pelo StackScript Linode é configurado com um nível de segurança ainda maior. Isto pode ser limitante, ou pode te impedir de fazer algumas coisas que você esperava conseguir fazer. O que segue são algumas notas à respeito disso: + +### Serviços Protegidos + +A instalação do seu Bitcoin VPS é mïnima e permite quase nenhum tipo de comunicação. Isto é feito através do "uncomplicated firewall" (`ufw`), que bloqueia tudo exceto conexões SSH. Também existe alguma segurança adicional possível para suas portas RFC, graças aos serviços ocultos instalados pelo Tor. + +**Ajustando UFW.** Você provavelmente deve deixar o UFW no estágio de super-protegido! Você não deve usar uma máquina Bitcoin para outros serviços, porque cada um aumenta sua vulnerabilidade! Se você decidir o oposto, existem vários [guias para UFW](https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands) que te ajudarão a adicionar serviços. Como o nome diz, é _uncomplicated_. Por exemplo, adicionar serviços de email requeriria apenas abrir a porta de mail: `sudo ufw allow 25`. Mas não faça isso. + +**Ajustando Tor.** Você pode querer proteger seus serviços como SSH de uma maneira melhor. Referencie o [Capítulo 12: Usando o Tor](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/12_0_Using_Tor.md) para maiores informações sobre o Tor. + +### Shells Protegidas + +Se você definiu "SSH-allowed IPs", acesso SSH (e SCP) ao servidor é bastante restrito. `/etc/hosts.deny` impede qualquer um de logar. _Nós não recomendamos que altere isso_. `/etc/hosts.allow` então autoriza endereços de IP específicos. Apenas adicione mais endereços de IP em uma lista separada por vírgulas se você precisar oferecer mais acesso. + +Por exemplo: +``` +sshd: 127.0.0.1, 192.128.23.1 +``` + +### Atualizações Automáticas + +Debian is also set up to automatically upgrade itself, to ensure that it remains abreast of the newest security patches. O Debian também é configurado para se atualizar automaticamente para garantir de que ele mantenha lado a lado aos patches de segurança mais recentes. + +Se, por alguma razão, você desejasse alterar isso (_algo que não recomendamos_), você poderia fazer o seguinte: + +``` +echo "unattended-upgrades unattended-upgrades/enable_auto_updates boolean false" | debconf-set-selections +``` + +_Se você quiser saber mais sobre o que o Bitcoin Standup StackScript faz, veja o [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md)_. + +## Brincando com o Bitcoin + +Então agora você provavelmente deseja brincar com o Bitcoin! + +Mas calma, provavelmente o seu daemon do Bitcoin ainda está baixando blocos. O `bitcoin-cli getblockcount` irá dizer como está indo: +``` +$ bitcoin-cli getblockcount +1771352 +``` +Se o resultado for diferente a cada vez que você digitar o comando, você precisará esperar antes de começar a trabalhar com o Bitcoin. Isto levará, atualmente, de 1 a 6 horas para um node prunado, dependendo da sua máquina específica. + +Mas quando estabilizar em um número, você estará pronto para continuar! + +Mesmo assim, pode ser uma boa hora para mais alguns cafézinhos. Mas logo logo o seu sistema estará pronto, e você também! + +## Resumo: Configurando um Bitcoin-Core VPS Manualmente + +Criar um Bitcoin-Core VPS com os scripts Standup fizeram com que todo o processo fosse rápido, simples, e (esperamos) indolor. + +## O Que Vem A Seguir? + +Você tem algumas opções para o que se seguirá: + + * Leia o [StackScript](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) para entender a sua configuração. + * Leia o que o StackScript faz no [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md). + * Escolha uma metodologia inteiramente alternativa em [§2.2: Configurando uma Máquina Bitcoin-Core de Outras Maneiras](02_2_Setting_Up_Bitcoin_Core_Other.md). + * Siga em frente para "bitcoin-cli" com o [Capítulo Três: Compreendendo a Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). + +## Sinopse: Tipos de Instalação do Bitcoin + +**Mainnet.** Isto irá fazer o download da blockchain inteira do Bitcoin. São 280GB de dados (e aumentando a cada dia). + +**Mainnet Prunada.** Isto irá reduzir a blockchain que você irá armazenar para apenas os últimos 550 blocos. Se você não estiver minerando ou executando outro serviço do Bitcoin, isso deve ser o suficiente para validação. + +**Testnet.** Isto te dará acesso a uma blockchain alternativa do Bitcoin onde os bitcoins não têm valor algum. É feita para experimentos e testes. + +**Testnet Prunada.** Isto são apenas os últimos 550 blocos da Testnet ... porque a blockchain da Testnet está meio grande agora também. + +**Regtest Privada.** Este é o modo Regression Testing, que te permite rodar um servidor de Bitcoin totalmente local. Te permite também realizar testes mais detalhados. Não há um modo prunado aqui, porque você estará começando do zero. Esta é uma configuração bem diferente, então é discutida no [Apêndice 3](A3_0_Using_Bitcoin_Regtest.md). From ea54a60021a2591ecc4a4f3cd87ae956a8554553 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 31 Aug 2021 16:32:43 -0300 Subject: [PATCH 108/155] Translate 02_2 --- pt/02_2_Setting_Up_Bitcoin_Core_Other.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 pt/02_2_Setting_Up_Bitcoin_Core_Other.md diff --git a/pt/02_2_Setting_Up_Bitcoin_Core_Other.md b/pt/02_2_Setting_Up_Bitcoin_Core_Other.md new file mode 100644 index 0000000..d83f7e1 --- /dev/null +++ b/pt/02_2_Setting_Up_Bitcoin_Core_Other.md @@ -0,0 +1,18 @@ +# 2.2: Configurando uma Máquina Bitcoin-Core de Outras Maneiras + +A seção anterior, [§2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), assumia que você criaria um full node em um VPS usando um StackScript Linode. Entretanto, você pode, na verdade, criar uma instância do Bitcoin-Core via qualquer outra metodologia de sua escolha e ainda assim acompanhar as próximas etapas deste tutorial. + + +A seguir estão outras metodologias de configuração das quais temos conhecimento: + +* *[Compilar da Fonte](A2_0_Compiling_Bitcoin_from_Source.md).* Se você preferir compilar o Bitcoin Core manualmente, a maneira como fazê-lo é discutida no Apêndice 2. +* *[Usando GordianNode-macOS](https://github.com/BlockchainCommons/GordianNode-macOS).* Se você possuir um Mac moderno, você pode usar o aplicativo *GordianNode* da Blockchain Commons, que é capacitado pelo *BitcoinStandup*, para instalar um full node no seu Mac. +* *[Usando Outros Scripts de Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts).* A Blockchain Commons também oferece uma versão do script Linode que você usou que pode ser executado pela linha de comando em qualquer máquina Debian ou Ubuntu. Esse tende a ser o script "topo-de-linha", o que significa que terá, mais provavelmente, novas funcionalidades e funções, como a instalação da Lightning. +* *[Configurando um Node Bitcoin na AWS](https://wolfmcnally.com/115/developer-notes-setting-up-a-bitcoin-node-on-aws/).* @wolfmcnally escreveu um tutorial passo-a-passo para a configuração de um Bitcoin-Core com o Amazon Web Services (AWS). +* *[Configurando um Node Bitcoin em uma Raspberry Pi 3](https://medium.com/@meeDamian/bitcoin-full-node-on-rbp3-revised-88bb7c8ef1d1).* Damian Mee explica como configurar um headless full node em uma Raspberry Pi 3. + +## O Que Vem A Seguir? + +A não ser que você queira retornar a alguma das outras metodologias de criação de um node Bitcoin-Core, você deve: + + * Seguir em frente para "bitcoin-cli" com o [Capítulo Três: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). From e1a8caf8ecd1e7f9efed98437ceb18d41007f32f Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Tue, 31 Aug 2021 19:43:30 -0300 Subject: [PATCH 109/155] Review finished Review of the files made. --- ..._Up_a_Bitcoin-Core_VPS_with_StackScript.md | 201 +++++++++--------- pt/02_2_Setting_Up_Bitcoin_Core_Other.md | 20 +- 2 files changed, 109 insertions(+), 112 deletions(-) diff --git a/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md b/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md index bc3d35f..3b6dc34 100644 --- a/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md +++ b/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md @@ -1,109 +1,108 @@ -# 2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup +# 2.1: Configurando um Bitcoin Core VPS com Bitcoin Standup -Este documento explica como configurar um VPS (Servidor Privado Virtual, ou no inglês, Virtual Private Server) para rodar um node do Bitcoin em Linode.com, instalado usando um StackScript automatizado do [projeto Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Você apenas precisa copiar e colar alguns comandos e inicializar o seu VPS. Quase que imediatamente após a inicialização, você encontrará o seu novo node do Bitcoin alegremente baixando blocos. +Este documento explica como configurar um VPS (Virtual Private Server, ou no português, Servidor Privado Virtual) para rodar um node do Bitcoin usando o Linode.com, instalado usando um StackScript automatizado do [projeto Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Apenas precisamos copiar e colar alguns comandos e inicializar o VPS. Quase que imediatamente após a inicialização, encontraremos o nosso novo node do Bitcoin baixando os blocos. +> :warning: **AVISO:** Não podemos usar o VPS para uma carteira de bitcoin com saldos significativos e reais; vamos ler o http://blog.thestateofme.com/2012/03/03/lessons-to-be-learned-from-the-linode-bitcoin-incident/. Ele é muito bom para poder experimentar com transações de bitcoin reais em um node online sem usar um servidor auto-hospedado na nossa rede local. Ele também é útil para poder usar em um iPhone ou iPad para se comunicar via SSH com o nosso VPS para fazer algumas tarefas Bitcoin simples. Mas é necessário um nível mais alto de segurança para utilizarmos saldos grandes e reais. -> :warning: **AVISO:** Não use o VPS para uma carteira de bitcoin com fundos reais significativos; veja http://blog.thestateofme.com/2012/03/03/lessons-to-be-learned-from-the-linode-bitcoin-incident/ . Ele é muito bom para poder experimentar com transações de bitcoin reais em um node online sem atar um servidor auto-hospedado na sua rede local. Ele também é útil para poder usar um iPhone ou iPad para comunicar via SSH com o seu VPS para fazer algumas tarefas Bitcoin simples. Mas um nível mais alto de segurança é preciso para fundos significantes. +* Se quisermos saber o que essa configuração faz, podemos ler o [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md) enquanto o instalamos; +* Se, ao invés disso, quisermos configurá-lo em outra máquina que não seja um VPS na Linode, como uma máquina na AWS ou um Mac, podemos ir para a seção [§2.2: Configurando um Bitcoin-Core de Outras Maneiras](02_2_Setting_Up_Bitcoin_Core_Other.md) +* Se já temos um node do Bitcoin rodando, podemos ir para o [Capítulo 03: Compreendendo a configuração do node Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). -* Se você quiser saber o que essa configuração faz, leia o [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md) enquanto o instala. -* Se, ao invés disso, você quiser configurá-lo em outra máquina que não seja um VPS na Linode, como uma máquina na AWS ou um Mac, vá para [§2.2: Configurando um Bitcoin-Core de Outras Maneiras](02_2_Setting_Up_Bitcoin_Core_Other.md) -* Se você já tem um node do Bitcoin rodando, vá para [Capítulo Três: Compreendendo a Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). +## Começando com o Linode -## Começando com a Linode +O Linode é um serviço de hospedagem na nuvem que oferece servidores rápidos e baratos com armazenamento SSD. Nós a utilizamos neste tutorial principalmente porque os StackScripts feitos para BASH oferecem uma maneira fácil de automaticamente configurar um node Bitcoin sem confusão e bagunça. -A Linode é um serviço de hospedagem na nuvem que oferece servidores rápidos e baratos com armazenamento SSD. Nós a utilizamos neste tutorial principalmente porque os seus StackScripts feitos para BASH oferecem uma maneira fácil de automaticamente configurar um node Bitcoin sem confusão e bagunça. +### Configurando uma Conta no Linode -### Configure uma Conta na Linode - -Você pode criar uma conta na Linode por aqui: +Podemos criar uma conta na Linode por aqui: ``` https://www.linode.com ``` -Se preferir, o seguinte código de indicação te dará dois meses de uso grátis (até U$100), ótimo para aprender sobre Bitcoin: +Se preferirmos, o seguinte código de indicação nos dará dois meses de uso grátis (até U$100), ótimo para aprender sobre o Bitcoin: [https://www.linode.com/?r=3c7fa15a78407c9a3d4aefb027539db2557b3765](https://www.linode.com/?r=3c7fa15a78407c9a3d4aefb027539db2557b3765) -Você precisará prover um endereço de email e depois pré-carregar dinheiro de um cartão de crédito ou do PayPal para eventuais custos futuros. +Precisaremos informar um endereço de email e depois pré-carregar o dinheiro usando um cartão de crédito ou conta do PayPal para eventuais custos futuros. -Quando estiver terminado, você deve cair em [https://cloud.linode.com/dashboard](https://cloud.linode.com/dashboard). +Quando estiver terminado, devemos cair na seguinte página [https://cloud.linode.com/dashboard](https://cloud.linode.com/dashboard). -### Considere Autenticação de Dois Fatores +### Considerando a Autenticação de Dois Fatores A segurança do seu servidor não estará completa se pessoas possam invadir a sua conta da Linode, então considere ativar a Autenticação de Dois Fatores para ele. Você pode encontrar essa configuração na [página Minha Conta: Senha e Autenticação](https://manager.linode.com/profile/auth). Se você não fizer isso agora, anote como tarefa para voltar e fazê-lo depois. ## Criando a Imagem Linode usando um StackScript -### Load the StackScript +### Carregando o StackScript -Faça o download do [Linode Standup Script](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) pelo [repositório do Bitcoin Standup Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Este script basicamente automatiza todas as instruções de configuração do VPS Bitcoin. Se você quiser ser particularmente prudente, leia-o com atenção. Se estiver satisfeito, pode copiar o StackScript para sua conta Linode e selecionar [Criar Novo StackScript](https://cloud.linode.com/stackscripts/create). Dê a ele um bom nome (nós usamos `Bitcoin Standup`), então copie e cole o script. Escolha Debian 10 para sua imagem alvo e clique em "Salvar". +Vamos fazer o download do [Linode Standup Script](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) pelo [repositório do Bitcoin Standup Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Este script basicamente automatiza todas as instruções de configuração do VPS Bitcoin. Se quisermos ser mais prudentes, podemos lê-lo com atenção. Se estivermos satisfeito, pode copiar o StackScript para nossa conta do Linode e selecionar [Criar Novo StackScript](https://cloud.linode.com/stackscripts/create). Vamos dar a ele um nome (usamos `Bitcoin Standup`), então vamos copiar e colar o script. Vamos escolher o Debian 10 para nossa imagem alvo e clicar em "Salvar". -### Faça a Configuração Inicial +### Fazendo a Configuração Inicial -Agora você está pronto para criar um node baseado no StackScript. +Agora estamos prontos para criar um node baseado no StackScript. -1. Na [página de StackScripts](https://cloud.linode.com/stackscripts?type=account), clique em "..." à esquerda do seu novo script e escolha "Deploy New Linode". -2. Coloque um hostname curto e qualificado por completo - * **Hostname Curto.** Escolha um nome para o seu VPS. Por exemplo, "meutestebtc". - * **Hostname Qualificado por Completo.** Se você for incluir este VPS como parte de uma rede com recordes DNS completos, escreva o hostname com seu domínio. Por exemplo, "meutestebtc.meudominio.com". Caso contrário, apenas repita o hostname curto e adicione ".local", por exemplo "meutestebtc.local". -3. Coloque a senha do usuário "standup". -4. Escolha um Tipo de Instalação nas opções avançadas. - * **Tipo de Instalação.** Provavelmente isto será "Mainnet" ou "Mainnet Prunado" se você estiver configurando um node para uso e "Testnet" ou "Testnet Prunado" se você estiver apenas testando. A maior parte deste tutorial irá assumir que você tenha escolhido "Testnet Prunado", mas você deve conseguir segui-lo mesmo com os outros tipos. Veja a [Sinopse](#synopsis-bitcoin-installation-types) para maiores informações sobre essas opções. (Perceba que se você estiver planejando a tentar os capítulos de Lightning, você provavelmente se dará melhor com um node não prunado, pois trabalhar com nodes prunados na Lightning é experimental. Refira à seção [§19.1](19_1_Verifying_Your_Lightning_Setup.md#compiling-the-source-code) para maiores informações.) -5. Preencha quaisquer outras opções avançadas aplicáveis. - * **Chave Pública X25519.** Esta é a chave pública para adicionar à lista de clientes autorizados do Tor. Se você não a utilizar, qualquer pessoa que obtiver acesso ao QR code do seu node poderá acessá-lo. Você receberá esta chave pública do cliente que você estiver utilizando para acessar o seu node. Por exemplo, se você estiver utilizando a [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2), você pode ir às configurações e clicar em "Export Tor V3 Authentication Public Key" para usá-la aqui. - * **Chave SSH.** Copie a chave SSH do seu computador local para este campo; isto permite que você possa fazer login automaticamente à conta standup via SSH. Se você ainda não configurou uma chave SSH no seu computador local, o [Github](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/) contém boas instruções para isto. Você provavelmente também irá querer adicionar sua chave SSH ao seu LISH (Linode Interactive Shell) através da sua "Linode Home Page / My Preferences / LISH Settings / LISH Keys". Usar SSH te proporcionará uma maneira mais fácil e simples de fazer login no seu servidor. - * **IPs Permitidos para SSH.** Esta é uma lista de endereços IP separados por vírgula que serão autorizados a se conectarem via SSH ao seu VPS. Por exemplo "192.168.1.15,192.168.1.16". Se você não adicionar nenhum IP, _o seu VPS não estará muito seguro_. Ele será bombardeado constantemente por hackers tentando encontrar uma forma de adentrá-lo, e podem conseguir. -4. Selecione uma Imagem - * **Imagem Alvo.** Se você seguiu as instruções, isto apenas irá deixá-lo selecionar "Debian 10" (apesar de que "Debian 9" tem funcionado com versões posteriores deste StackScript e pode ser que ainda funcione). +1. Na [página de StackScripts](https://cloud.linode.com/stackscripts?type=account), cliquemos em "..." à esquerda do novo script e vamos escolher o "Deploy New Linode"; +2. Coloquemos um Short Hostname e Fully Qualified Hostname; + * **Short Hostname.** Vamos escolher um nome para o VPS. Por exemplo, "meutestebtc"; + * **Fully Qualified Hostname.** Se formos incluir este VPS como parte de uma rede com informações de DNS completos, vamos escrever o hostname com nosso domínio. Por exemplo, "meutestebtc.meudominio.com". Caso contrário, vamos apenas repitir o hostname curto e adicione ".local", por exemplo "meutestebtc.local"; +3. Coloquemos a senha do usuário "standup"; +4. Vamos escolher um Installation Type nas opções avançadas. + * **Installation Type.** Provavelmente será "Mainnet" ou "Pruned Mainnet" se estivermos configurando um node para usar e "Testnet" ou "Pruned Testnet" se estivermos apenas testando. A maior parte deste tutorial irá assumir que tenhamos escolhido o "Pruned Testnet", mas devemos conseguir segui-lo mesmo com os outros tipos. Veja a [Sinopse](#synopsis-bitcoin-installation-types) para maiores informações sobre essas opções. (Percebamos que se estivermos planejando tentar colocar em prática os capítulos da Lightning, provavelmente nos daremos melhor com um node não prunado, pois trabalhar com nodes prunados na Lightning é algo bem experimental. Vamos até a seção [§19.1](19_1_Verifying_Your_Lightning_Setup.md#compiling-the-source-code) para maiores informações); +5. Vamos preencher quaisquer outras opções avançadas aplicáveis; + * **X25519 Public Key.** Esta é a chave pública para adicionar à lista de clientes autorizados do Tor. Se não a utilizarmos, qualquer pessoa que obtiver acesso ao QR code do nosso node podendo assim acessá-lo. Receberemos esta chave pública do cliente que estivermos utilizando para acessar o node. Por exemplo, se estivermos utilizando a [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2), podemos ir às configurações e clicar em "Export Tor V3 Authentication Public Key" para usá-la aqui; + * **SSH Key.** Vamos copiar a chave SSH do computador local para este campo; isto permite que possamos fazer login automaticamente usando a conta standup via SSH. Se ainda não configuramos uma chave SSH no nosso computador local, o [Github](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/) contém boas instruções para fazermos isso. Provavelmente também iremos querer adicionar nossa chave SSH ao nosso LISH (Linode Interactive Shell) através do nosso "Linode Home Page/My Preferences/LISH Settings/LISH Keys". Usar o SSH nos proporcionará uma maneira mais fácil e simples de fazer login no nosso servidor; + * **SSH-Allowed IPs.** Esta é uma lista de endereços IP separados por vírgula que serão autorizados a se conectarem via SSH ao nosso VPS. Por exemplo "192.168.1.15,192.168.1.16". Se não adicionarmos nenhum IP, _o nosso VPS não estará muito seguro_. Ele será bombardeado constantemente por hackers tentando encontrar uma forma de adentrá-lo, e podem conseguir; +4. Selecione uma Imagem; + * **Target Image.** Se seguimos as instruções, as configurações irão nos deixar selecionar apenas o "Debian 10" (apesar de que "Debian 9" tem funcionado com versões posteriores deste StackScript e pode ser que ainda funcione); 5. Escolha uma região para onde o Linode ficará hospedado. -*Todas as questões remanescentes têm a ver com as mecânicas de implantar o VPS e devem ser deixadas como estão, com uma exceção: aumente o Swap Disk de 256MB para 512MB, para se assegurar de que você terá memória suficiente para baixar a blockchain._ +*_Todas as questões remanescentes têm a ver com as mecânicas de implantar o VPS e devem ser deixadas como estão, com uma exceção: aumentar o Swap Disk de 256MB para 512MB, para assegurarmos de que teremos memória suficiente para baixar a blockchain._ -Finalmente, você deverâ preencher a senha root, que será a senha usada para a conta root. +Finalmente, deveremos preencher a senha root, que será a senha usada para a conta root. -### Escolha Outras Opções Standup +### Escolhendo Outras Opções do Standup -A Blockchain Commons ainda está no processo de expandir seus Bitcoin Standup Scripts com opções para a instalação da Lightning e outras aplicações notáveis de Bitcoin. Dê uma olhada nas opções extras e veja se elas são coisas com as quais você gostaria de brincar. Em particular, se Lightning for uma opção, nós sugerimos que a instale, porque facilitará bastante os capítulos [19](19_0_Understanding_Your_Lightning_Setup.md) e [20](20_0_Using_Lightning.md). +A Blockchain Commons ainda está no processo de expandir os Bitcoin Standup Scripts com opções para a instalação da Lightning e outras aplicações notáveis do Bitcoin. Podemo dar uma olhada nas opções extras para ver se elas são coisas com as quais gostaríamos de brincar. Em particular, se a Lightning for uma opção, nós sugerimos que instalá-la, porque facilitará bastante os capítulos [19](19_0_Understanding_Your_Lightning_Setup.md) e [20](20_0_Using_Lightning.md). -### Escolha um Plano da Linode +### Escolhendo um Plano da Linode -Em seguida, você escolherá um plano da Linode. +Em seguida, escolheremos um plano da Linode. -Um Linode de 4GB será suficiente para a maioria das configurações, incluindo: Mainnet Prunado, Testnet Prunado, e até Testnet não prunado. Todos estes usam menos de 50GB de armazenamento e 4GB é uma quantidade confortável de memória. Este é o plano que recomendamos. Ele gasta 20 dólares por mês. +Um Linode de 4GB será suficiente para a maioria das configurações, incluindo: Mainnet Prunada, Testnet Prunada, e até Testnet não prunada. Todos estes usam menos de 50GB de armazenamento e 4GB é uma quantidade confortável de memória. Este é o plano que recomendamos. Ele consome 20 dólares por mês. -Se, ao invés disso, você quiser ter um node Mainnet não prunado em um VPS, você precisará instalar um Linode em um disco com mais de 280GB(!), que no momento é o Linode 16GB, que tem 320GB de armazenamento e 16GB de memória, custando aproximadamente 80 dólares por mês. Nós _não_ recomendamos este plano. +Se, ao invés disso, quisermos ter um node Mainnet não prunada em um VPS, precisaremos instalar um Linode em um disco com mais de 280GB(!), que no momento é o Linode 16GB, que tem 320GB de armazenamento e 16GB de memória, custando aproximadamente 80 dólares por mês. Nós _não_ recomendamos este plano. -A tabela à seguir mostra os requisitos mínimos +A tabela à seguir mostra os requisitos mínimos: | Configuração | Memória | Armazenamento | Linode | |-------|--------|---------|---------| | Mainnet | 2G | 280G | Linode 16GB | -| Mainnet Prunado | 2G | ~5G | Linode 4GB | +| Mainnet Prunada | 2G | ~5G | Linode 4GB | | Testnet | 2G | ~15G | Linode 4GB | -| Testnet Prunado | 2G | ~5G | Linode 4GB | +| Testnet Prunada | 2G | ~5G | Linode 4GB | | Regtest | 2G | ~ | Linode 4GB | -Mas saiba que possam existir maneiras de reduzir custos. +Mas podem existir maneiras de reduzir os custos. -* Para as máquinas que sugerimos o **Linode 4GB**, você pode conseguir reduzí-las para um Linode 2GB. Algumas versões do Bitcoin Core têm funcionado bem com este tamanho, outras têm esgotado a memória de vez em quando e depois recuperado, e outras têm esgotado a memória continuamente. Lembre-se de aumentar o Swap Disk para maximizar as chances disto funcionar. Use por sua conta própria e risco. -* Para o Mainnet Não Prunado, que suregimos como um **Linode 16GB**, você provavelmente conseguirá utilizar um Linode 4GB, mas adicione [Block Storage](https://cloud.linode.com/volumes) suficiente para armazenar a blockchain. Esta é com certeza uma solução melhor para o longo prazo porque os requisitos de armazenamento da blockchain do Bitcoin aumentam continuamente se você não pruná-la, enquanto os requisitos de CPU não aumentam (ou pelo menos não nas mesmas proporções). Um armazenamento GibiByte de 320GB custaria U$32 por mês, que combinado com um Linode 4GB custa U$52 por mês, ao invés de U$80, e mais importante, você pode continuar crescendo-o. Nós não documentamos esta configuração por completo por duas razões: (1) nós não sugerimos a configuração mainnet não prunada, então suspeitamos ser uma configuração incomum; e (2) nós não testamos como volumes Linode comparam com seus SSDs intrínsecos em performance e uso. Mas existe uma documentação completa na página Block Storage. Você precisaria configurar o Linode, executar seu stackscript, e então interrompê-lo para mover o armazenamento da blockchain para um volume comissionado antes de continuar. +* Para as máquinas que sugerimos o **Linode 4GB**, podemos conseguir reduzí-las para um Linode 2GB. Algumas versões do Bitcoin Core têm funcionado bem com esta quantidade, outras têm esgotado a memória de vez em quando e depois recuperado, e outras têm esgotado a memória continuamente. Lembre-se de aumentar o Swap Disk para maximizar as chances de funcionar. Use por sua conta e risco; +* Para a Mainnet Não Prunada, surgerimos um **Linode 16GB**, porém provavelmente conseguiremos utilizar um Linode 4GB, mas precisaremos adicionar um [Block Storage](https://cloud.linode.com/volumes) suficiente para armazenar a blockchain. Esta é com certeza uma solução melhor para o longo prazo porque os requisitos de armazenamento da blockchain do Bitcoin aumentam continuamente se não a prunarmos, enquanto os requisitos de CPU não aumentam (ou pelo menos não nas mesmas proporções). Um armazenamento GibiByte de 320GB custaria U$32 por mês, que combinado com um Linode 4GB custa U$52 por mês, ao invés de U$80, e mais importante, podemos continuar aumentando-o. Nós não documentamos esta configuração por completo por duas razões: (1) nós não sugerimos a configuração mainnet não prunada, então suspeitamos ser uma configuração incomum; e (2) nós não testamos como volumes Linode comparam com nossos SSDs intrínsecos em performance e uso. Mas existe uma documentação completa na página do Block Storage. Precisaríamos configurar o Linode, executar o stackscript, e então interrompê-lo para mover o armazenamento da blockchain para um volume comissionado antes de continuarmos. -### Faça a Configuração Final +### Fazendo a Configuração Final -A última coisa que você precisa fazer é colocar a senha root. (Se você tiver se esquecido de algo, você será informado agora!) +A última coisa que precisamos fazer é colocar a senha root. (Se tivermos nos esquecido de algo, seremos informados agora). -Clique em "Deploy" para iniciallizar seus discos e preparar seu VPS. A fila inteira deve executar em menos de um minuto. Quando estiver pronto você verá, na "Host Job Queue", botões verdes de "Success" dizendo "Disk Create from StackScript - Setting password for root... done." e "Create Filesystem - 256MB Swap Image". +Clique em "Deploy" para inicializar os discos e preparar o VPS. Tudo deve ser executado em menos de um minuto. Quando estiver pronto veremos, na "Host Job Queue", botões verdes de "Success" dizendo "Disk Create from StackScript - Setting password for root... done." e "Create Filesystem - 256MB Swap Image". -Agora você pode querer alterar o nome do seu VPS Linode do padrão `linodexxxxxxxx`. Vá para a aba de configurações e altere o rótulo para algo mais útil, como o hostname curto do seu VPS. Por exemplo, você pode chamá-lo de `bitcoin-testnet-prunado` para diferenciá-lo de outros VPSs em sua conta. +Agora podemos querer alterar o nome do nosso VPS Linode do padrão `linodexxxxxxxx`. Vamos na aba de configurações e vamos alterar o rótulo para algo mais útil, como o hostname curto do nosso VPS. Por exemplo, podemos chamá-lo de `bitcoin-testnet-prunada` para diferenciá-lo de outros VPSs em nossa conta. -## Faça Login no Seu VPS +## Fazendo Login no Nosso VPS -Se você olhar o painel de controle do seu Linode, você deve ver o novo computador se iniciar. Quando o serviço atingir 100%, você poderá fazer login. +Se olharmos o painel de controle do nosso Linode, devemos ver o novo computador se iniciar. Quando o serviço atingir 100%, poderemos fazer o login. -Primeiramente, você precisará do endereço de IP. Clique na aba "Linodes" e uma lista dos seus VPSs deve aparecer, além do fato de que ele está rodando, o seu "plano", endereço de IP, e outras informações. +Primeiramente, precisaremos do endereço de IP. Clique na aba "Linodes" e uma lista dos nossos VPSs deve aparecer, além do fato de que ele está online, o seu "plano", endereço de IP, e outras informações. -Vá para o seu console local e faça login na conta `standup` usando aquele endereço: +Vamos para o console local e vamos fazer login na conta `standup` usando aquele endereço: ``` ssh standup@[IP-ADDRESS] @@ -115,88 +114,86 @@ Por exemplo: ssh standup@192.168.33.11 ``` -Se você configurou o seu VPS para usar uma chave SSH, o login deve ser automático (possivelmente requisitando sua senha SSH para desbloquear sua chave). Se você não tiver configurado uma chave SSH, então precisará escrever a senha do user1. +Se configuramos o nosso VPS para usar uma chave SSH, o login deve ser automático (possivelmente requisitando a senha SSH para desbloquear a chave). Se não tivermos configurado a chave SSH, então precisaremos escrever a senha do user1. -### Espere Alguns Instantes +### Esperando Alguns Instantes -Aqui vai uma pequena sacada: _o seu StackScript está executando agora_. O script BASH é executado na primeira vex que o VPS é ligado. O que significa que o seu VPS ainda não está pronto. +Aqui vai uma pequena sacada: _o nosso StackScript está executando agora_. O script BASH é executado na primeira vez que o VPS é ligado. O que significa que o nosso VPS ainda não está pronto. -O tempo total de execução é por volta de 10 minutos. Então, tire um intervalo, vá buscar um café, ou apenas relaxe por alguns instantes. Há duas partes do script que demoram um pouco: a atualização de todos os pacotes do Debian e o download do código do Bitcoin. Eles devem demorar não mais do que 5 minutos cada, o que significa que se você voltar em uns 10 minutos, provavelmente tudo estará pronto. +O tempo total de execução é por volta de 10 minutos. Então, vamos usar este intervalo para fazer um café, ou apenas relaxar por alguns instantes. Há duas partes do script que demoram um pouco: a atualização de todos os pacotes do Debian e o download do código do Bitcoin. Eles devem demorar não mais que 5 minutos cada, o que significa que se voltarmos em uns 10 minutos, provavelmente tudo estará pronto. -Se você estiver impaciente, pode pular e fazer `sudo tail -f /standup.log`, que mostrará o progresso da instalação, como descrito na próxima seção. +Se estivermos impaciente, podemos pular e usar o `sudo tail -f /standup.log`, que mostrará o progresso da instalação, como descrito na próxima seção. -## Verifique Sua Instalação +## Verificando Nossa Instalação -Você saberâ que o stackscript terminou quando a `tail` do `standup.log` disser algo como o seguinte: +Saberemos que o stackscript terminou quando a `tail` do `standup.log` disser algo como o seguinte: ``` /root/StackScript - Bitcoin is setup as a service and will automatically start if your VPS reboots and so is Tor /root/StackScript - You can manually stop Bitcoin with: sudo systemctl stop bitcoind.service /root/StackScript - You can manually start Bitcoin with: sudo systemctl start bitcoind.service ``` -Naquele momento, seu diretório home se parecerá com isso: +Nesse momento, nosso diretório home se parecerá com isso: ``` $ ls bitcoin-0.20.0-x86_64-linux-gnu.tar.gz laanwj-releases.asc SHA256SUMS.asc ``` -Essas são os vários arquivos que foram usados para instalar o Bitcoin no seu VPS. _Nenhum_ deles é necessário. Nós apenas os deixamos lá caso você queira fazer qualquer verificacão adicional. Caso contrário, você pode deletá-los: +Esses são os vários arquivos que foram usados para instalar o Bitcoin no nosso VPS. _Nenhum_ deles é necessário. Nós apenas os deixamos lá caso queiramos fazer qualquer verificacão adicional. Caso contrário, podemos deletá-los: ``` $ rm * ``` -### Verifique a Configuração do Bitcoin +### Verificando a Configuração do Bitcoin -Para ter certeza de que o Bitcoin baixado é válido, o StackScript checa a assinatura e o checksum SHA. Você deve verificar que ambos estes testes foram bem sucedidos: +Para ter certeza de que o Bitcoin baixado é válido, o StackScript checa a assinatura e o checksum SHA. Devemos verificar se ambos os testes foram bem sucedidos: ``` $ sudo grep VERIFICATION /standup.log ``` -Se você ver algo como o seguinte, tudo deve estar OK: +Se observarmos algo como o descrito abaixo, tudo estará OK: ``` /root/StackScript - VERIFICATION SUCCESS / SIG: gpg: Good signature from "Wladimir J. van der Laan (Bitcoin Core binary release signing key) " [unknown] /root/StackScript - VERIFICATION SUCCESS / SHA: 35ec10f87b6bc1e44fd9cd1157e5dfa4``` ``` -However, if either of those two checks instead reads "VERIFICATION ERROR", then there's a problem. Since this is all scripted, it's possible that there's just been a minor change that has caused the script's checks not to work right. (This has happened a few times over the existence of the script that became Standup.) But, it's also possible that someone is trying to encourage you to run a fake copy of the Bitcoin daemon. So, _be very sure you know what happened before you make use of Bitcoin!_ +Entretanto, se qualquer uma dessas verificações retornar "VERIFICATION ERROR", então temos um problema. Como tudo isso é programado, é possível que tenha ocorrido apenas uma mudança pequena que causou erros nas verificações do script. Isto aconteceu poucas vezes durante a existência do script que virou o Standup. Mas, também é possível que alguém esteja tentando te empurrar uma cópia falsa do daemon do Bitcoin. Então, _precisamos ter a certeza absoluta que sabemos o que de fato aconteceu antes de usarmos o Bitcoin!_ -Entretanto, se qualquer um desses dois cheques disser "VERIFICATION ERROR", então temos um problema. Como tudo isso é programado, é possível que tenha ocorrido apenas uma mudança pequena que causou erros nos cheques do script. (Isto aconteceu poucas vezes durante a existência do script que virou o Standup.) Mas, também é possível que alguém esteja tentando te empurrar uma cópia falsa do daemon do Bitcoin. Então, _tenha absoluta que você saiba o que de fato aconteceu antes de usar o Bitcoin!_ +### Lendo os Logs -### Leia os Logs +Também podemos querer ler todos os logs dos arquivos de configuração para se assegurar de que nada imprevisível aconteceu durante a instalação. -Você também pode querer ler todos os logs dos arquivos de configuração para se assegurar de que nada imprevisível aconteceu durante a instalação. - -É melhor olhar o arquivo de log padrão do StackScript, que tem todas as saídas, incluindo erros: +É melhor olhar o arquivo de log padrão do StackScript, que tem todas as saídas, incluindo os erros: `$ sudo more /standup.log` -Observe que é totalmente normal ver _alguns_ erros, particularmente quando executando o software gpg e quando várias coisas tentam accessar o dispositivo `/dev/tty` inexistente. +Podemos observar que é totalmente normal ver _alguns_ erros, particularmente quando executamos o software gpg e quando várias coisas tentam acessar o dispositivo `/dev/tty` inexistente. -Se, ao invés disso, você quiser olhar para um conjunto menor de informação, todos os erros devem estar em: +Se, ao invés disso, quisermos olhar para um conjunto menor de informação, todos os erros devem estar em: `$ sudo more /standup.err` Ele ainda contém uma certa quantidade de informação além de erros, mas é uma leitura mais rápida. -Se tudo estiver OK, parabéns, você tem um node Bitcoin funcionando usando a Linode! +Se tudo estiver OK, parabéns, temos um node Bitcoin funcionando usando o Linode! -## O Que Nós Temos Feito +## O Que Nós Fizemos -Apesar de a imagem padrão do Debian 10 que estamos usando para o VPS ter sido modificada pela Linode para ser razoavelmente segura, o seu node Bitcoin instalado pelo StackScript Linode é configurado com um nível de segurança ainda maior. Isto pode ser limitante, ou pode te impedir de fazer algumas coisas que você esperava conseguir fazer. O que segue são algumas notas à respeito disso: +Apesar de a imagem padrão do Debian 10 que estamos usando para o VPS ter sido modificada pelo Linode para ser razoavelmente seguro, o nosso node Bitcoin instalado pelo StackScript Linode é configurado com um nível de segurança ainda maior. Isto pode ser limitante, ou pode nos impedir de fazer algumas coisas que esperávamos conseguir fazer. O que segue são algumas dicas à respeito disso: ### Serviços Protegidos -A instalação do seu Bitcoin VPS é mïnima e permite quase nenhum tipo de comunicação. Isto é feito através do "uncomplicated firewall" (`ufw`), que bloqueia tudo exceto conexões SSH. Também existe alguma segurança adicional possível para suas portas RFC, graças aos serviços ocultos instalados pelo Tor. +A instalação do Bitcoin VPS é mínima e permite pouco tipo de comunicação. Isto é feito através do "uncomplicated firewall" (`ufw`), que bloqueia tudo, exceto conexões SSH. Também existe alguma segurança adicional possível para as portas RFC, graças aos serviços ocultos instalados pelo Tor. -**Ajustando UFW.** Você provavelmente deve deixar o UFW no estágio de super-protegido! Você não deve usar uma máquina Bitcoin para outros serviços, porque cada um aumenta sua vulnerabilidade! Se você decidir o oposto, existem vários [guias para UFW](https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands) que te ajudarão a adicionar serviços. Como o nome diz, é _uncomplicated_. Por exemplo, adicionar serviços de email requeriria apenas abrir a porta de mail: `sudo ufw allow 25`. Mas não faça isso. +**Ajustando o UFW.** Provavelmente deveremos deixar o UFW no estágio de super-protegido! Não devemos usar uma máquina Bitcoin para outros serviços, porque cada um aumenta a vulnerabilidade! Se decidirmos o oposto, existem vários [guias para o UFW](https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands) que podem nos ajudar a adicionar outros serviços. Como o nome diz, é _uncomplicated_. Por exemplo, adicionar serviços de email requeriria apenas abrir a porta de mail: `sudo ufw allow 25`. Mas não vamos fazer isso, não é mesmo. -**Ajustando Tor.** Você pode querer proteger seus serviços como SSH de uma maneira melhor. Referencie o [Capítulo 12: Usando o Tor](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/12_0_Using_Tor.md) para maiores informações sobre o Tor. +**Ajustando o Tor.** Podemos querer proteger os serviços como SSH de uma maneira melhor. Podemos ler sobre isso no [Capítulo 12: Usando o Tor](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/12_0_Using_Tor.md), para maiores informações sobre o Tor. -### Shells Protegidas +### Shells Protegidos -Se você definiu "SSH-allowed IPs", acesso SSH (e SCP) ao servidor é bastante restrito. `/etc/hosts.deny` impede qualquer um de logar. _Nós não recomendamos que altere isso_. `/etc/hosts.allow` então autoriza endereços de IP específicos. Apenas adicione mais endereços de IP em uma lista separada por vírgulas se você precisar oferecer mais acesso. +Se definimos o "SSH-allowed IPs", o acesso SSH (e SCP) ao servidor é bastante restrito. `/etc/hosts.deny` impede qualquer um de se logar. _Nós não recomendamos que isso seja alterado_. `/etc/hosts.allow` então autoriza endereços de IP específicos. Podemos apenas adicionar mais endereços de IP em uma lista separada por vírgulas se precisarmos oferecer mais acesso. Por exemplo: ``` @@ -205,52 +202,52 @@ sshd: 127.0.0.1, 192.128.23.1 ### Atualizações Automáticas -Debian is also set up to automatically upgrade itself, to ensure that it remains abreast of the newest security patches. O Debian também é configurado para se atualizar automaticamente para garantir de que ele mantenha lado a lado aos patches de segurança mais recentes. +O Debian também é configurado para se atualizar automaticamente para garantir de que mantenha atualizado aos patches de segurança mais recentes. -Se, por alguma razão, você desejasse alterar isso (_algo que não recomendamos_), você poderia fazer o seguinte: +Se, por alguma razão, desejarmos alterar isso (_algo que não recomendamos_), podemos fazer o seguinte: ``` echo "unattended-upgrades unattended-upgrades/enable_auto_updates boolean false" | debconf-set-selections ``` -_Se você quiser saber mais sobre o que o Bitcoin Standup StackScript faz, veja o [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md)_. +_Se quisermos saber mais sobre o que o Bitcoin Standup StackScript faz, podemos ler o [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md)_. ## Brincando com o Bitcoin -Então agora você provavelmente deseja brincar com o Bitcoin! +Agora, provavelmente desejaremos brincar com o Bitcoin! -Mas calma, provavelmente o seu daemon do Bitcoin ainda está baixando blocos. O `bitcoin-cli getblockcount` irá dizer como está indo: +Mas calma, provavelmente o nosso daemon do Bitcoin ainda está baixando os blocos. O `bitcoin-cli getblockcount` irá dizer como está indo: ``` $ bitcoin-cli getblockcount 1771352 ``` -Se o resultado for diferente a cada vez que você digitar o comando, você precisará esperar antes de começar a trabalhar com o Bitcoin. Isto levará, atualmente, de 1 a 6 horas para um node prunado, dependendo da sua máquina específica. +Se o resultado for diferente a cada vez que digitarmos o comando, precisaremos esperar antes de começar a trabalhar com o Bitcoin. Isto levará, atualmente, de 1 a 6 horas para um node prunado, dependendo das especificações da nossa máquina. -Mas quando estabilizar em um número, você estará pronto para continuar! +Mas quando estabilizar em um número, estaremos prontos para continuar! -Mesmo assim, pode ser uma boa hora para mais alguns cafézinhos. Mas logo logo o seu sistema estará pronto, e você também! +Mesmo assim, pode ser uma boa hora para mais alguns cafézinhos. Mas logo logo o nosso sistema estará pronto, e nós também! -## Resumo: Configurando um Bitcoin-Core VPS Manualmente +## Resumo: Configurando um Bitcoin Core VPS Manualmente -Criar um Bitcoin-Core VPS com os scripts Standup fizeram com que todo o processo fosse rápido, simples, e (esperamos) indolor. +Criar um Bitcoin Core VPS com os scripts Standup fizeram com que todo o processo fique rápido, simples, e (esperamos), indolor. -## O Que Vem A Seguir? +## O Que Vem Depois? -Você tem algumas opções para o que se seguirá: +Temos algumas opções para o que podemos seguir: - * Leia o [StackScript](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) para entender a sua configuração. - * Leia o que o StackScript faz no [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md). - * Escolha uma metodologia inteiramente alternativa em [§2.2: Configurando uma Máquina Bitcoin-Core de Outras Maneiras](02_2_Setting_Up_Bitcoin_Core_Other.md). - * Siga em frente para "bitcoin-cli" com o [Capítulo Três: Compreendendo a Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). + * Ler o [StackScript](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) para entender a configuração; + * Ler o que o StackScript faz no [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md); + * Escolher uma metodologia inteiramente alternativa, como descrito na seção [§2.2: Configurando uma Máquina Bitcoin-Core de Outras Maneiras](02_2_Setting_Up_Bitcoin_Core_Other.md); + * Usar o "bitcoin-cli" com o [Capítulo Três: Compreendendo a Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). ## Sinopse: Tipos de Instalação do Bitcoin -**Mainnet.** Isto irá fazer o download da blockchain inteira do Bitcoin. São 280GB de dados (e aumentando a cada dia). +**Mainnet.** Isto irá fazer o download da blockchain inteira do Bitcoin. São 280GB de dados (e está aumentando a cada dia). -**Mainnet Prunada.** Isto irá reduzir a blockchain que você irá armazenar para apenas os últimos 550 blocos. Se você não estiver minerando ou executando outro serviço do Bitcoin, isso deve ser o suficiente para validação. +**Mainnet Prunada.** Isto irá reduzir a blockchain que iremos armazenar para apenas os últimos 550 blocos. Se não estivermos minerando ou executando outro serviço do Bitcoin, isso deve ser o suficiente para validação. -**Testnet.** Isto te dará acesso a uma blockchain alternativa do Bitcoin onde os bitcoins não têm valor algum. É feita para experimentos e testes. +**Testnet.** Isto nos dará acesso a uma blockchain alternativa do Bitcoin onde os bitcoins não têm valor algum. É feita para experimentos e testes. **Testnet Prunada.** Isto são apenas os últimos 550 blocos da Testnet ... porque a blockchain da Testnet está meio grande agora também. -**Regtest Privada.** Este é o modo Regression Testing, que te permite rodar um servidor de Bitcoin totalmente local. Te permite também realizar testes mais detalhados. Não há um modo prunado aqui, porque você estará começando do zero. Esta é uma configuração bem diferente, então é discutida no [Apêndice 3](A3_0_Using_Bitcoin_Regtest.md). +**Regtest Privada.** Este é o modo Regression Testing, que nos permite rodar um servidor de Bitcoin totalmente local. Nos permite também realizar testes mais detalhados. Não há um modo prunado aqui, porque estaremos começando a blockchain do zero. Esta é uma configuração bem diferente, então é discutida no [Apêndice 3](A3_0_Using_Bitcoin_Regtest.md). \ No newline at end of file diff --git a/pt/02_2_Setting_Up_Bitcoin_Core_Other.md b/pt/02_2_Setting_Up_Bitcoin_Core_Other.md index d83f7e1..1e083b9 100644 --- a/pt/02_2_Setting_Up_Bitcoin_Core_Other.md +++ b/pt/02_2_Setting_Up_Bitcoin_Core_Other.md @@ -1,18 +1,18 @@ -# 2.2: Configurando uma Máquina Bitcoin-Core de Outras Maneiras +# 2.2: Configurando uma Máquina Bitcoin Core de Outras Maneiras -A seção anterior, [§2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), assumia que você criaria um full node em um VPS usando um StackScript Linode. Entretanto, você pode, na verdade, criar uma instância do Bitcoin-Core via qualquer outra metodologia de sua escolha e ainda assim acompanhar as próximas etapas deste tutorial. +A seção anterior, [§2.1: Configurando um Bitcoin Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), assumimos que iríamos criar um full node em um VPS usando um StackScript Linode. Entretanto, podemos querer criar uma instância do Bitcoin Core via qualquer outra metodologia a nossa escolha e ainda assim acompanhar as próximas etapas deste tutorial. A seguir estão outras metodologias de configuração das quais temos conhecimento: -* *[Compilar da Fonte](A2_0_Compiling_Bitcoin_from_Source.md).* Se você preferir compilar o Bitcoin Core manualmente, a maneira como fazê-lo é discutida no Apêndice 2. -* *[Usando GordianNode-macOS](https://github.com/BlockchainCommons/GordianNode-macOS).* Se você possuir um Mac moderno, você pode usar o aplicativo *GordianNode* da Blockchain Commons, que é capacitado pelo *BitcoinStandup*, para instalar um full node no seu Mac. -* *[Usando Outros Scripts de Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts).* A Blockchain Commons também oferece uma versão do script Linode que você usou que pode ser executado pela linha de comando em qualquer máquina Debian ou Ubuntu. Esse tende a ser o script "topo-de-linha", o que significa que terá, mais provavelmente, novas funcionalidades e funções, como a instalação da Lightning. -* *[Configurando um Node Bitcoin na AWS](https://wolfmcnally.com/115/developer-notes-setting-up-a-bitcoin-node-on-aws/).* @wolfmcnally escreveu um tutorial passo-a-passo para a configuração de um Bitcoin-Core com o Amazon Web Services (AWS). -* *[Configurando um Node Bitcoin em uma Raspberry Pi 3](https://medium.com/@meeDamian/bitcoin-full-node-on-rbp3-revised-88bb7c8ef1d1).* Damian Mee explica como configurar um headless full node em uma Raspberry Pi 3. +* *[Compilar da Fonte](A2_0_Compiling_Bitcoin_from_Source.md).* Se preferirmos compilar o Bitcoin Core manualmente, a maneira como fazer isso é discutida no Apêndice 2. +* *[Usando GordianNode-macOS](https://github.com/BlockchainCommons/GordianNode-macOS).* Se possuirmos um Mac moderno, podemos usar o aplicativo *GordianNode* da Blockchain Commons, que é capacitado pelo *BitcoinStandup*, para instalar um full node nosso Mac. +* *[Usando Outros Scripts de Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts).* A Blockchain Commons também oferece uma versão do script Linode que usamos que pode ser executada pela linha de comando em qualquer máquina Debian ou Ubuntu. Esse tende a ser o script "topo-de-linha", o que significa que terá, mais provavelmente, novas funcionalidades e funções, como a instalação da Lightning. +* *[Configurando um Node Bitcoin na AWS](https://wolfmcnally.com/115/developer-notes-setting-up-a-bitcoin-node-on-aws/).* @wolfmcnally escreveu um tutorial passo-a-passo para a configuração de um Bitcoin Core em um Amazon Web Services (AWS). +* *[Configurando um Node Bitcoin em uma Raspberry Pi 3](https://medium.com/@meeDamian/bitcoin-full-node-on-rbp3-revised-88bb7c8ef1d1).* Damian Mee explica como configurar um full node headless em um Raspberry Pi 3. -## O Que Vem A Seguir? +## O Que Vem Depois? -A não ser que você queira retornar a alguma das outras metodologias de criação de um node Bitcoin-Core, você deve: +A não ser que queiramos retornar a alguma das outras metodologias de criação de um node Bitcoin Core, devemos: - * Seguir em frente para "bitcoin-cli" com o [Capítulo Três: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). + * Seguir em frente usando o "bitcoin-cli" com o [Capítulo Três: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). From 8a3ebcb6bf17176dc62a0234c412eb919432beca Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 11:09:59 -0300 Subject: [PATCH 110/155] Delete old chapter 15 files --- pt/15_0_Talking_to_Bitcoind.md | 27 -- pt/15_1_Accessing_Bitcoind_with_C.md | 294 --------------- pt/15_2_Programming_Bitcoind_with_C.md | 354 ------------------ ...Receiving_Bitcoind_Notifications_with_C.md | 155 -------- 4 files changed, 830 deletions(-) delete mode 100644 pt/15_0_Talking_to_Bitcoind.md delete mode 100644 pt/15_1_Accessing_Bitcoind_with_C.md delete mode 100644 pt/15_2_Programming_Bitcoind_with_C.md delete mode 100644 pt/15_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/pt/15_0_Talking_to_Bitcoind.md b/pt/15_0_Talking_to_Bitcoind.md deleted file mode 100644 index 88bde29..0000000 --- a/pt/15_0_Talking_to_Bitcoind.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Capítulo 15: Conversando com Bitcoind usando C - -Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. - -Esta seção se concentra em três diferentes bibliotecas que podem ser usadas como base de programação C sofisticada: Uma biblioteca RPC e uma biblioteca JSON que juntas permitem recriar muito do que fazemos nos scripts de shell, porém, usando C; enquanto uma biblioteca ZMQ nos conecta a notificações, algo que não conseguiríamos acessar até agora. (O próximo capítulo cobrirá uma biblioteca ainda mais sofisticada chamada Libwally, para finalizar esta introdução à programação do Bitcoin com C). - -## Objetivos deste capítulo - -Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - - * Criar programas C que usam RPC para conversar com o Bitcoind; - * Criar programas C que usam ZMQ para conversar com o Bitcoind. - -Os objetivos secundários do capítulo incluem a capacidade de: - - * Entender como usar uma biblioteca RPC; - * Entender como usar uma biblioteca JSON; - * Compreender as capacidades do ZMQ; - * Entender como usar uma biblioteca ZMQ. - -## Tabela de conteúdo - - * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) - * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) - * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) - \ No newline at end of file diff --git a/pt/15_1_Accessing_Bitcoind_with_C.md b/pt/15_1_Accessing_Bitcoind_with_C.md deleted file mode 100644 index 2e97e1c..0000000 --- a/pt/15_1_Accessing_Bitcoind_with_C.md +++ /dev/null @@ -1,294 +0,0 @@ - -# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -Você já viu uma maneira alternativa de acessar as portas RPC do Bitcoind: Usando o ``curl``, que cobrimos no [Capítulo 4 Prefácio](04_4__interlude_using_curl.md). Interagir com o ``Bitcoind`` através de uma biblioteca de RPC usando C não é diferente do que já vimos, só precisamos de boas bibliotecas para nos auxiliar. Esta seção introduz um pacote chamado ``libbitcoinrpc``, que permite acessar a porta JSON-RPC do ``bitcoind``. Ele usa uma biblioteca ``curl`` para acessar os dados e usa a biblioteca ``jansson`` para codificar e decodificar o JSON. - -## Configurando o libbitcoinrpc - -Para usar o ``libbitcoinrpc``, precisaremos instalar uma configuração básica C e os pacotes dependentes, que são ``libcurl``, ``libjansson``, e ``libuuid``. Depois faremos isso no seu servidor Standup Bitcoin (ou em qualquer outro servidor Ubuntu). - -``` -$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev -Suggested packages: - libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev -The following NEW packages will be installed: - libcurl4-openssl-dev libjansson-dev uuid-dev -0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. -Need to get 358 kB of archives. -After this operation, 1.696 kB of additional disk space will be used. -Do you want to continue? [Y/n] y -``` -Agora, podemos baixar o [libbitcoinrpc no github](https://github.com/gitmarek/libbitcoinrpc/blob/master/readme.md). Vamos clonar ou pegar um arquivo zip, do jeito que preferir. - -``` -$ sudo apt-get install git -$ git clone https://github.com/gitmarek/libbitcoinrpc -``` - -> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. - -### Compilando o libbitcoinrpc. - -Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: -``` -$ PATH="/sbin:$PATH" -``` - -Para o Ubuntu, também precisaremos ajustar o ``install_libpath`` no ``makefile`` do ``libbitcoinrpc`` para instalar no ``/usr/lib`` ao invés do ``/usr/local/lib``: - -``` -$ emacs ~/libbitcoinrpc/Makefile -... -INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib -``` - -(Se preferir não usar o ``/usr/lib``, precisará alterar o ``etc/ld.so.conf`` ou os arquivos dependentes de maneira apropriada... Porém, para uma configuração de teste em uma máquina de teste, acredito que isso não seja um problema). - -Da mesma forma, vamos precisar ajustar o ``install_headerpath`` no ``Makefile`` do ``libbitcoinrpc`` para instalar no caminho ``/usr/include`` ao invés do ``/usr/local/inclusve``: - -``` -... -INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include -``` - -Agora, podemos compilar: -``` -$ cd libbitcoinrpc -~/libbitcoinrpc$ make - -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ -src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ --o .lib/libbitcoinrpc.so.0.2 \ --Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl -ldconfig -v -n .lib -.lib: - libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) -ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so -``` -Se tudo correr bem, podemos instalar o pacote: -``` -$ sudo make install -Installing to -install .lib/libbitcoinrpc.so.0.2 /usr/local/lib -ldconfig -n /usr/local/lib -ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so -install -m 644 src/bitcoinrpc.h /usr/local/include -Installing docs to /usr/share/doc/bitcoinrpc -mkdir -p /usr/share/doc/bitcoinrpc -install -m 644 doc/*.md /usr/share/doc/bitcoinrpc -install -m 644 CREDITS /usr/share/doc/bitcoinrpc -install -m 644 LICENSE /usr/share/doc/bitcoinrpc -install -m 644 Changelog.md /usr/share/doc/bitcoinrpc -Installing man pages -install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 -``` - -## Preparando o código - -``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. - -Para usar o ``libbitcoinrpc``, é importante certificar de que nossos arquivos do código incluam os cabeçalhos apropriados: -``` c -#include -#include -``` - -Precisaremos também vincular as bibliotecas apropriadas sempre que possamos compilar: - -``` -$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode -``` - -## Construindo a conexão - -Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. - -Primeiro, inicialize a biblioteca: -``` -bitcoinrpc_global_init(); -``` -Em seguida, vamos conectar ao ``Bitcoind`` com ``bitcoinrpc_cl_init_params``. Os quatro argumentos necessários para o ``bitcoinrpc_cl_init_params`` são o nome de usuário, a senha, o endereço IP e a porta. A esta altura, você deve saber todas essas informações, já que foram necessárias para realizar o trabalho com o [curl](04_4__interlude_using_curl.md). Apenas para recordar, o endereço de IP é 127.0.0.1 e a porta 18332 devem estar corretos para a configuração padrão da testenet descrita neste documento, enquanto podemos encontrar o usuário e a senha no arquivo ``~/.bitcoin/bitcoin.conf``. -``` -$ cat bitcoin.conf -server=1 -dbcache=1536 -par=1 -maxuploadtarget=137 -maxconnections=16 -rpcuser=StandUp -rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba -rpcallowip=127.0.0.1 -debug=tor -prune=550 -testnet=1 -[test] -rpcbind=127.0.0.1 -rpcport=18332 -[main] -rpcbind=127.0.0.1 -rpcport=8332 -[regtest] -rpcbind=127.0.0.1 -rpcport=18443 -``` -Com essas informações, vamos colocá-las no ``bitcoinrpc_cl_init_params``: -``` c -bitcoinrpc_cl_t *rpc_client; -rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); -``` - -> **MAINNET VS TESTNET:** A porta seria a 8332 caso estivéssemos usando a configuração da rede principal. - -Se o ``rpc_client`` for inicializado com sucesso, poderemos enviar os comandos do RPC. - -Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fechar da seguinte maneira: -``` c -bitcoinrpc_global_cleanup(); -``` - -### Testando o código de teste - -O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). - -Podemos compilar e executar o código da seguinte maneira: -``` -$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin -$ ./testbitcoin -Successfully connected to server! -``` - -> :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. - -## Fazendo uma chamada ao RPC - -Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). -``` c -bitcoinrpc_method_t *getmininginfo = NULL; -getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); -``` -Normalmente definiríamos os parâmetros em seguida, mas o ``GetMiningInfo`` não requer parâmetros, por isso podemos pular essa parte. - -Também devemos criar outros dois objetos, um "objeto de resposta" e um "objeto de erro". Eles podem ser inicializados da seguinte forma: -``` c -bitcoinrpc_resp_t *btcresponse = NULL; -btcresponse = bitcoinrpc_resp_init(); - -bitcoinrpc_err_t btcerror; -``` -Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos adicionar nosso método ``getmininginfo`` e os outros dois objetos: -``` c -bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); -``` - -### Mostrando o retorno da chamada - -Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: -``` c -json_t *jsonresponse = NULL; -jsonresponse = bitcoinrpc_resp_get(btcresponse); -``` -Se quisermos gerar os resultados completos da chamada RPC no JSON, podemos fazer com uma simples invocação do ``json_dumps``, da biblioteca ``jansson``: -``` c -printf("%s\n", json_dumps(j, JSON_INDENT(2))); -``` -No entanto, como agora estamos escrevendo programas completos, provavelmente iremos querer fazer um trabalho mais sutil, como retirar valores individuais do JSON para algum uso específico. A [Referência do Jansson](https6//jansson.readthedocs.Io/en/2.10/apiref.html) traz detalhes de como fazer. - -Assim como estávamos usando o [curl](04_4__interlude_using_curl.md), descobrimos que o RPC retorna um objeto JSON contendo um ``ID``, um ``error`` e, mais importante, um objeto JSON do tipo ``result``. - -A função ``json_object_get`` permite recuperar um valor (como o ``result``) de um objeto JSON usando chaves: -``` c -json_t *jsonresult = NULL; -jsonresult = json_object_get(jsonresponse,"result"); -printf("%s\n", json_dumps(jsonresult, JSON_INDENT(2))); -``` - -No entanto, provavelmente iremos querer analisar informações ainda mais profundas, para obter uma variável específica. Depois de recuperar o valor apropriado, precisaremos convertê-lo em um objeto C padrão usando a função ``JSON_*_value``. Por exemplo, para acessar um integer usamos o ``json_integer_value``: -``` c -json_t *jsonblocks = NULL; -jsonblocks = json_object_get(jsonresult,"blocks"); - -int blocks; -blocks = json_integer_value(jsonblocks); -printf("Block Count: %d\n",blocks); -``` - -> :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. - -### Testando o código de informação - -Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). -``` -$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo -$ ./getmininginfo -Full Response: { - "result": { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" - }, - "error": null, - "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" -} - -Just the Result: { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" -} - -Block Count: 1804406 -``` - -## Fazendo uma chamada RPC usando argumentos - -Mas e se a sua chamada RPC tiver argumentos? - -### Criando uma matriz JSON - -Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. - -Vamos criar a matriz JSON usando a função ``json_array do`` do ``jansson``: -``` c -json_t *params = NULL; -params = json_array(); -``` -Vamos fazer o processo inverso que fizemos para acessar valores do JSON: Vamos converter objetos no C para objetos no JSON usando as funções ``JSON_*``. Depois, vamos anexar tudo à matriz: -``` c -json_array_append_new(params,json_string(tx_rawhex)); -``` - -Observe que existem duas variantes para o comando de anexação: ``json_array_apend_new``, que acrescenta uma variável recém-criada, e ``json_array_apend``, que anexa uma variável existente. - -Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. - -### Atribuindo os parâmetros - -Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: -``` c -bitcoinrpc_method_set_params(rpc_method, params) -``` -Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. - -## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC - -Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. - -* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. - -## O Que Vem Depois? - -Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). diff --git a/pt/15_2_Programming_Bitcoind_with_C.md b/pt/15_2_Programming_Bitcoind_with_C.md deleted file mode 100644 index c1fdc38..0000000 --- a/pt/15_2_Programming_Bitcoind_with_C.md +++ /dev/null @@ -1,354 +0,0 @@ - -# 15.2: Programando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. - -## Planejando o código - -Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: - - 1. Solicitar um endereço e uma quantia; - 2. Definir uma taxa arbitrária; - 3. Preparar nosso RPC; - 4. Encontrar um UTXO que seja grande o suficiente para pagar o valor + a taxa; - 5. Criar uma mudança de endereço; - 6. Criar uma transação bruta que envie o UTXO para o endereço e altere o endereço; - 7. Assinar a transação; - 8. Enviar a transação. - -### Planejando para o futuro - -Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: - - 1. Testar e/ou higienizar as entradas; - 2. Calcular uma taxa automaticamente; - 3. Pensar logicamente sobre qual UTXO seria válido utilizar; - 4. Combinar vários UTXOs, caso seja necessário; - 5. Ficar atento a mais erros nos comandos ``libbitcoinrpc`` ou no ``jansson``; - 6. Observar se há erros nas respostas RPC. - -Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. - -## Escrevendo o sistema de transação - -Agora estamos prontos para realizar o passo a passo do nosso plano - -### Etapa 1: Solicitando um endereço e uma quantia - -Inserir as informações é bem simples se usarmos os argumentos na linha de comando: -``` c -if(argc != 3) { - - printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); - exit(-1); - -} - -char *tx_recipient = argv[1]; -float tx_amount = atof(argv[2]); - -printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); -``` - -> :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. - -### Etapa 2: Definindo uma taxa arbitrária - -Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: - -``` c -float tx_fee = 0.0005; -float tx_total = tx_amount + tx_fee; -``` - -> :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. - -### Etapa 3: Preparando nosso RPC - -Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: -``` c -bitcoinrpc_global_init(); -rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); -btcresponse = bitcoinrpc_resp_init(); -``` - -### Etapa 4: Encontrando um UTXO - -Para encontrar um UTXO, precisaremos chamar a função RPC ``listunspent``: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -``` - -No entanto, o verdadeiro trabalho consiste em decodificar a resposta. Na seção anterior vimos que a biblioteca ``jansson`` era "um tanto quanto desajeitada" e esta é a razão: Precisamos criar (e limpar) um conjunto muito grande de objetos ``json_t`` para descobrir o que queremos. - -Primeiro, precisamos nos recuperar o campo ``result`` do JSON: -``` c -json_t *lu_response = NULL; -json_t *lu_result = NULL; - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -``` - -> :warning: **ATENÇÃO:** Só obteremos um resultado se não houver nenhum erro. Aqui temos um momento para melhorar nossa verificação de erros no código que iremos colocar em produção. - -Em seguida, vamos fazer um laço, examinando cada transação que não foi gasta, que aparece como um elemento em sua matriz do resultado JSON: -``` c -int i; - -const char *tx_id = 0; -int tx_vout = 0; -double tx_value = 0.0; - -for(i = 0 ; i < json_array_size(lu_result) ; i++) { - - json_t *lu_data = NULL; - lu_data = json_array_get(lu_result, i); - - json_t *lu_value = NULL; - lu_value = json_object_get(lu_data,"amount"); - tx_value = json_real_value(lu_value); -``` - -O UTXO é grande o suficiente para pagar sua transação? Se sim, pegue-o! - -> :warning: **ATENÇÃO:** Um programa em produção pensaria com mais cuidado sobre qual UTXO utilizar, com base no tamanho e em outros fatores. Provavelmente não pegaria apenas o primeiro mais simples e pronto. - -``` c - if(tx_value > tx_total) { - - json_t *lu_txid = NULL; - lu_txid = json_object_get(lu_data,"txid"); - tx_id = strdup(json_string_value(lu_txid)); - - json_t *lu_vout = NULL; - lu_vout = json_object_get(lu_data,"vout"); - tx_vout = json_integer_value(lu_vout); - - json_decref(lu_value); - json_decref(lu_txid); - json_decref(lu_vout); - json_decref(lu_data); - break; - - } -``` -Você também deve limpar os principais elementos do JSON: -``` c -} - -json_decref(lu_result); -json_decref(lu_response); -``` - -> :warning: **ATENÇÃO:** Um programa em produção também se certificaria de que os UTXOs são passíveis de serem `gastos`. - -Se não encontramos nenhum UTXOs grande o suficiente, teremos que relatar este infortúnio ao usuário... E talvez, sugerir que ele deva usar um programa melhor, que irá mesclar os UTXOs de maneira correta. -``` c -if(!tx_id) { - - printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); - exit(-1); -} -``` - -> **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. - -### Etapa 5: Criando um endereço de troco - -Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); - -if(!rpc_method) { - - printf("ERROR: Unable to initialize listunspent method!\n"); - exit(-1); - -} - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -if(btcerror.code != BITCOINRPCE_OK) { - -printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); - - exit(-1); - -} - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -char *changeaddress = strdup(json_string_value(lu_result)); -``` -A única diferença é quais informações específicas são extraídas do objeto JSON. - -> :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. - -### Etapa 6: Criando uma transação bruta - -Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. - -Para criarmos esses parâmetros corretamente, precisaremos revisar o que o RPC ``createrawtransaction`` espera que passemos como argumento. Felizmente, isso é fácil de determinar usando a funcionalidade ``bitcoin-cli help``: -``` -$ bitcoin-cli help createrawtransaction -createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) -``` - -Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. - -#### Etapa 6.1: Criando os parâmetros de entrada - -Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): -``` c -json_t *inputtxid = NULL; -inputtxid = json_object(); - -json_object_set_new(inputtxid,"txid",json_string(tx_id)); -json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); -``` - -Pode-se notar que teremos que traduzir novamente cada tipo de variável C em um tipo de variável JSON usando a função apropriada, como ``json_string`` ou ``json_integer``. - -Para criar o array de entrada para todos os UTXOs, vamos usar o ``json_array`` e, em seguida, preenchê-lo com os objetos usando o ``json_array_append``: -``` c -json_t *inputparams = NULL; -inputparams = json_array(); -json_array_append(inputparams,inputtxid); -``` - -#### Etapa 6.2: Criando os parâmetros de saída - -Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: -``` c -json_t *outputparams = NULL; -outputparams = json_object(); - -char tx_amount_string[32]; -sprintf(tx_amount_string,"%.8f",tx_amount); -char tx_change_string[32]; -sprintf(tx_change_string,"%.8f",tx_value - tx_total); - -json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); -json_object_set(outputparams, changeaddress, json_string(tx_change_string)); -``` - -> :warning: **ATENÇÃO:** É possível pensar que teremos que inserir os valores do Bitcoin como sendo números, usando a função ``json_real``. Infelizmente, isso expõe um dos maiores problemas com a integração da biblioteca ``jansson`` e o Bitcoin. O Bitcoin só é válido até oito dígitos depois da casa decimal. Devemos nos lembrar que 0,00000001 BTC é um satoshi, e essa é a menor divisão possível de um Bitcoin. O tipo ``double`` no C oferecem mais dígitos do que precisamos, embora sejam frequentemente imprecisos depois das oito casas decimais. Se tentarmos convertê-los diretamente do nosso valor ``double`` no C (ou de um tipo ``float``, neste caso) para um valor Bitcoin, a imprecisão frequentemente criará um valor Bitcoin com mais de oito dígitos. Antes da versão Bitcoin Core 0.12, isso não era problema, e podíamos usar a função ``json_real``. Mas à partir dessa versão, se tentarmos usar a função ``createrawtransaction`` com mais do que oito dígitos, obteremos um erro e a transação não será criada. Como resultado, se o valor do Bitcoin _sempre_ se tornar um ``double`` ou ``float``, devemos deixar com apenas oito casas decimais antes de transformá-lo em uma ``string``. Obviamente, isso é um erro, portanto, certifique-se disso para que o código continue funcionando nas versões mais novas do Bitcoin Core. - -#### Etapa 6.3: Criando a Matriz de Parâmetros - -Para terminarmos de criar os parâmetros, só precisaremos agrupá-los em uma matriz JSON: -``` c -json_t *params = NULL; -params = json_array(); -json_array_append(params,inputparams); -json_array_append(params,outputparams); -``` - -#### Etapa 6.4: Fazendo a chamada ao RPC - -Vamos usar o método normal para criar uma chamada ao RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); -``` -Agora, porém, devemos adicionar os nossos parâmetros. Isso pode ser feito facilmente com a função ``bitcoinrpc_method_set_params``: -``` c -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for createrawtransaction"); - -} -``` -Depois, é só executar o RPC e obter os resultados: -``` c -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_rawhex = strdup(json_string_value(lu_result)); -``` -### Etapa 7. Assinando a transação - -É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_rawhex)); -``` -Por fim, vamos assinar a transação seguindo o rigamarole típico para criar uma chamada RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for signrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -``` -Novamente, usar a função ``jansson`` para acessar a saída pode ser complicado. Devemos lembrar que ``hex`` é parte de um objeto JSON, não um resultado independente, como era quando criamos a transação bruta. Claro, sempre podemos acessar essas informações a partir da ajuda da linha de comando: ``bitcoin-cli help signrawtransaction`` -``` c -lu_result = json_object_get(lu_response,"result"); -json_t *lu_signature = json_object_get(lu_result,"hex"); -char *tx_signrawhex = strdup(json_string_value(lu_signature)); -json_decref(lu_signature); -``` -> :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. - -### Etapa 8. Enviando a transação - -Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_signrawhex)); - -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); - -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for sendrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_newid = strdup(json_string_value(lu_result)); - -printf("Txid: %s\n",tx_newid); -``` - -O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. - -## Testando o código - -O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). - -Compile-o como de costume: -``` -$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress -``` -Agora, é possível utilizá-lo para enviar fundos para um endereço: - -``` -./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 -Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 -``` -Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). - -## Resumo do Programando o Bitcoind usando C com bibliotecas RPC - -Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. - -## O Que Vem Depois? - -Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md deleted file mode 100644 index fe166ac..0000000 --- a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md +++ /dev/null @@ -1,155 +0,0 @@ - -# 15.3 Recebendo notificações usando C com a biblioteca ZMQ - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. - -> :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). - -## Configurando o ZMQ - -Antes de podemos ouvir a blockchain, precisaremos configurar o ``bitcoind`` para permitir as notificações ZMQ. Por isso, precisamos instalar a biblioteca ZMQ para tirar proveito dessas notificações. - -### Configurando o ``bitcoind`` para usar o ZMQ - -O Bitcoin Core está pronto para ZMQ, mas devemos especificar os endpoints do ZMQ. O ZeroMQ publish-sockets prefixa cada item de dados com um prefixo de tópico arbitrário que permite aos clientes assinantes solicitarem apenas os itens com um prefixo correspondente. Existem atualmente quatro tópicos suportados pelo ``bitcoind``: -``` -$ bitcoind --help | grep zmq | grep address - -zmqpubhashblock=
- -zmqpubhashtx=
- -zmqpubrawblock=
- -zmqpubrawtx=
-``` - -Podemos executar o ``bitcoind`` com argumentos de linha de comando para endpoints ZMQ, como mostrado acima, mas também podemos criar um endpoint acessível adicionando linhas apropriadas ao nosso arquivo ``~/.bitcoin/bitcoin.conf`` e reiniciando o sistema. - -``` -zmqpubrawblock=tcp://127.0.0.1:28332 -zmqpubrawtx=tcp://127.0.0.1:28333 -``` -Podemos então testar se os nossos endpoints estão funcionando usando o RPC ``getzmqnotifications``: - -``` -$ bitcoin-cli getzmqnotifications -[ - { - "type": "pubrawblock", - "address": "tcp://127.0.0.1:28332", - "hwm": 1000 - }, - { - "type": "pubrawtx", - "address": "tcp://127.0.0.1:28333", - "hwm": 1000 - } -] -``` -Nosso ``bitcoind`` agora irá emitir as notificações ZMQ - -### Instalando o ZMQ - -Para aproveitar essas notificações, precisamos de uma biblioteca ZMQ para usar com o C, portanto, estaremos usando uma nova biblioteca ZMQ ao invés da biblioteca ``libbitcoinrpc`` nesta seção, mas no futuro, podemos combinar ambas. - -Felizmente, as bibliotecas ZMQ estão disponíveis por meio de pacotes Debian padrão: -``` -$ sudo apt-get install libzmq3-dev -$ sudo apt-get install libczmq-dev -``` -Agora estamos pronto para escrever o código! - -## Escrevendo o programa de notificação - -O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. - -O programa requer dois parâmetros: O primeiro é o "servidor", que é o ponto de conexão TCP exposto pelo ``bitcoind``. O segundo é o "tópico", que atualmente é o ``zmqpubhashblock``,``zmqpubhashtx``, ``zmqpubrawblock`` ou ``zmqpubrawtx``. O tópico precisa ter suporte do ``bitcoin.conf`` e o endereço IP e a porta do servidor devem corresponder ao que está definido no arquivo de configuração. - -``` c -#include -int main(int argc, char ** argv) { - - char *zmqserver; - char *topic; - - if(argc < 3) { - printf("\nUSAGE:\nchainlistener \n\n"); - return 0; - } else { - zmqserver = argv[1]; - topic = argv[2]; - } -``` -Abriremos um soquete ZMQ para o servidor e para o tópico definido: -``` c - zsock_t *socket = zsock_new_sub(zmqserver, topic); - assert(socket); -``` -Depois, vamos esperar: -``` c - while(1) { - zmsg_t *msg; - int rc = zsock_recv(socket, "m", &msg); - assert(rc == 0); - - char *header = zmsg_popstr(msg); - zframe_t *zdata = zmsg_pop(msg); - unsigned int *no = (unsigned int*)zmsg_popstr(msg); - - char *data = zframe_strhex(zdata); - int len = zframe_size(zdata); - printf("Size: %d\n", len); - printf("Data: %s", data); - printf("\nNo: %d\n", *no); - - free(header); - free(data); - free(no); - free(zdata); - zmsg_destroy(&msg); - sleep(1); - } -``` -Enquanto esperamos, observamos as mensagens no soquete ZMQ. Sempre que recebermos uma mensagem, iremos retirá-la da pilha, relatando o número, comprimento e, o os dados que foram importante para nós. - -É isso! - -Claro, quando terminar o processo, precisamos limpar tudo: -``` c - zsock_destroy(&socket); - return 0; -} -``` - -### Testando o código de notificação - -O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: -``` -$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq -``` -Depois, podemos executá-lo com os tópicos e endereços que definimos no nosso ``bitcoin.conf``: -``` -$ ./chainlistener tcp://127.0.0.1:28333 rawtx -Size: 250 -Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 -No: 67 -Size: 249 -Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 -No: 68 -Size: 250 -Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 -No: 69 -Size: 250 -Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 -No: 70 -....... -``` - -### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ - -Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. - -> :fire: ***Qual é o poder das notificações?*** Com as notificações, não dependemos mais dos usuários para emitir os comandos. Ou seja, podemos criar programas que monitoram o blockchain do Bitcoin e tomar as ações apropriadas quando certas coisas ocorrem. Isso, por sua vez, pode ser utilizado juntamente com os comandos RPC que programamos nas seções anteriores. Este também é um grande passo além do que poderíamos fazer com os scripts shell: Certamente, podemos criar scripts shell que fica ouvindo infinitamente, mas existem outras linguagens de programação que possuem ferramentas melhores para isso. - -## O Que Vem Depois? - -Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file From 9b3388b2c8c3cf2d5c17fec8973f3bd0ea68e138 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 11:12:20 -0300 Subject: [PATCH 111/155] Rename files chapter 19 to 20 --- pt/{19_0_Using_Lightning.md => 20_0_Using_Lightning.md} | 0 ...te_a_Payment_Request.md => 20_1_Generate_a_Payment_Request.md} | 0 pt/{19_2_Paying_a_Invoice.md => 20_2_Paying_a_Invoice.md} | 0 pt/{19_3_Closing_a_Channel.md => 20_3_Closing_a_Channel.md} | 0 ...ghtning_Network_Review.md => 20_4_Lightning_Network_Review.md} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename pt/{19_0_Using_Lightning.md => 20_0_Using_Lightning.md} (100%) rename pt/{19_1_Generate_a_Payment_Request.md => 20_1_Generate_a_Payment_Request.md} (100%) rename pt/{19_2_Paying_a_Invoice.md => 20_2_Paying_a_Invoice.md} (100%) rename pt/{19_3_Closing_a_Channel.md => 20_3_Closing_a_Channel.md} (100%) rename pt/{19_4_Lightning_Network_Review.md => 20_4_Lightning_Network_Review.md} (100%) diff --git a/pt/19_0_Using_Lightning.md b/pt/20_0_Using_Lightning.md similarity index 100% rename from pt/19_0_Using_Lightning.md rename to pt/20_0_Using_Lightning.md diff --git a/pt/19_1_Generate_a_Payment_Request.md b/pt/20_1_Generate_a_Payment_Request.md similarity index 100% rename from pt/19_1_Generate_a_Payment_Request.md rename to pt/20_1_Generate_a_Payment_Request.md diff --git a/pt/19_2_Paying_a_Invoice.md b/pt/20_2_Paying_a_Invoice.md similarity index 100% rename from pt/19_2_Paying_a_Invoice.md rename to pt/20_2_Paying_a_Invoice.md diff --git a/pt/19_3_Closing_a_Channel.md b/pt/20_3_Closing_a_Channel.md similarity index 100% rename from pt/19_3_Closing_a_Channel.md rename to pt/20_3_Closing_a_Channel.md diff --git a/pt/19_4_Lightning_Network_Review.md b/pt/20_4_Lightning_Network_Review.md similarity index 100% rename from pt/19_4_Lightning_Network_Review.md rename to pt/20_4_Lightning_Network_Review.md From 271f867edc6801e10fb7af9e31cba2e8cb6b57f0 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 11:14:11 -0300 Subject: [PATCH 112/155] Review 20_0 --- pt/20_0_Using_Lightning.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pt/20_0_Using_Lightning.md b/pt/20_0_Using_Lightning.md index d783afe..748bcde 100644 --- a/pt/20_0_Using_Lightning.md +++ b/pt/20_0_Using_Lightning.md @@ -1,25 +1,26 @@ -# Capítulo 19: Usando a Lightning +# Capítulo 20: Usando a Lightning > :information_source: **NOTA:** Este é um rascunho que está em andamento, para que possa obter alguns comentários dos revisores iniciais. Ainda não está pronto. Neste capítulo, continuaremos trabalhando com a interface de linha de comando `lightning-cli`. Criaremos invoices, realizaremos pagamentos e fecharemos canais, todas as principais atividades para se usar a Lightning. -## Objetivos deste capítulo +## Objetivos Deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: * Efetuar pagamentos na Lightning Network; - * Aplicar o fechamento a um canal Lightning. - + * Aplicar o fechamento de um canal Lightning. + Os objetivos secundários do capítulo incluem a capacidade de: * Compreender o formato dos invoices; * Entender o ciclo de vida dos pagamentos da Lightning Network; * Saber como expandir a Lightning Network. - + ## Tabela de Conteúdo * [Seção 1: Gerando um Invoice](19_1_Generate_a_Payment_Request.md) * [Seção 2: Pagando um Invoice](19_2_Paying_a_Invoice.md) -* [Seção 3: Fechando um canal na Lightning](19_3_Closing_a_Channel.md) +* [Seção 3: Fechando um Canal na Lightning](19_3_Closing_a_Channel.md) * [Seção 4: Expandindo a Lightning Network](19_4_Lightning_Network_Review.md) + From 53f83e1d41da5a7cc99f1a3277de89de0ab2c47e Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 17:47:48 -0300 Subject: [PATCH 113/155] Review 20_1 --- pt/20_1_Generate_a_Payment_Request.md | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pt/20_1_Generate_a_Payment_Request.md b/pt/20_1_Generate_a_Payment_Request.md index e56860c..312e008 100644 --- a/pt/20_1_Generate_a_Payment_Request.md +++ b/pt/20_1_Generate_a_Payment_Request.md @@ -1,12 +1,12 @@ -# 19.1: Gerando um Invoice +# 20.1: Gerando um Invoice > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Esta seção descreve como os pagamentos funcionam na Lightning Network, como criar uma solicitação de pagamento (ou _invoice_) e, finalmente, como entendê-la. A emissão de invoices depende de termos um segundo node Lightning, conforme descrito na seção [Acessando um segundo node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md). Esses exemplos usarão um node LND como nosso node secundário, para demonstrar ainda mais as possibilidades da Lightning Network. Para diferenciar entre os nodes nestes exemplos, os prompts serão mostrados como `c $` para o node c-lightning e `lnd $` para o node LND. Se quisermos reproduzir essas etapas, devemos [instalar nosso próprio node LND secundário](18_2__Interlude_Accessing_a_Second_Lightning_Node.md#Creating-a-new-lnd-node). +Esta seção descreve como os pagamentos funcionam na Lightning Network, como criar uma solicitação de pagamento (ou _invoice_) e, finalmente, como entendê-la. A emissão de invoices depende de termos um segundo node Lightning, conforme descrito na seção [Acessando um Segundo Node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md). Esses exemplos usarão um node LND como nosso node secundário, para demonstrar ainda mais as possibilidades da Lightning Network. Para diferenciar entre os nodes nestes exemplos, os prompts serão mostrados como `c $` para o node c-lightning e `lnd $` para o node LND. Se quisermos reproduzir essas etapas, devemos [instalar nosso próprio node LND secundário](19_2__Interlude_Accessing_a_Second_Lightning_Node.md#Creating-a-new-lnd-node). > :book: ***O que é um invoice?*** Quase todos os pagamentos feitos na Lightning Network exigem um invoice, que nada mais é do que um **pedido de pagamento** feito pelo destinatário do dinheiro e enviado por qualquer meio para o usuário que irá pagar. Todos os invoices são de uso único. Os invoices da Lightning usam a codificação bech32, que já é usada pela Segregated Witness para Bitcoin. -## Criando um invoice +## Criando um Invoice Para criar um novo invoice na c-lightning, usaríamos o comando `lightning-cli --testnet invoice`. @@ -21,7 +21,7 @@ c$ lightning-cli --testnet invoice 100000 joe-payment "The money you owe me for "warning_mpp_capacity": "The total incoming capacity is still insufficient even if the payer had MPP capability." } ``` -No entanto, para este exemplo, vamos gerar um invoice em um node LND e, em seguida, pagá-la no node c-lightning. Isso requer o comando `addinvoice` ligeiramente diferente na LND. Podemos usar o argumento `--amt` para indicar a quantia a ser paga (em milisats) e adicionar uma descrição usando o argumento `--memo`. +No entanto, para este exemplo, vamos gerar um invoice em um node LND e, em seguida, pagá-lo no node c-lightning. Isso requer o comando `addinvoice` ligeiramente diferente na LND. Podemos usar o argumento `--amt` para indicar a quantia a ser paga (em milisats) e adicionar uma descrição usando o argumento `--memo`. ``` lnd$ lncli -n testnet addinvoice --amt 10000 --memo "First LN Payment - Learning Bitcoin and Lightning from the Command line." @@ -33,13 +33,13 @@ lnd$ lncli -n testnet addinvoice --amt 10000 --memo "First LN Payment - Learning ``` Observe que esses invoices não fazem referência direta ao canal que criamos: isso é necessário para o pagamento, mas não para solicitar o pagamento. -## Compreendendo um invoice +## Compreendendo um Invoice O `bolt11 payment_request` que criamos é composto de duas partes: uma é legível por humanos e a outra são apenas dados. > :book: **O que é um BOLT?** Os BOLTs são as [especificações individuais da Lightning Network](https://github.com/lightningnetwork/lightning-rfc). -### Lendo a parte legível do invoice +### Lendo a Parte Legível do Invoice A parte legível dos invoices começa com um `ln`. É `lnbc` para Bitcoin mainnet, `lntb` para Bitcoin testnet ou `lnbcrt` para Bitcoin regtest. Em seguida, listamos os fundos solicitados no invoice. @@ -61,9 +61,9 @@ O `100u` diz que é para 100 bitcoins vezes o multiplicador microsatoshi. Existe 100 BTC * 0,000001 = 0,0001 BTC, que é o mesmo que 10.000 satoshis. -### Lendo a parte do invoice referente aos dados +### Lendo a Parte do Invoice Referente aos Dados -O resto do invoice ( `1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd`) contém um marcador de tempo, dados especificamente marcados, e uma assinatura. Obviamente, não pode ler sem decodificá-lo, mas podemos pedir ao `lightning-cli` para fazer isso com o comando `decodepay`: +O resto do invoice (`1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd`) contém um marcador de tempo, dados especificamente marcados e uma assinatura. Obviamente, não pode ler sem decodificá-lo, mas podemos pedir ao `lightning-cli` para fazer isso com o comando `decodepay`: ``` c$ lightning-cli --testnet decodepay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd { @@ -85,7 +85,7 @@ c$ lightning-cli --testnet decodepay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm Aqui temos o que os elementos mais relevantes significam: 1. `currency`: A moeda a ser paga; -2. `created_at`: Momento em que a fatura foi criada. O valor é dado em tempo UNIX, que é segundos desde 1970. +2. `created_at`: O momento em que a fatura foi criada. O valor é dado em tempo UNIX, que é segundos desde 1970. 3. `expiry`: O momento em que nosso node marca a fatura como inválida. O padrão é 1 hora ou 3600 segundos. 4. `payee`: A chave pública da pessoa (node) que recebe o pagamento da Lightning Network; 5. `msatoshi` e `amount_msat`: O valor de satoshis a ser pago; @@ -95,11 +95,11 @@ Aqui temos o que os elementos mais relevantes significam: > :book: ***O que são pagamentos condicionais?*** Embora os canais Lightning sejam criados entre dois participantes, vários canais podem ser conectados juntos, formando uma rede de pagamento que permite envio de valores entre todos os participantes da rede, mesmo aqueles sem um canal direto entre eles. Isso é feito usando um contrato inteligente denominado **Hashed Time Locked Contract**. -> :book: ***O que é um Hashed Time Locked Contract (HTLC)?*** Um HTLC é um pagamento condicional que usa hashlocks e timelocks para garantir a segurança do pagamento. O destinatário deve apresentar uma pré-imagem do pagamento ou gerar um comprovante criptográfico de pagamento antes de um determinado prazo, caso contrário o pagador pode cancelar o contrato gastando-o. Esses contratos são criados como saídas da **Transação de compromisso**. +> :book: ***O que é um Hashed Time Locked Contract (HTLC)?*** Um HTLC é um pagamento condicional que usa hashlocks e timelocks para garantir a segurança do pagamento. O destinatário deve apresentar uma pré-imagem do pagamento ou gerar um comprovante criptográfico de pagamento antes de um determinado prazo, caso contrário o pagador pode cancelar o contrato gastando-o. Esses contratos são criados como saídas da **Transação de Compromisso**. -> :book: ***O que é uma transação de compromisso?*** Uma transação de compromisso é uma transação que gasta a transação de financiamento original. Cada par possui a assinatura do outro par, o que significa que qualquer um pode gastar sua transação do compromisso como quiser. Depois que cada nova transação de confirmação é criada, a antiga é revogada. A transação de confirmação é uma maneira pela qual a transação de financiamento pode ser desbloqueada na blockchain, conforme discutiremos na seção [§19.3](19_3_Closing_a_Channel.md). +> :book: ***O que é uma transação de compromisso?*** Uma transação de compromisso é uma transação que gasta a transação de financiamento original. Cada par possui a assinatura do outro par, o que significa que qualquer um pode gastar sua transação do compromisso como quiser. Depois que cada nova transação de confirmação é criada, a antiga é revogada. A transação de confirmação é uma maneira pela qual a transação de financiamento pode ser desbloqueada na blockchain, conforme discutiremos na seção [§20.3](20_3_Closing_a_Channel.md). -### Verificando nosso invoice +### Verificando Nosso Invoice Existem dois elementos cruciais para verificar o invoice. O primeiro, obviamente, é o valor do pagamento, que já examinamos na parte legível. O segundo é o dado do `payee`, que é o pubkey do destinatário (node): ``` @@ -107,7 +107,7 @@ Existem dois elementos cruciais para verificar o invoice. O primeiro, obviamente ``` Precisamos verificar se ele é o destinatário esperado. -Olhando nas seções anteriores, mais precisamente na seção [§18.3](18_3_Setting_Up_a_Channel.md#opening-a-channel), podemos observar que é de fato o ID do par que usamos quando criamos nosso canal. Também podemos verificá-lo no outro node com o comando `getinfo`. +Olhando nas seções anteriores, mais precisamente na seção [§19.3](19_3_Setting_Up_a_Channel.md#opening-a-channel), podemos observar que é de fato o ID do par que usamos quando criamos nosso canal. Também podemos verificá-lo no outro node com o comando `getinfo`. ``` lnd$ lncli -n testnet getinfo { @@ -173,12 +173,12 @@ lnd$ lncli -n testnet getinfo } } ``` -No entanto, o `payee` também pode ser alguém novo, caso em que provavelmente precisaremos verificar com a pessoa que emitiu o invoice para garantir que está tudo correto. +No entanto, o `payee` também pode ser alguém novo, caso no qual provavelmente precisaremos verificar com a pessoa que emitiu o invoice para garantir que tudo está correto. ## Resumo: Gerando um Invoice -Na maioria dos casos, precisamos receber um invoice para usar os pagamentos da Lightning Network. Neste exemplo, criamos um manualmente, mas se estivermos em um ambiente de produção, provavelmente teria sistemas fazendo isso automaticamente sempre que alguém adquirir produtos ou serviços. Claro, depois de receber um invoice, precisamos saber como lê-lo! +Na maioria dos casos, precisamos receber um invoice para usar os pagamentos da Lightning Network. Neste exemplo, criamos um manualmente, mas se estivermos em um ambiente de produção, provavelmente teriam sistemas fazendo isso automaticamente sempre que alguém adquirir produtos ou serviços. Claro, depois de receber um invoice, precisamos saber como lê-lo! ## O Que Vem Depois? -Vamos continuar "Usando a Lightning" na seção [§19.2: Pagando um Invoice](06_3_Sending_an_Automated_Multisig.md). \ No newline at end of file +Vamos continuar "Usando a Lightning" na seção [§20.2: Pagando um Invoice](20_2_Paying_a_Invoice.md). \ No newline at end of file From e18d52dd9a55bb398d2ca0206d0baa3481d89e30 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 17:53:13 -0300 Subject: [PATCH 114/155] Review 20_2 --- pt/20_2_Paying_a_Invoice.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pt/20_2_Paying_a_Invoice.md b/pt/20_2_Paying_a_Invoice.md index d464dfa..3abb6d5 100644 --- a/pt/20_2_Paying_a_Invoice.md +++ b/pt/20_2_Paying_a_Invoice.md @@ -1,12 +1,12 @@ -# 19.2: Pagando um Invoice +# 20.2: Pagando um Invoice > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -Neste capítulo, aprenderemos como pagar um invoice usando o comando `lightning-cli pay`. Presume-se que já sabemos como analisar um invoice, de acordo com a seção [§19.1](19_1_Generate_a_Payment_Request.md) e sabemos que ele é válido. +Neste capítulo, aprenderemos como pagar um invoice usando o comando `lightning-cli pay`. Presume-se que já sabemos como analisar um invoice, de acordo com a seção [§20.1](20_1_Generate_a_Payment_Request.md), e se ele é válido. -## Verificando o saldo +## Verificando o Saldo -Obviamente, a primeira coisa que precisamos fazer é nos certificarmos de que possuímos fundos suficientes para pagar o invoice. Neste caso, o canal configurado anteriormente com `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543` contém 100.000 satoshis. Este será o canal de pagamento do inoice. +Obviamente, a primeira coisa que precisamos fazer é nos certificarmos de que possuímos fundos suficientes para pagar o invoice. Neste caso, o canal configurado anteriormente com `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543` contém 100.000 satoshis. Este será o canal de pagamento do invoice. ``` c$ lightning-cli --testnet listfunds @@ -42,7 +42,7 @@ c$ lightning-cli --testnet listfunds ``` Se não tivermos fundos suficientes, precisamos criar um novo canal. -## Pagando nosso invoice +## Pagando Nosso Invoice Vamos usar o comando `lightning-cli pay` para pagar o invoice. Ele tentará encontrar uma rota para o destino fornecido, para posteriormente enviar os fundos solicitados. Isso é muito simples porque há um canal direto entre o pagador e o destinatário: ``` @@ -60,9 +60,9 @@ c$ lightning-cli --testnet pay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk "status": "complete" } ``` -Vamos observar todos os valores que estão em `msats`, não em `sats`! +Vamos observar que todos os valores estão em `msats`, não em `sats`! -### Pagando o invoice pela Lightning +### Pagando o Invoice pela Lightning No entanto, _não_ precisamos ter um canal com um node para pagá-lo. Só precisamos ter uma rota razoável pela Lightning Network. @@ -117,13 +117,13 @@ c$ lightning-cli --testnet pay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7 "status": "complete" } ``` -Essa é a verdadeira beleza da Lightning Network: Sem nenhum esforço dos participantes ponto a ponto, nossos canais individuais se tornam uma rede! +Essa é a verdadeira beleza da Lightning Network: sem nenhum esforço dos participantes ponto a ponto, nossos canais individuais se tornam uma rede! -> :book: ***Como funcionam os pagamentos na rede?*** Digamos que o node A tem um canal aberto com o node B, o node B tem um canal aberto com o node C e o node A recebe uma fatura do node C de 11.111 msat. O node A paga ao node B 11.111 msat, mais uma pequena taxa, e então o node B paga 11.111 msat ao node C. Muito fácil. Mas lembre-se de que todos os canais são, na verdade, apenas registros de quem é o proprietário e de quanto é a Transação de Financiamento. Então o que realmente acontece é 11.111 msat da Transação de Financiamento no canal AB muda de A para B e, em seguida, 11.111 msat da Transação de Financiamento no canal BC muda de B para C. Isso significa que duas coisas são necessárias para que este pagamento funcione: Primeiro, cada canal deve ter capacidade suficiente para o pagamento e; Segundo, o pagador em cada canal deve possuir o suficiente da capacidade para fazer o pagamento. +> :book: ***Como funcionam os pagamentos na rede?*** Digamos que o node A tem um canal aberto com o node B, o node B tem um canal aberto com o node C e o node A recebe uma fatura do node C de 11.111 msat. O node A paga ao node B 11.111 msat, mais uma pequena taxa, e então o node B paga 11.111 msat ao node C. Muito fácil. Mas lembre-se de que todos os canais são, na verdade, apenas registros de quem é o proprietário e de quanto é a Transação de Financiamento. Então o que realmente acontece é 11.111 msat da Transação de Financiamento no canal AB muda de A para B e, em seguida, 11.111 msat da Transação de Financiamento no canal BC muda de B para C. Isso significa que duas coisas são necessárias para que este pagamento funcione: primeiro, cada canal deve ter capacidade suficiente para o pagamento; e segundo, o pagador em cada canal deve possuir o suficiente da capacidade para fazer o pagamento. Observe que, neste exemplo, 12.111 msat foram enviados para pagar uma fatura de 11.111 msat: o extra sendo uma taxa fixa muito pequena (não uma porcentagem) que foi paga ao intermediário. -## Verificando nosso saldo +## Verificando Nosso Saldo Após efetuar um pagamento com sucesso, veremos que nossos fundos foram alterados corretamente. @@ -160,7 +160,7 @@ c$ lightning-cli --testnet listfunds ] } ``` -Observe que a capacidade do canal permanece em 100.000 satoshis (isso nunca irá mudar!), Mas que o `our_amount` agora é de apenas 90.000 satoshis (ou 90.000.000 msat). +Observe que a capacidade do canal permanece em 100.000 satoshis (isso nunca irá mudar!), mas que o `our_amount` agora é de apenas 90.000 satoshis (ou 90.000.000 msat). Depois de pagar a segunda fatura, de 11.111 msat, os fundos mudam novamente: ``` @@ -203,4 +203,4 @@ Depois de recebermos um invoice, é fácil pagar com um único comando na Lightn ## O Que Vem Depois? -Vamos continuar "Usando a Lightning" na seção [§19.3: Fechando um Canal na Lightning](19_3_Closing_a_Channel.md). \ No newline at end of file +Vamos continuar "Usando a Lightning" na seção [§20.3: Fechando um Canal na Lightning](20_3_Closing_a_Channel.md). \ No newline at end of file From 4122c56e166df671c270f2a4637dad259ebcc378 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 18:07:04 -0300 Subject: [PATCH 115/155] Review 20_3 --- pt/20_3_Closing_a_Channel.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pt/20_3_Closing_a_Channel.md b/pt/20_3_Closing_a_Channel.md index bfb8881..15b1683 100644 --- a/pt/20_3_Closing_a_Channel.md +++ b/pt/20_3_Closing_a_Channel.md @@ -1,4 +1,4 @@ -# 19.3: Fechando um canal +# 20.3: Fechando um Canal > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -6,7 +6,7 @@ Neste capítulo, aprenderemos como fechar um canal usando a interface de linha d Para fechar um canal, primeiro precisamos saber o ID do node remoto. Podemos recuperá-lo de duas maneiras. -## Encontrando nossos canais pelos saldos +## Encontrando Nossos Canais Pelos Saldos Podemos usar o comando `lightning-cli listfunds` para ver nossos canais. Este comando RPC exibe todos os fundos disponíveis, em `outputs` não gastos (UTXOs) na carteira interna ou bloqueados em `channels` (canais) abertos. ``` @@ -59,11 +59,11 @@ Poderíamos também recuperar o ID do enésimo canal em uma variável como esta: c$ nodeidremote=$(lightning-cli --testnet listfunds | jq '.channels[0] | .peer_id') ``` -## Encontrando os canais usando o JQ +## Encontrando Canais Usando o JQ A outra maneira de encontrar canais para serem fechados é usando o comando `listchannels`. Ele retorna dados dos canais que são conhecidos pelo node. Como os canais podem ser bidirecionais, até dois nodes serão retornados por cada canal (um para cada direção). -No entanto, assim como no mundo real, a fofoca (gossip) da Lightning Network é muito eficaz e, em pouco tempo, iremos conhecer os milhares de canais. Isso é ótimo para enviar pagamentos via Lightning Network, mas é pouco útil para descobrir os nossos próprios canais. Fazer isso requer um pouco de trabalho do `jq`. +No entanto, assim como no mundo real, a fofoca (gossip) da Lightning Network é muito eficaz e, em pouco tempo, iremos conhecer milhares de canais. Isso é ótimo para enviar pagamentos via Lightning Network, mas é pouco útil para descobrir os nossos próprios canais. Fazer isso requer um pouco de trabalho com `jq`. Primeiro, precisamos saber nosso próprio ID do node, que pode ser recuperado com o `getinfo`: ``` @@ -101,9 +101,9 @@ Depois de saber o que temos, podemos armazená-lo em uma variável: c$ nodeidremote=$(lightning-cli --testnet listchannels | jq '.channels[] | select(.source == '$nodeid' or .destination == '$nodeid') | .destination') ``` -## Fechando um canal +## Fechando um Canal -Agora que temos um ID do node remoto, estamos prontos para usar o comando `lightning-cli close` para fechar um canal. Por padrão, ele tentará fechar o canal cooperativamente com o par, se quisermos fechá-lo unilateralmente, precisamos definir o argumento `unilateraltimeout` com o número de segundos de espera. Se definirmos como sendo 0 e o par estiver online, um fechamento mútuo ainda irá ser tentado. Para este exemplo, tentaremos um fechamento mútuo. +Agora que temos um ID do node remoto, estamos prontos para usar o comando `lightning-cli close` para fechar um canal. Por padrão, ele tentará fechar o canal cooperativamente com o par; se quisermos fechá-lo unilateralmente, precisamos definir o argumento `unilateraltimeout` com o número de segundos de espera. Se definirmos como sendo 0 e o par estiver online, um fechamento mútuo ainda irá ser tentado. Para este exemplo, tentaremos um fechamento mútuo. ``` c$ lightning-cli --testnet close $nodeidremote 0 { @@ -112,7 +112,7 @@ c$ lightning-cli --testnet close $nodeidremote 0 "type": "mutual" } ``` -A transação de fechamento na cadeia é [f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f] (https://blockstream.info/testnet/tx/f68de52d80a1076e36c67795f9f9db4f13048519489593f]. +A transação de fechamento na blockchain é [f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f] (https://blockstream.info/testnet/tx/f68de52d80a1076e36c67795f9f9db4f13048519489593f]. É essa transação de fechamento que realmente gasta os fundos que foram negociados de um lado para outro por meio de transações Lightning. Isso pode ser visto examinando a transação: ``` @@ -177,7 +177,7 @@ $ bitcoin-cli --named getrawtransaction txid=f68de52d80a1076e36c677ef640539c50e3 "blocktime": 1602713519 } ``` -A entrada da transação é `66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d`, que foi a transação de financiamento feita na seção [§18.3](18_3_Setting_Up_a_Channel.md). A transação tem duas saídas, uma para o node remoto e outra para a carteira local da c-lightning. A saída no índice 0 corresponde ao node remoto com um valor de 0,00010012 BTC e, a saída no índice 1 corresponde ao node local com um valor de 0,00089804 BTC. +A entrada da transação é `66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d`, que foi a transação de financiamento feita na seção [§19.3](19_3_Setting_Up_a_Channel.md). A transação tem duas saídas, uma para o node remoto e outra para a carteira local da c-lightning. A saída no índice 0 corresponde ao node remoto com um valor de 0,00010012 BTC e, a saída no índice 1 corresponde ao node local com um valor de 0,00089804 BTC. A Lightning mostrará da mesma forma 89.804 satoshis retornados como um novo UTXO em nossa carteira: @@ -226,7 +226,7 @@ $ lightning-cli --network=testnet listfunds ``` -### Compreendendo os tipos de canais de fechamento. +### Compreendendo os Tipos de Canais de Fechamento. O comando `close` do RPC tenta fechar um canal cooperativamente com nosso par ou unilateralmente após o argumento `unilateraltimeout` expirar. Isso traz alguma discussão adicional, pois vai ao cerne do design que não precisa de nenhuma confiança da Lightning: @@ -238,7 +238,7 @@ No caso de um fechamento cooperativo, ambos os participantes do canal concordam #### Fechamento Forçado -No caso de fechamento forçado, apenas um participante está online ou os participantes discordam sobre o estado final do canal. Nessa situação, um par pode realizar um fechamento unilateral do canal sem a cooperação do outro node. É executado transmitindo uma transação de confirmação que confirma o estado do canal anterior que ambas as partes concordaram. Esta transação de compromisso contém o estado do canal dividido em duas partes: O saldo de cada participante e todos os pagamentos pendentes (HTLCs). +No caso de fechamento forçado, apenas um participante está online ou os participantes discordam sobre o estado final do canal. Nessa situação, um par pode realizar um fechamento unilateral do canal sem a cooperação do outro node. É executado transmitindo uma transação de confirmação que confirma o estado do canal anterior que ambas as partes concordaram. Esta transação de compromisso contém o estado do canal dividido em duas partes: o saldo de cada participante e todos os pagamentos pendentes (HTLCs). Para realizar este tipo de fechamento, devemos especificar um argumento `unilateraltimeout`. Se este valor não for zero, o comando de fechamento fechará unilateralmente o canal quando esse número de segundos for atingido: ``` @@ -250,10 +250,10 @@ c$ lightning-cli --network=testnet close $newidremote 60 } ``` -## Resumo: Fechando um canal +## Resumo: Fechando um Canal Ao fechar um canal, realizamos uma transação na blockchain encerrando nosso relacionamento financeiro com o node remoto. Para fechar um canal, devemos levar em consideração nosso status e o tipo de fechamento que desejamos executar. ## O Que Vem Depois? -Vamos continuar "Usando a Lightning" na seção [§19.4: Expandindo a rede Lightning](19_3_Closing_a_Channel.md). \ No newline at end of file +Vamos continuar "Usando a Lightning" na seção [§20.4: Expandindo a Rede Lightning](20_4_Lightning_Network_Review.md). \ No newline at end of file From 5633bb4cd257dca09b0ea7dafb6da5824fd5202e Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 1 Sep 2021 18:15:22 -0300 Subject: [PATCH 116/155] Review 20_4 --- pt/20_4_Lightning_Network_Review.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pt/20_4_Lightning_Network_Review.md b/pt/20_4_Lightning_Network_Review.md index acee240..bed52ba 100644 --- a/pt/20_4_Lightning_Network_Review.md +++ b/pt/20_4_Lightning_Network_Review.md @@ -1,10 +1,10 @@ -# 19.4: Expandindo a Lightning Network +# 20.4: Expandindo a Lightning Network > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Esses dois capítulos cobriram apenas algumas das atividades mais importantes da Lightning. Há muito mais que pode ser feito e muitas variedades possíveis. A seguir, daremos algumas dicas importantes. -## Usando plugins c-lightning +## Usando Plugins c-lightning O c-lightning é uma implementação leve, altamente personalizável e compatível com o padrão do protocolo Lightning Network. Ele estende a funcionalidade usando plugins. Principalmente, esses são subprocessos que são iniciados pelo daemon `lightningd` e podem interagir com o `lightningd` de várias maneiras: @@ -17,7 +17,7 @@ Um plugin pode ser escrito em qualquer linguagem e pode se comunicar com o `ligh O repositório `lightningd` GitHub mantém uma lista atualizada de [plugins](https://github.com/lightningd/plugins) disponíveis. -## Usando Mobile Wallets +## Usando Carteiras Mobile Atualmente, sabemos de duas carteiras de dispositivos móveis da Lightning que suportam a implementação do c-lightning. @@ -29,9 +29,9 @@ O SparkWallet é uma carteira GUI minimalista para a c-lightning, acessível pel * [SparkWallet](https://github.com/shesek/spark-wallet) -## Usando diferentes implementações da Lightning +## Usando Diferentes Implementações da Lightning -O c-lightning não é a nossa única opção. Hoje, existem três implementações amplamente utilizadas para a Lightning Network. Todos seguem as [Documentações Base para a Tecnologia Lightning (BOLT)](https://github.com/lightningnetwork/lightning-rfc), que descrevem um protocolo de segunda camada para transferências de bitcoins offchain. As especificações são atualmente um trabalho em andamento que ainda está sendo elaborado. +O c-lightning não é a nossa única opção. Hoje, existem três implementações amplamente utilizadas para a Lightning Network. Todos seguem as [Documentações Base para a Tecnologia Lightning (BOLT)](https://github.com/lightningnetwork/lightning-rfc), que descrevem um protocolo de segunda camada para transferências de bitcoins off-chain. As especificações são atualmente um trabalho em andamento que ainda está sendo elaborado. | Nome | Descrição | BitcoinStandup | Linguagem | Repositório | | ------------- | ------------- | :---: | ------------- | ------------- | @@ -39,9 +39,9 @@ O c-lightning não é a nossa única opção. Hoje, existem três implementaçõ | LND | Lightning Labs | X | Go | [Download](https://github.com/lightningnetwork/lnd) | | Eclair | ACINQ | - | Scala | [Download](https://github.com/ACINQ/eclair) | -## Fazendo backups +## Fazendo Backups -Nosso node Lightning precisa estar online o tempo todo, caso contrário, nossa contraparte pode enviar um status de canal anterior e roubar nossos fundos. No entanto, há outro cenário em que os fundos podem ser perdidos, que é quando ocorre uma falha no hardware que impede o node de estabelecer um fechamento cooperativo com a contraparte. Isso provavelmente significará que, se não tivermos uma cópia exata do estado do canal antes da falha, teremos um estado inválido que pode fazer com que o outro node o considere como uma tentativa de fraude e use a transação penalizada. Nesse caso, todos os fundos serão perdidos. Para evitar esta situação indesejável, uma solução baseada na alta disponibilidade do banco de dados postgresQL [existe](https://github.com/gabridome/docs/blob/master/c-lightning_with_postgresql_reliability.md). +Nosso node Lightning precisa estar online o tempo todo, caso contrário, nossa contraparte pode enviar um status de canal anterior e roubar nossos fundos. No entanto, há outro cenário em que os fundos podem ser perdidos, que é quando ocorre uma falha no hardware que impede o node de estabelecer um fechamento cooperativo com a contraparte. Isso provavelmente significará que, se não tivermos uma cópia exata do estado do canal antes da falha, teremos um estado inválido que pode fazer com que o outro node o considere como uma tentativa de fraude e use a transação penalizada. Nesse caso, todos os fundos serão perdidos. Para evitar esta situação indesejável, uma solução baseada na alta disponibilidade do banco de dados postgreSQL [existe](https://github.com/gabridome/docs/blob/master/c-lightning_with_postgresql_reliability.md). PS: Não testamos esta solução. @@ -51,10 +51,10 @@ Podemos usar diferentes implementações, plugins, carteiras para celular e back ## O Que Vem Depois? -Concluímos todo o livro Aprendendo sobre o Bitcoin usando a Linha de Comando, embora não precise visitar os [Apêndices](A0_Apêndices.md) que possuem configurações alternativas, podemos fazer isso agora. +Concluímos todo o livro Aprendendo sobre o Bitcoin usando a Linha de Comando. Embora não precisemos visitar os [Apêndices](A0_Appendices.md), que possuem configurações alternativas, podemos fazer isso agora. -Caso contrário, nós o encorajamos a ingressar nas comunidades de desenvolvedores e programadores e também, colocar nosso novo conhecimento para funcionar. +Caso contrário, nós o encorajamos a ingressar nas comunidades de desenvolvedores e programadores e também, colocar seu novo conhecimento para funcionar. -Também podemos nos ajudar aqui em Blockchain Commons com issues ou PRs para aprender sobre o Bitcoin ou para qualquer um de nossos outros repositórios, ou podemos até mesmo nos tornar um [patrocinador](https://github.com/sponsors/BlockchainCommons). Também podemos ajudar divulgando o trabalho, contando às pessoas nas redes sociais sobre o curso e o que aprendemos com ele! +Você também pode nos ajudar aqui na Blockchain Commons com issues ou PRs para Aprendendo Bitcoin ou para qualquer um de nossos outros repositórios, ou pode até mesmo se tornar um [patrocinador](https://github.com/sponsors/BlockchainCommons). Também pode ajudar divulgando o trabalho, contando às pessoas nas redes sociais sobre o curso e o que aprendeu com ele! Agora vá lá e faça da comunidade do Bitcoin um lugar melhor! \ No newline at end of file From 00298f9e0d06b108f5f54a49ec6ca72016e56665 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 8 Sep 2021 10:45:46 -0300 Subject: [PATCH 117/155] Delete out of date files --- pt/15_0_Talking_to_Bitcoind.md | 27 -- pt/15_1_Accessing_Bitcoind_with_C.md | 294 --------------- pt/15_2_Programming_Bitcoind_with_C.md | 354 ------------------ ...Receiving_Bitcoind_Notifications_with_C.md | 155 -------- 4 files changed, 830 deletions(-) delete mode 100644 pt/15_0_Talking_to_Bitcoind.md delete mode 100644 pt/15_1_Accessing_Bitcoind_with_C.md delete mode 100644 pt/15_2_Programming_Bitcoind_with_C.md delete mode 100644 pt/15_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/pt/15_0_Talking_to_Bitcoind.md b/pt/15_0_Talking_to_Bitcoind.md deleted file mode 100644 index 88bde29..0000000 --- a/pt/15_0_Talking_to_Bitcoind.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Capítulo 15: Conversando com Bitcoind usando C - -Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. - -Esta seção se concentra em três diferentes bibliotecas que podem ser usadas como base de programação C sofisticada: Uma biblioteca RPC e uma biblioteca JSON que juntas permitem recriar muito do que fazemos nos scripts de shell, porém, usando C; enquanto uma biblioteca ZMQ nos conecta a notificações, algo que não conseguiríamos acessar até agora. (O próximo capítulo cobrirá uma biblioteca ainda mais sofisticada chamada Libwally, para finalizar esta introdução à programação do Bitcoin com C). - -## Objetivos deste capítulo - -Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - - * Criar programas C que usam RPC para conversar com o Bitcoind; - * Criar programas C que usam ZMQ para conversar com o Bitcoind. - -Os objetivos secundários do capítulo incluem a capacidade de: - - * Entender como usar uma biblioteca RPC; - * Entender como usar uma biblioteca JSON; - * Compreender as capacidades do ZMQ; - * Entender como usar uma biblioteca ZMQ. - -## Tabela de conteúdo - - * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) - * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) - * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) - \ No newline at end of file diff --git a/pt/15_1_Accessing_Bitcoind_with_C.md b/pt/15_1_Accessing_Bitcoind_with_C.md deleted file mode 100644 index 2e97e1c..0000000 --- a/pt/15_1_Accessing_Bitcoind_with_C.md +++ /dev/null @@ -1,294 +0,0 @@ - -# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -Você já viu uma maneira alternativa de acessar as portas RPC do Bitcoind: Usando o ``curl``, que cobrimos no [Capítulo 4 Prefácio](04_4__interlude_using_curl.md). Interagir com o ``Bitcoind`` através de uma biblioteca de RPC usando C não é diferente do que já vimos, só precisamos de boas bibliotecas para nos auxiliar. Esta seção introduz um pacote chamado ``libbitcoinrpc``, que permite acessar a porta JSON-RPC do ``bitcoind``. Ele usa uma biblioteca ``curl`` para acessar os dados e usa a biblioteca ``jansson`` para codificar e decodificar o JSON. - -## Configurando o libbitcoinrpc - -Para usar o ``libbitcoinrpc``, precisaremos instalar uma configuração básica C e os pacotes dependentes, que são ``libcurl``, ``libjansson``, e ``libuuid``. Depois faremos isso no seu servidor Standup Bitcoin (ou em qualquer outro servidor Ubuntu). - -``` -$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev -Suggested packages: - libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev -The following NEW packages will be installed: - libcurl4-openssl-dev libjansson-dev uuid-dev -0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. -Need to get 358 kB of archives. -After this operation, 1.696 kB of additional disk space will be used. -Do you want to continue? [Y/n] y -``` -Agora, podemos baixar o [libbitcoinrpc no github](https://github.com/gitmarek/libbitcoinrpc/blob/master/readme.md). Vamos clonar ou pegar um arquivo zip, do jeito que preferir. - -``` -$ sudo apt-get install git -$ git clone https://github.com/gitmarek/libbitcoinrpc -``` - -> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. - -### Compilando o libbitcoinrpc. - -Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: -``` -$ PATH="/sbin:$PATH" -``` - -Para o Ubuntu, também precisaremos ajustar o ``install_libpath`` no ``makefile`` do ``libbitcoinrpc`` para instalar no ``/usr/lib`` ao invés do ``/usr/local/lib``: - -``` -$ emacs ~/libbitcoinrpc/Makefile -... -INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib -``` - -(Se preferir não usar o ``/usr/lib``, precisará alterar o ``etc/ld.so.conf`` ou os arquivos dependentes de maneira apropriada... Porém, para uma configuração de teste em uma máquina de teste, acredito que isso não seja um problema). - -Da mesma forma, vamos precisar ajustar o ``install_headerpath`` no ``Makefile`` do ``libbitcoinrpc`` para instalar no caminho ``/usr/include`` ao invés do ``/usr/local/inclusve``: - -``` -... -INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include -``` - -Agora, podemos compilar: -``` -$ cd libbitcoinrpc -~/libbitcoinrpc$ make - -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c -gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ -src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ --o .lib/libbitcoinrpc.so.0.2 \ --Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl -ldconfig -v -n .lib -.lib: - libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) -ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so -``` -Se tudo correr bem, podemos instalar o pacote: -``` -$ sudo make install -Installing to -install .lib/libbitcoinrpc.so.0.2 /usr/local/lib -ldconfig -n /usr/local/lib -ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so -install -m 644 src/bitcoinrpc.h /usr/local/include -Installing docs to /usr/share/doc/bitcoinrpc -mkdir -p /usr/share/doc/bitcoinrpc -install -m 644 doc/*.md /usr/share/doc/bitcoinrpc -install -m 644 CREDITS /usr/share/doc/bitcoinrpc -install -m 644 LICENSE /usr/share/doc/bitcoinrpc -install -m 644 Changelog.md /usr/share/doc/bitcoinrpc -Installing man pages -install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 -``` - -## Preparando o código - -``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. - -Para usar o ``libbitcoinrpc``, é importante certificar de que nossos arquivos do código incluam os cabeçalhos apropriados: -``` c -#include -#include -``` - -Precisaremos também vincular as bibliotecas apropriadas sempre que possamos compilar: - -``` -$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode -``` - -## Construindo a conexão - -Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. - -Primeiro, inicialize a biblioteca: -``` -bitcoinrpc_global_init(); -``` -Em seguida, vamos conectar ao ``Bitcoind`` com ``bitcoinrpc_cl_init_params``. Os quatro argumentos necessários para o ``bitcoinrpc_cl_init_params`` são o nome de usuário, a senha, o endereço IP e a porta. A esta altura, você deve saber todas essas informações, já que foram necessárias para realizar o trabalho com o [curl](04_4__interlude_using_curl.md). Apenas para recordar, o endereço de IP é 127.0.0.1 e a porta 18332 devem estar corretos para a configuração padrão da testenet descrita neste documento, enquanto podemos encontrar o usuário e a senha no arquivo ``~/.bitcoin/bitcoin.conf``. -``` -$ cat bitcoin.conf -server=1 -dbcache=1536 -par=1 -maxuploadtarget=137 -maxconnections=16 -rpcuser=StandUp -rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba -rpcallowip=127.0.0.1 -debug=tor -prune=550 -testnet=1 -[test] -rpcbind=127.0.0.1 -rpcport=18332 -[main] -rpcbind=127.0.0.1 -rpcport=8332 -[regtest] -rpcbind=127.0.0.1 -rpcport=18443 -``` -Com essas informações, vamos colocá-las no ``bitcoinrpc_cl_init_params``: -``` c -bitcoinrpc_cl_t *rpc_client; -rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); -``` - -> **MAINNET VS TESTNET:** A porta seria a 8332 caso estivéssemos usando a configuração da rede principal. - -Se o ``rpc_client`` for inicializado com sucesso, poderemos enviar os comandos do RPC. - -Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fechar da seguinte maneira: -``` c -bitcoinrpc_global_cleanup(); -``` - -### Testando o código de teste - -O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). - -Podemos compilar e executar o código da seguinte maneira: -``` -$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin -$ ./testbitcoin -Successfully connected to server! -``` - -> :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. - -## Fazendo uma chamada ao RPC - -Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). -``` c -bitcoinrpc_method_t *getmininginfo = NULL; -getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); -``` -Normalmente definiríamos os parâmetros em seguida, mas o ``GetMiningInfo`` não requer parâmetros, por isso podemos pular essa parte. - -Também devemos criar outros dois objetos, um "objeto de resposta" e um "objeto de erro". Eles podem ser inicializados da seguinte forma: -``` c -bitcoinrpc_resp_t *btcresponse = NULL; -btcresponse = bitcoinrpc_resp_init(); - -bitcoinrpc_err_t btcerror; -``` -Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos adicionar nosso método ``getmininginfo`` e os outros dois objetos: -``` c -bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); -``` - -### Mostrando o retorno da chamada - -Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: -``` c -json_t *jsonresponse = NULL; -jsonresponse = bitcoinrpc_resp_get(btcresponse); -``` -Se quisermos gerar os resultados completos da chamada RPC no JSON, podemos fazer com uma simples invocação do ``json_dumps``, da biblioteca ``jansson``: -``` c -printf("%s\n", json_dumps(j, JSON_INDENT(2))); -``` -No entanto, como agora estamos escrevendo programas completos, provavelmente iremos querer fazer um trabalho mais sutil, como retirar valores individuais do JSON para algum uso específico. A [Referência do Jansson](https6//jansson.readthedocs.Io/en/2.10/apiref.html) traz detalhes de como fazer. - -Assim como estávamos usando o [curl](04_4__interlude_using_curl.md), descobrimos que o RPC retorna um objeto JSON contendo um ``ID``, um ``error`` e, mais importante, um objeto JSON do tipo ``result``. - -A função ``json_object_get`` permite recuperar um valor (como o ``result``) de um objeto JSON usando chaves: -``` c -json_t *jsonresult = NULL; -jsonresult = json_object_get(jsonresponse,"result"); -printf("%s\n", json_dumps(jsonresult, JSON_INDENT(2))); -``` - -No entanto, provavelmente iremos querer analisar informações ainda mais profundas, para obter uma variável específica. Depois de recuperar o valor apropriado, precisaremos convertê-lo em um objeto C padrão usando a função ``JSON_*_value``. Por exemplo, para acessar um integer usamos o ``json_integer_value``: -``` c -json_t *jsonblocks = NULL; -jsonblocks = json_object_get(jsonresult,"blocks"); - -int blocks; -blocks = json_integer_value(jsonblocks); -printf("Block Count: %d\n",blocks); -``` - -> :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. - -### Testando o código de informação - -Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). -``` -$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo -$ ./getmininginfo -Full Response: { - "result": { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" - }, - "error": null, - "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" -} - -Just the Result: { - "blocks": 1804406, - "difficulty": 4194304, - "networkhashps": 54842097951591.781, - "pooledtx": 127, - "chain": "test", - "warnings": "Warning: unknown new rules activated (versionbit 28)" -} - -Block Count: 1804406 -``` - -## Fazendo uma chamada RPC usando argumentos - -Mas e se a sua chamada RPC tiver argumentos? - -### Criando uma matriz JSON - -Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. - -Vamos criar a matriz JSON usando a função ``json_array do`` do ``jansson``: -``` c -json_t *params = NULL; -params = json_array(); -``` -Vamos fazer o processo inverso que fizemos para acessar valores do JSON: Vamos converter objetos no C para objetos no JSON usando as funções ``JSON_*``. Depois, vamos anexar tudo à matriz: -``` c -json_array_append_new(params,json_string(tx_rawhex)); -``` - -Observe que existem duas variantes para o comando de anexação: ``json_array_apend_new``, que acrescenta uma variável recém-criada, e ``json_array_apend``, que anexa uma variável existente. - -Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. - -### Atribuindo os parâmetros - -Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: -``` c -bitcoinrpc_method_set_params(rpc_method, params) -``` -Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. - -## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC - -Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. - -* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. - -## O Que Vem Depois? - -Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). diff --git a/pt/15_2_Programming_Bitcoind_with_C.md b/pt/15_2_Programming_Bitcoind_with_C.md deleted file mode 100644 index c1fdc38..0000000 --- a/pt/15_2_Programming_Bitcoind_with_C.md +++ /dev/null @@ -1,354 +0,0 @@ - -# 15.2: Programando o Bitcoind usando C com bibliotecas RPC - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. - -## Planejando o código - -Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: - - 1. Solicitar um endereço e uma quantia; - 2. Definir uma taxa arbitrária; - 3. Preparar nosso RPC; - 4. Encontrar um UTXO que seja grande o suficiente para pagar o valor + a taxa; - 5. Criar uma mudança de endereço; - 6. Criar uma transação bruta que envie o UTXO para o endereço e altere o endereço; - 7. Assinar a transação; - 8. Enviar a transação. - -### Planejando para o futuro - -Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: - - 1. Testar e/ou higienizar as entradas; - 2. Calcular uma taxa automaticamente; - 3. Pensar logicamente sobre qual UTXO seria válido utilizar; - 4. Combinar vários UTXOs, caso seja necessário; - 5. Ficar atento a mais erros nos comandos ``libbitcoinrpc`` ou no ``jansson``; - 6. Observar se há erros nas respostas RPC. - -Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. - -## Escrevendo o sistema de transação - -Agora estamos prontos para realizar o passo a passo do nosso plano - -### Etapa 1: Solicitando um endereço e uma quantia - -Inserir as informações é bem simples se usarmos os argumentos na linha de comando: -``` c -if(argc != 3) { - - printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); - exit(-1); - -} - -char *tx_recipient = argv[1]; -float tx_amount = atof(argv[2]); - -printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); -``` - -> :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. - -### Etapa 2: Definindo uma taxa arbitrária - -Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: - -``` c -float tx_fee = 0.0005; -float tx_total = tx_amount + tx_fee; -``` - -> :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. - -### Etapa 3: Preparando nosso RPC - -Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: -``` c -bitcoinrpc_global_init(); -rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); -btcresponse = bitcoinrpc_resp_init(); -``` - -### Etapa 4: Encontrando um UTXO - -Para encontrar um UTXO, precisaremos chamar a função RPC ``listunspent``: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -``` - -No entanto, o verdadeiro trabalho consiste em decodificar a resposta. Na seção anterior vimos que a biblioteca ``jansson`` era "um tanto quanto desajeitada" e esta é a razão: Precisamos criar (e limpar) um conjunto muito grande de objetos ``json_t`` para descobrir o que queremos. - -Primeiro, precisamos nos recuperar o campo ``result`` do JSON: -``` c -json_t *lu_response = NULL; -json_t *lu_result = NULL; - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -``` - -> :warning: **ATENÇÃO:** Só obteremos um resultado se não houver nenhum erro. Aqui temos um momento para melhorar nossa verificação de erros no código que iremos colocar em produção. - -Em seguida, vamos fazer um laço, examinando cada transação que não foi gasta, que aparece como um elemento em sua matriz do resultado JSON: -``` c -int i; - -const char *tx_id = 0; -int tx_vout = 0; -double tx_value = 0.0; - -for(i = 0 ; i < json_array_size(lu_result) ; i++) { - - json_t *lu_data = NULL; - lu_data = json_array_get(lu_result, i); - - json_t *lu_value = NULL; - lu_value = json_object_get(lu_data,"amount"); - tx_value = json_real_value(lu_value); -``` - -O UTXO é grande o suficiente para pagar sua transação? Se sim, pegue-o! - -> :warning: **ATENÇÃO:** Um programa em produção pensaria com mais cuidado sobre qual UTXO utilizar, com base no tamanho e em outros fatores. Provavelmente não pegaria apenas o primeiro mais simples e pronto. - -``` c - if(tx_value > tx_total) { - - json_t *lu_txid = NULL; - lu_txid = json_object_get(lu_data,"txid"); - tx_id = strdup(json_string_value(lu_txid)); - - json_t *lu_vout = NULL; - lu_vout = json_object_get(lu_data,"vout"); - tx_vout = json_integer_value(lu_vout); - - json_decref(lu_value); - json_decref(lu_txid); - json_decref(lu_vout); - json_decref(lu_data); - break; - - } -``` -Você também deve limpar os principais elementos do JSON: -``` c -} - -json_decref(lu_result); -json_decref(lu_response); -``` - -> :warning: **ATENÇÃO:** Um programa em produção também se certificaria de que os UTXOs são passíveis de serem `gastos`. - -Se não encontramos nenhum UTXOs grande o suficiente, teremos que relatar este infortúnio ao usuário... E talvez, sugerir que ele deva usar um programa melhor, que irá mesclar os UTXOs de maneira correta. -``` c -if(!tx_id) { - - printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); - exit(-1); -} -``` - -> **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. - -### Etapa 5: Criando um endereço de troco - -Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); - -if(!rpc_method) { - - printf("ERROR: Unable to initialize listunspent method!\n"); - exit(-1); - -} - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -if(btcerror.code != BITCOINRPCE_OK) { - -printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); - - exit(-1); - -} - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); -char *changeaddress = strdup(json_string_value(lu_result)); -``` -A única diferença é quais informações específicas são extraídas do objeto JSON. - -> :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. - -### Etapa 6: Criando uma transação bruta - -Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. - -Para criarmos esses parâmetros corretamente, precisaremos revisar o que o RPC ``createrawtransaction`` espera que passemos como argumento. Felizmente, isso é fácil de determinar usando a funcionalidade ``bitcoin-cli help``: -``` -$ bitcoin-cli help createrawtransaction -createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) -``` - -Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. - -#### Etapa 6.1: Criando os parâmetros de entrada - -Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): -``` c -json_t *inputtxid = NULL; -inputtxid = json_object(); - -json_object_set_new(inputtxid,"txid",json_string(tx_id)); -json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); -``` - -Pode-se notar que teremos que traduzir novamente cada tipo de variável C em um tipo de variável JSON usando a função apropriada, como ``json_string`` ou ``json_integer``. - -Para criar o array de entrada para todos os UTXOs, vamos usar o ``json_array`` e, em seguida, preenchê-lo com os objetos usando o ``json_array_append``: -``` c -json_t *inputparams = NULL; -inputparams = json_array(); -json_array_append(inputparams,inputtxid); -``` - -#### Etapa 6.2: Criando os parâmetros de saída - -Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: -``` c -json_t *outputparams = NULL; -outputparams = json_object(); - -char tx_amount_string[32]; -sprintf(tx_amount_string,"%.8f",tx_amount); -char tx_change_string[32]; -sprintf(tx_change_string,"%.8f",tx_value - tx_total); - -json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); -json_object_set(outputparams, changeaddress, json_string(tx_change_string)); -``` - -> :warning: **ATENÇÃO:** É possível pensar que teremos que inserir os valores do Bitcoin como sendo números, usando a função ``json_real``. Infelizmente, isso expõe um dos maiores problemas com a integração da biblioteca ``jansson`` e o Bitcoin. O Bitcoin só é válido até oito dígitos depois da casa decimal. Devemos nos lembrar que 0,00000001 BTC é um satoshi, e essa é a menor divisão possível de um Bitcoin. O tipo ``double`` no C oferecem mais dígitos do que precisamos, embora sejam frequentemente imprecisos depois das oito casas decimais. Se tentarmos convertê-los diretamente do nosso valor ``double`` no C (ou de um tipo ``float``, neste caso) para um valor Bitcoin, a imprecisão frequentemente criará um valor Bitcoin com mais de oito dígitos. Antes da versão Bitcoin Core 0.12, isso não era problema, e podíamos usar a função ``json_real``. Mas à partir dessa versão, se tentarmos usar a função ``createrawtransaction`` com mais do que oito dígitos, obteremos um erro e a transação não será criada. Como resultado, se o valor do Bitcoin _sempre_ se tornar um ``double`` ou ``float``, devemos deixar com apenas oito casas decimais antes de transformá-lo em uma ``string``. Obviamente, isso é um erro, portanto, certifique-se disso para que o código continue funcionando nas versões mais novas do Bitcoin Core. - -#### Etapa 6.3: Criando a Matriz de Parâmetros - -Para terminarmos de criar os parâmetros, só precisaremos agrupá-los em uma matriz JSON: -``` c -json_t *params = NULL; -params = json_array(); -json_array_append(params,inputparams); -json_array_append(params,outputparams); -``` - -#### Etapa 6.4: Fazendo a chamada ao RPC - -Vamos usar o método normal para criar uma chamada ao RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); -``` -Agora, porém, devemos adicionar os nossos parâmetros. Isso pode ser feito facilmente com a função ``bitcoinrpc_method_set_params``: -``` c -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for createrawtransaction"); - -} -``` -Depois, é só executar o RPC e obter os resultados: -``` c -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); - -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_rawhex = strdup(json_string_value(lu_result)); -``` -### Etapa 7. Assinando a transação - -É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_rawhex)); -``` -Por fim, vamos assinar a transação seguindo o rigamarole típico para criar uma chamada RPC: -``` c -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for signrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -``` -Novamente, usar a função ``jansson`` para acessar a saída pode ser complicado. Devemos lembrar que ``hex`` é parte de um objeto JSON, não um resultado independente, como era quando criamos a transação bruta. Claro, sempre podemos acessar essas informações a partir da ajuda da linha de comando: ``bitcoin-cli help signrawtransaction`` -``` c -lu_result = json_object_get(lu_response,"result"); -json_t *lu_signature = json_object_get(lu_result,"hex"); -char *tx_signrawhex = strdup(json_string_value(lu_signature)); -json_decref(lu_signature); -``` -> :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. - -### Etapa 8. Enviando a transação - -Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: -``` c -params = json_array(); -json_array_append_new(params,json_string(tx_signrawhex)); - -rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); - -if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { - - fprintf(stderr, "Error: Could not set params for sendrawtransaction"); - -} - -json_decref(params); - -bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); -lu_response = bitcoinrpc_resp_get(btcresponse); -lu_result = json_object_get(lu_response,"result"); - -char *tx_newid = strdup(json_string_value(lu_result)); - -printf("Txid: %s\n",tx_newid); -``` - -O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. - -## Testando o código - -O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). - -Compile-o como de costume: -``` -$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress -``` -Agora, é possível utilizá-lo para enviar fundos para um endereço: - -``` -./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 -Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 -``` -Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). - -## Resumo do Programando o Bitcoind usando C com bibliotecas RPC - -Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. - -## O Que Vem Depois? - -Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md deleted file mode 100644 index fe166ac..0000000 --- a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md +++ /dev/null @@ -1,155 +0,0 @@ - -# 15.3 Recebendo notificações usando C com a biblioteca ZMQ - -> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. - -As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. - -> :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). - -## Configurando o ZMQ - -Antes de podemos ouvir a blockchain, precisaremos configurar o ``bitcoind`` para permitir as notificações ZMQ. Por isso, precisamos instalar a biblioteca ZMQ para tirar proveito dessas notificações. - -### Configurando o ``bitcoind`` para usar o ZMQ - -O Bitcoin Core está pronto para ZMQ, mas devemos especificar os endpoints do ZMQ. O ZeroMQ publish-sockets prefixa cada item de dados com um prefixo de tópico arbitrário que permite aos clientes assinantes solicitarem apenas os itens com um prefixo correspondente. Existem atualmente quatro tópicos suportados pelo ``bitcoind``: -``` -$ bitcoind --help | grep zmq | grep address - -zmqpubhashblock=
- -zmqpubhashtx=
- -zmqpubrawblock=
- -zmqpubrawtx=
-``` - -Podemos executar o ``bitcoind`` com argumentos de linha de comando para endpoints ZMQ, como mostrado acima, mas também podemos criar um endpoint acessível adicionando linhas apropriadas ao nosso arquivo ``~/.bitcoin/bitcoin.conf`` e reiniciando o sistema. - -``` -zmqpubrawblock=tcp://127.0.0.1:28332 -zmqpubrawtx=tcp://127.0.0.1:28333 -``` -Podemos então testar se os nossos endpoints estão funcionando usando o RPC ``getzmqnotifications``: - -``` -$ bitcoin-cli getzmqnotifications -[ - { - "type": "pubrawblock", - "address": "tcp://127.0.0.1:28332", - "hwm": 1000 - }, - { - "type": "pubrawtx", - "address": "tcp://127.0.0.1:28333", - "hwm": 1000 - } -] -``` -Nosso ``bitcoind`` agora irá emitir as notificações ZMQ - -### Instalando o ZMQ - -Para aproveitar essas notificações, precisamos de uma biblioteca ZMQ para usar com o C, portanto, estaremos usando uma nova biblioteca ZMQ ao invés da biblioteca ``libbitcoinrpc`` nesta seção, mas no futuro, podemos combinar ambas. - -Felizmente, as bibliotecas ZMQ estão disponíveis por meio de pacotes Debian padrão: -``` -$ sudo apt-get install libzmq3-dev -$ sudo apt-get install libczmq-dev -``` -Agora estamos pronto para escrever o código! - -## Escrevendo o programa de notificação - -O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. - -O programa requer dois parâmetros: O primeiro é o "servidor", que é o ponto de conexão TCP exposto pelo ``bitcoind``. O segundo é o "tópico", que atualmente é o ``zmqpubhashblock``,``zmqpubhashtx``, ``zmqpubrawblock`` ou ``zmqpubrawtx``. O tópico precisa ter suporte do ``bitcoin.conf`` e o endereço IP e a porta do servidor devem corresponder ao que está definido no arquivo de configuração. - -``` c -#include -int main(int argc, char ** argv) { - - char *zmqserver; - char *topic; - - if(argc < 3) { - printf("\nUSAGE:\nchainlistener \n\n"); - return 0; - } else { - zmqserver = argv[1]; - topic = argv[2]; - } -``` -Abriremos um soquete ZMQ para o servidor e para o tópico definido: -``` c - zsock_t *socket = zsock_new_sub(zmqserver, topic); - assert(socket); -``` -Depois, vamos esperar: -``` c - while(1) { - zmsg_t *msg; - int rc = zsock_recv(socket, "m", &msg); - assert(rc == 0); - - char *header = zmsg_popstr(msg); - zframe_t *zdata = zmsg_pop(msg); - unsigned int *no = (unsigned int*)zmsg_popstr(msg); - - char *data = zframe_strhex(zdata); - int len = zframe_size(zdata); - printf("Size: %d\n", len); - printf("Data: %s", data); - printf("\nNo: %d\n", *no); - - free(header); - free(data); - free(no); - free(zdata); - zmsg_destroy(&msg); - sleep(1); - } -``` -Enquanto esperamos, observamos as mensagens no soquete ZMQ. Sempre que recebermos uma mensagem, iremos retirá-la da pilha, relatando o número, comprimento e, o os dados que foram importante para nós. - -É isso! - -Claro, quando terminar o processo, precisamos limpar tudo: -``` c - zsock_destroy(&socket); - return 0; -} -``` - -### Testando o código de notificação - -O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: -``` -$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq -``` -Depois, podemos executá-lo com os tópicos e endereços que definimos no nosso ``bitcoin.conf``: -``` -$ ./chainlistener tcp://127.0.0.1:28333 rawtx -Size: 250 -Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 -No: 67 -Size: 249 -Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 -No: 68 -Size: 250 -Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 -No: 69 -Size: 250 -Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 -No: 70 -....... -``` - -### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ - -Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. - -> :fire: ***Qual é o poder das notificações?*** Com as notificações, não dependemos mais dos usuários para emitir os comandos. Ou seja, podemos criar programas que monitoram o blockchain do Bitcoin e tomar as ações apropriadas quando certas coisas ocorrem. Isso, por sua vez, pode ser utilizado juntamente com os comandos RPC que programamos nas seções anteriores. Este também é um grande passo além do que poderíamos fazer com os scripts shell: Certamente, podemos criar scripts shell que fica ouvindo infinitamente, mas existem outras linguagens de programação que possuem ferramentas melhores para isso. - -## O Que Vem Depois? - -Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file From 786c307a09688f43b88cc77a5519064e767c0c44 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 8 Sep 2021 10:51:13 -0300 Subject: [PATCH 118/155] Review A0 --- pt/A0_Appendices.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pt/A0_Appendices.md b/pt/A0_Appendices.md index c324e3f..da03947 100644 --- a/pt/A0_Appendices.md +++ b/pt/A0_Appendices.md @@ -1,12 +1,12 @@ -# Apêndice +# Apêndices -O foco principal deste curso sugere uma configuração bastante padrão para os testes de Bitcoin. À seguir, vamos ver alguns apêndices que irão explicar melhor a configuração e algumas opções alternativas. +O foco principal deste curso sugere uma configuração bastante padrão para os testes de Bitcoin. À seguir, vamos ver alguns apêndices que irão explicar melhor dessa configuração e algumas opções alternativas. -## Objetivos deste apêndice +## Objetivos desta Seção Depois de trabalhar nestes apêndices, um desenvolvedor será capaz de: - * Decidir entre vários métodos de como criar uma blockchain do Bitcoin. + * Decidir entre vários métodos de como criar uma blockchain do Bitcoin. Os objetivos secundários do apêndice incluem a capacidade de: @@ -15,8 +15,8 @@ Os objetivos secundários do apêndice incluem a capacidade de: * Compreender o poder do Regtest; * Use um ambiente Regtest. -## Tabela de conteúdo +## Tabela de Conteúdo * [Apêndice 1: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md) - * [Apêndice 2: Compilando Bitcoin na Fonte](A2_0_Compiling_Bitcoin_from_Source.md) - * [Apêndice 3: Usando o Bitcoin Regtest](A3_0_Using_Bitcoin_Regtest.md) \ No newline at end of file + * [Apêndice 2: Compilando Bitcoin da Fonte](A2_0_Compiling_Bitcoin_from_Source.md) + * [Apêndice 3: Usando o Regtest do Bitcoin](A3_0_Using_Bitcoin_Regtest.md) \ No newline at end of file From 787affa4d6e4a94fd83ea2332635fe8ad9e42f55 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 8 Sep 2021 10:56:31 -0300 Subject: [PATCH 119/155] Review A1 --- pt/A1_0_Understanding_Bitcoin_Standup.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pt/A1_0_Understanding_Bitcoin_Standup.md b/pt/A1_0_Understanding_Bitcoin_Standup.md index c10c2a1..1e04418 100644 --- a/pt/A1_0_Understanding_Bitcoin_Standup.md +++ b/pt/A1_0_Understanding_Bitcoin_Standup.md @@ -1,12 +1,12 @@ # Apêndice 1: Compreendendo o Bitcoin Standup -Na seção [§2.1: Configurando um Bitcoin Core VPS com StackScript](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) explicamos o processo de criação de um node de Bitcoin usando [Bitcoin-Standup-Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup -Scripts). O apêndice à seguir explica o que as principais seções do script fazem. Podemos acompanhar em [Linode Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) em outra janela. +Na seção [§2.1: Configurando um Bitcoin Core VPS com StackScript](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) explicamos o processo de criação de um node de Bitcoin usando [Bitcoin-Standup-Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). O apêndice à seguir explica o que as principais seções do script fazem. Podemos acompanhar em [Linode Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) em outra janela. -## Etapa 1: Nome do host +## Etapa 1: Nome do Host O nome do seu host é armazenado em `/etc/hostname` e definido com o comando `hostname`. Ele também aparece em `/etc/hosts`. -## Etapa 2: Fuso horário +## Etapa 2: Fuso Horário O fuso horário do nosso host é armazenado em `/etc/timezone`, então um arquivo apropriado do `/usr/share/zoneinfo/` é copiado para o `/etc/localtime`. @@ -14,11 +14,11 @@ O fuso horário do nosso host é armazenado em `/etc/timezone`, então um arquiv O gerenciador de pacotes `apt-get` é usado para deixar nossa máquina atualizada e instalar o `gnupg`, o gerador de números aleatórios `haveged`, e o firewall simples `ufw`. -Nossa máquina está configurada para se manter automaticamente atualizada com o `echo" unattended-upgrades unattended-upgrades / enable_auto_updates boolean true "| debconf-set-selections`. +Nossa máquina está configurada para se manter automaticamente atualizada com o `echo "unattended-upgrades unattended-upgrades / enable_auto_updates boolean true "| debconf-set-selections`. -## Etapa 4: Configurando um usuário +## Etapa 4: Configurando um Usuário -Um usuário `standup` é criado, o qual será usado para nossas aplicações do Bitcoin. Ele também tem permissões `sudo`, permitindo que executemos ações privilegiadas com esta usuário. +Um usuário `standup` é criado, o qual será usado para nossas aplicações do Bitcoin. Ele também tem permissões `sudo`, permitindo que executemos ações privilegiadas com este usuário. Se fornecemos uma chave SSH, ela permitirá o acesso a esta conta (caso contrário, devemos usar a senha criada na configuração). @@ -26,7 +26,7 @@ Se fornecemos um endereço IP, o acesso `ssh` será limitado a esse endereço, d ## Etapa 5: Configurando o Tor -O Tor é instalado para fornecer serviços protegidos (ocultos) para acessar os comandos RPC do Bitcoin através do nosso servidor. Podemos consultar a seção [§14.1: Verificando a Configuração do Tor]14_1_Verifying_Your_Tor_Setup.md) para obter mais informações sobre a configuração. +O Tor é instalado para fornecer serviços protegidos (ocultos) para acessar os comandos RPC do Bitcoin através do nosso servidor. Podemos consultar a seção [§14.1: Verificando a Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) para obter mais informações sobre a configuração do Tor. Se criarmos um cliente autorizado para os serviços ocultos, o acesso será limitado a essa chave, que está em `/var/lib/tor/standup/authorized_clients`. Caso contrário, na seção [§14.2](14_2_Changing_Your_Bitcoin_Hidden_Services.md) explicamos como podemos fazê-la depois. @@ -34,7 +34,7 @@ Se criarmos um cliente autorizado para os serviços ocultos, o acesso será limi Bitcoin é instalado no `~standup/.bitcoin`. Nossa configuração é armazenada no `~standup/.bitcoin/bitcoin.conf`. -Precisamos nos certificar de que as somas de verificação foram analisadas de acordo com a seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), caso contrário, podemos estar expostos a um ataque à blockchain. +Precisamos nos certificar de que as somas de verificação (checksum) foram analisadas de acordo com a seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), caso contrário, podemos estar expostos a um ataque de cadeia de produção. ## Etapa 7: Instalando o Codificador QR @@ -48,4 +48,4 @@ O Bitcoin Standup usa scripts para tentar combinar muitas das funcionalidades de Se estivermos no processo de criação de um node Bitcoin para o uso neste curso, devemos voltar para a seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md). -Se estivermos lendo os apêndices, podemos continuar no [Apêndice 2: Compilando Bitcoin na Fonte](A2_0_Compiling_Bitcoin_from_Source.md). \ No newline at end of file +Se estivermos lendo os apêndices, podemos continuar no [Apêndice 2: Compilando Bitcoin da Fonte](A2_0_Compiling_Bitcoin_from_Source.md). \ No newline at end of file From fdd3234dac347bcad20d62ddcd0c12bdf4c3d8e3 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 8 Sep 2021 11:08:58 -0300 Subject: [PATCH 120/155] Review A2 --- pt/A2_0_Compiling_Bitcoin_from_Source.md | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/pt/A2_0_Compiling_Bitcoin_from_Source.md b/pt/A2_0_Compiling_Bitcoin_from_Source.md index 88cf08f..cc24de8 100644 --- a/pt/A2_0_Compiling_Bitcoin_from_Source.md +++ b/pt/A2_0_Compiling_Bitcoin_from_Source.md @@ -1,39 +1,39 @@ -# Apêndice 2: Compilando Bitcoin na Fonte +# Apêndice 2: Compilando Bitcoin da Fonte -Este curso presume que usará um script para criar um ambiente Bitcoin, seja usando o Bitcoin Standup do Linode de acordo com o especificado na seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou por algum outro meio de acordo com a seção [§2.2](02_2_Setting_Up_Bitcoin_Core_Other.md). No entanto, podemos querer compilar o Bitcoin manualmente. +Este curso presume o uso de um script para criar um ambiente Bitcoin, seja usando o Bitcoin Standup do Linode de acordo com o especificado na seção [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou por algum outro meio de acordo com a seção [§2.2](02_2_Setting_Up_Bitcoin_Core_Other.md). No entanto, podemos querer compilar o Bitcoin manualmente. Isso tem os seguintes benefícios: -1. Sempre estará atualizados com a versão mais recente. Mas atenção! Estar sempre atualizado não é necessário para o Bitcoin Core, pois o software é sempre compatível com versões anteriores, o que significa que uma versão antiga do Bitcoin Core ainda poderá participar da rede Bitcoin, embora possamos não ter os recursos mais recentes. Devemos sempre verificar os recursos de uma nova versão antes de atualizarmos. -2. Não precisaremos depender de binários do Bitcoin Core pré-compilados. Isso requer menos confiança. Mesmo que os mantenedores do Bitcoin Core façam um ótimo trabalho em manter a integridade do código, um binário pré-compilado é removido algumas etapas do código-fonte. Quando compilamos a partir do código-fonte, o código pode ser inspecionado antes da compilação. +1. Sempre estará atualizado com a versão mais recente. Mas atenção! Estar sempre atualizado não é necessário para o Bitcoin Core, pois o software é sempre compatível com versões anteriores, o que significa que uma versão antiga do Bitcoin Core ainda poderá participar da rede Bitcoin, embora possamos não ter os recursos mais recentes. Devemos sempre verificar os recursos de uma nova versão antes de atualizarmos. +2. Não precisaremos depender de binários do Bitcoin Core pré-compilados. Isso requer menos confiança. Mesmo que os mantenedores do Bitcoin Core façam um ótimo trabalho em manter a integridade do código, algumas etapas do código-fonte são removidas de um binário pré-compilado. Quando compilamos a partir do código-fonte, o código pode ser inspecionado antes da compilação. 3. Podemos personalizar a construção, fazendo coisas como desabilitar a carteira ou a GUI. -## Preparando nosso ambiente +## Preparando Nosso Ambiente Este tutorial usa o sistema operacional Debian 10.4.kv0 em uma arquitetura amd64 (computadores de 64 bits), mas podemos usar este tutorial em qualquer sistema baseado no Debian (por exemplo, Ubuntu, Mint, etc). Para outros sistemas Linux, podemos adaptar as etapas a seguir com o gerenciador de pacotes do sistema. -Podemos ter pouca familiaridade ou nenhuma com a linha de comando, desde que tenhamos vontade de aprender. O terminal é o nosso aliado mais poderoso, não algo a ser temido. Podemos simplesmente copiar e colar os seguintes comandos para compilar Bitcoin. Um comando com um "$" é um comando do usuário normal e um com um "#" é um comando de super usuário/root. +Podemos ter pouca ou nenhuma familiaridade com a linha de comando, desde que tenhamos vontade de aprender. O terminal é o nosso aliado mais poderoso, e não algo a ser temido. Podemos simplesmente copiar e colar os seguintes comandos para compilar o Bitcoin. Um comando com um "$" é um comando do usuário normal e um com um "#" é um comando de super usuário/root. Se o nosso usuário não estiver na lista dos super usuários, podemos o seguinte: ``` $ su root - + # apt-get install sudo -# usermod -aG sudo +# usermod -aG sudo # reboot ``` ## Instalando o Bitcoin -### Etapa 1: atualizando nosso sistema +### Etapa 1: Atualizando Nosso Sistema Primeiro, vamos atualizar o sistema usando: ``` $ sudo apt-get update ``` -### Etapa 2: Instalando o Git e as dependências +### Etapa 2: Instalando o Git e as Dependências Vamos instalar o `git`, que permitirá que baixemos o código-fonte, e o `build-essential`, que compila o código: ``` @@ -45,7 +45,7 @@ Depois, vamos instalar as dependências restantes: $ sudo apt-get install libtool autotools-dev automake pkg-config bsdmainutils python3 libssl-dev libevent-dev libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libminiupnpc-dev libzmq3-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler ccache -y ``` -### Etapa 3: Baixando o código-fonte +### Etapa 3: Baixando o Código-Fonte Assim que as dependências forem instaladas, baixamos o repositório (repo) que contém o código-fonte do Bitcoin no github: ``` @@ -64,7 +64,7 @@ Devemos corresponder aproximadamente ao seguinte conteúdo: 1. Vamos entrar no diretório `contrib`:`$ cd bitcoin/contrib/`; 2. Vamos executar o seguinte comando: ```$ ./install_db4.sh `pwd` ```. -Depois de fazer o download, veremos o seguinte retorno. Podemos observar o retorno, e o usaremos para configurar o bitcoin durante o build: +Depois de fazer o download, veremos o seguinte retorno. Devemos observar bem este retorno, porque o usaremos para configurar o bitcoin durante o build: ![db4](./public/LBftCLI-compiling_bitcoin-db4.png) @@ -88,25 +88,25 @@ $ ./configure BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PR $ make # build bitcoin core ``` -### Etapa 6: Testando o build +### Etapa 6: Testando o Build Se quisermos verificar nossa compilação (o que é uma boa ideia), podemos executar os seguintes testes: -1. `$ make check` irá executar os Testes de Unidade, que devem retornar `PASS`; +1. `$ make check` irá executar os Testes de Unidade (unit tests), que devem retornar `PASS`; 2. `$ test/functional/test_runner.py --extended` executará os testes funcionais estendidos. Podemos retirar a sinalização `--extended` se quisermos pular alguns testes. Isso vai demorar um pouco. -### Etapa 7: Executando ou instalando o Bitcoin Core +### Etapa 7: Executando ou Instalando o Bitcoin Core -Agora que compilou o Bitcoin Core a partir da fonte, podemos começar a usá-lo ou instalá-lo. +Agora que compilamos o Bitcoin Core a partir da fonte, podemos começar a usá-lo ou instalá-lo. -#### Executando o Bitcoin Core sem instalar +#### Executando o Bitcoin Core sem Instalar Para executar o Bitcoin Core: `$ src/qt/bitcoin-qt` para iniciar a GUI; `$ src/bitcoind` para executar bitcoin na linha de comando. -### Instalando Bitcoin Core +### Instalando o Bitcoin Core Para instalar: @@ -114,14 +114,14 @@ Para instalar: ## Finalizando Nosso Sistema -Ao compilar Bitcoin a partir da fonte, aumentamos a confiança que temos em nossa configuração. No entanto, estamos muito aquém de toda a segurança adicional fornecida por uma configuração Bitcoin Standup. Para resolver isso, podemos percorrer todo o [Linode Stackscript](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) e executar passo a passo todos os comandos. O único lugar que precisamos ter cuidado é na Etapa 6, que instala o Bitcoin. Pulando o ponto onde já verificamos os binários e continuemos a partir daí. +Ao compilar Bitcoin a partir da fonte, aumentamos a confiança que temos em nossa configuração. No entanto, estamos muito aquém de toda a segurança adicional fornecida por uma configuração Bitcoin Standup. Para resolver isso, podemos percorrer todo o [Linode Stackscript](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) e executar passo a passo todos os comandos. O único lugar que precisamos ter cuidado é na Etapa 6, que instala o Bitcoin, pulando o ponto onde já verificamos os binários e continando a partir daí. -## Resumo: Compilando Bitcoin na Fonte +## Resumo: Compilando Bitcoin da Fonte -Se quisermos aumentar a segurança da instalação do Bitcoin a partir da fonte, agora podemos fazer ter isso. Felizmente, também passamos pelo Linode Stackscript para configurar um servidor mais seguro. +Se quisermos aumentar a segurança da instalação do Bitcoin a partir da fonte, agora sabemos fazê-lo. Felizmente, também passamos pelo Linode Stackscript para configurar um servidor mais seguro. ## O Que Vem Depois? -Se estávamos no processo de criação de um node de Bitcoin para usar neste curso, devemos continuar com o [Capítulo 3: Compreendendo a configuração do node Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). +Se estávamos no processo de criação de um node de Bitcoin para usar neste curso, devemos continuar com o [Capítulo 3: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). Se estivermos lendo os apêndices, vamos continuar com o [Apêndice 3: Usando o Bitcoin Regtest](A3_0_Using_Bitcoin_Regtest.md). \ No newline at end of file From 15d860a289eca54080ef6eb07132020c2dcf6014 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 8 Sep 2021 11:21:04 -0300 Subject: [PATCH 121/155] Review A3 --- pt/A3_0_Using_Bitcoin_Regtest.md | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pt/A3_0_Using_Bitcoin_Regtest.md b/pt/A3_0_Using_Bitcoin_Regtest.md index 362b5d9..387fbef 100644 --- a/pt/A3_0_Using_Bitcoin_Regtest.md +++ b/pt/A3_0_Using_Bitcoin_Regtest.md @@ -2,11 +2,11 @@ > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. -A maior parte deste curso presume que usaremos a Mainnet ou a Testnet. No entanto, essas não são as únicas opções. Ao desenvolver aplicações no Bitcoin, podemos querer manter nossos aplicativos isolados das blockchains públicas. Para fazer isso, podemos criar um blockchain do zero usando o Regtest, que tem uma outra grande vantagem sobre a Testnet. Escolhemos quando criar novos blocos, para ter controle total sobre o ambiente. +A maior parte deste curso presume que usaremos a Mainnet ou a Testnet. No entanto, essas não são as únicas opções. Ao desenvolver aplicações no Bitcoin, podemos querer manter nossos aplicativos isolados das blockchains públicas. Para fazer isso, podemos criar uma blockchain do zero usando a Regtest, que tem uma outra grande vantagem sobre a Testnet. Escolhemos quando criar novos blocos, para ter controle total sobre o ambiente. -## Iniciando o Bitcoind no Regtest +## Iniciando o Bitcoind na Regtest -Depois de [configurar nosso VPS no Bitcoin-Core ](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) ou depois que o [compilamos na fonte](A2_0_Compiling_Bitcoin_from_Source.md), podemos usar o regtest. Para iniciar o `bitcoind` no regtest e criar uma Blockchain privada, iremos usar o seguinte comando: +Depois de [configurar nosso Bitcoin-Core em um VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) ou depois de [compilarmos da fonte](A2_0_Compiling_Bitcoin_from_Source.md), podemos usar a regtest. Para iniciar o `bitcoind` na regtest e criar uma blockchain privada, iremos usar o seguinte comando: ``` $ bitcoind -regtest -daemon -fallbackfee=1.0 -maxtxfee=1.1 ``` @@ -19,17 +19,17 @@ No teste, geralmente não há transações suficientes, então o bitcoind não p Se desejarmos, podemos reiniciar nossa Regtest posteriormente com uma nova blockchain. -As carteiras do Regtest e o estado do blockchain (chainstate) são salvos no subdiretório regtest do diretório de configuração do Bitcoin: +As carteiras da Regtest e o estado da blockchain (chainstate) são salvos no subdiretória regtest do diretório de configuração do Bitcoin: ``` user@mybtc:~/.bitcoin# ls bitcoin.conf regtest testnet3 ``` -Para iniciar uma nova Blockchain usando o regtest, tudo que precisamos fazer é excluir a pasta `regtest` e reiniciar o Bitcoind: +Para iniciar uma nova blockchain usando a regtest, tudo que precisamos fazer é excluir a pasta `regtest` e reiniciar o Bitcoind: ``` $ rm -rf regtest ``` -## Gerando uma carteira do Regtest +## Gerando uma Carteira da Regtest Antes de gerar os blocos, é necessário carregar uma carteira usando `loadwallet` ou criar uma nova com `createwallet`. Desde a versão 0.21, o Bitcoin Core não cria automaticamente novas carteiras na inicialização. @@ -38,9 +38,9 @@ O argumento `descriptors=true` cria uma carteira de descritores nativos, que arm $ bitcoin-cli -regtest -named createwallet wallet_name="regtest_desc_wallet" descriptors=true ``` -## Geraando Blocos +## Gerando Blocos -Podemos gerar (minerar) novos blocos em uma blockchain de regtest usando o método RPC `generate` com um argumento para quantos blocos queremos gerar. Só faz sentido usar esse método na regtest, devido à grande dificuldade, é muito improvável que ele produza novos blocos na rede principal ou na rede de teste: +Podemos gerar (minerar) novos blocos em uma blockchain de regtest usando o método RPC `generate` com um argumento para quantos blocos queremos gerar. Só faz sentido usar esse método na regtest; devido à grande dificuldade, é muito improvável que ele produza novos blocos na rede principal ou na rede de teste: ``` $ bitcoin-cli -regtest -generate 101 [ @@ -52,25 +52,25 @@ $ bitcoin-cli -regtest -generate 101 ] ``` -> :warning: **AVISO**. Note que devemos adicionar o argumento `-regtest` após cada comando `bitcoin-cli` para acessar corretamente nosso ambiente Regtest. Se preferirmos, podemos incluir um comando `regtest=1` em nosso arquivo de configuração em `~/.bitcoin/bitcoin.conf`. +> :warning: **AVISO**. Note que devemos adicionar o argumento `-regtest` após cada comando `bitcoin-cli` para acessar corretamente nosso ambiente Regtest. Ou, se preferirmos, podemos incluir um comando `regtest=1` em nosso arquivo de configuração em `~/.bitcoin/bitcoin.conf`. -Como um bloco deve ter 100 confirmações antes que a recompensa possa ser gasta, iremos gerar 101 blocos, fornecendo acesso à transação da coinbase do bloco #1. Como este é uma nova blockchain usando as regras padrão do Bitcoin, os primeiros blocos pagam uma recompensa de bloco de 50 bitcoins. Ao contrário do mainnet, no modo regtest apenas os primeiros 150 blocos pagam uma recompensa de 50 bitcoins. A recompensa diminui pela metade após 150 blocos, então paga 25, 12,5 e assim por diante... +Como um bloco deve ter 100 confirmações antes que a recompensa possa ser gasta, iremos gerar 101 blocos, fornecendo acesso à transação da coinbase do bloco #1. Como esta é uma nova blockchain usando as regras padrão do Bitcoin, os primeiros blocos pagam uma recompensa de bloco de 50 bitcoins. Ao contrário do mainnet, no moda regtest apenas os primeiros 150 blocos pagam uma recompensa de 50 bitcoins. A recompensa diminui pela metade após 150 blocos, então paga 25, 12,5 e assim por diante... -A saída é o hash de bloco de cada bloco gerado. +A saída é o hash de cada bloco gerado. -> :book: ***O que é uma transação do tipo coinbase?*** Uma coinbase é a transação sem entrada criada quando um novo bloco é extraído e entregue ao minerador. É assim que novos bitcoins entram no ecossistema. O valor das transações coinbase decai com o tempo. Na rede principal, ele cai pela metade a cada 210.000 transações e termina inteiramente com o bloco 6.929.999, que está previsto atualmente para o século 22. Em maio de 2020, a recompensa pela coinbase é 6,25 BTC. +> :book: ***O que é uma transação do tipo coinbase?*** Uma coinbase é a transação sem entrada criada quando um novo bloco é extraído e entregue ao minerador. É assim que novos bitcoins entram no ecossistema. O valor das transações coinbase decai com o tempo. Na rede principal, ele cai pela metade a cada 210.000 blocos e termina inteiramente com o bloco 6.929.999, que está previsto atualmente para o século 22. Em maio de 2020, a recompensa pela coinbase é 6,25 BTC. -### Verificando nosso saldo +### Verificando Nosso Saldo -Depois de minerar blocos e receber as recompensas, podemos verificar o saldo em nossa carteira: +Depois de minerar os blocos e receber as recompensas, podemos verificar o saldo em nossa carteira: ``` $ bitcoin-cli -regtest getbalance 50.00000000 ``` -## Usando o Regtest +## Usando a Regtest -Agora devemos ser capazes de usar este saldo para qualquer tipo de interação em nossa Blockchain privada, como o envio de transações Bitcoin de acordo com o [Capítulo 4](04_0_Sending_Bitcoin_Transactions.md). +Agora devemos ser capazes de usar este saldo para qualquer tipo de interação em nossa blockchain privada, como o envio de transações Bitcoin de acordo com o [Capítulo 4](04_0_Sending_Bitcoin_Transactions.md). É importante notar que para que qualquer transação seja concluída, teremos que gerar (minerar) novos blocos, para que as transações possam ser incluídas. @@ -118,7 +118,7 @@ $ bitcoin-cli -regtest gettransaction e834a4ac6ef754164c8e3f0be4f34531b74b768199 } ``` No entanto, agora devemos finalizá-la criando blocos na blockchain. -A maioria das aplicações requer seis confirmações de bloco para considerar a transação como irreversível. Se for esse o nosso caso, podemos minerar seis blocos adicionais em nossa blockchain de teste: +A maioria das aplicações requer seis confirmações de bloco para considerar a transação como irreversível. Se este for o nosso caso, podemos minerar seis blocos adicionais em nossa blockchain de teste: ``` $ bitcoin-cli -regtest -generate 6 [ @@ -138,7 +138,7 @@ Quando estamos fazendo testes, somos capazes de simular casos extremos e ataques Conforme discutido em outro lugar neste curso, o uso de bibliotecas de software pode fornecer acesso mais sofisticado a alguns comandos RPC. Nesse caso, o [bitcointest criado por dgarage](https://github.com/dgarage/bitcointest) para o NodeJS pode ser usado para simular uma transação de uma carteira para outra; podemos verificar [a documentação](https://www.npmjs.com/package/bitcointest) para simularmos ataque mais específicos, como o de gasto duplo. -Vejamos a seção [§17.3](17_3_Accessing_Bitcoind_with_NodeJS.md) para as informações mais atualizadas sobre a instalação do NodeJS, em seguida, podemos adicionar ao `bitcointest`: +Vejamos a seção [§18.3](18_3_Accessing_Bitcoind_with_NodeJS.md) para as informações mais atualizadas sobre a instalação do NodeJS, em seguida, podemos adicionar ao `bitcointest`: ``` $ npm install -g bitcointest ``` @@ -197,10 +197,10 @@ n2.after (before) = 100 Um ambiente regtest para o Bitcoin funciona como qualquer ambiente testnet, exceto que teremos a capacidade de gerar blocos de maneira rápida e fácil. - > :fire: ***Qual é o poder da regtest?*** O maior poder da regtest é que podemos minerar blocos rapidamente, permitindo que nos apressemos na blockchain, para testar transações, timelocks e outros recursos que podemos querer, caso contrário, teríamos de sentar e esperar. No entanto, o outro poder é que podemos executar de forma privada, sem nos conectarmos a uma blockchain pública, nos permitindo testar nossas ideias antes de liberá-las para o mundo. + > :fire: ***Qual é o poder da regtest?*** O maior poder da regtest é que podemos minerar blocos rapidamente, permitindo que nos apressemos na blockchain para testar transações, timelocks e outros recursos que podemos querer, caso contrário, teríamos de sentar e esperar. No entanto, o outro poder é que podemos executar de forma privada, sem nos conectarmos a uma blockchain pública, nos permitindo testar nossas ideias antes de liberá-las para o mundo. ## O Que Vem Depois? Se estamos visitando o Apêndice enquanto trabalhamos em alguma outra parte do curso, devemos voltar para lá. -Mas, caso contrário, chegamos ao fim! Outras pessoas que trabalharam neste curso tornaram-se desenvolvedores e engenheiros profissionais no mundo do Bitcoin, incluindo alguns dos quais contribuíram para o [Blockchain Commons](https://www.blockchaincommons.com/). Nós o encorajamos a fazer o mesmo! Basta sair e começar a trabalhar em alguns dos códigos do Bitcoin usando o que aprendemos. \ No newline at end of file +Mas, caso contrário, chegamos ao fim! Outras pessoas que trabalharam neste curso tornaram-se desenvolvedores e engenheiros profissionais no mundo do Bitcoin, incluindo alguns dos quais contribuíram para a [Blockchain Commons](https://www.blockchaincommons.com/). Nós o encorajamos a fazer o mesmo! Basta sair e começar a trabalhar em alguns dos códigos do Bitcoin usando o que aprendemos. \ No newline at end of file From e8e4236f8b83e2a3f760fc27b178331cbcc67e3e Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Fri, 10 Sep 2021 09:23:49 -0300 Subject: [PATCH 122/155] Commiting review made by @hgrams --- pt/11_1_Understanding_Timelock_Options.md | 12 +++++------ pt/11_2_Using_CLTV_in_Scripts.md | 15 +++++++------- pt/11_3_Using_CSV_in_Scripts.md | 25 +++++++++++------------ 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/pt/11_1_Understanding_Timelock_Options.md b/pt/11_1_Understanding_Timelock_Options.md index 5c4c109..56dd5c7 100644 --- a/pt/11_1_Understanding_Timelock_Options.md +++ b/pt/11_1_Understanding_Timelock_Options.md @@ -11,7 +11,7 @@ O ```nLockTime``` é uma maneira simples e poderosa de bloquear uma transação, 3. **Sem Scripts.** O uso simples e original do ```nLockTime``` não permitia que fosse usado em Scripts; 4. **Sem proteção.** O ```nLockTime``` permite que os fundos sejam gastos com uma transação diferente e não bloqueada. -O último item costumava ser o _dealbreaker_ para o ```nLockTime```. Isso evitou que uma transação fosse gasta, mas não impediu que os fundos fossem usados em uma transação diferente. Então, haviam certos usos, mas todos dependiam de confiança. +O último item costumava ser o _dealbreaker_ para o ```nLockTime```. Isso evitou que uma transação fosse gasta, mas não impediu que os fundos fossem usados em uma transação diferente. Então, havia certos usos, mas todos dependiam de confiança. ## Compreendendo as possibilidades dos scripts de Timelock @@ -19,19 +19,19 @@ Nos últimos anos, o Bitcoin Core foi expandido para permitir a manipulação do _Eles são opcodes._ Por serem opcodes, o CLTV e o CSV podem ser usados ​​como parte de condições de resgate mais complexas. Na maioria das vezes, eles estão vinculados às condicionais que ireimos descrever no próximo capítulo. -_Eles bloqueiam as saídas._ Por serem opcodes incluídos nas transações como parte de uma ```sigPubKey```, eles apenas bloqueiam aquela saída única. Isso significa que as transações são aceitas na rede Bitcoin e que os UTXOs usados ​​para financiar essas transações são gastos. Não há como voltar atrás em uma transação bloqueada por tempo com o CLTV ou o CSV como acontece com um ```nLockTime``` vazio. Gastar novamente o UTXO resultante requer que as condições do timelock sejam atendidas. +_Eles bloqueiam as saídas._ Por serem opcodes incluídos nas transações como parte de uma ```sigPubKey```, eles apenas bloqueiam aquela saída única. Isso significa que as transações são aceitas na rede Bitcoin e que as UTXOs usadas ​​para financiar essas transações são gastos. Não há como voltar atrás em uma transação bloqueada por tempo com o CLTV ou o CSV como acontece com um ```nLockTime``` vazio. Gastar novamente a UTXO resultante requer que as condições do timelock sejam atendidas. Aqui está um ponto importante sobre a utilização dos timelocks: _Eles são bloqueios de mão única._ Os bloqueios de tempo são projetados para desbloquear fundos em um determinado momento. Eles não podem bloquear novamente um fundo: Uma vez que um fundo bloqueado por tempo está disponível, ele ficará disponível para ser gasto. ### Compreendendo as possibilidades do CLTV -O _OP_CHECKLOCKTIMEVERIFY_ ou CLTV é uma combinação para o recurso clássicos usando o ```nLockTime```, mas no novo paradigma baseado em opcode. Ele permite que um UTXO se torne acessível em um determinado momento ou em uma determinada altura de bloco. +O _OP_CHECKLOCKTIMEVERIFY_ ou CLTV é compativel com o clássico recurso ```nLockTime```, mas no novo paradigma baseado em opcode. Ele permite que uma UTXO se torne acessível em um determinado momento ou em uma determinada altura de bloco. O CLTV foi detalhado pela primeira vez no [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki). ### Compreendendo as possibilidades do CSV -O _OP_CHECKSEQUENCEVERIFY_ ou CSV depende de um novo tipo de "locktime relativo", que é definido no campo _nSequence_ da transação. Como de costume, ele pode ser definido como uma data/hora ou uma altura de bloco. Se for definido como um tempo "n", então uma transação bloqueada em um tempo relativo pode ser gasta "n x 512" segundos depois que o UTXO foi minerado, e se for definido como um bloco "n", então uma transação bloqueada em tempo relativo pode ser gasta em "n" blocos depois que o UTXO foi minerado. +O _OP_CHECKSEQUENCEVERIFY_ ou CSV depende de um novo tipo de "locktime relativo", que é definido no campo _nSequence_ da transação. Como de costume, ele pode ser definido como uma data/hora ou uma altura de bloco. Se for definido como um tempo "n", então uma transação bloqueada em um tempo relativo pode ser gasta "n x 512" segundos depois que a UTXO foi minerada, e se for definido como um bloco "n", então uma transação bloqueada em tempo relativo pode ser gasta em "n" blocos depois que a UTXO foi minerada. O uso do ```nSequence``` para um bloqueio de tempo relativo foi detalhado primeiramente no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki), e o opcode CSV foi adicionado no [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki). @@ -41,8 +41,8 @@ Agora possuímos quatro opções de Timelocks: * ```nLockTime``` para manter uma transação fora do blockchain até um dado momento específico; * ```nSequence``` para manter uma transação fora do blockchain até um dado momento relativo; -* CLTV para tornar um UTXO impossível de ser gasto até uma data/hora específica; -* CSV para tornar um UTXO impossível de ser gasto até uma data/hora ou altura do bloco relativa. +* CLTV para tornar uma UTXO impossível de ser gasto até uma data/hora específica; +* CSV para tornar uma UTXO impossível de ser gasto até uma data/hora ou altura do bloco relativa. ## O Que Vem Depois? diff --git a/pt/11_2_Using_CLTV_in_Scripts.md b/pt/11_2_Using_CLTV_in_Scripts.md index d8ee5cd..6b6a88f 100644 --- a/pt/11_2_Using_CLTV_in_Scripts.md +++ b/pt/11_2_Using_CLTV_in_Scripts.md @@ -1,6 +1,6 @@ # 11.2: Usando o CLTV nos Scripts -O ```OP_CHECKLOCKTIMEVERIFY``` (ou CLTV) é o complemento natural para o ```nLockTime```. Ele muda a ideia de bloquear transações por um tempo absoluto ou altura de bloco para o reino dos opcodes, permitindo o bloqueio de UTXOs individuais. +O ```OP_CHECKLOCKTIMEVERIFY``` (ou CLTV) é o complemento natural para o ```nLockTime```. Ele muda a ideia de bloquear transações por um tempo absoluto ou altura de bloco para o âmbito dos opcodes, permitindo o bloqueio das UTXOs individuais. > :warning: **AVISO DE VERSÃO:** O CLTV ficou disponível no Bitcoin Core 0.11.2, mas deve ser amplamente implementado neste momento. @@ -13,7 +13,7 @@ Conforme detalhado na seção [§8.1:Enviando uma transação com Locktime](08_1 * Se o ```nLockTime``` for inferior a 500 milhões, será interpretado como uma altura de bloco; * Se o ```nLockTime``` for 500 milhões ou mais, será interpretado como um carimbo de data/hora UNIX. -Uma transação com ```nLockTime``` definida não pode ser gasta (ou mesmo colocada na blockchain) até que a altura do bloco ou a data/hora sejam alcançados. Nesse ínterim, a transação pode ser cancelada gastando-se qualquer um dos UTXOs que constituem a transação. +Uma transação com ```nLockTime``` definida não pode ser gasta (ou mesmo colocada na blockchain) até que a altura do bloco ou a data/hora sejam alcançados. Neste meio tempo, a transação pode ser cancelada, ao se utilizar qualquer uma das UTXOs que constituem a transação. ## Compreendendo o Opcode CLTV @@ -51,14 +51,14 @@ Mas geralmente vamos abstrair assim: A explicação acima é suficiente para usar e entender o CLTV. No entanto, o [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) apresenta todos os seguintes detalhes. -Um script de bloqueio só permitirá que uma transação reenvie um UTXO bloqueado com um CLTV se o ```OP_CHECKLOCKTIMEVALUE``` verificar todas as seguintes condições: +Um script de bloqueio só permitirá que uma transação reenvie uma UTXO bloqueado com um CLTV se o ```OP_CHECKLOCKTIMEVALUE``` verificar todas as seguintes condições: * O campo ```nSequence``` deve ser definido como sendo menor do que 0xffffffff, geralmente 0xffffffff-1 para evitar conflitos com os timelocks relativos; * CLTV deve retirar um operando da pilha e deve ser 0 ou maior. * Tanto o operando da pilha quanto o ```nLockTime``` devem estar acima ou abaixo de 500 milhões, para representar o mesmo tipo de locktime absoluto; * O valor ```nLockTime``` deve ser maior ou igual ao operando da pilha. -Portanto, a primeira coisa a se notar aqui é que o ```nLockTime``` ainda é utilizado com o CLTV. Para ser mais preciso, ele é necessário na transação que tenta _gastar novamente_ um UTXO com o temporizador CLTV. Isso significa que não faz parte dos requisitos do script. É apenas o cronômetro que é usado para liberar os fundos, _como definido no script_. +Portanto, a primeira coisa a se notar aqui é que o ```nLockTime``` ainda é utilizado com o CLTV. Para ser mais preciso, ele é necessário na transação que tenta _gastar novamente_ uma UTXO com o temporizador CLTV. Isso significa que não faz parte dos requisitos do script. É apenas o cronômetro que é usado para liberar os fundos, _como definido no script_. Isso é gerenciado por meio de um entendimento inteligente de como o ```nLockTime``` funciona: Um valor para o ```nLockTime``` deve sempre ser escolhido sendo menor ou igual ao tempo presente (ou altura do bloco), de modo que a transação de gasto possa ser colocada na blockchain. Porém, devido aos requisitos do CLTV, também deve ser escolhido um valor maior ou igual ao operando do CLTV. A união desses dois conjuntos é ```NULL``` até que o tempo presente corresponda ao operando CLTV. Posteriormente, qualquer valor pode ser escolhido entre o operando do CLTV e o tempo atual. Normalmente, apenas iríamos configurar para a hora atual (ou para o bloco atual). @@ -109,9 +109,8 @@ O RPC ```decodescript``` pode verificar se acertamos a decodificação: Não vamos mostrar continuamente como todos os Scripts do Bitcoin são codificados em transações P2SH, ao invés disso, ofereceremos estes atalhos: Quando descrevemos um script, ele será um ```redeemScript```, que normalmente seria serializado e codificado em um script de bloqueio e serializado no script de desbloqueio. Quando mostramos um procedimento de desbloqueio, será a segunda rodada de validação, seguindo a confirmação do hash do script de bloqueio. -## Gastando um UTXO do CLTV +## Gastando uma UTXO do CLTV -In the case of the above example, the following unlocking script would suffice, provided that `nLockTime` was set to somewhere in advance of the `` date, and provided it was indeed at least ``: No caso do exemplo acima, o script de desbloqueio abaixo seria suficiente, desde que o ```nLockTime``` fosse definido em algum lugar antes da data ``````, e desde que o momento atual fosse, de fato, pelo menos ``````: ``` @@ -145,9 +144,9 @@ Finalmente, o restante do script é executado, que é uma verificação normal d ## Resumo: Usando o CLTV nos Scripts -O ```OP-CHECKLOCKTIMEVERIFY``` é um opcode simples que olha para um único argumento, o interpreta como uma altura de bloco ou timestamp UNIX, e só permite que o UTXO seja desbloqueado se aquela altura de bloco ou timestamp UNIX estiver no passado. Definir o ```nLockTime``` na transação de gastos é o que permite ao Bitcoin fazer este cálculo. +O ```OP-CHECKLOCKTIMEVERIFY``` é um opcode simples que olha para um único argumento, o interpreta como uma altura de bloco ou timestamp UNIX, e só permite que a UTXO seja desbloqueada se àquela altura de bloco ou timestamp UNIX estiver no passado. Definir o ```nLockTime``` na transação de gastos é o que permite ao Bitcoin fazer este cálculo. -> :fire: ***Qual é o poder do CLTV?*** Já vimos que os tempos de bloqueio simples eram uma das bases dos Contratos Inteligentes. O CLTV dá o próximo passo. Agora podemos garantir que um UTXO não pode ser gasto antes de um certo tempo _e_ podemos garantir que ele também não será gasto. Em sua forma mais simples, isso poderia ser usado para criar um fundo que alguém só poderia ter acesso aos 18 anos ou um fundo de aposentadoria que só poderia ser acessado quando fizesse 50 anos. No entanto, o verdadeiro poder vem quando combinado com condicionais, onde apenas o CLTV apenas é ativado em certas situações. +> :fire: ***Qual é o poder do CLTV?*** Já vimos que os tempos de bloqueio simples eram uma das bases dos Contratos Inteligentes. O CLTV dá o próximo passo. Agora podemos garantir que uma UTXO não possa ser gasta antes de um certo tempo _e_ podemos garantir que ela também não será gasta. Em sua forma mais simples, isso poderia ser usado para criar um fundo que alguém só poderia ter acesso aos 18 anos ou um fundo de aposentadoria que só poderia ser acessado quando fizesse 50 anos. No entanto, o verdadeiro poder vem quando combinado com condicionais, onde apenas o CLTV apenas é ativado em certas situações. ## O Que Vem Depois? diff --git a/pt/11_3_Using_CSV_in_Scripts.md b/pt/11_3_Using_CSV_in_Scripts.md index 1efbdd7..ed337a4 100644 --- a/pt/11_3_Using_CSV_in_Scripts.md +++ b/pt/11_3_Using_CSV_in_Scripts.md @@ -8,7 +8,7 @@ O ```nLockTime``` e o ```OP_CHECKLOCKTIMEVERIFY``` (ou CLTV) são apenas um lado Cada entrada em uma transação tem um valor ```nSequence``` (ou se preferirmos ```sequence```). Tem sido uma ferramenta principal para melhorias do Bitcoin, conforme discutido anteriormente na seção [§5.2: Reenviando uma transação com o RBF](05_2_Resending_a_Transaction_with_RBF.md) e na [§8.1 Enviando uma transação com Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md), onde o usamos para sinalizar o RBF e o ```nLockTime```, respectivamente. No entanto, há mais um uso para o ```nSequence```, descrito no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Podemos usá-lo para criar um timelock relativo em uma transação. -Um timelock relativo é um bloqueio colocado em uma entrada específica de uma transação e que é calculado em relação à data de mineração do UTXO que está sendo usado na entrada. Por exemplo, se um UTXO foi minerado no bloco #468260 e uma transação foi criada onde a entrada para aquele UTXO foi uma ```nSequence``` de 100, então a nova transação não poderia ser minerada até o bloco #468360. +Um timelock relativo é um bloqueio colocado em uma entrada específica de uma transação e que é calculado em relação à data de mineração da UTXO que está sendo usado na entrada. Por exemplo, se uma UTXO foi minerada no bloco #468260 e uma transação foi criada onde a entrada para aquela UTXO foi uma ```nSequence``` de 100, então a nova transação não poderia ser minerada até o bloco #468360. Simples assim! @@ -18,7 +18,7 @@ Simples assim! ### Criando um CSV de Tempo de Bloco Relativo -O formato para usar o ```nSequence``` para representar bloqueios de tempo relativos é definido no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) e é um pouco mais complexo do que apenas inserir um número qualquer, como fizemos no ```nTimeLock```. Ao invés disso, as especificações BIP dividem o número de quatro bytes em três partes: +O formato para usar o ```nSequence``` para representar bloqueios de tempo relativos é definido no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) e é um pouco mais complexo do que apenas inserir um número qualquer, como fizemos no ```nTimeLock```. Ao invés disso, as especificações do BIP dividem o número de quatro bytes em três partes: * Os primeiros dois bytes são usados ​​para especificar um timelock relativo; * O 23º bit é usado para sinalizar positivamente se o bloqueio se refere a um tempo ou a uma altura de bloco; @@ -35,7 +35,7 @@ A fim de fazer isso, precisamos: 1. Decidir o quanto no futuro definiremos o nosso bloqueio de tempo relativo; 2. Converter isso para segundos; 3. Dividir por 512; -4. Arredondar esse valor para cima ou para baixo e definí-lo como ```nSequence```; +4. Arredondar esse valor para cima ou para baixo e defini-lo como ```nSequence```; 5. Definir o 23º bit como verdadeiro. Para definir um período de 6 meses no futuro, devemos primeiro calcular da seguinte forma: @@ -59,9 +59,9 @@ Se convertermos de volta, teremos o valor de 4224679 = 10000000111011010100111. Então desejamos criar uma transação simples com um timelock relativo? Tudo que precisamos fazer é emitir uma transação onde o ```nSequence``` de uma entrada é definido como mostramos acima: Com o ```nSequence``` para essa entrada definido de forma que os primeiros dois bytes definam o timelock, o 23º bit define o tipo do timelock, e o 32º bit é definido como sendo falso. -Vamos enviar a transação e veremos que ela não pode ser legalmente minerada até que blocos ou tempo suficientes tenham passado além do tempo que o UTXO foi minerado. +Vamos enviar a transação e veremos que ela não pode ser legalmente minerada até que blocos ou tempo suficientes tenham passado além do tempo que a UTXO foi minerada. -Exceto que praticamente ninguém faz isso. As definições do [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) para ```nSequence``` foram incorporadas ao Bitcoin Core ao mesmo tempo que o [BIP 112](https: //github.com/bitcoin/bips/blob/master/bip-0112.mediawiki), que descreve o opcode CSV e o ```nSequence``` equivalente ao opcode CLTV. Assim como o CLTV, o CSV oferece recursos aprimorados. Portanto, quase todo o uso dos timelocks relativos foi com o opcode CSV, não com o valor ```nSequence``` bruto por si só. +Exceto que praticamente ninguém faz isso. As definições do [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) para ```nSequence``` foram incorporadas ao Bitcoin Core ao mesmo tempo que o [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki), que descreve o opcode CSV e o ```nSequence``` equivalente ao opcode CLTV. Assim como o CLTV, o CSV oferece recursos aprimorados. Portanto, quase todo o uso dos timelocks relativos foi com o opcode CSV, não com o valor ```nSequence``` bruto por si só. | | Absolute Timelock | Relative Timelock | |:--------------------:|-------------------|-------------------| @@ -72,11 +72,11 @@ Exceto que praticamente ninguém faz isso. As definições do [BIP 68](https://g O ```OP_SEQUENCEVERIFY``` nos Scripts do Bitcoin funciona quase como o ```OP_LOCKTIMEVERIFY```. -Podemos exigir que um UTXO seja mantido por cem blocos após sua mineração: +Podemos exigir que uma UTXO seja mantida por cem blocos após sua mineração: ``` 100 OP_CHECKSEQUENCEVERIFY ``` -Ou podemos fazer um cálculo mais complexo para exigir que um UTXO seja retido daqui seis meses, neste caso acabaremos com um número mais complexo: +Ou podemos fazer um cálculo mais complexo para exigir que uma UTXO seja retida daqui seis meses, neste caso acabaremos com um número mais complexo: ``` 4224679 OP_CHECKSEQUENCEVERIFY ``` @@ -85,7 +85,7 @@ Neste caso, usaremos uma abreviatura: <+6Months> OP_CHECKSEQUENCEVERIFY ``` -> :warning: **ATENÇÃO:** Lembre-se de que um timelock relativo é um intervalo de tempo desde a mineração do UTXO usado como uma entrada. _Não_ é um intervalo de tempo após a criação da transação. Se usarmos um UTXO que já foi confirmado cem vezes, e colocarmos um timelock relativo de 100 blocos nele, ele será elegível para mineração imediatamente. Os timelocks relativos têm alguns usos muito específicos, mas provavelmente não se aplicam se nosso único objetivo for determinar algum tempo definido no futuro. +> :warning: **ATENÇÃO:** Lembre-se de que um timelock relativo é um intervalo de tempo desde a mineração da UTXO usada como uma entrada. _Não_ é um intervalo de tempo após a criação da transação. Se usarmos uma UTXO que já foi confirmada cem vezes, e colocarmos um timelock relativo de 100 blocos nela, ela será elegível para mineração imediatamente. Os timelocks relativos têm alguns usos muito específicos, mas provavelmente não se aplicam se nosso único objetivo for determinar algum tempo definido no futuro. ### Entendendo como o CSV realmente funciona @@ -97,7 +97,7 @@ O CSV tem muitas das mesmas sutilezas de uso que CLTV: * Tanto o operando da pilha quanto o ```nSequence``` devem ter o mesmo valor no 23º bit; * O ```nSequence``` deve ser maior ou igual ao operando da pilha. -Assim como no CLTV, quando estamos repensando um UTXO com um CSV em condições de bloqueio, devemos definir o ```nSequence``` para habilitar a transação. Normalmente, o configuraremos com o valor exato no script de bloqueio. +Assim como no CLTV, quando estiver usando uma UTXO com um CSV em condições de bloqueio, devemos definir o ```nSequence``` para habilitar a transação. Normalmente, o configuraremos com o valor exato no script de bloqueio. ## Escrevendo um script CSV @@ -133,16 +133,15 @@ Length: 3 bytes Hexcode: 03a77640 ``` -## Gastando um UTXO do CSV +## Gastando uma UTXO do CSV -Para gastar um UTXO bloqueado com um script CSV, devemos definir o ```nSequence``` dessa entrada para um valor maior que o requerido no script, mas menor que o tempo entre o UTXO e o bloco atual. Isso mesmo, isso significa que precisamos saber o requisito exato no script de bloqueio. Mas temos uma cópia do ```redeemScript```, então se não conhecermos os requisitos, podemos desserializá-lo e, em seguida, definir o ```nSequence``` como sendo o número que é mostrado lá. +Para gastar uma UTXO bloqueado com um script CSV, devemos definir o ```nSequence``` dessa entrada para um valor maior que o requerido no script, mas menor que o tempo entre a UTXO e o bloco atual. Isso mesmo, isso significa que precisamos saber o requisito exato no script de bloqueio. Mas temos uma cópia do ```redeemScript```, então se não conhecermos os requisitos, podemos desserializá-lo e, em seguida, definir o ```nSequence``` como sendo o número que é mostrado lá. ## Resumo: Usando o CSV nos Scripts O ```nSequence``` e o CSV oferecem uma alternativa para o ```nLockTime``` e o CLTV onde bloqueamos uma transação com base em um tempo relativo desde que a entrada foi extraída, ao invés de basear o bloqueio em um tempo definido no futuro. Eles funcionam quase de forma idêntica, exceto pelo fato de que o valor do ```nSequence``` é codificado de forma ligeiramente diferente do valor do ```nLockTime```, com bits específicos significando coisas específicas. -> :fire: ***What is the power of CSV?*** CSV isn't just a lazy way to lock, when you don't want to calculate a time in the future. Instead, it's a totally different paradigm, a lock that you would use if it was important to create a specific minimum duration between when a transaction is mined and when its funds can be respent. The most obvious usage is (once more) for an escrow, when you want a precise time between the input of funds and their output. However, it has much more powerful possibilities in off-chain transactions, including payment channels. These applications are by definition built on transactions that are not actually put onto the blockchain, which means that if they are later put on the blockchain an enforced time-lapse can be very helpful. [Hashed Timelock Contracts](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) have been one such implementation, empowering the Lightning payment network. They're discussed in [§13.3: Empowering Bitcoin with Scripts](13_3_Empowering_Bitcoin_with_Scripts.md). -> :fire: ***Qual é o poder do CSV?*** O CSV não é apenas uma maneira preguiçosa de bloquear uma transação, quando não queremos calcular um tempo no futuro. Ele é um paradigma totalmente diferente, um bloqueio que usaríamos se fosse importante criar uma duração mínima específica entre o momento em que uma transação é minerada e o momento em que os fundos podem ser gastos. O uso mais óbvio é (mais uma vez) para um depósito, quando desejamos um tempo preciso entre a entrada dos fundos e a saída. No entanto, ele tem possibilidades muito mais poderosas em transações fora da rede, incluindo canais de pagamento. Esses aplicativos são, por definição, construídos em transações que não são realmente colocadas na blockchain, o que significa que, se forem posteriormente colocados em um bloco, um período de tempo pode ser muito útil. Os [Hashed Timelock Contracts](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) foram uma dessas implementações, dando a base para a rede de pagamento Lightning. Eles serão discutidos na seção [§13.3: Expandindo os Scripts do Bitcoin](13_3_Empowering_Bitcoin_with_Scripts.md). +> :fire: ***Qual é o poder do CSV?*** O CSV não é apenas uma maneira preguiçosa de bloquear uma transação, quando não queremos calcular um tempo no futuro. Ele é um paradigma totalmente diferente, um bloqueio que usaríamos se fosse importante criar uma duração mínima específica entre o momento em que uma transação é minerada e o momento em que os fundos podem ser gastos. O uso mais óbvio é (mais uma vez) para uma conta de garantia, quando desejamos um tempo preciso entre a entrada dos fundos e a saída. No entanto, ele tem possibilidades muito mais poderosas em transações fora da rede, incluindo canais de pagamento. Esses aplicativos são, por definição, construídos em transações que não são realmente colocadas na blockchain, o que significa que, se forem posteriormente colocados em um bloco, um período de tempo pode ser muito útil. Os [Hashed Timelock Contracts](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) foram uma dessas implementações, dando a base para a rede de pagamento Lightning. Eles serão discutidos na seção [§13.3: Expandindo os Scripts do Bitcoin](13_3_Empowering_Bitcoin_with_Scripts.md). ## O Que Vem Depois? From 702a1dd4034318361ba7514cd90f4af2f3e1e300 Mon Sep 17 00:00:00 2001 From: namcios Date: Fri, 17 Sep 2021 17:13:48 -0300 Subject: [PATCH 123/155] Translate 15_0 --- pt/15_0_Using_i2p.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 pt/15_0_Using_i2p.md diff --git a/pt/15_0_Using_i2p.md b/pt/15_0_Using_i2p.md new file mode 100644 index 0000000..2255045 --- /dev/null +++ b/pt/15_0_Using_i2p.md @@ -0,0 +1,20 @@ +# Capítulo 15: Usando o I2P + +Existem alternativas ao Tor. Uma é o Projeto Internet Invisível (I2P, ou Invisible Internet Project em inglês), uma camada de rede privada e totalmente criptografada. Ele utiliza um [banco de dados de rede](https://geti2p.net/pt-br/docs/how/network-database) distribuído e túneis criptografados unidirecionais entre os usuários. A maior diferença do I2P para o Tor é que o Tor é, em essência, uma rede de proxy que oferece serviços de internet de uma forma privada, enquanto que o I2P é fundamentalmente uma rede sequestrada que oferece serviços I2P apenas à rede I2P, criando uma "rede em uma rede". No entanto, você pode querer tê-la apenas como uma alternativa, para que você não dependa apenas do Tor. + +No momento, o I2P não é instalado pelo [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts) porque suporte ao I2P foi adicionado recentemente ao Bitcoin Core. No entanto, este capítulo explica como podemos instalá-lo manualmente. + +## Objetivos para Este Capítulo + +Depois de trabalharmos neste capítulo, um desenvolvedor será capaz de: + +* Executar o Bitcoin Core como um serviço I2P + +Objetivos secundários incluem a abilidade de: + +- Compreender a rede I2P +- Aprender a diferença entre o Tor e o I2P + +## Tabela de Conteúdo + +* [Seção Um: Bitcoin Core como um Serviço I2P (Projeto Internet Invisível)](15_1_i2p_service.md) \ No newline at end of file From 214dd882ec012aaf53927fc58a7311778c7f8ca3 Mon Sep 17 00:00:00 2001 From: namcios Date: Fri, 17 Sep 2021 17:14:05 -0300 Subject: [PATCH 124/155] Translate 15_1 --- pt/15_1_i2p_service.md | 124 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 pt/15_1_i2p_service.md diff --git a/pt/15_1_i2p_service.md b/pt/15_1_i2p_service.md new file mode 100644 index 0000000..f5444f6 --- /dev/null +++ b/pt/15_1_i2p_service.md @@ -0,0 +1,124 @@ +# 15.1: Bitcoin Core como um Serviço I2P (Projeto Internet Invisível) + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e ainda é um rascunho inicial que pode estar aguardando revisão. Proceda com cuidado, leitor. + +Ao invés de utilizarmos o serviço baseado em proxy do Tor para garantir a privacidade das nossas comunicações no Bitcoin, podemos querer utilizar o I2P, que é projetado para agir como uma rede privada dentro da internet, ao invés de simplesmente oferecer acesso privado a serviços de internet. + +## Compreendendo as Diferenças + +Tanto o Tor quanto o I2P oferecem acesso privado a serviços online, mas com roteamentos, bancos de dados e arquiteturas para retransmissões diferentes. Como serviços ocultos (como acesso ao Bitcoin) são centrais ao design do I2P, eles também foram otimizados: + +| | Tor | I2P | +| ---------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| Roteamento | [Onion](https://www.onion-router.net/) | [Garlic](https://geti2p.net/en/docs/how/garlic-routing) | +| Banco de Dados da Rede | [Servidores de Diretório](https://blog.torproject.org/possible-upcoming-attempts-disable-tor-network) Confiados | [Banco de Dados de Rede Distribuído](https://geti2p.net/en/docs/how/network-database) | +| Retransmissão | Conexões criptografadas de **mão-dupla** entre cada Retransmissor | Conexões de **mão-única** entre todo servidor em seus túneis | +| Serviços Ocultos | Devagar | Rápido | + +Podemos encontrar uma comparação mais detalhada em [geti2p.net](https://geti2p.net/pt-br/comparison/tor). + +### Compreenda os Tradeoffs para Limitar Conexões de Saída + +Existem [tradeoffs](https://bitcoin.stackexchange.com/questions/107060/tor-and-i2p-tradeoffs-in-bitcoin-core) caso escolhamos suportar apenas o I2P, apenas o Tor, ou ambos. Essas configurações, que limitam conexões de saída de clearnet, são feitas no Bitcoin Core usando o argumento `onlynet` em `bitcoin.conf`. + +* `onlynet=onion`, que limita conexões de saída ao Tor, pode expor um node a ataques "Sybil" e criar partições na rede, devido às conexões limitadas entre Tornet e clearnet. +* `onlynet=onion` e `onlynet=i2p`, juntas, que executa serviço Onion com serviço I2P, é experimental por enquanto. + +## Instalando o I2P + +Para instalar o I2P, devemos nos certificar de que configuramos as portas devidamente e apenas então continuar com o processo. + +### Preparando as Portas + +Para usar o I2P, devemos abrir as seguintes portas, necessárias para o I2P: + +1. **De saída (olhando para a internet):** uma porta aleatória entre 9000 e 31000 é selecionada. É melhor se todas essas portas estiverem abertas para conexões de saída, o que não afeta nossa segurança. + - Podemos checar o status do nosso firewall usando `sudo ufw status verbose`, o que não deve negar conexões de saída por padrão +2. De entrada (olhando para a internet): opcional. A variedade de portas de entrada são listadas na [documentação do I2P](https://geti2p.net/pt-br/faq#ports) + - Para maximizarmos privacidade, é preferível desabilitarmos conexões de entrada. + +### Executando o I2P + +O seguinte irá executar serviços I2P no Bitcoin Core: + +1. Instalando `i2pd` no Ubuntu: + + ``` + sudo add-apt-repository ppa:purplei2p/i2pd + sudo apt-get update + sudo apt-get install i2pd + ``` + + Para instalarmos em outros sistemas operacionais, podemos ver [estes documentos](https://i2pd.readthedocs.io/en/latest/user-guide/install/). + +2. [Executando](https://i2pd.readthedocs.io/en/latest/user-guide/run/) o serviço I2P: + + ``` + $ sudo systemctl start i2pd.service + ``` + +3. Verificando se o I2P está em execução, devemos vê-lo na porta 7656: + + ``` + $ ss -nlt + + State Recv-Q Send-Q Local Address:Port Peer Address:Port Process + + LISTEN 0 4096 127.0.0.1:7656 0.0.0.0:* + ``` + +4. Devemos adicionar as seguintes linhas em `bitcoin.conf`: + + ``` + i2psam=127.0.0.1:7656 + debug=i2p + ``` + + A opção para os logs, `debug=i2p`, é utilizada para recordarmos informações adicionais no debug log sobre nossas configurações e conexões I2P. O lugar padrão para esse arquivo de debug no Linux é: `~/.bitcoin/debug.log` + +5. Reiniciando o `bitcoind` + + ``` + $ bitcoind + ``` + +6. Devemos verificar se o I2P foi configurado corretamente olhando o `debug.log`, ou se algum erro apareceu nos logs. + + ``` + 2021-06-15T20:36:16Z i2paccept thread start + 2021-06-15T20:36:16Z I2P: Creating SAM session with 127.0.0.1:7656 + + 2021-06-15T20:36:56Z I2P: SAM session created: session id=3e0f35228b, my address=bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333 + 2021-06-15T20:36:56Z AddLocal(bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333,4) + ``` + + O nosso endereço I2P é mencionado nos logs, e termina com _b32.i2p_. Por exemplo `bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333`. + +7. Devemos confirmar que `i2p_private_key` foi criado no diretório do Bitcoin Core. A primeira vez que o Bitcoin Core conectar ao roteador I2P, o endereço I2P (e a chave privada correspondente) será automaticamente gerado e salvado em um arquivo chamado *i2p_private_key*: + + ``` + ~/.bitcoin/testnet3$ ls + + anchors.dat chainstate i2p_private_key settings.json + banlist.dat debug.log mempool.dat wallets + blocks fee_estimates.dat peers.dat + ``` + +8. Devemos verificar que `bitcoin-cli -netinfo` ou `bitcoin-cli getnetworkinfo` retorna o endereço I2P: + + ``` + Local addresses + bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p port 18333 score 4 + ``` + + Agora temos um servidor do Bitcoin acessível através da rede I2P no nosso novo endereço local. + +## Resumo: Bitcoin Core como um Serviço I2P (Projeto Internet Invisível) + +É sempre positivo termos alternativas para privacidade e não dependermos exclusivamente do Tor para executarmos o Bitcoin Core como um serviço oculto. Como I2P foi adicionado recentemente ao Bitcoin Core, poucas pessoas o utilizam. Podemos experimentar com ele e reportar bugs se encontrarmos algum problema. + +> :information_source: **NOTA:** Para a implementação oficial do I2P em Java, podemos visitar a [página de download do I2P](https://geti2p.net/en/download) e seguirmos as instruções para nosso Sistema Operacional. Após instalado, podemos abrir uma janela do Terminal e escrever `i2prouter start`. Em seguida, podemos visitar o endereço `127.0.0.1:76571` em um navegador e permitirmos o SAM. Para fazermos isso, selecionamos: "Configure Homepage", então "Clients", e finalmente selecionar o "Play Button" ao lado da Bridge de aplicativo SAM. No lado esquerdo da página, devemos ver uma luz verde próximo a "Shared Clients". + +Siga em frente para "Programando com RPC" no [Capítulo Dezesseis: Conversando com o Bitcoind com C](16_0_Talking_to_Bitcoind.md). + +Ou, se não formos programadores, podemos pular para o [Capítulo Dezenove: Compreendendo Sua Configuração Lightning](https://github.com/namcios/Learning-Bitcoin-from-the-Command-Line/blob/portuguese-translation/pt/18_0_Understanding_Your_Lightning_Setup.md) para continuarmos nosso aprendizado da linha de comando com a rede Lightning. \ No newline at end of file From 8f308d4e1c2ba544863f30697974aeac0aae1b08 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sun, 19 Sep 2021 14:44:27 -0300 Subject: [PATCH 125/155] reviewed --- pt/15_0_Using_i2p.md | 12 ++++---- pt/15_1_i2p_service.md | 68 +++++++++++++++++++++--------------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/pt/15_0_Using_i2p.md b/pt/15_0_Using_i2p.md index 2255045..db432a1 100644 --- a/pt/15_0_Using_i2p.md +++ b/pt/15_0_Using_i2p.md @@ -1,19 +1,19 @@ # Capítulo 15: Usando o I2P -Existem alternativas ao Tor. Uma é o Projeto Internet Invisível (I2P, ou Invisible Internet Project em inglês), uma camada de rede privada e totalmente criptografada. Ele utiliza um [banco de dados de rede](https://geti2p.net/pt-br/docs/how/network-database) distribuído e túneis criptografados unidirecionais entre os usuários. A maior diferença do I2P para o Tor é que o Tor é, em essência, uma rede de proxy que oferece serviços de internet de uma forma privada, enquanto que o I2P é fundamentalmente uma rede sequestrada que oferece serviços I2P apenas à rede I2P, criando uma "rede em uma rede". No entanto, você pode querer tê-la apenas como uma alternativa, para que você não dependa apenas do Tor. +Existem alternativas ao Tor. Uma é o Projeto Internet Invisível (I2P, ou Invisible Internet Project em inglês), uma camada de rede privada e totalmente criptografada. Ele utiliza um [banco de dados de rede](https://geti2p.net/pt-br/docs/how/network-database) distribuído e túneis criptografados unidirecionais entre os usuários. A maior diferença do I2P para o Tor é que o segundo é, em essência, uma rede de proxy que oferece serviços de internet de uma forma privada, enquanto que o I2P é fundamentalmente uma rede separada que oferece serviços I2P apenas à rede I2P, criando uma "rede dentro de uma rede". No entanto, podemos querer tê-la apenas como uma alternativa, para que não dependamos apenas do Tor. -No momento, o I2P não é instalado pelo [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts) porque suporte ao I2P foi adicionado recentemente ao Bitcoin Core. No entanto, este capítulo explica como podemos instalá-lo manualmente. +No momento, o I2P não está instalada com o [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts) porque o suporte ao I2P foi adicionado recentemente ao Bitcoin Core. No entanto, neste capítulo, iremos explicar como podemos instalá-lo manualmente. ## Objetivos para Este Capítulo Depois de trabalharmos neste capítulo, um desenvolvedor será capaz de: -* Executar o Bitcoin Core como um serviço I2P +- Executar o Bitcoin Core como um serviço I2P. -Objetivos secundários incluem a abilidade de: +Objetivos secundários incluem a habilidade de: -- Compreender a rede I2P -- Aprender a diferença entre o Tor e o I2P +- Compreender a rede I2P; +- Aprender a diferença entre o Tor e o I2P. ## Tabela de Conteúdo diff --git a/pt/15_1_i2p_service.md b/pt/15_1_i2p_service.md index f5444f6..5d288f5 100644 --- a/pt/15_1_i2p_service.md +++ b/pt/15_1_i2p_service.md @@ -6,119 +6,119 @@ Ao invés de utilizarmos o serviço baseado em proxy do Tor para garantir a priv ## Compreendendo as Diferenças -Tanto o Tor quanto o I2P oferecem acesso privado a serviços online, mas com roteamentos, bancos de dados e arquiteturas para retransmissões diferentes. Como serviços ocultos (como acesso ao Bitcoin) são centrais ao design do I2P, eles também foram otimizados: +Tanto o Tor quanto o I2P oferecem acesso privado a serviços online, mas com roteamentos, bancos de dados e arquiteturas para retransmissões diferentes. Como serviços ocultos (como acesso ao Bitcoin) são a base do design do I2P, eles também foram otimizados: | | Tor | I2P | | ---------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | Roteamento | [Onion](https://www.onion-router.net/) | [Garlic](https://geti2p.net/en/docs/how/garlic-routing) | -| Banco de Dados da Rede | [Servidores de Diretório](https://blog.torproject.org/possible-upcoming-attempts-disable-tor-network) Confiados | [Banco de Dados de Rede Distribuído](https://geti2p.net/en/docs/how/network-database) | +| Banco de Dados da Rede | [Servidores de Diretório](https://blog.torproject.org/possible-upcoming-attempts-disable-tor-network) Confiáveis | [Banco de Dados de Rede Distribuído](https://geti2p.net/en/docs/how/network-database) | | Retransmissão | Conexões criptografadas de **mão-dupla** entre cada Retransmissor | Conexões de **mão-única** entre todo servidor em seus túneis | | Serviços Ocultos | Devagar | Rápido | Podemos encontrar uma comparação mais detalhada em [geti2p.net](https://geti2p.net/pt-br/comparison/tor). -### Compreenda os Tradeoffs para Limitar Conexões de Saída +### Compreenda os Tradeoffs para Limitar as Conexões de Saída -Existem [tradeoffs](https://bitcoin.stackexchange.com/questions/107060/tor-and-i2p-tradeoffs-in-bitcoin-core) caso escolhamos suportar apenas o I2P, apenas o Tor, ou ambos. Essas configurações, que limitam conexões de saída de clearnet, são feitas no Bitcoin Core usando o argumento `onlynet` em `bitcoin.conf`. +Existem [tradeoffs](https://bitcoin.stackexchange.com/questions/107060/tor-and-i2p-tradeoffs-in-bitcoin-core) caso escolhamos usar apenas o I2P, apenas o Tor, ou ambos. Essas configurações, que limitam conexões de saída na clearnet, são feitas no Bitcoin Core usando o argumento `onlynet` no `bitcoin.conf`. -* `onlynet=onion`, que limita conexões de saída ao Tor, pode expor um node a ataques "Sybil" e criar partições na rede, devido às conexões limitadas entre Tornet e clearnet. +* `onlynet=onion`, que limita conexões de saída ao Tor, pode expor um node a ataques "Sybil" e criar redes separadas, devido às conexões limitadas entre o Tornet e a clearnet. * `onlynet=onion` e `onlynet=i2p`, juntas, que executa serviço Onion com serviço I2P, é experimental por enquanto. ## Instalando o I2P -Para instalar o I2P, devemos nos certificar de que configuramos as portas devidamente e apenas então continuar com o processo. +Para instalar o I2P, devemos nos certificar de que configuramos as portas de maneira correta, para então, continuar com o processo. ### Preparando as Portas Para usar o I2P, devemos abrir as seguintes portas, necessárias para o I2P: -1. **De saída (olhando para a internet):** uma porta aleatória entre 9000 e 31000 é selecionada. É melhor se todas essas portas estiverem abertas para conexões de saída, o que não afeta nossa segurança. - - Podemos checar o status do nosso firewall usando `sudo ufw status verbose`, o que não deve negar conexões de saída por padrão -2. De entrada (olhando para a internet): opcional. A variedade de portas de entrada são listadas na [documentação do I2P](https://geti2p.net/pt-br/faq#ports) - - Para maximizarmos privacidade, é preferível desabilitarmos conexões de entrada. +1. **De saída (para a internet):** uma porta aleatória entre 9000 e 31000 é selecionada. É melhor se todas essas portas estiverem abertas para conexões de saída, o que não afeta nossa segurança. + - Podemos checar o status do nosso firewall usando `sudo ufw status verbose`, o que não deve negar conexões de saída por padrão. +2. **De entrada (olhando para a internet)**: opcional. A variedade de portas de entrada são listadas na [documentação do I2P](https://geti2p.net/pt-br/faq#ports) + - Para maximizarmos privacidade, é preferível desabilitarmos as conexões de entrada. ### Executando o I2P -O seguinte irá executar serviços I2P no Bitcoin Core: +Os comandos à seguir irão executar os serviços I2P no Bitcoin Core: 1. Instalando `i2pd` no Ubuntu: - ``` +``` sudo add-apt-repository ppa:purplei2p/i2pd sudo apt-get update sudo apt-get install i2pd - ``` +``` - Para instalarmos em outros sistemas operacionais, podemos ver [estes documentos](https://i2pd.readthedocs.io/en/latest/user-guide/install/). + Para instalarmos em outros sistemas operacionais, podemos ver [a documentação](https://i2pd.readthedocs.io/en/latest/user-guide/install/). 2. [Executando](https://i2pd.readthedocs.io/en/latest/user-guide/run/) o serviço I2P: - ``` +``` $ sudo systemctl start i2pd.service - ``` +``` -3. Verificando se o I2P está em execução, devemos vê-lo na porta 7656: +3. Para verificar se o I2P está executando, devemos observar a porta 7656: - ``` +``` $ ss -nlt State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 127.0.0.1:7656 0.0.0.0:* - ``` +``` -4. Devemos adicionar as seguintes linhas em `bitcoin.conf`: +4. Devemos adicionar as seguintes linhas no `bitcoin.conf`: - ``` +``` i2psam=127.0.0.1:7656 debug=i2p - ``` +``` - A opção para os logs, `debug=i2p`, é utilizada para recordarmos informações adicionais no debug log sobre nossas configurações e conexões I2P. O lugar padrão para esse arquivo de debug no Linux é: `~/.bitcoin/debug.log` + A opção para os logs, `debug=i2p`, é utilizada para observarmos as informações adicionais no debug log sobre nossas configurações e conexões I2P. O lugar padrão para esse arquivo de debug no Linux é: `~/.bitcoin/debug.log` 5. Reiniciando o `bitcoind` - ``` +``` $ bitcoind - ``` +``` 6. Devemos verificar se o I2P foi configurado corretamente olhando o `debug.log`, ou se algum erro apareceu nos logs. - ``` +``` 2021-06-15T20:36:16Z i2paccept thread start 2021-06-15T20:36:16Z I2P: Creating SAM session with 127.0.0.1:7656 2021-06-15T20:36:56Z I2P: SAM session created: session id=3e0f35228b, my address=bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333 2021-06-15T20:36:56Z AddLocal(bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333,4) - ``` +``` O nosso endereço I2P é mencionado nos logs, e termina com _b32.i2p_. Por exemplo `bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333`. 7. Devemos confirmar que `i2p_private_key` foi criado no diretório do Bitcoin Core. A primeira vez que o Bitcoin Core conectar ao roteador I2P, o endereço I2P (e a chave privada correspondente) será automaticamente gerado e salvado em um arquivo chamado *i2p_private_key*: - ``` +``` ~/.bitcoin/testnet3$ ls anchors.dat chainstate i2p_private_key settings.json banlist.dat debug.log mempool.dat wallets blocks fee_estimates.dat peers.dat - ``` +``` 8. Devemos verificar que `bitcoin-cli -netinfo` ou `bitcoin-cli getnetworkinfo` retorna o endereço I2P: - ``` +``` Local addresses bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p port 18333 score 4 - ``` +``` - Agora temos um servidor do Bitcoin acessível através da rede I2P no nosso novo endereço local. +Agora temos um servidor do Bitcoin acessível através da rede I2P no nosso novo endereço local. ## Resumo: Bitcoin Core como um Serviço I2P (Projeto Internet Invisível) -É sempre positivo termos alternativas para privacidade e não dependermos exclusivamente do Tor para executarmos o Bitcoin Core como um serviço oculto. Como I2P foi adicionado recentemente ao Bitcoin Core, poucas pessoas o utilizam. Podemos experimentar com ele e reportar bugs se encontrarmos algum problema. +É sempre positivo termos alternativas para privacidade e não dependermos exclusivamente do Tor para executarmos o Bitcoin Core como um serviço oculto. Como I2P foi adicionado recentemente ao Bitcoin Core, poucas pessoas o utilizam. Podemos experimentá-lo e reportar bugs se encontrarmos algum problema. > :information_source: **NOTA:** Para a implementação oficial do I2P em Java, podemos visitar a [página de download do I2P](https://geti2p.net/en/download) e seguirmos as instruções para nosso Sistema Operacional. Após instalado, podemos abrir uma janela do Terminal e escrever `i2prouter start`. Em seguida, podemos visitar o endereço `127.0.0.1:76571` em um navegador e permitirmos o SAM. Para fazermos isso, selecionamos: "Configure Homepage", então "Clients", e finalmente selecionar o "Play Button" ao lado da Bridge de aplicativo SAM. No lado esquerdo da página, devemos ver uma luz verde próximo a "Shared Clients". -Siga em frente para "Programando com RPC" no [Capítulo Dezesseis: Conversando com o Bitcoind com C](16_0_Talking_to_Bitcoind.md). +Siga em frente para o "Programando com RPC" no [Capítulo Dezesseis: Conversando com o Bitcoind com C](16_0_Talking_to_Bitcoind.md). Ou, se não formos programadores, podemos pular para o [Capítulo Dezenove: Compreendendo Sua Configuração Lightning](https://github.com/namcios/Learning-Bitcoin-from-the-Command-Line/blob/portuguese-translation/pt/18_0_Understanding_Your_Lightning_Setup.md) para continuarmos nosso aprendizado da linha de comando com a rede Lightning. \ No newline at end of file From 38989135332f4a352a9fdc565f19d636c442168a Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 10:57:02 -0300 Subject: [PATCH 126/155] Update README: chapter, file names --- pt/README.md | 120 +++++++++++++++++++++++++-------------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/pt/README.md b/pt/README.md index 0086802..9e71b7b 100644 --- a/pt/README.md +++ b/pt/README.md @@ -3,7 +3,7 @@ ![](https://www.blockchaincommons.com/images/projects/lbtc-screen.png) -"Aprendendo Bitcoin pela Linha de Comando", esta é a versão em português de [Learning Bitcoin from the Command Line](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line), um tutorial para trabalhar com Bitcoin (e Lightning) que ensina a interação direta com os servidores da maneira mais robusta e segura, para começar a trabalhar com criptomoedas. +"Aprendendo Bitcoin pela Linha de Comando" é a versão em português de [Learning Bitcoin from the Command Line](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line), um tutorial para trabalhar com Bitcoin (e Lightning) que ensina a interação direta com os próprios servidores como a maneira mais robusta e segura para começar a trabalhar com criptomoedas. > NOTA: Este é um rascunho em progresso, para que eu possa receber algum feedback de revisores iniciais. Ainda não está pronto para uso. @@ -22,19 +22,19 @@ Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuin **Estado**: Finalizado. Atualizado para 0.20. * [1.0: Introdução à Programação com Bitcoin Core e Lightning](01_0_Introduction.md) - * [Prefácio: Introduzindo o Bitcoin](01_1_Introducing_Bitcoin.md) + * [Prefácio: Apresentando o Bitcoin](01_1_Introducing_Bitcoin.md) * [2.0: Configurando um Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) * [2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) - * [2.2: Configurando uma Máquina Bitcoin-Core de Outras Formas](02_2_Setting_Up_Bitcoin_Core_Other.md) + * [2.2: Configurando uma Máquina Bitcoin-Core de Outras Maneiras](02_2_Setting_Up_Bitcoin_Core_Other.md) -### PARTE DOIS: USANDO BITCOIN-CLI +### PARTE DOIS: USANDO O BITCOIN-CLI **Estado:** Finalizado. Atualizado para 0.20. -* [3.0: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md) - * [3.1: Verificando Sua Configuração do Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) - * [3.2: Conhecendo Sua Configuração do Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) - * [3.3: Configurando Sua Carteira](03_3_Setting_Up_Your_Wallet.md) +* [3.0: Compreendendo Nossa Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md) + * [3.1: Verificando Nossa Configuração do Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) + * [3.2: Conhecendo Nossa Configuração do Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) + * [3.3: Configurando Nossa Carteira](03_3_Setting_Up_Your_Wallet.md) * [Prefácio: Usando Variáveis de Linha de Comando](03_3__Interlude_Using_Command-Line_Variables.md) * [3.4: Recebendo uma Transação](03_4_Receiving_a_Transaction.md) * [3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md) @@ -49,7 +49,7 @@ Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuin * [4.6: Criando uma Transação SegWit](04_6_Creating_a_Segwit_Transaction.md) * [5.0: Controlando Transações no Bitcoin](05_0_Controlling_Bitcoin_Transactions.md) * [5.1 Atentando-se para Transações Presas](05_1_Watching_for_Stuck_Transactions.md) - * [5.2: Re-enviando uma Transação com RBF](05_2_Resending_a_Transaction_with_RBF.md) + * [5.2: Reenviando uma Transação com RBF](05_2_Resending_a_Transaction_with_RBF.md) * [5.3: Financiando uma Transação com CPFP](05_3_Funding_a_Transaction_with_CPFP.md) * [6.0: Expandindo Transações no Bitcoin com Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md) * [6.1: Enviando uma Transação com Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md) @@ -58,7 +58,7 @@ Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuin * [7.0: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md) * [7.1: Criando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) * [7.2: Usando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) - * [7.3: Integrando com Carteiras de Hardware](07_3_Integrating_with_Hardware_Wallets.md) + * [7.3: Integrando com Hardware Wallets](07_3_Integrating_with_Hardware_Wallets.md) * [8.0: Expandindo Transações no Bitcoin de Outras Maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md) * [8.1: Enviando uma Transação com um Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) * [8.2: Enviando uma Transação com Dados](08_2_Sending_a_Transaction_with_Data.md) @@ -67,81 +67,81 @@ Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuin **Estado:** Finalizado. Atualizado para 0.20 e btcdeb. -* [9.0: Introduzindo Scripts no Bitcoin](09_0_Introducing_Bitcoin_Scripts.md) - * [9.1: Compreendendo a Fundação de Transações](09_1_Understanding_the_Foundation_of_Transactions.md) - * [9.2: Rodando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md) - * [9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md) +* [9.0: Apresentando os Scripts do Bitcoin](09_0_Introducing_Bitcoin_Scripts.md) + * [9.1: Compreendendo a Base das Transações](09_1_Understanding_the_Foundation_of_Transactions.md) + * [9.2: Executando um Script do Bitcoin](09_2_Running_a_Bitcoin_Script.md) + * [9.3: Testando um Script do Bitcoin](09_3_Testing_a_Bitcoin_Script.md) * [9.4: Programando um P2PKH](09_4_Scripting_a_P2PKH.md) * [9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md) -* [10.0: Embutindo Scripts em Transações P2SH no Bitcoin](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md) - * [10.1: Compreendendo a Fundação do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) +* [10.0: Incorporando Scripts em Transações P2SH no Bitcoin](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md) + * [10.1: Compreendendo a Base do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) * [10.2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md) - * [10.3: Rodando um Script no Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) + * [10.3: Executando um Script do Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) * [10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md) * [10.5: Programando um Script Segwit](10_5_Scripting_a_Segwit_Script.md) * [10.6: Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md) -* [11.0: Capacitando Timelock com Scripts no Bitcoin](11_0_Empowering_Timelock_with_Bitcoin_Scripts.md) - * [11.1: Compreendendo Opções de Timelock](11_1_Understanding_Timelock_Options.md) +* [11.0: Capacitando Timelock com Scripts do Bitcoin](11_0_Empowering_Timelock_with_Bitcoin_Scripts.md) + * [11.1: Compreendendo As Opções de Timelock](11_1_Understanding_Timelock_Options.md) * [11.2: Usando CLTV em Scripts](11_2_Using_CLTV_in_Scripts.md) * [11.3: Usando CSV em Scripts](11_3_Using_CSV_in_Scripts.md) -* [12.0: Expandindo Scripts no Bitcoin](12_0_Expanding_Bitcoin_Scripts.md) - * [12.1: Usando Condicionais de Script](12_1_Using_Script_Conditionals.md) - * [12.2: Usando Outros Comandos de Script](12_2_Using_Other_Script_Commands.md) +* [12.0: Expandindo os Scripts do Bitcoin](12_0_Expanding_Bitcoin_Scripts.md) + * [12.1: Usando Condicionais no Script](12_1_Using_Script_Conditionals.md) + * [12.2: Usando Outros Comandos no Script](12_2_Using_Other_Script_Commands.md) * [13.0: Projetando Scripts Reais no Bitcoin](13_0_Designing_Real_Bitcoin_Scripts.md) * [13.1: Escrevendo Scripts de Quebra-Cabeças](13_1_Writing_Puzzle_Scripts.md) * [13.2: Escrevendo Scripts Complexos de Multisig](13_2_Writing_Complex_Multisig_Scripts.md) * [13.3: Capacitando o Bitcoin com Scripts](13_3_Empowering_Bitcoin_with_Scripts.md) -### PARTE QUATRO: USANDO TOR +### PARTE QUATRO: PRIVACIDADE **Estado:** Finalizado. -* [14.0: Usando Tor](14_0_Using_Tor.md) - * [14.1: Verificando Sua Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) - * [14.2: Mudando Seus Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) - * [14.3: Adicionando SSH aos Seus Serviços Ocultos](14_3_Adding_SSH_Hidden_Services.md) +* [14.0: Usando o Tor](14_0_Using_Tor.md) + * [14.1: Verificando Nossa Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) + * [14.2: Mudando Nossos Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) + * [14.3: Adicionando Serviços SSH Ocultos](14_3_Adding_SSH_Hidden_Services.md) -* [15.0: Usando i2p](15_0_Using_i2p.md) - * [15.1: Bitcoin Core como um Serviço I2P (Invisible Internet Project)](15_1_i2p_service.md) +* [15.0: Usando o I2P](15_0_Using_i2p.md) + * [15.1: Bitcoin Core como um Serviço I2P (Projeto Internet Invisível)](15_1_i2p_service.md) ### PARTE CINCO: PROGRAMANDO COM RPC **Estado:** Finalizado. -* [16.0: Conversando com o Bitcoind com C](15_0_Talking_to_Bitcoind.md) - * [16.1: Acessando o Bitcoind em C com Livrarias RPC](15_1_Accessing_Bitcoind_with_C.md) - * [16.2: Programando o Bitcoind em C com Livrarias RPC](15_2_Programming_Bitcoind_with_C.md) - * [16.3: Recebendo Notificações em C com Livrarias ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) -* [17.0: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md) - * [17.1: Configurando a Libwally](16_1_Setting_Up_Libwally.md) - * [17.2: Usando BIP39 na Libwally](16_2_Using_BIP39_in_Libwally.md) - * [17.3: Usando BIP32 na Libwally](16_3_Using_BIP32_in_Libwally.md) - * [17.4: Usando PSBTs na Libwally](16_4_Using_PSBTs_in_Libwally.md) - * [17.5: Usando Scripts na Libwally](16_5_Using_Scripts_in_Libwally.md) - * [17.6: Usando Outras Funções na Libwally](16_6_Using_Other_Functions_in_Libwally.md) - * [17.7: Integrando Libwally e Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md) -* [18.0: Conversando com o Bitcoind com Outras Linguagens](17_0_Talking_to_Bitcoind_Other.md) - * [18.1: Acessando o Bitcoind com Go](17_1_Accessing_Bitcoind_with_Go.md) - * [18.2: Acessando o Bitcoind com Java](17_2_Accessing_Bitcoind_with_Java.md) - * [18.3: Acessando o Bitcoind com Node JS](17_3_Accessing_Bitcoind_with_NodeJS.md) - * [18.4: Acessando o Bitcoind com Python](17_4_Accessing_Bitcoind_with_Python.md) - * [18.5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md) - * [18.6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md) +* [16.0: Conversando com o Bitcoind com C](16_0_Talking_to_Bitcoind.md) + * [16.1: Acessando o Bitcoind em C com Bibliotecas RPC](16_1_Accessing_Bitcoind_with_C.md) + * [16.2: Programando o Bitcoind em C com Bibliotecas RPC](16_2_Programming_Bitcoind_with_C.md) + * [16.3: Recebendo Notificações em C com Bibliotecas ZMQ](16_3_Receiving_Bitcoind_Notifications_with_C.md) +* [17.0: Programando o Bitcoin com Libwally](17_0_Programming_with_Libwally.md) + * [17.1: Configurando a Libwally](17_1_Setting_Up_Libwally.md) + * [17.2: Usando BIP39 na Libwally](17_2_Using_BIP39_in_Libwally.md) + * [17.3: Usando BIP32 na Libwally](17_3_Using_BIP32_in_Libwally.md) + * [17.4: Usando PSBTs na Libwally](17_4_Using_PSBTs_in_Libwally.md) + * [17.5: Usando Scripts na Libwally](17_5_Using_Scripts_in_Libwally.md) + * [17.6: Usando Outras Funções na Libwally](17_6_Using_Other_Functions_in_Libwally.md) + * [17.7: Integrando Libwally e Bitcoin-CLI](17_7_Integrating_Libwally_and_Bitcoin-CLI.md) +* [18.0: Conversando com o Bitcoind com Outras Linguagens](18_0_Talking_to_Bitcoind_Other.md) + * [18.1: Acessando o Bitcoind com Go](18_1_Accessing_Bitcoind_with_Go.md) + * [18.2: Acessando o Bitcoind com Java](18_2_Accessing_Bitcoind_with_Java.md) + * [18.3: Acessando o Bitcoind com Node JS](18_3_Accessing_Bitcoind_with_NodeJS.md) + * [18.4: Acessando o Bitcoind com Python](18_4_Accessing_Bitcoind_with_Python.md) + * [18.5: Acessando o Bitcoind com Rust](18_5_Accessing_Bitcoind_with_Rust.md) + * [18.6: Acessando o Bitcoind com Swift](18_6_Accessing_Bitcoind_with_Swift.md) -### PARTE SEIS: USANDO LIGHTNING-CLI +### PARTE SEIS: USANDO A LIGHTNING-CLI **Estado:** Finalizado. -* [19.0: Compreendendo Sua Configuração Lightning](18_0_Understanding_Your_Lightning_Setup.md) - * [19.1: Verificando Sua Configuração c-lightning](18_1_Verifying_Your_Lightning_Setup.md) - * [19.2: Conhecendo Sua Configuração c-lightning](18_2_Knowing_Your_lightning_Setup.md) - * [Prefácio: Acessando um Segundo Node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md) - * [19.3: Criando um Canal Lightning](18_3_Setting_Up_a_Channel.md) -* [20.0: Usando Lightning](19_0_Using_Lightning.md) - * [20.1: Gerando um Pedido de Pagamento](19_1_Generate_a_Payment_Request.md) - * [20.2: Pagando uma Fatura](19_2_Paying_a_Invoice.md) - * [20.3: Fechando um Canal Lighnting]((19_3_Closing_a_Channel.md)) - * [20.4: Expandindo a Rede Lightning](19_4_Lightning_Network_Review.md) +* [19.0: Compreendendo Nossa Configuração da Lightning](19_0_Understanding_Your_Lightning_Setup.md) + * [19.1: Verificando Nossa Configuração da c-lightning](19_1_Verifying_Your_Lightning_Setup.md) + * [19.2: Conhecendo Nossa Configuração da c-lightning](19_2_Knowing_Your_lightning_Setup.md) + * [Prefácio: Acessando um Segundo Node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md) + * [19.3: Criando um Canal Lightning](19_3_Setting_Up_a_Channel.md) +* [20.0: Usando a Lightning](20_0_Using_Lightning.md) + * [20.1: Gerando um Invoice](20_1_Generate_a_Payment_Request.md) + * [20.2: Pagando um Invoice](20_2_Paying_a_Invoice.md) + * [20.3: Fechando um Canal Lighnting]((20_3_Closing_a_Channel.md)) + * [20.4: Expandindo a Lightning Network](20_4_Lightning_Network_Review.md) ### APÊNDICES @@ -222,4 +222,4 @@ As seguintes chaves podem ser utilizadas para comunicar informação confidencia | ----------------- | -------------------------------------------------- | | Christopher Allen | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | -Você pode importar uma chave rodando o seguinte comando com a fingerprint daquele indivíduo: `gpg --recv-keys ""` Se certifique de colocar o fingerprint entre aspas caso o mesmo contenha espaços. \ No newline at end of file +Você pode importar uma chave executando o seguinte comando com a fingerprint daquele indivíduo: `gpg --recv-keys ""` Se certifique de colocar o fingerprint entre aspas caso o mesmo contenha espaços. \ No newline at end of file From 5573718e84429f21a635da50d53b49c11aac3400 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 10:58:08 -0300 Subject: [PATCH 127/155] Revise chapter 1 titles, fix typos --- pt/01_0_Introduction.md | 39 ++++++++++++++-------------- pt/01_1_Introducing_Bitcoin.md | 47 +++++++++++++++++----------------- 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/pt/01_0_Introduction.md b/pt/01_0_Introduction.md index 116b7e4..195418e 100644 --- a/pt/01_0_Introduction.md +++ b/pt/01_0_Introduction.md @@ -1,5 +1,4 @@ - -# CAPÍTULO 1: Introdução à Aprendizagem do Bitcoin Core (& Lightning Network) pela linha de comando +# Capítulo 1: Introdução à Aprendizagem do Bitcoin Core (& Lightning) pela Linha de Comando ## Introdução @@ -19,18 +18,18 @@ Você não precisa ser particularmente uma pessoa da área técnica para boa par Uma minoria deste curso requer conhecimento de programação, e você deve pular essas seções, se necessário, conforme iremos discutir na próxima seção. -## Resumo dos tópicos +## Resumo dos Tópicos Este livro é dividido nas seguintes seções: | Parte | Descrição | Habilidades | |-------|---------|---------| -| **Parte 1: Se preparando para o Bitcoin** | Entendendo os fundamentos do Bitcoin e configurando um servidor para uso. | Linha de Comando | -| **Parte 2: Usando o bitcoin-cli** | Usando o Bitcoin-cli para criar transações. | Linha de Comando | -| **Parte 3: Fazendo scripts com Bitcoin** | Expandindo seu trabalho no bitcoin com scripts. | Conceitos de Programação | -| **Parte 4: Usando o Tor** | Melhorando a segurança do _node_ com tor | Linha de Comando | -| **Parte 5: Programando com RPC** | Acessando o RPC com C e outras linguagens. | Programando em C | -| **Parte 6: Usando a lightning-cli** | Usando a Lightning-CLI para criar transações. | Linha de Comando | +| **Parte Um: Se Preparando para o Bitcoin** | Entendendo os fundamentos do Bitcoin e configurando um servidor para uso. | Linha de Comando | +| **Parte Dois: Usando o Bitcoin-CLI** | Usando o Bitcoin-CLI para criar transações. | Linha de Comando | +| **Parte Três: Programando no Bitcoin** | Expandindo nosso trabalho no Bitcoin com scripts. | Conceitos de Programação | +| **Parte Quatro: Privacidade** | Melhorando a segurança do nosso node com Tor ou I2P | Linha de Comando | +| **Parte Cinco: Programando com RPC** | Acessando o RPC com C e outras linguagens. | Programando em C | +| **Parte Seis: Usando a Lightning-CLI** | Usando a Lightning-CLI para criar transações. | Linha de Comando | | **Apêndices.** | Utilizando configurações incomuns no Bitcoin. | Linha de Comando | ## Como Usar Este Curso @@ -39,12 +38,12 @@ Então, por onde você começa? Este livro é destinado principalmente para ser Se você tem diferentes níveis de habilidade ou se quiser aprender coisas diferentes, poderá pular para algumas partes diferentes do livro: -* Se você já tem um ambiente pronto do Bitcoin para ser utilizado, vá para o [Capítulo 3: Entendendo sua configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). -* Se você só se importa com os Scriptos em Bitcoin, pule para o [Capítulo 9: Apresentando os Scripts no Bitcoin](09_0_Introducing_Bitcoin_Scripts.md). -* Se você quiser apenas ler sobre o uso das linguagens de programação, pule para o [Capítulo 15: Falando com o Bitcoin](15_0_Talking_to_Bitcoind.md). -* Se não quer programar nada, definitivamente ignore os capítulos 15 ao 17 enquanto estiver lendo, e talvez seja melhor pular os capítulos 9 ao 13. O resto do curso ainda deve fazer sentido sem eles. -* Se estiver interessado apenas na Lightning Network, corra para o [Capítulo 18: Entendendo sua configuração da Lightning Network](18_0_Understanding_Your_Lightning_Setup.md). -* Se quiser ler o conteúdo novo adicionado na versão 2 do curso (2020), seguido da versão 1 (2017), leia [§3.5: Entendendo o descritor](03_5_Understanding_the_Descriptor.md), [§4.6: Criando uma transação SegWit](04_6_Creating_a_Segwit_Transaction.md), [Capítulo 7: Expandindo o Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md), [§9.5: Criando um script P2WPKH](09_5_Scripting_a_P2WPKH.md), [§10.5: Criando um script SegWit](10_5_Scripting_a_Segwit_Script.md), [Capítulo 14: Usando o Tor](14_0_Using_Tor.md), [Capítulo 15: Conversando com o Bitcoin com C](15_0_Talking_to_Bitcoind.md), [Capítulo 16: Programando com Libwally](16_0_Programming_with_Libwally.md), [Capítulo 17: Conversando com o Bitcoind usando outras linguagens](17_0_Talking_to_Bitcoind_Other.md), [Capítulo 18: Entendendo sua configuração da Lightning ](18_0_Understanding_Your_Lightning_Setup.md), e [Capítulo 19: Usando a Lightning](19_0_Using_Lightning.md). +* Se você já tem um ambiente pronto do Bitcoin para ser utilizado, vá para o [Capítulo 3: Compreendendo Nossa Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). +* Se você só se importa com programar no Bitcoin, pule para o [Capítulo 9: Apresentando os Scripts do Bitcoin](09_0_Introducing_Bitcoin_Scripts.md). +* Se você quiser apenas ler sobre o uso das linguagens de programação, pule para o [Capítulo 16: Conversando com o Bitcoind com C](16_0_Talking_to_Bitcoind.md). +* Se não quer programar nada, definitivamente ignore os capítulos 16 ao 18 enquanto estiver lendo, e talvez seja melhor pular os capítulos 9 ao 13. O resto do curso ainda deve fazer sentido sem eles. +* Se estiver interessado apenas na Lightning Network, corra para o [Capítulo 19: Compreendendo Nossa Configuração da Lightning](19_0_Understanding_Your_Lightning_Setup.md). +* Se quiser ler o conteúdo novo adicionado na versão 2 do curso (2020), seguido da versão 1 (2017), leia [§3.5: Entendendo o Descritor](03_5_Understanding_the_Descriptor.md), [§4.6: Criando uma Transação SegWit](04_6_Creating_a_Segwit_Transaction.md), [Capítulo 7: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md), [§9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md), [§10.5: Programando um Script SegWit](10_5_Scripting_a_Segwit_Script.md), [Capítulo 14: Usando o Tor](14_0_Using_Tor.md), [Capítulo 16: Conversando com o Bitcoind com C](16_0_Talking_to_Bitcoind.md), [Capítulo 17: Programando o Bitcoin com Libwally](17_0_Programming_with_Libwally.md), [Capítulo 18: Conversando com o Bitcoind com Outras Linguagens](18_0_Talking_to_Bitcoind_Other.md), [Capítulo 19: Compreendendo Nossa Configuração da Lightning](19_0_Understanding_Your_Lightning_Setup.md), e [Capítulo 20: Usando a Lightning](20_0_Using_Lightning.md). ## Por Que Utilizar Este Curso @@ -52,13 +51,13 @@ Obviamente, você está querendo fazer este curso porque está interessado no Bi ## Como Ajudar Este Curso -* Por favor, use a área de [Issues](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) para quaisquer dúvidas. A Blockchain Commons não tem uma equipe ativa de suporte, e não podemos abordar problemas ou perguntas individuais, mas olharemos iremos tratá-los com o tempo e os usaremos para melhorar nossas futuras iterações no curso. +* Por favor, use a área de [Issues](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) para quaisquer dúvidas. A Blockchain Commons não tem uma equipe ativa de suporte, e não podemos abordar problemas ou perguntas individuais, mas iremos tratá-los com o tempo e os usaremos para melhorar nossas futuras iterações no curso. * Por favor, use os [PRs](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/pulls) para quaisquer correções de erros de digitação ou comandos incorretos (ou que foram alterados). Para alterações técnicas ou de linha de comando, é muito útil se você usar também os comentários para explicar por que fez o que você fez, para que não precisemos gastar tempo pesquisando o motivo. -* Por favor, use nossa [Área de Discussão da Comunidade](https://github.com/BlockchainCommons/Community/discussions) para falar sobre carreiras e habilidades. A Blockchain Commons ocasionalmente oferece estágios, como falado em nosso repo da comunidade. -* Por favor, [torne-se um patrono](https://github.com/sponsors/BlockchainCommons) se achar este curso útil ou se quiser ajudar a educar a próxima geração de programadores da blockchain. +* Por favor, use nossa [Área de Discussão da Comunidade](https://github.com/BlockchainCommons/Community/discussions) para falar sobre carreiras e habilidades. A Blockchain Commons ocasionalmente oferece estágios, como falado em nosso repositório da comunidade. +* Por favor, [torne-se um patrocinador](https://github.com/sponsors/BlockchainCommons) se achar este curso útil ou se quiser ajudar a educar a próxima geração de programadores da blockchain. ## O Que Vem Depois? -Se você quiser uma introdução básica ao Bitcoin, criptografia de chave pública, ECC, blockchains e Lightning Network, leia o prefácio [Introdução ao Bitcoin](01_1_Introducing_Bitcoin.md). +Se você quiser uma introdução básica ao Bitcoin, criptografia de chave pública, ECC, blockchains e Lightning Network, leia o prefácio [Apresentando o Bitcoin](01_1_Introducing_Bitcoin.md). -Caso contrário, se já estiver pronto para mergulhar de cabeça no curso, vá para [Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md). +Caso contrário, se já estiver pronto para mergulhar de cabeça no curso, vá para [Configurando um Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md). diff --git a/pt/01_1_Introducing_Bitcoin.md b/pt/01_1_Introducing_Bitcoin.md index 5408df8..94fc136 100644 --- a/pt/01_1_Introducing_Bitcoin.md +++ b/pt/01_1_Introducing_Bitcoin.md @@ -1,4 +1,3 @@ - # Prefácio: Apresentando o Bitcoin Antes de começar a programar em Bitcoin (e Lightning), você deve ter uma compreensão básica do que são e como funcionam. Esta seção fornece essa visão geral. Várias outras definições irão aparecer mais à frente. O objetivo deste capítulo é apenas dar o conteúdo base. @@ -25,11 +24,11 @@ Os fundos são protegidos pelo uso de hashes. As chaves públicas não são real No entanto, esses scripts do Bitcoin são o nível mais baixo de funcionalidade deste protocolo. Grande parte do trabalho do Bitcoin é feito através do `bitcoind` do Bitcoin, que é controlado por meio de comandos RPC. Muitas pessoas enviam esses comandos RPC por meio do programa chamado `bitcoin-cli`, que fornece uma interface ainda mais simples. Os não programadores nem mesmo se preocupam com essas minúcias, permitindo o uso de carteiras programáveis com interfaces mais simples. -### Resumindo o Bitcoin +### Bitcoin –– Em Resumo Uma maneira de pensar no Bitcoin é como _uma sequência de transações atômicas_. Cada transação é autenticada por um remetente com a solução para um quebra-cabeça criptográfico anterior que foi armazenado como um script. A nova transação é bloqueada para o destinatário com um novo quebra-cabeça criptográfico que também é armazenado como um script. Cada transação é registrada no livro razão global imutável. -## Sobre criptografia de chave pública +## Sobre Criptografia de Chave Pública A criptografia de chave pública é um sistema matemático para proteção de dados e comprovação de propriedade por meio de um par assimétrico de chaves que estão vinculadas entre si: a chave pública e a chave privada. @@ -45,15 +44,15 @@ A criptografia de chave pública é um sistema matemático para proteção de da O Bitcoin aproveita a capacidade do hash de disfarçar os dados originais, o que permite ocultar a chave pública real do usuário, tornando as transações resistentes à computação quântica. -### Resumindo a criptografia de chave pública +### Criptografia de Chave Pública –– Em Resumo Uma maneira de pensar na criptografia de chave pública é: _um jeito de qualquer pessoa proteger os dados de forma que apenas uma pessoa autorizada possa acessá-los e também possa provar que tem esse acesso._ ## Sobre CCE -O CCE é um acrônimo para criptografia de curva elíptica. É um ramo específico da criptografia de chave pública que depende de cálculos matemáticos usando curvas elípticas definidas sobre campos finitos. É mais complexo e difícil de explicar do que a criptografia de chave pública clássica (que usava números primos), mas tem algumas vantagens interessantes. +CCE é um acrônimo para criptografia de curva elíptica(em inglês: ECC, ou Elliptic-Curve Cryptography). É um ramo específico da criptografia de chave pública que depende de cálculos matemáticos usando curvas elípticas definidas sobre campos finitos. É mais complexo e difícil de explicar do que a criptografia de chave pública clássica (que usava números primos), mas tem algumas vantagens interessantes. -O CCE não terá tanta atenção neste tutorial. Isso porque falaremos mais sobre a integração com servidores Bitcoin Core e Lightning, que já cuidaram da parte criptografia para você. Na verdade, a intenção deste tutorial é que você não precise se preocupar com a criptografia, porque isso é algo que você _realmente_ deseja que os especialistas lidem. +A CCE não receberá tanta atenção neste tutorial. Isso porque falaremos mais sobre a integração com servidores Bitcoin Core e Lightning, que já cuidaram da parte criptografia para você. Na verdade, a intenção deste tutorial é que você não precise se preocupar com a criptografia, porque isso é algo que você _realmente_ deseja que os especialistas lidem. **_O que é uma curva elíptica?_** Uma curva elíptica é uma curva geométrica que assume a forma ``y`` `` 2`` = ``x`` ``3`` `` + ax + b``. Uma curva elíptica específica é escolhida selecionando valores específicos de ``a`` e ``b``. A curva deve ser examinada cuidadosamente para determinar se funciona bem para criptografia. Por exemplo, a curva secp256k1 usada pelo Bitcoin é definida como ``a = 0`` e ``b = 7``. @@ -67,11 +66,11 @@ Qualquer linha que cruze uma curva elíptica o fará em 1 ou 3 pontos... e essa Essa metodologia específica também explica por que os campos finitos são usados ​​em curvas elípticas: Ela garante que a chave privada não ficará muito grande. Observe que o campo finito para secp256k1 é ligeiramente menor que 256 bits, o que significa que todas as chaves públicas terão 256 bits, assim como as chaves privadas. -**_Quais são as vantagens do CCE?_** A principal vantagem do CCE é que ele permite a mesma segurança da criptografia de chave pública clássica com uma chave muito menor. Uma chave pública de curva elíptica de 256 bits corresponde a uma chave pública tradicional (RSA) de 3072 bits. +**_Quais são as vantagens da CCE?_** A principal vantagem da CCE é que ele permite a mesma segurança da criptografia de chave pública clássica com uma chave muito menor. Uma chave pública de curva elíptica de 256 bits corresponde a uma chave pública tradicional (RSA) de 3072 bits. -### Resumindo o CCE +### CCE –– Em Resumo -Uma maneira de pensar no CCE é: _Um jeito de permitir a criptografia de chave pública usando chaves muito pequenas e uma matemática bem obscura._ +Uma maneira de pensar na CCE é: _um jeito de permitir a criptografia de chave pública usando chaves muito pequenas e uma matemática bem obscura._ ## Sobre Blockchains @@ -83,16 +82,16 @@ Embora precise entender os fundamentos de como uma blockchain funciona para ente **_O que é um fork?_** Ocasionalmente, dois blocos são criados ao mesmo tempo. Isso cria, temporariamente, um fork de um bloco, onde qualquer um dos blocos atuais pode ser o "verdadeiro". De vez em quando, um fork pode se expandir para dois blocos, três blocos ou mesmo quatro blocos de comprimento, mas muito rapidamente um lado da bifurcação é determinado como o verdadeiro e o outro se torna o que chamamos de "órfão". Isso faz parte do processo estocástico de criação de bloco e demonstra por que vários blocos devem ser construídos sobre um bloco antes que ele possa ser considerado verdadeiramente confiável e não rejeitável. -### Resumindo a blockchain +### Blockchain –– Em Resumo Uma maneira de pensar na blockchain é: _Uma série vinculada de blocos de dados imutáveis, até o seu bloco inicial._ Outra forma é: _Uma série de blocos vinculados para ordenar dados absolutos que podem ser conflitantes_. -## A Blockchain é adequada para mim? +## A Blockchain é Adequada para Mim? Se você deseja negociar bitcoins, então obviamente a Bitcoin é adequada para você. No entanto, de forma mais ampla, a blockchain se tornou uma cultura pop da atualidade, embora não seja uma solução mágica para todos os problemas técnicos. Dito isso, existem muitas situações específicas em que a blockchain é uma tecnologia superior. -Blockchains provavelmente _são_ úteis nos seguintes casos: +Blockchains provavelmente _serão_ úteis nos seguintes casos: * Os usuários não confiam uns nos outros. * Ou: Os usuários estão em diferentes localidades. @@ -119,32 +118,32 @@ Blockchains provavelmente _não_ serão úteis caso: Observe que ainda pode haver soluções para algumas dessas situações dentro do ecossistema Bitcoin. Por exemplo, os canais de pagamento estão lidando rapidamente com questões de liquidez e finalização do pagamento. -## Sobre a Lightning (Network) +## Sobre a Lightning -A lightning é um protocolo de segunda camada que interage com o Bitcoin para permitir que os usuários troquem seus bitcoins "offchain" (fora da blockchain). Possui vantagens e desvantagens em relação ao uso da camada principal do Bitcoin. +A Lightning é um protocolo de segunda camada que interage com o Bitcoin para permitir que os usuários troquem seus bitcoins "offchain" (fora da blockchain). Possui vantagens e desvantagens em relação ao uso da camada principal do Bitcoin. -A lightning também é um dos focos deste tutorial. Embora o ponto principal seja sobre a interação direta com o Bitcoin (e o `bitcoind`), vamos falar um pouco sobre a lightning e o porque é uma tecnologia que está prestes a se tornar uma alternativa popular ao Bitcoin, em um futuro próximo. Este livro tem a mesma abordagem para a lightning e para o Bitcoin: Ele ensina como interagir diretamente com a Lightning de maneira confiável à partir da linha de comando. +A Lightning também é um dos focos deste tutorial. Embora o ponto principal seja sobre a interação direta com o Bitcoin (e o `bitcoind`), vamos falar um pouco sobre a Lightning e o porque é uma tecnologia que está prestes a se tornar uma alternativa popular ao Bitcoin, em um futuro próximo. Este livro tem a mesma abordagem para a Lightning e para o Bitcoin: Ele ensina como interagir diretamente com a Lightning de maneira confiável à partir da linha de comando. -Ao contrário do Bitcoin, existem várias variantes da lightning. Este tutorial usa a implementação compatível do padrão [C-lightning](https://github.com/ElementsProject/lightning) como sendo seu servidor lightning confiável. +Ao contrário do Bitcoin, existem várias variantes da Lightning. Este tutorial usa a implementação compatível do padrão [c-lightning](https://github.com/ElementsProject/lightning) como sendo seu servidor Lightning confiável. -**_O que é um protocolo de segunda camada?_** Um protocolo de segunda camada no Bitcoin funciona tendo como base o Bitcoin. Nesse caso, a lightning trabalha em cima do Bitcoin, interagindo com ele por meio de contratos inteligentes. +**_O que é um protocolo de segunda camada?_** Um protocolo de segunda camada no Bitcoin funciona tendo como base o Bitcoin. Nesse caso, a Lightning trabalha em cima do Bitcoin, interagindo com ele por meio de contratos inteligentes. -**_O que é um canal lightning?_** Um canal Lightning é uma conexão entre dois usuários utilizando a lightning. Cada um dos usuários bloqueia uma quantidade de bitcoins na blockchain do Bitcoin usando uma assinatura multi-sig, criada e assinada por ambos. Os dois usuários podem, então, trocar bitcoins por meio do canal lightning sem precisar gravar nada na blockchain Bitcoin. Somente quando desejam fechar o canal, eles liquidam os bitcoins, com base na divisão no saldo final das partes. +**_O que é um canal Lightning?_** Um canal Lightning é uma conexão entre dois usuários utilizando a Lightning. Cada um dos usuários bloqueia uma quantidade de bitcoins na blockchain do Bitcoin usando uma assinatura multi-sig, criada e assinada por ambos. Os dois usuários podem, então, trocar bitcoins por meio do canal Lightning sem precisar gravar nada na blockchain Bitcoin. Somente quando desejam fechar o canal, eles liquidam os bitcoins, com base na divisão no saldo final das partes. -**_O que é a Lightning Network?_** A junção de todos os canais da lightning criam a Lightning Network. Isso permite que dois usuários que não tenham um canal entre si troquem bitcoins usando Lightning: O protocolo forma uma cadeia de canais entre os dois usuários e, em seguida, troca as moedas através da cadeia usando transações que chamamos de _time-locked transactions_. +**_O que é a Lightning Network?_** A junção de todos os canais da Lightning criam a Lightning Network. Isso permite que dois usuários que não tenham um canal entre si troquem bitcoins usando Lightning: O protocolo forma uma cadeia de canais entre os dois usuários e, em seguida, troca as moedas através da cadeia usando transações que chamamos de _time-locked transactions_. -**_Quais são as vantagens da lightning?_** A lightning permite transações mais rápidas com taxas mais baixas. Isso cria a possibilidade real de micropagamentos usando bitcoin. Ela também oferece maior privacidade, uma vez que está fora da rede, com apenas o primeiro e o último estado da transação sendo gravados blockchain do Bitcoin. +**_Quais são as vantagens da Lightning?_** A Lightning permite transações mais rápidas com taxas mais baixas. Isso cria a possibilidade real de micropagamentos usando bitcoin. Ela também oferece maior privacidade, uma vez que está fora da rede, com apenas o primeiro e o último estado da transação sendo gravados blockchain do Bitcoin. -**_Quais são as desvantagens do Lightning?_** A lightning ainda é uma tecnologia muito nova e não foi testada tão exaustivamente quanto o Bitcoin. Isso não é apenas uma questão de implementação tecnológica, mas também se o design que pode ser manipulado de maneiras não pensadas anteriormente. +**_Quais são as desvantagens do Lightning?_** A Lightning ainda é uma tecnologia muito nova e não foi testada tão exaustivamente quanto o Bitcoin. Isso não é apenas uma questão de implementação tecnológica, mas também se o design que pode ser manipulado de maneiras não pensadas anteriormente. -### Resumindo a lightning +### Resumindo a Lightning Uma maneira de pensar na Lightning é: _Um jeito de transacionar bitcoins usando canais offchain entre duas pessoas, de modo que apenas o primeiro e o último estado precisem ser gravados na blockchain_. ## Resumo: Apresentando o Bitcoin -O Bitcoin é um sistema _peer-to-peer_ que permite a transferência de fundos por meio de transações bloqueadas por quebra-cabeças. Esses quebra-cabeças dependem da criptografia de curva elíptica de chave pública. Quando você generaliza as ideias por trás do Bitcoin, encontra-se as blockchains, uma tecnologia que atualmente está crescendo e inovando muitos setores. Quando você expande as ideias por trás do Bitcoin, obtém protocolos de segunda camada, como a lightning, que expandem o potencial da moeda. +O Bitcoin é um sistema _peer-to-peer_ que permite a transferência de fundos por meio de transações bloqueadas por quebra-cabeças. Esses quebra-cabeças dependem da criptografia de curva elíptica de chave pública. Quando você generaliza as ideias por trás do Bitcoin, encontra-se as blockchains, uma tecnologia que atualmente está crescendo e inovando muitos setores. Quando você expande as ideias por trás do Bitcoin, obtém protocolos de segunda camada, como a Lightning, que expandem o potencial da moeda. ## O Que Vem Depois? -Vamos avançar para "se preparar para o Bitcoin" com o [Capítulo Dois: Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md). \ No newline at end of file +Vamos avançar em "Se Prepararando para o Bitcoin" com o [Capítulo Dois: Configurando um Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md). \ No newline at end of file From 66228ec5b9d751d6ae0fe9e37776a6a2fca06f8a Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 10:58:33 -0300 Subject: [PATCH 128/155] Revise chapter 2 titles, fix typos --- pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md | 7 +++---- pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md | 6 +++--- pt/02_2_Setting_Up_Bitcoin_Core_Other.md | 6 +++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md b/pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md index 5f5ae45..3821479 100644 --- a/pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md +++ b/pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md @@ -1,5 +1,4 @@ - -# Capítulo 2: Configurando um Bitcoin-Core no VPS +# Capítulo 2: Configurando um Bitcoin-Core VPS Para começar a usar o Bitcoin, primeiro precisamos configurar uma máquina que execute o Bitcoin. Os artigos neste capítulo descrevem como fazer isso, principalmente usando um VPS (Virtual Private Server). @@ -23,5 +22,5 @@ Os objetivos secundários incluem a capacidade de: Na verdade, não é preciso ler este capítulo inteiro. Decida se gostaria de executar um StackScript para configurar um node em um VPS Linode (§2.2); Ou você deseja configurar em um ambiente diferente, como em uma máquina AWS ou um Mac (§2.3). Em seguida, vá para a seção mais apropriada. Informações adicionais sobre nossas configurações sugeridas também podem ser encontradas no [Apêndice I](A1_0_Understanding_Bitcoin_Standup.md). - * [Seção Um: Configurando um Bitcoin Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) - * [Seção Dois: Configurando uma máquina Bitcoin Core usando outros meios](02_2_Setting_Up_Bitcoin_Core_Other.md) \ No newline at end of file + * [Seção Um: Configurando um Bitcoin-Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) + * [Seção Dois: Configurando uma Máquina Bitcoin-Core de Outras Maneiras](02_2_Setting_Up_Bitcoin_Core_Other.md) \ No newline at end of file diff --git a/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md b/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md index 3b6dc34..62afee9 100644 --- a/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md +++ b/pt/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md @@ -1,4 +1,4 @@ -# 2.1: Configurando um Bitcoin Core VPS com Bitcoin Standup +# 2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup Este documento explica como configurar um VPS (Virtual Private Server, ou no português, Servidor Privado Virtual) para rodar um node do Bitcoin usando o Linode.com, instalado usando um StackScript automatizado do [projeto Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Apenas precisamos copiar e colar alguns comandos e inicializar o VPS. Quase que imediatamente após a inicialização, encontraremos o nosso novo node do Bitcoin baixando os blocos. @@ -227,7 +227,7 @@ Mas quando estabilizar em um número, estaremos prontos para continuar! Mesmo assim, pode ser uma boa hora para mais alguns cafézinhos. Mas logo logo o nosso sistema estará pronto, e nós também! -## Resumo: Configurando um Bitcoin Core VPS Manualmente +## Resumo: Configurando um Bitcoin-Core VPS Manualmente Criar um Bitcoin Core VPS com os scripts Standup fizeram com que todo o processo fique rápido, simples, e (esperamos), indolor. @@ -238,7 +238,7 @@ Temos algumas opções para o que podemos seguir: * Ler o [StackScript](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) para entender a configuração; * Ler o que o StackScript faz no [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md); * Escolher uma metodologia inteiramente alternativa, como descrito na seção [§2.2: Configurando uma Máquina Bitcoin-Core de Outras Maneiras](02_2_Setting_Up_Bitcoin_Core_Other.md); - * Usar o "bitcoin-cli" com o [Capítulo Três: Compreendendo a Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). + * Usar o "bitcoin-cli" com o [Capítulo Três: Compreendendo Nossa Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). ## Sinopse: Tipos de Instalação do Bitcoin diff --git a/pt/02_2_Setting_Up_Bitcoin_Core_Other.md b/pt/02_2_Setting_Up_Bitcoin_Core_Other.md index 1e083b9..ebda189 100644 --- a/pt/02_2_Setting_Up_Bitcoin_Core_Other.md +++ b/pt/02_2_Setting_Up_Bitcoin_Core_Other.md @@ -1,6 +1,6 @@ -# 2.2: Configurando uma Máquina Bitcoin Core de Outras Maneiras +# 2.2: Configurando uma Máquina Bitcoin-Core de Outras Maneiras -A seção anterior, [§2.1: Configurando um Bitcoin Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), assumimos que iríamos criar um full node em um VPS usando um StackScript Linode. Entretanto, podemos querer criar uma instância do Bitcoin Core via qualquer outra metodologia a nossa escolha e ainda assim acompanhar as próximas etapas deste tutorial. +A seção anterior, [§2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), assumimos que iríamos criar um full node em um VPS usando um StackScript Linode. Entretanto, podemos querer criar uma instância do Bitcoin Core via qualquer outra metodologia a nossa escolha e ainda assim acompanhar as próximas etapas deste tutorial. A seguir estão outras metodologias de configuração das quais temos conhecimento: @@ -15,4 +15,4 @@ A seguir estão outras metodologias de configuração das quais temos conhecimen A não ser que queiramos retornar a alguma das outras metodologias de criação de um node Bitcoin Core, devemos: - * Seguir em frente usando o "bitcoin-cli" com o [Capítulo Três: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). + * Seguir em frente para o "bitcoin-cli" com o [Capítulo Três: Compreendendo Nossa Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). From ed9557875f91d6a4f8f0d4c965fbc7a8a786f946 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 10:58:55 -0300 Subject: [PATCH 129/155] Revise chapter 3 titles, fix typos --- pt/03_0_Understanding_Your_Bitcoin_Setup.md | 16 ++++++++-------- pt/03_1_Verifying_Your_Bitcoin_Setup.md | 13 ++++++------- pt/03_2_Knowing_Your_Bitcoin_Setup.md | 13 ++++++------- pt/03_3_Setting_Up_Your_Wallet.md | 17 ++++++++--------- ...3__Interlude_Using_Command-Line_Variables.md | 6 +++--- 5 files changed, 31 insertions(+), 34 deletions(-) diff --git a/pt/03_0_Understanding_Your_Bitcoin_Setup.md b/pt/03_0_Understanding_Your_Bitcoin_Setup.md index 5bea404..1814070 100644 --- a/pt/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/pt/03_0_Understanding_Your_Bitcoin_Setup.md @@ -1,8 +1,8 @@ -# Capítulo 3: Compreendendo a configuração do node Bitcoin +# Capítulo 3: Compreendendo Nossa Configuração do Bitcoin Agora que estamos prontos para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que entendamos a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. -Neste e nos próximos capítulos, presumimos que uma VPS com Bitcoin instalado esteja sendo utilizada, e que iremos executar o `bitcoind`. Também presumimos que estamos conectados à testnet, permitindo o acesso a bitcoins sem usar fundos reais. Podemos fazer isso com Bitcoin Standup em linode.com, como vimos na sessão [2.1: Configurando um Bitcoin-Core no VPS c Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou usando os demais métodos, descritos na sessão [2.2: Configurando um node Bitcoin Core por outros métodos](02_2_Setting_Up_Bitcoin_Core_Other.md). +Neste e nos próximos capítulos, presumimos que uma VPS com Bitcoin instalado esteja sendo utilizada, e que iremos executar o `bitcoind`. Também presumimos que estamos conectados à testnet, permitindo o acesso a bitcoins sem usar fundos reais. Podemos fazer isso com Bitcoin Standup em linode.com, como vimos na sessão [2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou usando os demais métodos, descritos na sessão [2.2: Configurando uma Máquina Bitcoin Core de Outras Maneiras](02_2_Setting_Up_Bitcoin_Core_Other.md). ## Objetivos deste Capítulo @@ -23,9 +23,9 @@ Os objetivos secundários incluem a capacidade de: ## Tabela de Conteúdo -* [Seção Um: Verificando a configuração do seu node Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) -* [Seção Dois: conhecendo a configuração do seu node Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) -* [Seção Três: Configurando sua carteira](03_3_Setting_Up_Your_Wallet.md) - * [Usando variável de linha de comando](03_3__Interlude_Using_Command-Line_Variables.md) -* [Seção Quatro: Recebendo uma transação](03_4_Receiving_a_Transaction.md) -* [Seção Cinco: Entendendo um descritor](03_5_Understanding_the_Descriptor.md) \ No newline at end of file +* [Seção Um: Verificando Nossa Configuração do Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) +* [Seção Dois: Conhecendo Nossa Configuração do Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) +* [Seção Três: Configurando Nossa Carteira](03_3_Setting_Up_Your_Wallet.md) + * [Usando Variáveis de Linha de Comando](03_3__Interlude_Using_Command-Line_Variables.md) +* [Seção Quatro: Recebendo uma Transação](03_4_Receiving_a_Transaction.md) +* [Seção Cinco: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md) \ No newline at end of file diff --git a/pt/03_1_Verifying_Your_Bitcoin_Setup.md b/pt/03_1_Verifying_Your_Bitcoin_Setup.md index 528af90..8526730 100644 --- a/pt/03_1_Verifying_Your_Bitcoin_Setup.md +++ b/pt/03_1_Verifying_Your_Bitcoin_Setup.md @@ -1,9 +1,8 @@ - -# 3.1: Verificando a configuração do node Bitcoin +# 3.1: Verificando Nossa Configuração do Bitcoin Antes de começarmos a brincar com Bitcoin, devemos nos certificar de que tudo está configurado corretamente. -## Crie os aliases +## Crie os Aliases Sugerimos a criação de alguns aliases (um tipo de atalho) para facilitar o uso do Bitcoin. @@ -32,7 +31,7 @@ standup 455 1.3 34.4 3387536 1392904 ? SLsl Jun16 59:30 /usr/local/bin/ Se ele não estiver listado, podemos executar o `/usr/local/bin/bitcoind -daemon` manualmente e também colocá-lo em crontab. -## Verificando os blocos +## Verificando os Blocos Vamos partir do pressuposto que já tenhamos baixado todo o blockchain antes de começarmos a brincar. Basta executar o comando `bitcoin-cli getblockcount` para ver tudo está carregado corretamente. ``` @@ -59,7 +58,7 @@ $ btcblock Se a nossa blockchain não estiver atualizada, mas nosso `getblockcount` estiver aumentando, não há problema. O tempo total de download pode levar de uma a várias horas, dependendo da configuração. -## Opcional: Conhecendo os tipos de servidores +## Opcional: Conhecendo os Tipos de Servidores > **TESTNET vs MAINNET:** Ao configurar o node Bitcoin, precisamos escolher se vamos criá-lo como sendo um Mainnet, Testnet ou Regtest. Embora este documento presuma uma configuração de Testnet, vale a pena entender como podemos acessar e usar os outros tipos de configuração, inclusive, como ter todos na mesma máquina! Mas, se formos iniciantes, podemos pular isso, pois não é necessário para uma configuração básica. @@ -95,10 +94,10 @@ EOF ``` Para ainda mais complexidade, podemos fazer com que cada um dos aliases 'start' use o sinalizador -conf para carregar a configuração de um arquivo diferente. Isso vai muito além do escopo deste tutorial, mas o oferecemos como um ponto de partida para quando nossas explorações de Bitcoin atingirem o próximo nível. -## Resumo do Verificando a configuração do seu node Bitcoin +## Resumo: Verificando Nossa Configuração do Bitcoin Antes de começar a brincar com o Bitcoin, devemos nos certificar de que nossos aliases estão configurados, nosso bitcoind está rodando e os blocos foram baixados. Também podemos querer configurar algum acesso a configurações alternativas de Bitcoin, se formos usuários mais avançados. ## O Que Vem Depois? -Continue "Understanding Your Bitcoin Setup" com [3.2: Knowing Your Bitcoin Setup](03_2_Knowing_Your_Bitcoin_Setup.md). \ No newline at end of file +Continue "Compreendendo Nossa Configuração do Bitcoin" com [3.2: Conhecendo Nossa Configuração do Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md). \ No newline at end of file diff --git a/pt/03_2_Knowing_Your_Bitcoin_Setup.md b/pt/03_2_Knowing_Your_Bitcoin_Setup.md index a1123a7..2b18d18 100644 --- a/pt/03_2_Knowing_Your_Bitcoin_Setup.md +++ b/pt/03_2_Knowing_Your_Bitcoin_Setup.md @@ -1,9 +1,8 @@ - -# 3.2: Conhecendo a configuração do node Bitcoin +# 3.2: Conhecendo Nossa Configuração do Bitcoin Antes de começarmos a brincar com Bitcoin, é sempre bom entender melhor nossa configuração. -## Conhecendo o diretório do Bitcoin +## Conhecendo o Diretório do Bitcoin Para começar, devemos entender onde tudo está guardado: O diretório `~/.bitcoin`. @@ -24,7 +23,7 @@ Não deve mexer com a maioria desses arquivos e diretórios, particularmente os > :link: **TESTNET vs MAINNET:** Se estivermos usando a Mainnet, então _tudo_ será colocado no diretório principal `~/.bitcoin`. Então se estivermos usando a Mainnet, Testnet e a Regtest, veremos que o `~/.bitcoin` contém nosso arquivo de configuração e nossos dados da mainnet, o diretório `~/.bitcoin/testnet3` contém nossos dados da Testnet, e o diretório `~/.bitcoin/regtest` contém os dados do regtest. -## Conhecendo os comandos do Bitcoin-cli +## Conhecendo os Comandos do Bitcoin-CLI A maior parte do nosso trabalho inicial será feito com o comando `bitcoin-cli`, que oferece uma interface simples para o `bitcoind`. Se quisermos mais informações sobre como utilizá-lo, basta executá-lo com o argumento `help`. Sem nenhum outro argumento, ele mostrara todos os possíveis comandos: ``` @@ -202,7 +201,7 @@ Examples: ``` > :book: ***O que é o RPC?*** O`bitcoin-cli` é apenas uma interface útil que permite enviar comandos para o`bitcoind`. Mais especificamente, é uma interface que permite enviar comandos RPC (Remote Procedure Protocol ou, protocolo de procedimento remoto, no português) para o `bitcoind`. Frequentemente, o comando `bitcoin-cli` e o comando RPC possuem nomes e interfaces idênticos, mas alguns comandos no `bitcoin-cli` fornecem atalhos para solicitações RPC mais complexas. Geralmente, a interface `bitcoin-cli` é muito mais limpa e simples do que tentar enviar comandos RPC manualmente, usando `curl` ou algum outro método. No entanto, ele também tem limitações quanto ao que podemos fazer. -## Opcional: Conhecendo as informações do node Bitcoin +## Opcional: Conhecendo as Informações do Node Bitcoin Uma variedade de comandos bitcoin-cli podem fornecer informações adicionais sobre nossos node Bitcoin. Os mais comuns são: @@ -307,10 +306,10 @@ $ bitcoin-cli getnetworkinfo Vamos testar à vontade qualquer um deles e usar `bitcoin-cli help` se quisermos saber mais informações sobre o que qualquer um deles faz. -## Resumo do Conhecendo a configuração do seu node Bitcoin +## Resumo: Conhecendo Nossa Configuração do Bitcoin O diretório `~/.bitcoin` contém todos os arquivos, enquanto o `bitcoin-cli help` nos retorna uma variedade de informações de comandos que podem ser usados para obter mais informações sobre como nossa configuração e o Bitcoin funcionam. ## O Que Vem Depois? -Vamos continuar "Compreendendo a configuração do node Bitcoin" na sessão [3.3: Configurando nossa carteira](03_3_Setting_Up_Your_Wallet.md). \ No newline at end of file +Vamos continuar "Compreendendo Nossa Configuração do Bitcoin" na sessão [3.3: Configurando Nossa Carteira](03_3_Setting_Up_Your_Wallet.md). \ No newline at end of file diff --git a/pt/03_3_Setting_Up_Your_Wallet.md b/pt/03_3_Setting_Up_Your_Wallet.md index 724eeac..3f62862 100644 --- a/pt/03_3_Setting_Up_Your_Wallet.md +++ b/pt/03_3_Setting_Up_Your_Wallet.md @@ -1,9 +1,8 @@ - -# 3.3: Configurando nossa carteira +# 3.3: Configurando Nossa carteira Agora estamos prontos para começar a brincar com o Bitcoin. Para começar, precisaremos criar um endereço para receber fundos. -## Criando um endereço +## Criando um Endereço A primeira coisa que precisamos fazer é criar um endereço para recebimento de pagamentos. Podemos fazer isso usando o comando `bitcoin-cli getnewaddress`. Temos que lembrar que se quisermos mais informações sobre este comando, podemos digitar `bitcoin-cli help getnewaddress`. Atualmente, existem três tipos de endereços: Os `legacy` e os dois tipos de endereço SegWit, `p2sh-segwit` e `bech32`. Se não especificarmos qual queremos criar, sempre teremos por padrão o `bech32`. @@ -28,7 +27,7 @@ Anote cuidadosamente o endereço. Precisaremos utilizá-lo para quando recebermo Com um único endereço em mãos, podemos pular direto para a próxima seção e começar a receber alguns satoshinhos. No entanto, antes de chegarmos lá, vamos discutir brevemente os outros tipos de endereços que encontraremos no futuro e falar sobre alguns outros comandos de carteira que podemos querer usar mais pra frente. -### Conhecendo os endereços do Bitcoin +### Conhecendo os Endereços do Bitcoin Existem três tipos de endereços Bitcoin que podemos criar com o comando RPC `getnewaddress`. Usaremos um endereço `legacy` (P2PKH) aqui, mas iremos utilizar um endereço SegWit (P2SH-SegWit) ou Bech32 na sessão [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md). @@ -50,7 +49,7 @@ Existem dois endereços desse tipo: Existem outros tipos de endereços de Bitcoin, como P2PK (que paga a uma chave pública simples e está obsoleto devido à sua insegurança futura) e P2SH (que paga a um Hash de script e que é usado pelo SegWit e esta aninhado com a primeira geração endereços. Vamos conhecê-lo mais detalhadamente nos próximos capítulos). -## Opcional: Assinando uma mensagem +## Opcional: Assinando uma Mensagem Às vezes, precisamos provar que controlamos um endereço Bitcoin (ou melhor, que controlamos a chave privada). Isso é importante porque permite que as pessoas saibam que estão enviando fundos para a pessoa certa. Isso pode ser feito criando uma assinatura com o comando `bitcoin-cli signmessage`, na forma `bitcoin-cli signmessage [endereço] [mensagem]`. Por exemplo: @@ -77,7 +76,7 @@ error message: Invalid address ``` -## Opcional: Fazendo o dump da nossa carteira +## Opcional: Fazendo o Dump da Nossa Carteira Pode parecer perigoso ter todas as chaves privadas insubstituíveis em um único arquivo. É para isso que serve o comando `bitcoin-cli dumpwallet`. Ele permite que façamos uma cópia do nosso arquivo `wallet.dat`: ``` @@ -97,7 +96,7 @@ error message: Importing wallets is disabled when blocks are pruned ``` -## Opcional: Visualizando as chaves privadas +## Opcional: Visualizando as Chaves Privadas Às vezes, podemos querer realmente olhar para as chaves privadas associadas aos nossos endereços Bitcoin. Talvez queremos assinar uma mensagem ou gastar bitcoins em uma máquina diferente. Talvez só estamos querendo fazer backup de algumas chaves privadas importantes. Também pode fazer isso com nosso arquivo criado acima, já que ele pode ser lido por humanos. ``` @@ -123,10 +122,10 @@ Novamente, é esperado que isso exija um node não prunado. Isso provavelmente v _Nós digitamos aquele endereço Bitcoin que gerou, enquanto assinávamos uma mensagem e agora estamos fazendo o dump as chaves. Se por acaso achar que isso é muito complicado, os autores e tradutores também concordam com isso. Também estamos sujeitos a erros, um tópico que abordaremos na próxima sessão._ -## Resumo do Configurando nossa carteira +## Resumo: Configurando Nossa carteira Precisamos criar um endereço para receber fundos. Nosso endereço é armazenado em uma carteira, da qual podemos fazer o backup. Podemos fazer muito coisas com nosso endereço, como fazer o dump da nossa chave privada ou usá-la para assinar mensagens. Mas, realmente, criar esse endereço é _tudo_ que precisaremos fazer para receber alguns satoshinhos. ## O Que Vem Depois? -Vamos dar uma pausa no capítulo "Compreendendo a configuração do node Bitcoin" na sessão [Usando variáveis de linha de comando](03_3__Interlude_Using_Command-Line_Variables.md). \ No newline at end of file +Vamos dar uma pausa no capítulo "Compreendendo Nossa Configuração do Bitcoin" com o [Prefácio: Usando Variáveis de Linha de Comando](03_3__Interlude_Using_Command-Line_Variables.md). \ No newline at end of file diff --git a/pt/03_3__Interlude_Using_Command-Line_Variables.md b/pt/03_3__Interlude_Using_Command-Line_Variables.md index 5c1f67b..6b72384 100644 --- a/pt/03_3__Interlude_Using_Command-Line_Variables.md +++ b/pt/03_3__Interlude_Using_Command-Line_Variables.md @@ -1,4 +1,4 @@ -# Usando variáveis de linha de comando +# Usando Variáveis de Linha de Comando A sessão anterior demonstrou vários comandos de linha de comando usados sem ofuscação ou interferência. No entanto, geralmente essa não é a melhor maneira de executar o Bitcoin usando a linha de comando. Como estamos lidando com variáveis longas, complexas e difíceis de serem lidas, é fácil cometer um erro se estivermos copiando essas variáveis (ou, perder alguns satoshis, se as digitarmos manualmente). Como essas variáveis podem significar a diferença entre receber e perder dinheiro quando usarmos a Mainnet, não _queremos_ cometer erros. Por esses motivos, sugerimos enfaticamente o uso de variáveis de linha de comando para salvar endereços, assinaturas ou outras cadeias de informações longas sempre que isso for razoável. @@ -31,10 +31,10 @@ O restante deste tutorial usará esse estilo de armazenamento de informações q > :book: ***Quando não é prático usar variáveis de linha de comando?*** Variáveis de linha de comando não são práticas se precisarmos usar as informações em algum lugar diferente da linha de comando. Por exemplo, salvar a assinatura pode não ser útil se tivermos que enviá-la a outra pessoa por e-mail. Além disso, alguns comandos futuros produzirão objetos JSON ao invés de informações simples, e as variáveis não podem ser usadas para capturar essas informações, ao menos não sem um _pouco_ mais de mais trabalho. -## Resumo do Usando variáveis de linha de comando +## Resumo: Usando Variáveis de Linha de Comando Variáveis de shell podem ser usadas para manter longas strings, minimizando as chances de erros. ## O Que Vem Depois? -Vamos continuar "Compreendendo a configuração do node Bitcoin" na sessão [3.4: Recebendo uma transação](03_4_Receiving_a_Transaction.md). \ No newline at end of file +Vamos continuar "Compreendendo Nossa Configuração do Bitcoin" na sessão [3.4: Recebendo uma Transação](03_4_Receiving_a_Transaction.md). \ No newline at end of file From c4cf1ef060f8557d916a2e11b982a1505a940a1e Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 10:59:13 -0300 Subject: [PATCH 130/155] Revise chapter 4 titles, fix typos --- pt/04_1_Sending_Coins_The_Easy_Way.md | 2 +- pt/04_2_Creating_a_Raw_Transaction.md | 2 +- pt/04_4_Sending_Coins_with_a_Raw_Transaction.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pt/04_1_Sending_Coins_The_Easy_Way.md b/pt/04_1_Sending_Coins_The_Easy_Way.md index c99e251..58c8a22 100644 --- a/pt/04_1_Sending_Coins_The_Easy_Way.md +++ b/pt/04_1_Sending_Coins_The_Easy_Way.md @@ -2,7 +2,7 @@ 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 uma possui seus prós e contras. Este primeiro método de envio será o mais simples. -## Definindo Sua Taxa de Transação +## Definindo Nossa Taxa de Transação Antes de enviar qualquer bitcoin pela rede, devemos pensar sobre as taxas de transação que iremos pagar. diff --git a/pt/04_2_Creating_a_Raw_Transaction.md b/pt/04_2_Creating_a_Raw_Transaction.md index 64399ff..dfe12b8 100644 --- a/pt/04_2_Creating_a_Raw_Transaction.md +++ b/pt/04_2_Creating_a_Raw_Transaction.md @@ -270,4 +270,4 @@ Quando satoshinhos entram na nossa carteira Bitcoin, eles permanecem em quantida ## O Que Vem Depois? -Vamos fazer uma pausa do "Enviando Transações no Bitcoin" para lermos o [Prefácio: Usando JQ](04_2__Interlude_Using_JQ.md). \ No newline at end of file +Vamos fazer uma pausa em "Enviando Transações no Bitcoin" para lermos o [Prefácio: Usando JQ](04_2__Interlude_Using_JQ.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 index d9d8ca9..8c1d828 100644 --- a/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md +++ b/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -182,6 +182,6 @@ Para enviar moedas usando transações brutas, precisamos criar uma transação ## O Que Vem Depois? -Veja uma forma alternativa de inserir comandos no [Prefácio: Usando JQ](04_4__Interlude_Using_Curl.md). +Veja uma forma alternativa de inserir comandos no [Prefácio: Usando Curl](04_4__Interlude_Using_Curl.md). Ou, se preferir pular o que é francamente uma digressão, podemos aprender mais uma forma de enviar transações no Bitcoin na seção [§4.5 Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file From 7ce59c0584c06f3c127c82539101469c53ba6cac Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 10:59:33 -0300 Subject: [PATCH 131/155] Revise chapter 5 titles, fix typos --- pt/05_0_Controlling_Bitcoin_Transactions.md | 12 +++++------ pt/05_1_Watching_for_Stuck_Transactions.md | 10 ++++----- pt/05_2_Resending_a_Transaction_with_RBF.md | 24 ++++++++++----------- pt/05_3_Funding_a_Transaction_with_CPFP.md | 14 ++++++------ 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/pt/05_0_Controlling_Bitcoin_Transactions.md b/pt/05_0_Controlling_Bitcoin_Transactions.md index d283e81..c01bea2 100644 --- a/pt/05_0_Controlling_Bitcoin_Transactions.md +++ b/pt/05_0_Controlling_Bitcoin_Transactions.md @@ -1,8 +1,8 @@ -# Capítulo 5: Controlando as transações de Bitcoin +# Capítulo 5: Controlando Transações no 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 +## Objetivos deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: @@ -16,8 +16,8 @@ Os objetivos secundários do capítulo incluem a capacidade de: * Entender a diferença entre o RBF e o CPFP; * Planejar a taxa do RBF. -## Tabela de conteúdo +## 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 + * [Seção 1: Atentando-se para Transações Presas](05_1_Watching_for_Stuck_Transactions.md) + * [Seção 2: Reenviando uma Transação com RBF](05_2_Resending_a_Transaction_with_RBF.md) + * [Seção 3: Financiando uma Transação com 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 index 9a08734..8c81e1f 100644 --- a/pt/05_1_Watching_for_Stuck_Transactions.md +++ b/pt/05_1_Watching_for_Stuck_Transactions.md @@ -1,8 +1,8 @@ -# 5.1: Observando as transações presas na mempool +# 5.1: Atentando-se para Transações Presas À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 +## 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. @@ -50,10 +50,10 @@ Se sua transação ficar paralisada por mais tempo do que esperamos, normalmente **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 +## Resumo: Atentando-se para Transações Presas 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? +## 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). +Continuemos "Controlando Transações no Bitcoin" com a sessão [§5.2: Reenviando uma Transação com 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 index 2b2d632..23d5fe6 100644 --- a/pt/05_2_Resending_a_Transaction_with_RBF.md +++ b/pt/05_2_Resending_a_Transaction_with_RBF.md @@ -1,10 +1,10 @@ -# 5.2: Reenviando uma transação com o RBF +# 5.2: Reenviando uma Transação com 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 +## Optando pelo 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). @@ -42,19 +42,19 @@ O sinalizador ```bip125-replaceeable``` permanecerá como ```yes``` até que a t > :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```. +> :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 seçã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 +### 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```. +Se preferirmos, podemos optar por _sempre_ 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 +## 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. +> 1. As transações originais sinalizam a possibilidade de serem substituídas de maneira explicita ou por herança, conforme descrito na seçã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. @@ -73,7 +73,7 @@ Diante desse conflito, os mineradores saberão usar aquele com a taxa mais alta > :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 +## Substituindo uma Transação no Modo Difícil: 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)]. @@ -154,7 +154,7 @@ $ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d ``` 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 +## Substituindo uma Transação no Modo Fácil: 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```. @@ -201,7 +201,7 @@ $ bitcoin-cli -named gettransaction txid=75208c5c8cbd83081a0085cd050fc7a4064d87c ``` > :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 +## Resumo: Reenviando uma Transação com 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```). @@ -209,6 +209,6 @@ Se uma transação ficar presa na mempool e não quisermos esperar que ela expir > 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? +## 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). +Vamos continuar "Controlando Transações no Bitcoin" na seção [§5.3: Financiando uma Transação com 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 index 3e36c38..2730b18 100644 --- a/pt/05_3_Funding_a_Transaction_with_CPFP.md +++ b/pt/05_3_Funding_a_Transaction_with_CPFP.md @@ -1,10 +1,10 @@ -# 5.3: Financiando uma transação com o CPFP +# 5.3: Financiando uma Transação com 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 +## 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. @@ -12,7 +12,7 @@ Basicamente, a ideia do CPFP é que um destinatário tenha uma transação que n 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 +## 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: @@ -108,7 +108,7 @@ Nossas transações podem ser processadas rapidamente, ou não. Tudo depende se E isso realmente é tudo o que podemos fazer. -### Atenção aos nuances +### 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. @@ -116,12 +116,12 @@ A parte que está _enviando_ poderia usar o CPFP para liberar uma transação se 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 +## Resumo: Financiando uma Transação com 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: ***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? +## 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 +Vamos avançar para o [Capítulo 6: Expandindo Transações no Bitcoin com Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md). \ No newline at end of file From bf1400eb6c1d80eae62d6cb0004dc3cb35fb9185 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 10:59:50 -0300 Subject: [PATCH 132/155] Revise chapter 6 titles, fix typos --- pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md | 4 ++-- pt/06_1_Sending_a_Transaction_to_a_Multisig.md | 2 +- pt/06_3_Sending_an_Automated_Multisig.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md b/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md index 6bf524f..7a7d58a 100644 --- a/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md +++ b/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md @@ -2,7 +2,7 @@ Transações básicas no Bitcoin: (1) enviam fundos; (2) para um único destinatário P2PKH ou SegWit; (3) de uma única máquina; (4) imediatamente. No entanto, todas as quatro partes desta definição podem ser expandidas usando transações mais complexas no Bitcoin. Este primeiro capítulo sobre "Expansão" mostra como variar os pontos (2) e (3) enviando saldos para um endereço que representa vários destinatários (ou, pelo menos, vários assinantes). -## Objetivos deste capítulo +## Objetivos deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: * Criar endereços de Bitcoin multi-assinatura (multisig) usando os fundamentos do Bitcoin; @@ -16,4 +16,4 @@ Os objetivos secundários do capítulo incluem a capacidade de: * [Seção 1: Enviando uma Transação com Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) * [Seção 2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) - * [Seção 3: Enviando e Gastando um Multisig de Maneira Automatizada](06_3_Sending_an_Automated_Multisig.md) \ No newline at end of file + * [Seção 3: Enviando & Gastando um Multisig Automatizado](06_3_Sending_an_Automated_Multisig.md) \ No newline at end of file diff --git a/pt/06_1_Sending_a_Transaction_to_a_Multisig.md b/pt/06_1_Sending_a_Transaction_to_a_Multisig.md index 13936d0..850c6d9 100644 --- a/pt/06_1_Sending_a_Transaction_to_a_Multisig.md +++ b/pt/06_1_Sending_a_Transaction_to_a_Multisig.md @@ -196,7 +196,7 @@ b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 ``` Como podemos ver, não houve nada de incomum na criação da transação e ela parece normal, embora com um endereço com um prefixo diferente do normal (```2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr```). Sem surpresa, como também não vimos diferença quando enviamos para endereços Bech32 pela primeira vez na seção [§4.6](04_6_Creating_a_Segwit_Transaction.md). -## Resumo: Enviando uma Transação Multisig +## Resumo: Enviando uma Transação com Multisig Os endereços multisig trancam os fundos usando várias chaves privadas, possivelmente exigindo todas essas chaves privadas para resgate e, possivelmente, exigindo apenas algumas do conjunto. Eles são fáceis de serem criados com o ```bitcoin-cli``` e são simples para serem enviados. Essa facilidade se deve em grande parte ao uso invisível de endereços P2SH (Pay-To-Script-Hash), um tópico extenso que já falamos duas vezes, com endereços P2SH-SegWit e agora com os multisigs, e um outro que receberá mais atenção no futuro. diff --git a/pt/06_3_Sending_an_Automated_Multisig.md b/pt/06_3_Sending_an_Automated_Multisig.md index f07ba8c..d272aed 100644 --- a/pt/06_3_Sending_an_Automated_Multisig.md +++ b/pt/06_3_Sending_an_Automated_Multisig.md @@ -117,4 +117,4 @@ Existe uma maneira mais fácil de gastar fundos enviados para os nossos endereç ## O Que Vem Depois? -Saiba mais sobre "Expandindo Transações no Bitcoin com Multisigs" no [Capítulo 7: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md). \ No newline at end of file +Saiba mais sobre "Expandindo Transações no Bitcoin" no [Capítulo 7: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md). \ No newline at end of file From 1b7776a040ff1d4e4690a08934bf0f0481f23529 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:00:04 -0300 Subject: [PATCH 133/155] Revise chapter 7 titles, fix typos --- pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md | 4 ++-- pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md | 6 +++--- pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md b/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md index 4ede529..1404805 100644 --- a/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md +++ b/pt/07_0_Expanding_Bitcoin_Transactions_PSBTs.md @@ -19,6 +19,6 @@ Os objetivos secundários do capítulo incluem a capacidade de: ## Tabela de Conteúdo - * [Seção Um: Criando uma Transação Bitcoin Parcialmente Assinada](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) - * [Seção Dois: Usando uma Transação Bitcoin Parcialmente Assinada](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) + * [Seção Um: Criando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) + * [Seção Dois: Usando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) * [Seção Três: Integrando com Hardware Wallets](07_3_Integrating_with_Hardware_Wallets.md) \ No newline at end of file diff --git a/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md b/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md index f1f7d58..cf6c894 100644 --- a/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md +++ b/pt/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md @@ -1,4 +1,4 @@ -# 7.1: Criando uma Transação Bitcoin Parcialmente Assinada +# 7.1: Criando uma Transação Parcialmente Assinada no Bitcoin (PSBT) > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -505,10 +505,10 @@ Finalmente, se precisarmos de mais controle e optarmos por usar o comando ```utx ![](images/psbt-roles-for-cli-3.png) -## Resumo: Criando uma Transação Bitcoin Parcialmente Assinada +## Resumo: Criando uma Transação Parcialmente Assinada no Bitcoin (PSBT) A criação de uma PSBT envolve um fluxo de trabalho um tanto complexo de criação, atualização, assinatura, finalização e extração da PSBT, após o qual ela se converte novamente em uma transação bruta. Por que teríamos tanto trabalho? Porque desejamos colaborar entre vários usuários ou vários programas. Agora que entendemos esse fluxo de trabalho, a próxima seção irá apresentar alguns exemplos reais de como fazer isso. ## O Que Vem Depois? -Vamos continuar "Expandindo Transações no Bitcoin com PSBTs" na seção [§7.2: Usando uma Transação Bitcoin Parcialmente Assinada](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md). +Vamos continuar "Expandindo Transações no Bitcoin com PSBTs" na seção [§7.2: Usando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md). diff --git a/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md b/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md index 4686c87..0f21cc7 100644 --- a/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md +++ b/pt/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md @@ -1,4 +1,4 @@ -# 7.2: Usando uma Transação Bitcoin Parcialmente Assinada +# 7.2: Usando uma Transação Parcialmente Assinada no Bitcoin (PSBT) > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -588,7 +588,7 @@ Cada usuário coloca o próprio UTXO e cada um recebe uma saída correspondente. A melhor maneira de gerenciar um CoinJoin é enviar a PSBT básica para todas as partes (que podem ser inúmeras) e, em seguida, fazer com que cada uma assine a PSBT e envie de volta para uma única parte que irá combinar, finalizar e enviar. -## Resumo: Usando uma Transação Bitcoin Parcialmente Assinada +## Resumo: Usando uma Transação Parcialmente Assinada no Bitcoin (PSBT) Agora vimos o processo PSBT que aprendemos na seção [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) em uso em três exemplos da vida real: criando um multisig, um financiamento e fazendo CoinJoin. Tudo isso era teoricamente possível no Bitcoin com várias pessoas assinando transações cuidadosamente construídas, mas as PSBTs tornam isso padronizado e simples. From d0ccb881a2f453e13b84f025076f5035a9102baf Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:00:23 -0300 Subject: [PATCH 134/155] Revise chapter 8 titles, fix typos --- ..._0_Expanding_Bitcoin_Transactions_Other.md | 8 ++++---- ...1_Sending_a_Transaction_with_a_Locktime.md | 20 +++++++++---------- pt/08_2_Sending_a_Transaction_with_Data.md | 18 ++++++++--------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/pt/08_0_Expanding_Bitcoin_Transactions_Other.md b/pt/08_0_Expanding_Bitcoin_Transactions_Other.md index 6779937..6453a79 100644 --- a/pt/08_0_Expanding_Bitcoin_Transactions_Other.md +++ b/pt/08_0_Expanding_Bitcoin_Transactions_Other.md @@ -1,4 +1,4 @@ -# Capítulo 8: Expandindo Transações de Bitcoin de Outras Maneiras +# Capítulo 8: Expandindo Transações no Bitcoin de Outras Maneiras A definição de transações básicas descrita no [Capítulo Seis](06_0_Expanding_Bitcoin_Transactions_Multisigs.md) diz que enviamos os _fundos_ _imediatamente_, mas esses são os dois elementos que podem ser alterados. Esta seção final sobre _Expandindo transações de Bitcoin_ fala sobre como enviar coisas que não sejam moedas e como fazer isso em um momento diferente do atual. @@ -15,7 +15,7 @@ Os objetivos secundários incluem a capacidade de: * Planejar usando o poder do Locktime; * Planejar usando o poder de OP_RETURN. -## Tabela de conteúdo +## Tabela de Conteúdo - * [Seção Um: Enviando uma transação com Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) - * [Seção Dois: Enviando uma transação com dados](08_2_Sending_a_Transaction_with_Data.md) \ No newline at end of file + * [Seção Um: Enviando uma Transação com um Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) + * [Seção Dois: Enviando uma Transação com Dados](08_2_Sending_a_Transaction_with_Data.md) \ No newline at end of file diff --git a/pt/08_1_Sending_a_Transaction_with_a_Locktime.md b/pt/08_1_Sending_a_Transaction_with_a_Locktime.md index 6b4d446..cdf66d3 100644 --- a/pt/08_1_Sending_a_Transaction_with_a_Locktime.md +++ b/pt/08_1_Sending_a_Transaction_with_a_Locktime.md @@ -1,8 +1,8 @@ -# 8.1: Enviando uma transação com Locktime +# 8.1: Enviando uma Transação com um Locktime Os capítulos anteriores mostraram duas maneiras diferentes de enviar fundos de várias máquinas e para vários destinatários. Mas, existem duas outras maneiras de alterar fundamentalmente as transações básicas. A primeira delas é variar o tempo, escolhendo um tempo de bloqueio ou mais conhecido pela expressão em inglês locktime. Isso nos dá a capacidade de enviar transações brutas em algum momento no futuro. -## Entendendo como o Locktime funciona +## Entendendo Como o Locktime Funciona Ao criar uma transação do tipo locktime, a bloqueamos com um número que representa a altura do bloco (se for um número pequeno) ou um carimbo de data/hora usando o padrão UNIX (se for um número grande). Isso informa à rede Bitcoin que a transação não pode ser colocada no bloco até que o tempo especificado chegue ou a blockchain tenha atingido a altura especificada. @@ -16,11 +16,11 @@ Quando uma transação do tipo locktime está esperando para entrar em um bloco, > O Bitcoin Script capacita ainda mais os dois tipos de timelocks, permitindo o bloqueio de saídas individuais ao invés de toda a transação. Os timelocks absolutos (como Locktime) estão vinculados ao opcode Script OP_CHECKLOCKTIMEVERIFY, que é definido no [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) e que será estudado na seção [§11.2: Usando CLTV em Scripts](11_2_Using_CLTV_in_Scripts.md), enquanto os timelocks relativos (como o Timelock) estão vinculados ao opcode de Script OP_CHECKSEQUENCEVERIFY, que é definido no [BIP 112](https://github.com/bitcoin/bips /blob/master/bip-0112.mediawiki) e que também será abordado na seção [§11.3](11_3_Using_CSV_in_Scripts.md). -## Criando uma transação de Locktime +## Criando uma Transação com Locktime Para criar uma transação com locktime, precisamos primeiro determinar como definiremos o tempo. -### Descobrindo nosso tempo de bloqueio usando o carimbo de data/hora do UNIX +### Descobrindo Nosso Locktime Usando o Carimbo de Data/Hora do UNIX Provavelmente, iremos definir com muito mais frequência o nosso tempo de bloqueio usando um carimbo de data/hora do tipo UNIX que representa uma data e hora específica. Podemos calcular um carimbo de data/hora UNIX usando sites que fazem essa conversão, como o [UNIX Time Stamp](http://www.unixtimestamp.com/) ou o [Epoch Convertor](https://www.epochconverter.com/). No entanto, seria melhor [escrevermos nosso próprio script](https://www.epochconverter.com/#code) em nossa máquina local, para que saibamos que o carimbo de data/hora UNIX que recebemos está correto (lembre-se, não confie, verifique). Se não fizermos isso, pelo menos seria interessante verificar em dois sites diferentes para ter a certeza que tudo está correto. @@ -28,7 +28,7 @@ Provavelmente, iremos definir com muito mais frequência o nosso tempo de bloque > :warning: **AVISO:** O Locktime com carimbos de data/hora tem menos flexibilidade, pois a liberação de blocos não é regular e os tempos de bloqueio podem ser duas horas antes do tempo real, então um locktime significa "mais ou menos nesta data e nesta hora". -### Descobrir o locktime usando a altura do bloco +### Descobrindo Nossoo Locktime Usando a Altura do Bloco Como alternativa, podemos definir o locktime usando um número menor, que representa a altura de um bloco. Para calcular a altura do bloco futuro, precisamos primeiro saber qual é a altura do bloco atual. O ```bitcoin-cli getblockcount``` nos dirá a altura do bloco atual baseado na blockchain da máquina local. Podemos verificar um explorador do Bitcoin como a [mempool.space](https://mempool.space/). @@ -38,7 +38,7 @@ Depois de descobrir a altura atual, podemos decidir até que ponto no futuro ire > :warning: **AVISO:** Se desejamos definir um locktime usando a altura do bloco, devemos definir o tempo de bloqueio para menos de 500 milhões. Se definirmos como sendo 500 milhões ou mais, nosso número será interpretado como um carimbo de data/hora. Como o carimbo de data/hora usando o padrão UNIX com valor de 500 milhões era dia 5 de novembro de 1985, provavelmente significa que nossa transação será permitida a qualquer momento a entrar na blockchain. -## Escrevendo a transação +## Escrevendo a Transação Depois de descobrir o locktime, tudo o que precisamos fazer é escrever uma transação bruta padrão, com uma terceira variável para o ```locktime```: ``` @@ -104,7 +104,7 @@ Observe que o número de sequência (```4294967294```) é menor que ```0xfffffff > :warning: **ATENÇÃO:** Se estivermos criando uma transação bruta com locktime por algum outro meio que não seja o ```bitcoin-cli```, teremos que definir a sequência para um valor menor que ```0xffffffff``` manualmente. -## Enviando a transação +## Enviando a Transação Agora, já estamos familiarizados com a parte final, que é enviar a transação para a rede: ``` @@ -120,11 +120,11 @@ Desde 2013, geralmente não podemos colocar a transação usando um timelock na Assim que o bloqueio de tempo expirar, qualquer pessoa pode enviar a transação assinada para a rede, e o destinatário receberá o saldo como esperado... Desde que a transação não tenha sido cancelada. -## Cancelando uma transação com timelock +## Cancelando uma Transação com Locktime Cancelar uma transação de tempo de bloqueio é _muito_ simples: precisamos apenas enviar uma nova transação usando pelo menos um dos UTXOs. -## Resumo: Enviando uma transação com Locktime +## Resumo: Enviando uma Transação com um Locktime O Locktime oferece uma maneira de criar uma transação que _precisa_ esperar e que _não será aceita_ até que um determinado bloco chegue ou um momento pré-definido passe. Enquanto isso, ela pode ser cancelada simplesmente reutilizando um dos UTXO da transação. @@ -132,4 +132,4 @@ O Locktime oferece uma maneira de criar uma transação que _precisa_ esperar e ## O que vem depois? -Vamos continuar "Expandindo transações de Bitcoin" na seção [§8.2: Enviando uma transação com dados](08_2_Sending_a_Transaction_with_Data.md). \ No newline at end of file +Vamos continuar "Expandindo Transações no Bitcoin" na seção [§8.2: Enviando uma Transação com Dados](08_2_Sending_a_Transaction_with_Data.md). \ No newline at end of file diff --git a/pt/08_2_Sending_a_Transaction_with_Data.md b/pt/08_2_Sending_a_Transaction_with_Data.md index a367ed7..8e5476b 100644 --- a/pt/08_2_Sending_a_Transaction_with_Data.md +++ b/pt/08_2_Sending_a_Transaction_with_Data.md @@ -1,10 +1,10 @@ -# 8.2: Enviando uma transação com dados +# 8.2: Enviando uma Transação com Dados O último jeito de variar a forma como enviamos uma transação simples é usar a transação para enviar dados ao invés de saldos (ou, na prática, enviar algo além dos saldos). Isso nos dá a capacidade de inserir informações na blockchain. Isso é feito através de um comando especial, o ```OP_RETURN```. A pegadinha? Só podemos armazenar 80 bytes por vez! -## Criando nossos dados +## Criando Nossos Dados A primeira coisa que precisamos fazer é criar os 80 bytes (ou menos) de dados que iremos gravar no nosso ```OP_RETURN```. Isso pode ser tão simples quanto preparar uma mensagem ou podemos usar o hash dos dados existentes. Por exemplo, o ```sha256sum``` produz 256 bits de dados, que são apenas 32 bytes, bem abaixo do nosso limite: ``` @@ -14,7 +14,7 @@ $ op_return_data="b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e ``` > :book: _O que é um OP_RETURN?_ Todas as transações Bitcoin são construídas com scripts que iremos ver mais a fundo no próximo capítulo. O ```OP_RETURN``` é um script simples que define o OUTPUT como sendo inválido. A convenção resultou no uso dele para incorporar dados na blockchain. -## Separando algumas moedas +## Separando Algumas Moedas Nosso objetivo ao criar uma transação de dados não é enviar dinheiro para alguém, mas colocar dados dentro da blockchain. No entanto, _devemos_ gastar algumas moedas para fazer isso. Só precisamos usar um endereço de troco como sendo nosso _ único_ destinatário. Em seguida, podemos identificar um UTXO e enviá-lo para nosso endereço de troco, sem esquecer da taxa de transação, ao mesmo tempo que usamos a mesma transação para criar um OP_RETURN. @@ -41,7 +41,7 @@ $ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') $ changeaddress=$(bitcoin-cli getrawchangeaddress) ``` -## Escrevendo uma transação bruta +## Escrevendo uma Transação Bruta Agora podemos escrever uma nova transação bruta com duas saídas: uma é o nosso endereço de alteração para recuperar (a maior parte) do nosso saldo, a outra é um endereço de dados, que é uma variável ```bitcoin-cli``` para um OP_RETURN. ``` @@ -97,18 +97,18 @@ Esta é a cara da transação: ``` Como podemos observar, ela envia a maior parte do dinheiro de volta para o endereço de troco (`tb1qnx9fkrksw6aaaswc3kj0gademhn4ud3q7cz4fm`) menos a taxa de transação. Mais importante, a primeira saída mostra um OP_RETURN com os dados (`b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75`) logo depois. -## Enviando uma transação bruta +## Enviando uma Transação Bruta Assine a transação bruta e envie-a, e logo esse OP_RETURN será incorporado a blockchain! -## Verificando nosso OP_RETURN +## Verificando Nosso OP_RETURN Novamente, podemos olhar para essa transação usando um explorador da blockchain: [https://mempool.space/pt/testnet/tx/a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8/] Podemos observar um aviso sobre os dados estarem em um "protocolo desconhecido". Se estivermos projetando algum uso regular dos dados ```OP_RETURN```, provavelmente iremos marcar com um prefixo especial, para marcar esse protocolo. Então, os dados OP_RETURN reais podem ser algo como "CONTRACTS3b110a164aa18d3a5ab064ba93fdce62". Este exemplo não usa um prefixo para evitar qualquer tipo de confusão com os espaços de dados. -## Resumo: Enviando uma transação com dados +## Resumo: Enviando uma Transação com Dados Podemos usar o ```OP_RETURN``` para armazenar até 80 bytes de dados na blockchain. Fazemos isso com a palavra-código ```data``` em um ```vout```. Ainda precisaremos enviar alguns satoshinhos, mas basta enviá-lo de volta para um endereço de troco, retirando a taxa de transação. @@ -116,6 +116,6 @@ Podemos usar o ```OP_RETURN``` para armazenar até 80 bytes de dados na blockcha Observe que há alguma controvérsia sobre o uso da blockchain do Bitcoin usando-a para este fim. -## O que vem depois? +## O Que Vem Depois? -Vamos conhecer mais sobre o "Script no Bitcoin" no [Capítulo Nove: Apresentando os Scripts no Bitcoin](09_0_Introducing_Bitcoin_Scripts.md). \ No newline at end of file +Vamos conhecer mais sobre "Programando no Bitcoin" no [Capítulo Nove: Apresentando os Scripts do Bitcoin](09_0_Introducing_Bitcoin_Scripts.md). \ No newline at end of file From 586d16c79af59d15e32636da091386c21969e984 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:00:40 -0300 Subject: [PATCH 135/155] Revise chapter 9 titles, fix typos --- pt/09_0_Introducing_Bitcoin_Scripts.md | 10 +++++----- ...9_1_Understanding_the_Foundation_of_Transactions.md | 6 +++--- pt/09_2_Running_a_Bitcoin_Script.md | 4 ++-- pt/09_3_Testing_a_Bitcoin_Script.md | 6 +++--- pt/09_4_Scripting_a_P2PKH.md | 4 ++-- pt/09_5_Scripting_a_P2WPKH.md | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pt/09_0_Introducing_Bitcoin_Scripts.md b/pt/09_0_Introducing_Bitcoin_Scripts.md index 9e4999f..8c148d7 100644 --- a/pt/09_0_Introducing_Bitcoin_Scripts.md +++ b/pt/09_0_Introducing_Bitcoin_Scripts.md @@ -1,10 +1,10 @@ -# Capítulo 9: Apresentando Scripts no Bitcoin +# Capítulo 9: Apresentando os Scripts do Bitcoin Até o momento, temos interagido com o Bitcoin em um nível relativamente alto de abstração. O programa ```bitcoin-cli``` oferece acesso a uma variedade de comandos RPC que suportam a criação e controle de transações brutas de Bitcoin que incluem saldos, dados, timelocks e multisigs. No entanto, o Bitcoin oferece muito mais complexidade do que isso. O software oferece uma linguagem de script simples que pode ser usada para criar condições de resgate ainda mais complexas. Se os multisigs e os timelocks fornecerem as bases para os contratos inteligentes, o script do Bitcoin constrói os alicerces. É o próximo passo para capacitar o Bitcoin. -## Objetivos deste capítulo +## Objetivos deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: @@ -20,8 +20,8 @@ Os objetivos secundários do capítulo incluem a capacidade de: ## Tabela de Conteúdo -* [Seção Um: Compreendendo o Alicerce das Transações](09_1_PriveStanding_the_foundation_of_transactions.md) -* [Seção Dois: Executando um Script no Bitcoin](09_2_running_a_bitcoin_script.md) -* [Seção Três: Testando um Script no Bitcoin](09_3_testing_a_bitcoin_script.md) +* [Seção Um: Compreendendo a Base das Transações](09_1_PriveStanding_the_foundation_of_transactions.md) +* [Seção Dois: Executando um Script do Bitcoin](09_2_running_a_bitcoin_script.md) +* [Seção Três: Testando um Script do Bitcoin](09_3_testing_a_bitcoin_script.md) * [Seção Quatro: Programando um P2PKH](09_4_scripting_a_p2pkh.md) * [Seção Cinco: Programando um P2WPKH](09_5_scripting_a_p2wpkh.md) \ No newline at end of file diff --git a/pt/09_1_Understanding_the_Foundation_of_Transactions.md b/pt/09_1_Understanding_the_Foundation_of_Transactions.md index 8ca5cdd..b189935 100644 --- a/pt/09_1_Understanding_the_Foundation_of_Transactions.md +++ b/pt/09_1_Understanding_the_Foundation_of_Transactions.md @@ -1,4 +1,4 @@ -# 9.1: Compreendendo a Base de Transações +# 9.1: Compreendendo a Base das Transações A base do Bitcoin é a capacidade de proteger transações, algo que é feito com uma linguagem de programação simples. @@ -131,9 +131,9 @@ Vamos comparar isso com o ```ScriptPubkey``` da nossa nova transação P2PKH: Essas duas transações são _definitivamente_ trancadas de maneiras diferentes. O Bitcoin reconhece a primeira como sendo ```scripthash``` (P2SH) e a segunda como sendo ```pubkeyhash``` (P2PKH), mas também devemos ser capazes de ver a diferença nos diferentes códigos ```asm```: ```OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL``` versus ```OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 Op_equalverify op_checksig```. Este é o poder da programação: conseguimos, de maneira bem simples, produzir alguns dos tipos drasticamente diferentes de transações que aprendemos nos capítulos anteriores. -## Resumo: Compreendendo a Base de Transações +## Resumo: Compreendendo a Base das Transações -Cada transação do bitcoin inclui pelo menos um script de desbloqueio (```scriptSig```), que resolve um quebra-cabeça criptográfico anterior, e pelo menos um script de bloqueio (```scriptPubKey```), que cria um novo quebra-cabeça criptográfico. Há um ```scriptSig``` para cada entrada e um ```scriptPubKey``` para cada saída. Cada um desses scripts é escrito usando o Bitcoin Script, uma linguagem semelhante à linguagem de programação Forth que fortalece ainda mais o Bitcoin. +Cada transação do Bitcoin inclui pelo menos um script de desbloqueio (```scriptSig```), que resolve um quebra-cabeça criptográfico anterior, e pelo menos um script de bloqueio (```scriptPubKey```), que cria um novo quebra-cabeça criptográfico. Há um ```scriptSig``` para cada entrada e um ```scriptPubKey``` para cada saída. Cada um desses scripts é escrito usando o Bitcoin Script, uma linguagem semelhante à linguagem de programação Forth que fortalece ainda mais o Bitcoin. > :fire: ***Qual é o poder dos scripts?*** Os scripts desbloqueiam todo o poder dos contratos inteligentes. Com os opcodes apropriados, podemos tomar decisões muito precisas sobre quem pode resgatar os fundos, quando podem ser resgatados e como eles podem resgatá-los. Regras mais complexas para saldos corporativos, endereços de parceria, gastos com proxy e outras metodologias também podem ser codificados dentro de um script. Os scripts também conseguem capacitar serviços mais complexos no Bitcoin, como a Lightning e sidechains. diff --git a/pt/09_2_Running_a_Bitcoin_Script.md b/pt/09_2_Running_a_Bitcoin_Script.md index 1ced01a..365a4a5 100644 --- a/pt/09_2_Running_a_Bitcoin_Script.md +++ b/pt/09_2_Running_a_Bitcoin_Script.md @@ -1,4 +1,4 @@ -# 9.2: Executando um Script no Bitcoin +# 9.2: Executando um Script do Bitcoin Os scripts de Bitcoin podem não parecer tão intuitivos no começo, mas sua execução é bastante simples usando a notação polonesa reversa e uma pilha (_stack_). @@ -116,7 +116,7 @@ O Bitcoin irá verificar uma transação e permitir que o UTXO possa ser gasto n No exemplo acima, a transação seria bem-sucedida porque a pilha tem um ```True``` no final. Mas, seria igualmente permitido terminar com uma pilha completa e o número ```42``` no topo (os leitores do Guia do Mochileiro das Galáxias pegaram a referência). -## Resumo: Executando um Script no Bitcoin +## Resumo: Executando um Script do Bitcoin Para processar um script no Bitcoin, um ```scriptSig``` é executado seguido pelo ```scriptPubKey``` que ele está desbloqueando. Esses comandos são executados em ordem, da esquerda para a direita, com constantes sendo colocadas em uma pilha e os operadores retirando elementos dessa pilha e, em seguida, enviando os resultados de volta para ela. Se o script não parar no meio e se o item no topo da pilha no final for diferente de zero, então o UTXO será desbloqueado. diff --git a/pt/09_3_Testing_a_Bitcoin_Script.md b/pt/09_3_Testing_a_Bitcoin_Script.md index b79a2a4..30f76e2 100644 --- a/pt/09_3_Testing_a_Bitcoin_Script.md +++ b/pt/09_3_Testing_a_Bitcoin_Script.md @@ -1,4 +1,4 @@ -# 9.3: Testando um Script no Bitcoin +# 9.3: Testando um Script do Bitcoin Programar no Bitcoin nos permite um controle adicional considerável sobre as transações no Bitcoin, mas também é um tanto quanto perigoso. Como descreveremos na seção [§10.1](10_1_Understanding_the_Foundation_of_P2SH.md), os scripts reais são um tanto isolados da rede Bitcoin, o que significa que é possível escrever um script e a rede aceitá-lo, mesmo que seja impossível resgatar daquele script! Portanto, precisamos testar exaustivamente nossos scripts antes de colocarmos nosso dinheiro neles. @@ -46,7 +46,7 @@ O ```btcdeb``` funciona como um depurador padrão. Ele pega um script (bem como Se ao invés disso nós quisermos inicializá-lo sem argumentos, iremos obter simplesmente um interpretador onde podemos emitir comandos ```exec [opcode]``` para realizar ações diretas. -### Usando o btcdeb para um Exemplo de Adição +### Usando o btcdeb com um Exemplo de Adição O exemplo a seguir mostra o uso do ```btcdeb``` usando como exemplo a adição da seção anterior, ```1 2 OP_ADD``` ``` @@ -200,7 +200,7 @@ E como podemos faz isso? Acontece que esse é o tópico do [capítulo 10](10_0_E _Quaisquer que sejam_ os outros métodos de teste que usamos, testar um script na Testnet deve ser nosso teste final _antes_ de colocar nosso script em Mainnet. Não podemos confiar que nosso código está correto. Não podemos fazer isso apenas olhando para ele. Nem mesmo podemos confiar em quaisquer simuladores ou depuradores que estivermos utilizando. Fazer isso é outra ótima maneira de perder seu saldo no Bitcoin. -## Resumo: Testando um Script no Bitcoin +## Resumo: Testando um Script do Bitcoin Você deve instalar o ```btcdeb``` como uma ferramenta de linha de comando para testar os scripts do Bitcoin. No momento em que este livro foi escrito, produzimos resultados precisos que podem percorrer todo o processo do script. Também podemos procurar em alguns sites online uma representação mais visual. Quando estivermos com tudo pronto, vamos precisar usar a testnet para ter certeza de que as coisas estão funcionando com precisão, antes de implantarmos na Mainnet. diff --git a/pt/09_4_Scripting_a_P2PKH.md b/pt/09_4_Scripting_a_P2PKH.md index 96cf863..416e5ff 100644 --- a/pt/09_4_Scripting_a_P2PKH.md +++ b/pt/09_4_Scripting_a_P2PKH.md @@ -350,7 +350,7 @@ Infelizmente, esta verificação pode ou não estar funcionando no momento do te Como mostramos, um P2PKH é bastante simples. Nossa proteção vem através da força de sua criptografia. -### Como Procurar uma Pub Key e uma Assinatura Manualmente +### Como Procurar uma PubKey e uma Assinatura Manualmente E se quiséssemos gerar a `````` e a ``````, informações necessárias para desbloquear um UTXO, sem usar o ```bitcoin-cli``` para criar uma transação? @@ -386,4 +386,4 @@ Enviar para um endereço P2PKH foi relativamente fácil quando estávamos usando ## O Que Vem Depois? -Vamos continuar "Apresentando Scripts no Bitcoin" na seção [§9.4: Programando um P2WPKH](09_4_Scripting_a_P2WPKH.md). \ No newline at end of file +Vamos continuar "Apresentando Scripts no Bitcoin" na seção [§9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md). \ No newline at end of file diff --git a/pt/09_5_Scripting_a_P2WPKH.md b/pt/09_5_Scripting_a_P2WPKH.md index e83fa6c..3470c34 100644 --- a/pt/09_5_Scripting_a_P2WPKH.md +++ b/pt/09_5_Scripting_a_P2WPKH.md @@ -1,4 +1,4 @@ -# 9.5: Criando um script P2WPKH +# 9.5: Programando um P2WPKH > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Cautela, leitor. @@ -106,7 +106,7 @@ Uma máquina que entende como o SegWit funciona faz exatamente as mesmas coisas Portanto, é outra maneira de fazer a mesma coisa, mas sem ter os scripts embutidos nas transações. Ao invés disso, o processo é integrado ao software do node. -## Resumo: Criando um script P2WPKH +## Resumo: Programando um P2WPKH Em grande parte, _não_ programamos um P2WPKH. Ao invés disso, o Bitcoin Core cria a transação de uma maneira diferente, colocando as informações da testemunha em um lugar diferente ao invés de um ```scriptSig``` tradicional. Isso significa que os P2WPKHs são uma digressão dos scripts de Bitcoin desta parte do livro, porque são uma expansão do Bitcoin que se distancia dos scripts tradicionais. From a69d882a6a4ac64c27625d51b2644f05b2d423b1 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:01:01 -0300 Subject: [PATCH 136/155] Revise chapter 10 titles, fix typos --- pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md | 4 ++-- pt/10_1_Understanding_the_Foundation_of_P2SH.md | 4 ++-- pt/10_2_Building_the_Structure_of_P2SH.md | 2 +- pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md | 2 +- pt/10_4_Scripting_a_Multisig.md | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md b/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md index 81de75a..cd75ea3 100644 --- a/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md +++ b/pt/10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md @@ -16,11 +16,11 @@ Os objetivos secundários do capítulo incluem a capacidade de: * Compreender as várias variações dos scripts Segwit; * Entender como gastar fundos enviados a um P2SH. -## Tabela de conteúdo +## Tabela de Conteúdo * [Seção 1: Compreendendo a Base do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) * [Seção 2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md) -* [Seção 3: Executando um Script Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) +* [Seção 3: Executando um Script do Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) * [Seção 4: Programando um Multisig](10_4_Scripting_a_Multisig.md) * [Seção 5: Programando um Script Segwit](10_5_Scripting_a_Segwit_Script.md) * [Seção 6: Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md) \ No newline at end of file diff --git a/pt/10_1_Understanding_the_Foundation_of_P2SH.md b/pt/10_1_Understanding_the_Foundation_of_P2SH.md index 557daee..123751c 100644 --- a/pt/10_1_Understanding_the_Foundation_of_P2SH.md +++ b/pt/10_1_Understanding_the_Foundation_of_P2SH.md @@ -1,4 +1,4 @@ -# 10.1: Compreendendo a Fundação do P2SH +# 10.1: Compreendendo a Base do P2SH Sabemos que os scripts do Bitcoin podem ser usados para controlar o resgate dos UTXOs. A próxima etapa é criar os nossos próprios scripts... mas isso requer uma técnica muito específica. @@ -89,7 +89,7 @@ Considerando que não podemos criar facilmente uma transação P2SH sem uma API, > :warning: **AVISO:** Podemos criar uma transação perfeitamente válida com um redeemScript com o hash correto, mas se o redeemScript não funcionar, ou não funcionar corretamente, os fundos serão perdidos para sempre. É por isso que é importantíssimo testar os scripts, conforme discutido na seção [§9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md). -## Resumo: Compreendendo a Fundação do P2SH +## Resumo: Compreendendo a Base do P2SH Scripts arbitrários não são o padrão no Bitcoin. No entanto, podemos incorporá-los em transações padrão usando o tipo de endereço P2SH. Precisamos apenas fazer um hash do nosso script como parte do script de bloqueio, então o revelamos e executamos como parte do script de desbloqueio. Contanto que também possamos satisfazer o ```redeemScript```, o UTXO poderá ser gasto. diff --git a/pt/10_2_Building_the_Structure_of_P2SH.md b/pt/10_2_Building_the_Structure_of_P2SH.md index 4cfc3b9..49ee5de 100644 --- a/pt/10_2_Building_the_Structure_of_P2SH.md +++ b/pt/10_2_Building_the_Structure_of_P2SH.md @@ -173,7 +173,7 @@ Dependendo de nossa API, podemos inserir isso como um ```scriptPubKey``` no esti Podemos observar que o ```hex scriptPubKey``` para a transação P2SH Script irá _sempre_ começar com um ```a914```, que é o ```OP_HASH160``` seguido por um ```OP_PUSHDATA``` de 20 bytes (hex: ```0x14```); e _sempre_ terminará com um ```87```, que é um ```OP_EQUAL```. Portanto, tudo o que precisamos fazer é colocar o script de resgate em hash entre esses números. -## Resumo: Construindo a Estrutura de P2SH +## Resumo: Construindo a Estrutura do P2SH Na verdade, a criação do script de bloqueio P2SH entra ainda mais nas entranhas do Bitcoin. Embora seja útil saber como tudo isso funciona em um nível muito baixo, é mais provável que tenhamos uma API cuidando de todo o trabalho pesado para nós. Nossa tarefa será simplesmente criar o Script Bitcoin para fazer o bloqueio... que é o tópico principal dos capítulos 9, 11 e 12. diff --git a/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md b/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md index fb2bd48..aa6a6bc 100644 --- a/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md +++ b/pt/10_3_Running_a_Bitcoin_Script_with_P2SH.md @@ -2,7 +2,7 @@ Agora que conhecemos a teoria e a prática por trás dos endereços P2SH, estamos prontos para transformar um script de Bitcoin não-padrão em uma transação real. Vamos utilizar o script de bloqueio simples da seção [§9.2: Executando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md), `OP_ADD 99 OP_EQUAL`. -## Criando uma transação P2SH +## Criando uma Transação P2SH Para bloquear uma transação com este script, precisamos fazer o seguinte: diff --git a/pt/10_4_Scripting_a_Multisig.md b/pt/10_4_Scripting_a_Multisig.md index 980dd99..6f04fda 100644 --- a/pt/10_4_Scripting_a_Multisig.md +++ b/pt/10_4_Scripting_a_Multisig.md @@ -100,7 +100,7 @@ Geralmente, esses eram problemas com qualquer tipo de script complexo do Bitcoin Os Multisigs P2SH são a metodologia moderna para a criação de multisigs na Blockchain. Elas podem ser criadas de forma muito simples, usando o mesmo processo visto nas seções anteriores. -### Criando o Bloqueio para o Multisig P2SH +### Criando um Bloqueio para o Multisig P2SH Para criar um multisig P2SH, siga as etapas padrão para criar um script de bloqueio P2SH: From 405c9fc7f9c3e6d96d5028943b512e21fae82030 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:01:19 -0300 Subject: [PATCH 137/155] Revise chapter 11 titles, fix typos --- ...0_Empowering_Timelock_with_Bitcoin_Scripts.md | 10 +++++----- pt/11_1_Understanding_Timelock_Options.md | 14 +++++++------- pt/11_2_Using_CLTV_in_Scripts.md | 16 ++++++++-------- pt/11_3_Using_CSV_in_Scripts.md | 14 +++++++------- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/pt/11_0_Empowering_Timelock_with_Bitcoin_Scripts.md b/pt/11_0_Empowering_Timelock_with_Bitcoin_Scripts.md index 935a8d7..73cd736 100644 --- a/pt/11_0_Empowering_Timelock_with_Bitcoin_Scripts.md +++ b/pt/11_0_Empowering_Timelock_with_Bitcoin_Scripts.md @@ -1,9 +1,9 @@ -# Capítulo 11: Expandindo o timelock com scripts do Bitcoin +# Capítulo 11: Capacitando Timelock com Scripts do Bitcoin O recurso ```nLockTime``` da seção [§8.1](08_1_Sending_a_Transaction_with_a_Locktime.md) foi apenas o começo dos Timelocks. Quando começamos a escrever scripts do Bitcoin, dois opcodes de timelocks ficam disponíveis. -## Objetivos deste capítulo +## Objetivos deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: @@ -18,6 +18,6 @@ Os objetivos secundários do capítulo incluem a capacidade de: ## Índice -* [Seção 1: Compreendendo as Opções de Timelocks](11_1_Understanding_Timelock_Options.md) -* [Seção 2: Usando o CLTV nos Scripts](11_2_Using_CLTV_in_Scripts.md) -* [Seção 3: Usando o CSV nos Scripts](11_3_Using_CSV_in_Scripts.md) \ No newline at end of file +* [Seção 1: Compreendendo As Opções de Timelock](11_1_Understanding_Timelock_Options.md) +* [Seção 2: Usando CLTV em Scripts](11_2_Using_CLTV_in_Scripts.md) +* [Seção 3: Usando CSV em Scripts](11_3_Using_CSV_in_Scripts.md) \ No newline at end of file diff --git a/pt/11_1_Understanding_Timelock_Options.md b/pt/11_1_Understanding_Timelock_Options.md index 56dd5c7..f9de3f2 100644 --- a/pt/11_1_Understanding_Timelock_Options.md +++ b/pt/11_1_Understanding_Timelock_Options.md @@ -1,8 +1,8 @@ -# 11.1: Compreendendo as Opções de Timelocks +# 11.1: Compreendendo As Opções de Timelock Na seção [§8.1: Enviando uma transação com Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md), o ```nLocktime``` ofereceu uma ótima opção inicial para bloquear as transações para que não pudessem ser gastas até algum ponto no futuro, com base no tempo (data/hora) ou na altura do bloco. Mas, essa não é a única maneira de colocar um timelock em uma transação. -## Compreendendo as limitações do nLockTime +## Compreendendo as Limitações do nLockTime O ```nLockTime``` é uma maneira simples e poderosa de bloquear uma transação, mas possui algumas limitações: @@ -13,7 +13,7 @@ O ```nLockTime``` é uma maneira simples e poderosa de bloquear uma transação, O último item costumava ser o _dealbreaker_ para o ```nLockTime```. Isso evitou que uma transação fosse gasta, mas não impediu que os fundos fossem usados em uma transação diferente. Então, havia certos usos, mas todos dependiam de confiança. -## Compreendendo as possibilidades dos scripts de Timelock +## Compreendendo as Possibilidades dos Scripts de Timelock Nos últimos anos, o Bitcoin Core foi expandido para permitir a manipulação dos timelocks no nível do opcode com os _OP_CHECKLOCKTIMEVERIFY_ (CLTV) e _OP_CHECKSEQUENCEVERIFY_ (CSV). Ambos trabalham sob uma nova metodologia que fortalece ainda mais o Bitcoin. @@ -23,19 +23,19 @@ _Eles bloqueiam as saídas._ Por serem opcodes incluídos nas transações como Aqui está um ponto importante sobre a utilização dos timelocks: _Eles são bloqueios de mão única._ Os bloqueios de tempo são projetados para desbloquear fundos em um determinado momento. Eles não podem bloquear novamente um fundo: Uma vez que um fundo bloqueado por tempo está disponível, ele ficará disponível para ser gasto. -### Compreendendo as possibilidades do CLTV +### Compreendendo as Possibilidades do CLTV O _OP_CHECKLOCKTIMEVERIFY_ ou CLTV é compativel com o clássico recurso ```nLockTime```, mas no novo paradigma baseado em opcode. Ele permite que uma UTXO se torne acessível em um determinado momento ou em uma determinada altura de bloco. O CLTV foi detalhado pela primeira vez no [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki). -### Compreendendo as possibilidades do CSV +### Compreendendo as Possibilidades do CSV O _OP_CHECKSEQUENCEVERIFY_ ou CSV depende de um novo tipo de "locktime relativo", que é definido no campo _nSequence_ da transação. Como de costume, ele pode ser definido como uma data/hora ou uma altura de bloco. Se for definido como um tempo "n", então uma transação bloqueada em um tempo relativo pode ser gasta "n x 512" segundos depois que a UTXO foi minerada, e se for definido como um bloco "n", então uma transação bloqueada em tempo relativo pode ser gasta em "n" blocos depois que a UTXO foi minerada. O uso do ```nSequence``` para um bloqueio de tempo relativo foi detalhado primeiramente no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki), e o opcode CSV foi adicionado no [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki). -## Resumo: Compreendendo as Opções de Timelocks +## Resumo: Compreendendo As Opções de Timelock Agora possuímos quatro opções de Timelocks: @@ -46,4 +46,4 @@ Agora possuímos quatro opções de Timelocks: ## O Que Vem Depois? -Vamos continuar "Aumentando o poder do timelock com scripts do Bitcoin" na seção [§11.2: Usando o CLTV nos Scripts](11_2_Using_CLTV_in_Scripts.md). \ No newline at end of file +Vamos continuar "Aumentando o poder do timelock com scripts do Bitcoin" na seção [§11.2: Usando CLTV em Scripts](11_2_Using_CLTV_in_Scripts.md). \ No newline at end of file diff --git a/pt/11_2_Using_CLTV_in_Scripts.md b/pt/11_2_Using_CLTV_in_Scripts.md index 6b6a88f..8281d33 100644 --- a/pt/11_2_Using_CLTV_in_Scripts.md +++ b/pt/11_2_Using_CLTV_in_Scripts.md @@ -1,4 +1,4 @@ -# 11.2: Usando o CLTV nos Scripts +# 11.2: Usando CLTV em Scripts O ```OP_CHECKLOCKTIMEVERIFY``` (ou CLTV) é o complemento natural para o ```nLockTime```. Ele muda a ideia de bloquear transações por um tempo absoluto ou altura de bloco para o âmbito dos opcodes, permitindo o bloqueio das UTXOs individuais. @@ -21,7 +21,7 @@ O ```OP_CHECKLOCKTIMEVERIFY``` funciona dentro do mesmo paradigma de altura de b Como o CLTV é apenas parte de um script (e presumivelmente parte de uma transação P2SH), uma transação CLTV não é mantida fora da mempool como uma transação ```nLockTime```. Logo, assim que for verificado, ele vai para a blockchain e os fundos são considerados gastos. O truque é que todas as saídas que foram bloqueadas com o CLTV não estão disponíveis para _serem gastas_ até que o CLTV permita. -### Compreendendo um CLTV de tempo absoluto +### Compreendendo um CLTV de Tempo Absoluto É assim que o ```OP_CHECKLOCKTIMEVERIFY``` seria utilizado para verificar o locktime de 24 de maio de 2017: ``` @@ -36,7 +36,7 @@ Ou assim: OP_CHECKLOCKTIMEVERIFY ``` -### Compreendendo um CLTV de altura de bloco absoluta +### Compreendendo um CLTV de Altura de Bloco Absoluta É assim que o ```OPCHECKLOCKTIMEVERIFY``` compararia a uma altura de bloqueio alcançada no dia 24 de maio de 2017: ``` @@ -47,7 +47,7 @@ Mas geralmente vamos abstrair assim: OP_CHECKLOCKTIMEVERIFY ``` -### Entendendo como o CLTV realmente funciona +### Entendendo como o CLTV Realmente Funciona A explicação acima é suficiente para usar e entender o CLTV. No entanto, o [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) apresenta todos os seguintes detalhes. @@ -71,7 +71,7 @@ O seguinte script de bloqueio simples pode ser usado para transformar uma saída OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ``` -### Codificando um script CLTV +### Codificando um Script CLTV Obviamente, como acontece com quaisquer scripts Bitcoin complexos, este script CLTV seria realmente codificado em um script P2SH, conforme explicado na seção [§10.1: Entendendo a Fundação do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) e na [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md). @@ -116,7 +116,7 @@ No caso do exemplo acima, o script de desbloqueio abaixo seria suficiente, desde ``` -### Executando um script CLTV +### Executando um Script CLTV Para executar o Script, primeiro devemos concatenar os scripts de desbloqueio e bloqueio: ``` @@ -142,7 +142,7 @@ Stack: [ ] ``` Finalmente, o restante do script é executado, que é uma verificação normal de uma assinatura e chave pública. -## Resumo: Usando o CLTV nos Scripts +## Resumo: Usando CLTV em Scripts O ```OP-CHECKLOCKTIMEVERIFY``` é um opcode simples que olha para um único argumento, o interpreta como uma altura de bloco ou timestamp UNIX, e só permite que a UTXO seja desbloqueada se àquela altura de bloco ou timestamp UNIX estiver no passado. Definir o ```nLockTime``` na transação de gastos é o que permite ao Bitcoin fazer este cálculo. @@ -150,4 +150,4 @@ O ```OP-CHECKLOCKTIMEVERIFY``` é um opcode simples que olha para um único argu ## O Que Vem Depois? -Vamos continuar "Aumentando o poder do timelock com scripts do Bitcoin" na seção [§11.3: Usando o CSV nos Scripts](11_3_Using_CSV_in_Scripts.md). \ No newline at end of file +Vamos continuar "Capacitando Timelock com Scripts no Bitcoin" na seção [§11.3: Usando CSV em Scripts](11_3_Using_CSV_in_Scripts.md). \ No newline at end of file diff --git a/pt/11_3_Using_CSV_in_Scripts.md b/pt/11_3_Using_CSV_in_Scripts.md index ed337a4..cb5ab94 100644 --- a/pt/11_3_Using_CSV_in_Scripts.md +++ b/pt/11_3_Using_CSV_in_Scripts.md @@ -1,4 +1,4 @@ -# 11.3: Usando o CSV nos Scripts +# 11.3: Usando CSV em Scripts O ```nLockTime``` e o ```OP_CHECKLOCKTIMEVERIFY``` (ou CLTV) são apenas um lado da equação do timelock. Do outro lado estão o ```nSequence``` e o ```OP_CHECKSEQUENCEVERIFY```, que podem ser usados ​​para verificar tempos relativos ao invés de tempos absolutos. @@ -55,7 +55,7 @@ $ echo $relativevalue ``` Se convertermos de volta, teremos o valor de 4224679 = 10000000111011010100111. O 23º dígito é definido como "1", enquanto os primeiros 2 bytes, 0111011010100111, são convertidos em 76A7 em hexadecimal ou 30375 em decimal. Multiplicando isso por 512, teremos 15,55 milhões de segundos, o que de fato é 180 dias. -## Criando uma transação com um timelock relativo +## Criando uma Transação com um Timelock Relativo Então desejamos criar uma transação simples com um timelock relativo? Tudo que precisamos fazer é emitir uma transação onde o ```nSequence``` de uma entrada é definido como mostramos acima: Com o ```nSequence``` para essa entrada definido de forma que os primeiros dois bytes definam o timelock, o 23º bit define o tipo do timelock, e o 32º bit é definido como sendo falso. @@ -87,7 +87,7 @@ Neste caso, usaremos uma abreviatura: > :warning: **ATENÇÃO:** Lembre-se de que um timelock relativo é um intervalo de tempo desde a mineração da UTXO usada como uma entrada. _Não_ é um intervalo de tempo após a criação da transação. Se usarmos uma UTXO que já foi confirmada cem vezes, e colocarmos um timelock relativo de 100 blocos nela, ela será elegível para mineração imediatamente. Os timelocks relativos têm alguns usos muito específicos, mas provavelmente não se aplicam se nosso único objetivo for determinar algum tempo definido no futuro. -### Entendendo como o CSV realmente funciona +### Entendendo como o CSV Realmente Funciona O CSV tem muitas das mesmas sutilezas de uso que CLTV: @@ -99,7 +99,7 @@ O CSV tem muitas das mesmas sutilezas de uso que CLTV: Assim como no CLTV, quando estiver usando uma UTXO com um CSV em condições de bloqueio, devemos definir o ```nSequence``` para habilitar a transação. Normalmente, o configuraremos com o valor exato no script de bloqueio. -## Escrevendo um script CSV +## Escrevendo um Script CSV Assim como o ```OP_CHECKLOCKTIMEVERIFY```, o ```OP_CHECKSEQUENCEVERIFY``` inclui um ```OP_VERIFY``` implícito e deixa os argumentos na pilha, exigindo um ```OP_DROP``` quando finalizar tudo. @@ -108,7 +108,7 @@ Um script que bloquearia fundos por até seis meses após a mineração e que ex <+6Months> OP_CHECKSEQUENCEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ``` -### Codificando um script CSV +### Codificando um Script CSV Ao codificar um script CSV, precisamos tomar cuidado ao codificar o valor inteiro para o timelock relativo. Deve ser passado como um número inteiro de 3 bytes, o que significa que iremos ignorar o maior byte, o que pode desativar o timelock relativo. Como é um número inteiro, precisamos nos certificar de convertê-lo para little-endian. @@ -137,7 +137,7 @@ Hexcode: 03a77640 Para gastar uma UTXO bloqueado com um script CSV, devemos definir o ```nSequence``` dessa entrada para um valor maior que o requerido no script, mas menor que o tempo entre a UTXO e o bloco atual. Isso mesmo, isso significa que precisamos saber o requisito exato no script de bloqueio. Mas temos uma cópia do ```redeemScript```, então se não conhecermos os requisitos, podemos desserializá-lo e, em seguida, definir o ```nSequence``` como sendo o número que é mostrado lá. -## Resumo: Usando o CSV nos Scripts +## Resumo: Usando CSV em Scripts O ```nSequence``` e o CSV oferecem uma alternativa para o ```nLockTime``` e o CLTV onde bloqueamos uma transação com base em um tempo relativo desde que a entrada foi extraída, ao invés de basear o bloqueio em um tempo definido no futuro. Eles funcionam quase de forma idêntica, exceto pelo fato de que o valor do ```nSequence``` é codificado de forma ligeiramente diferente do valor do ```nLockTime```, com bits específicos significando coisas específicas. @@ -145,4 +145,4 @@ O ```nSequence``` e o CSV oferecem uma alternativa para o ```nLockTime``` e o CL ## O Que Vem Depois? -Vamos avançar "Criando Scripts do Bitcoin" no capítulo [12: Expandindo os Scripts do Bitcoin](12_0_Expanding_Bitcoin_Scripts.md). \ No newline at end of file +Vamos avançar em "Programando no Bitcoin" com o [Capítulo 12: Expandindo os Scripts do Bitcoin](12_0_Expanding_Bitcoin_Scripts.md). \ No newline at end of file From df6329a101c422650b3eac32098af2979758a3c2 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:01:43 -0300 Subject: [PATCH 138/155] Revise chapter 13 titles, fix typos --- pt/13_1_Writing_Puzzle_Scripts.md | 2 +- pt/13_2_Writing_Complex_Multisig_Scripts.md | 4 ++-- pt/13_3_Empowering_Bitcoin_with_Scripts.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pt/13_1_Writing_Puzzle_Scripts.md b/pt/13_1_Writing_Puzzle_Scripts.md index 3b4ce1f..1c1950b 100644 --- a/pt/13_1_Writing_Puzzle_Scripts.md +++ b/pt/13_1_Writing_Puzzle_Scripts.md @@ -1,4 +1,4 @@ -# 13.1: Escrevendo Scripts de Quebra-Cabeça +# 13.1: Escrevendo Scripts de Quebra-Cabeças Os scripts de Bitcoin realmente _não_ precisam depender do conhecimento de uma chave secreta. Ao invés disso, eles podem ser quebra-cabeças de qualquer tipo. diff --git a/pt/13_2_Writing_Complex_Multisig_Scripts.md b/pt/13_2_Writing_Complex_Multisig_Scripts.md index e76e463..04be15a 100644 --- a/pt/13_2_Writing_Complex_Multisig_Scripts.md +++ b/pt/13_2_Writing_Complex_Multisig_Scripts.md @@ -1,4 +1,4 @@ -# 13.2: Escrevendo Scripts Multisig Complexos +# 13.2: Escrevendo Scripts Complexos de Multisig Até o momento, os multisigs descritos nesses documentos têm sido inteiramente simples, na forma m-de-n ou n-de-n. No entanto, podemos desejar multisigs mais complexos, onde as pessoas que assinam as transações variam ou onde diferentes opções podem se tornar disponíveis ao longo do tempo. @@ -140,7 +140,7 @@ Observe que este script requer que um ```True``` ou ```False``` seja passado par No início, o seguinte ```sigScript``` seria permitido: ```0 True```. Após 30 dias, Alice poderia produzir um ```sigScript``` como este: ``` False```. -## Resumo: Escrevendo Scripts Multisig Complexos +## Resumo: Escrevendo Scripts Complexos de Multisig Os multisigs mais complexos podem ser normalmente criados combinando assinaturas ou multi-assinaturas com condicionais e testes. Os multisigs resultantes podem ser variáveis, exigindo diferentes números de assinantes com base em quem são e quando estão assinando. diff --git a/pt/13_3_Empowering_Bitcoin_with_Scripts.md b/pt/13_3_Empowering_Bitcoin_with_Scripts.md index 03334e8..ad16bcf 100644 --- a/pt/13_3_Empowering_Bitcoin_with_Scripts.md +++ b/pt/13_3_Empowering_Bitcoin_with_Scripts.md @@ -271,6 +271,6 @@ Vamos ficar "Usando o Tor" no [Capítulo Quatorze: Usando o Tor](14_0_Using_Tor. Ou, se preferir, existem dois caminhos alternativos: -Se quiser manter o foco no Bitcoin, siga em frente para "Programando com o RPC" no [Capítulo Quinze: Conversando com Bitcoind usando C](15_0_Talking_to_Bitcoind.md). +Se quiser manter o foco no Bitcoin, siga em frente para "Programando com RPC" no [Capítulo Dezesseis: Conversando com Bitcoind com C](16_0_Talking_to_Bitcoind.md). -Ou, se quiser manter o foco na linha de comando porque não é um programador, pode pular para o [Capítulo Dezoito: Entendendo Nossa Configuração da Lightning](18_0_Understanding_Your_Lightning_Setup.md) para continuar seus estudos da linha de comando com a Lightning Network. \ No newline at end of file +Ou, se quiser manter o foco na linha de comando porque não é um programador, pode pular para o [Capítulo Dezenove: Compreendendo Nossa Configuração da Lightning](19_0_Understanding_Your_Lightning_Setup.md) para continuar seus estudos da linha de comando com a Lightning Network. \ No newline at end of file From c12abd193869e7bde6bf83f2da5c135aa1af232e Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:01:58 -0300 Subject: [PATCH 139/155] Revise chapter 14 titles, fix typos --- pt/14_0_Using_Tor.md | 6 +++--- pt/14_1_Verifying_Your_Tor_Setup.md | 2 +- pt/14_3_Adding_SSH_Hidden_Services.md | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pt/14_0_Using_Tor.md b/pt/14_0_Using_Tor.md index dc6b633..5633f1e 100644 --- a/pt/14_0_Using_Tor.md +++ b/pt/14_0_Using_Tor.md @@ -16,6 +16,6 @@ Os objetivos secundários incluem a capacidade de: ## Tabela de Conteúdo -* [Seção 1: Verificando a Sua Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) -* [Seção 2: Mudando os Seus Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) -* [Seção 3: Adicionando um Serviço SSH Oculto](14_3_Adding_SSH_Hidden_Services.md) \ No newline at end of file +* [Seção 1: Verificando Nossa Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) +* [Seção 2: Mudando Nossos Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) +* [Seção 3: Adicionando Serviços SSH Ocultos](14_3_Adding_SSH_Hidden_Services.md) \ No newline at end of file diff --git a/pt/14_1_Verifying_Your_Tor_Setup.md b/pt/14_1_Verifying_Your_Tor_Setup.md index 2fce253..6037656 100644 --- a/pt/14_1_Verifying_Your_Tor_Setup.md +++ b/pt/14_1_Verifying_Your_Tor_Setup.md @@ -1,4 +1,4 @@ -# 14.1: Verificando a Configuração do Tor +# 14.1: Verificando Nossa Configuração do Tor > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. diff --git a/pt/14_3_Adding_SSH_Hidden_Services.md b/pt/14_3_Adding_SSH_Hidden_Services.md index 56e7bec..34b3aef 100644 --- a/pt/14_3_Adding_SSH_Hidden_Services.md +++ b/pt/14_3_Adding_SSH_Hidden_Services.md @@ -1,10 +1,10 @@ -# 14.3: Adicionando um Serviço SSH Oculto +# 14.3: Adicionando Serviços SSH Ocultos >:information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Até agora, usamos o Tor com os nossos serviços Bitcoin, mas também podemos usá-lo para proteger outros serviços em nossa máquina, melhorando a segurança e a privacidade. Esta seção demonstra como fazer isso, introduzindo um serviço ```ssh``` oculto para fazer o login remotamente usando o Tor. -## Criando serviços SSH ocultos +## Criando Serviços SSH Ocultos Novos serviços são criados adicionando-os ao arquivo ```/etc/tor/torrc```: ``` @@ -48,12 +48,12 @@ Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion' (ECDSA) to the list of known hosts. standup@qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion's password: ``` -## Resumo: Adicionando um Serviço SSH Oculto +## Resumo: Adicionando Serviços SSH Ocultos Agora que instalamos o Tor e sabemos como usá-lo, podemos adicionar outros serviços ao Tor. Apenas adicionamos as linhas ao nosso ```torrc``` (no nosso servidor) e o conectamos com o ```torify``` (no nosso cliente). > :fire: ***Qual é o poder de utilizar outros serviços ocultos?*** Cada vez que acessamos um serviço em nosso servidor remotamente, deixamos pegadas na rede. Mesmo que os dados sejam criptografados usando SSH (ou TLS), os vigias da rede podem ver de onde estamos nos conectando, para onde estamos conectando e qual serviço estamos usando. Isso realmente importa pra nós? Esta é a pergunta que devemos fazer. Mas se a resposta for "Sim", podemos proteger a conexão com um serviço oculto. -Vamos seguir "Programando com o RPC" no [Capítulo Dezesseis: Conversando com o Bitcoind usando C](16_0_Talking_to_Bitcoind.md). +## O Que Vem Depois? -Ou, se você não for um programador, pode pular para o [Capítulo Dezenove: Entendendo Nossa Configuração da Lightning](19_0_Understanding_Your_Lightning_Setup.md) para aumentar nosso conhecimento sobre a Lightning Network usando a linha de comando. \ No newline at end of file +Para um tipo diferente de privacidade, vamos seguir para "Usando o I2P" com o [Capítulo Quize: Usando o I2P](15_0_Using_i2p.md) \ No newline at end of file From 41eefa15ff2e7746faed0ff37d7381f1581f0fcb Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:02:18 -0300 Subject: [PATCH 140/155] Revise chapter 16 titles, fix typos --- pt/16_0_Talking_to_Bitcoind.md | 11 +++-- pt/16_1_Accessing_Bitcoind_with_C.md | 29 +++++++------ pt/16_2_Programming_Bitcoind_with_C.md | 41 +++++++++---------- ...Receiving_Bitcoind_Notifications_with_C.md | 13 +++--- 4 files changed, 45 insertions(+), 49 deletions(-) diff --git a/pt/16_0_Talking_to_Bitcoind.md b/pt/16_0_Talking_to_Bitcoind.md index 88bde29..a3bc9a2 100644 --- a/pt/16_0_Talking_to_Bitcoind.md +++ b/pt/16_0_Talking_to_Bitcoind.md @@ -1,5 +1,4 @@ - -# Capítulo 15: Conversando com Bitcoind usando C +# Capítulo 16: Conversando com Bitcoind com C Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. @@ -19,9 +18,9 @@ Os objetivos secundários do capítulo incluem a capacidade de: * Compreender as capacidades do ZMQ; * Entender como usar uma biblioteca ZMQ. -## Tabela de conteúdo +## Tabela de Conteúdo - * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) - * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) - * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) + * [Seção 1: Acessando o Bitcoind em C com Bibliotecas RPC](16_1_Accessing_Bitcoind_with_C.md) + * [Seção 2: Programando o Bitcoind em C com Bibliotecas RPC](16_2_Programming_Bitcoind_with_C.md) + * [Seção 3: Recebendo Notificações em C com Bibliotecas ZMQ](16_3_Receiving_Bitcoind_Notifications_with_C.md) \ No newline at end of file diff --git a/pt/16_1_Accessing_Bitcoind_with_C.md b/pt/16_1_Accessing_Bitcoind_with_C.md index 2e97e1c..b6e3aec 100644 --- a/pt/16_1_Accessing_Bitcoind_with_C.md +++ b/pt/16_1_Accessing_Bitcoind_with_C.md @@ -1,5 +1,4 @@ - -# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC +# 16.1: Acessando o Bitcoind em C com Bibliotecas RPC > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. @@ -29,7 +28,7 @@ $ git clone https://github.com/gitmarek/libbitcoinrpc > :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. -### Compilando o libbitcoinrpc. +### Compilando o libbitcoinrpc Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: ``` @@ -91,7 +90,7 @@ Installing man pages install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 ``` -## Preparando o código +## Preparando o Código ``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. @@ -107,7 +106,7 @@ Precisaremos também vincular as bibliotecas apropriadas sempre que possamos com $ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode ``` -## Construindo a conexão +## Construindo a Conexão Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. @@ -154,7 +153,7 @@ Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fech bitcoinrpc_global_cleanup(); ``` -### Testando o código de teste +### Testando o Código de Teste O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). @@ -167,7 +166,7 @@ Successfully connected to server! > :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. -## Fazendo uma chamada ao RPC +## Fazendo uma Chamada ao RPC Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). ``` c @@ -188,7 +187,7 @@ Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos a bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); ``` -### Mostrando o retorno da chamada +### Mostrando o Retorno da Chamada Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: ``` c @@ -222,7 +221,7 @@ printf("Block Count: %d\n",blocks); > :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. -### Testando o código de informação +### Testando o Código de Informação Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). ``` @@ -253,11 +252,11 @@ Just the Result: { Block Count: 1804406 ``` -## Fazendo uma chamada RPC usando argumentos +## Fazendo uma Chamada RPC Usando Argumentos Mas e se a sua chamada RPC tiver argumentos? -### Criando uma matriz JSON +### Criando uma Matriz JSON Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. @@ -275,7 +274,7 @@ Observe que existem duas variantes para o comando de anexação: ``json_array_ap Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. -### Atribuindo os parâmetros +### Atribuindo os Parâmetros Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: ``` c @@ -283,12 +282,12 @@ bitcoinrpc_method_set_params(rpc_method, params) ``` Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. -## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC +## Resumo: Acessando o Bitcoind em C com Bibliotecas RPC Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. -* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. +* :fire: ***Qual é o poder do C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. ## O Que Vem Depois? -Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). +Vamos falar mais um pouco no "Conversando com o Bitcoind com C" no capítulo [16.2: Programando o Bitcoind em C com Bibliotecas RPC](16_2_Programming_bitcoind_with_c.md). diff --git a/pt/16_2_Programming_Bitcoind_with_C.md b/pt/16_2_Programming_Bitcoind_with_C.md index c1fdc38..67458a9 100644 --- a/pt/16_2_Programming_Bitcoind_with_C.md +++ b/pt/16_2_Programming_Bitcoind_with_C.md @@ -1,11 +1,10 @@ - -# 15.2: Programando o Bitcoind usando C com bibliotecas RPC +# 16.2: Programando o Bitcoind usando C com bibliotecas RPC > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. -A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. +A seção [§16.1](16_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. -## Planejando o código +## Planejando o Código Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: @@ -18,7 +17,7 @@ Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao 7. Assinar a transação; 8. Enviar a transação. -### Planejando para o futuro +### Planejando para o Futuro Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: @@ -31,11 +30,11 @@ Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. -## Escrevendo o sistema de transação +## Escrevendo o Sistema de Transação Agora estamos prontos para realizar o passo a passo do nosso plano -### Etapa 1: Solicitando um endereço e uma quantia +### Etapa 1: Solicitando um Endereço e uma Quantia Inserir as informações é bem simples se usarmos os argumentos na linha de comando: ``` c @@ -54,7 +53,7 @@ printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); > :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. -### Etapa 2: Definindo uma taxa arbitrária +### Etapa 2: Definindo uma Taxa Arbitrária Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: @@ -65,9 +64,9 @@ float tx_total = tx_amount + tx_fee; > :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. -### Etapa 3: Preparando nosso RPC +### Etapa 3: Preparando Nosso RPC -Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: +Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na seção [§16.1: Acessando o Bitcoind com C](16_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: ``` c bitcoinrpc_global_init(); rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); @@ -157,7 +156,7 @@ if(!tx_id) { > **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. -### Etapa 5: Criando um endereço de troco +### Etapa 5: Criando um Endereço de Troco Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: ``` c @@ -188,7 +187,7 @@ A única diferença é quais informações específicas são extraídas do objet > :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. -### Etapa 6: Criando uma transação bruta +### Etapa 6: Criando uma Transação Bruta Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. @@ -200,7 +199,7 @@ createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex" Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. -#### Etapa 6.1: Criando os parâmetros de entrada +#### Etapa 6.1: Criando os Parâmetros de Entrada Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): ``` c @@ -220,7 +219,7 @@ inputparams = json_array(); json_array_append(inputparams,inputtxid); ``` -#### Etapa 6.2: Criando os parâmetros de saída +#### Etapa 6.2: Criando os Parâmetros de Saída Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: ``` c @@ -248,7 +247,7 @@ json_array_append(params,inputparams); json_array_append(params,outputparams); ``` -#### Etapa 6.4: Fazendo a chamada ao RPC +#### Etapa 6.4: Fazendo a Chamada ao RPC Vamos usar o método normal para criar uma chamada ao RPC: ``` c @@ -271,7 +270,7 @@ lu_result = json_object_get(lu_response,"result"); char *tx_rawhex = strdup(json_string_value(lu_result)); ``` -### Etapa 7. Assinando a transação +### Etapa 7. Assinando a Transação É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: ``` c @@ -301,7 +300,7 @@ json_decref(lu_signature); ``` > :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. -### Etapa 8. Enviando a transação +### Etapa 8. Enviando a Transação Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: ``` c @@ -329,9 +328,9 @@ printf("Txid: %s\n",tx_newid); O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. -## Testando o código +## Testando o Código -O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). +O código completo pode ser encontrado no [diretório src/](src/16_2_sendtoaddress.c). Compile-o como de costume: ``` @@ -345,10 +344,10 @@ Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 ``` Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). -## Resumo do Programando o Bitcoind usando C com bibliotecas RPC +## Resumo: Programando o Bitcoind em C com Bibliotecas RPC Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. ## O Que Vem Depois? -Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file +Aprenda mais sobre "Programando o Bitcoind com C" na próxima seção [16.3: Recebendo notificações usando C com a biblioteca ZMQ](16_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md index fe166ac..4f081a8 100644 --- a/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md +++ b/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md @@ -1,9 +1,8 @@ - -# 15.3 Recebendo notificações usando C com a biblioteca ZMQ +# 16.3 Recebendo Notificações em C com Bibliotecas ZMQ > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. -As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. +As sessões [§16.1](16_1_Accessing_Bitcoind_with_C.md) e [§16.2](16_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: a capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. > :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). @@ -58,7 +57,7 @@ $ sudo apt-get install libczmq-dev ``` Agora estamos pronto para escrever o código! -## Escrevendo o programa de notificação +## Escrevendo o Programa de Notificação O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. @@ -120,7 +119,7 @@ Claro, quando terminar o processo, precisamos limpar tudo: } ``` -### Testando o código de notificação +### Testando o Código de Notificação O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: ``` @@ -144,7 +143,7 @@ No: 70 ....... ``` -### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ +### Resumo: Recebendo Notificações em C com Bibliotecas ZMQ Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. @@ -152,4 +151,4 @@ Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo- ## O Que Vem Depois? -Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file +Saiba mais sobre "Programando com RPC" no [Capítulo 17: Programando o Bitcoin com Libwally](17_0_Programming_with_Libwally.md). \ No newline at end of file From acb6c1f8f069d99329cb18cd0ff34d14f86c5609 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:02:32 -0300 Subject: [PATCH 141/155] Revise chapter 17 titles, fix typos --- pt/17_1_Setting_Up_Libwally.md | 6 +++--- pt/17_2_Using_BIP39_in_Libwally.md | 4 ++-- pt/17_3_Using_BIP32_in_Libwally.md | 6 +++--- pt/17_5_Using_Scripts_in_Libwally.md | 2 +- pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pt/17_1_Setting_Up_Libwally.md b/pt/17_1_Setting_Up_Libwally.md index 2e24409..57f5810 100644 --- a/pt/17_1_Setting_Up_Libwally.md +++ b/pt/17_1_Setting_Up_Libwally.md @@ -1,4 +1,4 @@ -# 16.1: Configurando a Libwally +# 17.1: Configurando a Libwally > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -129,7 +129,7 @@ Em ambos os casos, o argumento é para flags, mas atualmente está definido como ## Testando um Programa de Teste da Libwally -O diretório src contém o arquivo [testwally.c](src / 16_1_testwally.c), que apenas mostra como funcionam as funções de inicialização e de limpeza. +O diretório src contém o arquivo [testwally.c](src/17_1_testwally.c), que apenas mostra como funcionam as funções de inicialização e de limpeza. Podemos compilá-lo da seguinte maneira: ``` @@ -192,4 +192,4 @@ Então, o que exatamente podemos fazer agora? É para dar essa resposta que temo ## O Que Vem Depois? -Vamos aprender mais sobre "Programando Bitcoin com Libwally" na seção [§16.2: Usando BIP39 na Libwally](16_2_Using_BIP39_in_Libwally.md). \ No newline at end of file +Vamos aprender mais sobre "Programando o Bitcoin com Libwally" na seção [§17.2: Usando BIP39 na Libwally](17_2_Using_BIP39_in_Libwally.md). \ No newline at end of file diff --git a/pt/17_2_Using_BIP39_in_Libwally.md b/pt/17_2_Using_BIP39_in_Libwally.md index e8ab746..10967ab 100644 --- a/pt/17_2_Using_BIP39_in_Libwally.md +++ b/pt/17_2_Using_BIP39_in_Libwally.md @@ -1,4 +1,4 @@ -# 16.2: Usando BIP39 na Libwally +# 17.2: Usando BIP39 na Libwally > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -103,4 +103,4 @@ O BIP39 nos permite gerar um conjunto de 12-24 palavras Mnemônicas a partir de ## O Que Vem Depois? -Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§17.3: Usando o BIP32 no Libwally](16_3_Using_BIP32_in_Libwally.md). \ No newline at end of file +Vamos aprender mais sobre "Programando o Bitcoind usando o Libwally" na seção [§17.3: Usando o BIP32 no Libwally](17_3_Using_BIP32_in_Libwally.md). \ No newline at end of file diff --git a/pt/17_3_Using_BIP32_in_Libwally.md b/pt/17_3_Using_BIP32_in_Libwally.md index 46749c8..d85b510 100644 --- a/pt/17_3_Using_BIP32_in_Libwally.md +++ b/pt/17_3_Using_BIP32_in_Libwally.md @@ -1,4 +1,4 @@ -# 17.3: Usando o BIP32 na Libwally +# 17.3: Usando BIP32 na Libwally > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -129,7 +129,7 @@ Account xpub key: tpubDWFQG78gYHzCkACXxkeh2LwWo8MVLm3YkTGd85LJwtpBB6xp4KwseGTEvx [m/84'/1'/0'/0/0]: tb1q0knqq26ek59pfl7nukzqr28m2zl5wn2f0ldvwu ``` -## Resumo: Usando o BIP32 na Libwally +## Resumo: Usando BIP32 na Libwally Uma carteira HD permite gerar um grande número de chaves a partir de uma única seed. Agora sabemos como essas chaves são organizadas no BIP44, BIP84 e no Bitcoin Core, além de como derivá-las, começando com uma seed ou palavras mnemônicas. @@ -139,4 +139,4 @@ Uma carteira HD permite gerar um grande número de chaves a partir de uma única ## O Que Vem Depois? -Vamos aprender mais sobre "Programando Bitcoin com Libwally" na seção [§17.4: Usando PSBTs na Libwally](16_4_Using_PSBTs_in_Libwally.md). \ No newline at end of file +Vamos aprender mais sobre "Programando Bitcoin com Libwally" na seção [§17.4: Usando PSBTs na Libwally](17_4_Using_PSBTs_in_Libwally.md). \ No newline at end of file diff --git a/pt/17_5_Using_Scripts_in_Libwally.md b/pt/17_5_Using_Scripts_in_Libwally.md index 2fb7458..b8df034 100644 --- a/pt/17_5_Using_Scripts_in_Libwally.md +++ b/pt/17_5_Using_Scripts_in_Libwally.md @@ -6,7 +6,7 @@ Na seção 3 deste capítulo, ao apresentar os scripts, dissemos que era prováv ## Criando o Script -Criar o script é a coisa _mais fácil_ de se fazer na Libwally. Veja o exemplo a seguir, um simples [Script Quebra-Cabeça](13_1_Writing_Puzzle_Scripts.md) ao qual retornamos de vez em quando: +Criar o script é a coisa _mais fácil_ de se fazer na Libwally. Veja o exemplo a seguir, um simples [Script de Quebra-Cabeças](13_1_Writing_Puzzle_Scripts.md) ao qual retornamos de vez em quando: ``` OP_ADD 99 OP_EQUAL ``` diff --git a/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md b/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md index 91c267c..df3e176 100644 --- a/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md +++ b/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md @@ -1,4 +1,4 @@ -# 17.7: Integranda Libwally e Bitcoin-CLI +# 17.7: Integrando Libwally e Bitcoin-CLI > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. From 642a642e56a849abf688a2b96102e332fe070261 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:02:48 -0300 Subject: [PATCH 142/155] Revise chapter 18 titles, fix typos --- pt/18_1_Accessing_Bitcoind_with_Go.md | 2 +- pt/18_6_Accessing_Bitcoind_with_Swift.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pt/18_1_Accessing_Bitcoind_with_Go.md b/pt/18_1_Accessing_Bitcoind_with_Go.md index 76d5f64..1a3b43e 100644 --- a/pt/18_1_Accessing_Bitcoind_with_Go.md +++ b/pt/18_1_Accessing_Bitcoind_with_Go.md @@ -417,4 +417,4 @@ Embora o `btcd` e o `rpcclient` tenham alguns limites, ainda podemos executar os ## O Que Vem Depois? -Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§18.2: Acessando Bitcoin com Java](18_2_Accessing_Bitcoind_with_Java.md). \ No newline at end of file +Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§18.2: Acessando o Bitcoin com Java](18_2_Accessing_Bitcoind_with_Java.md). \ No newline at end of file diff --git a/pt/18_6_Accessing_Bitcoind_with_Swift.md b/pt/18_6_Accessing_Bitcoind_with_Swift.md index 27a4cd3..471c376 100644 --- a/pt/18_6_Accessing_Bitcoind_with_Swift.md +++ b/pt/18_6_Accessing_Bitcoind_with_Swift.md @@ -399,7 +399,7 @@ O Swift é uma linguagem de programação robusta e moderna que infelizmente ain ## O Que Vem Depois? -Aprenda sobre o Lightning em [Capítulo 19: Compreendendo Sua Configuração da Lightning](19_0_Understanding_Your_Lightning_Setup.md). +Aprenda sobre o Lightning em [Capítulo 19: Compreendendo Nossa Configuração da Lightning](19_0_Understanding_Your_Lightning_Setup.md). ## Variante: Implantando o Swift no Ubuntu From 7ed3215cf0eecd7bb77f4832a678a60924116d44 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:03:04 -0300 Subject: [PATCH 143/155] Revise chapter 19 titles, fix typos --- pt/19_0_Understanding_Your_Lightning_Setup.md | 8 ++++---- pt/19_1_Verifying_Your_Lightning_Setup.md | 6 +++--- pt/19_2_Knowing_Your_lightning_Setup.md | 6 +++--- pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md | 8 ++++---- pt/19_3_Setting_Up_a_Channel.md | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pt/19_0_Understanding_Your_Lightning_Setup.md b/pt/19_0_Understanding_Your_Lightning_Setup.md index 279604f..4edcb98 100644 --- a/pt/19_0_Understanding_Your_Lightning_Setup.md +++ b/pt/19_0_Understanding_Your_Lightning_Setup.md @@ -1,4 +1,4 @@ -# Capítulo 19: Compreendendo a Configuração da Lightning +# Capítulo 19: Compreendendo Nossa Configuração da Lightning > :information_source: **NOTA:** Este é um rascunho que está em andamento. Seu objetivo é que possa obter alguns comentários dos revisores iniciais. Ainda não está pronto para ser produzido. @@ -20,7 +20,7 @@ Os objetivos secundários do capítulo incluem a capacidade de: ## Tabela de Conteúdo -* [Seção 1: Verificando a Configuração da c-lightning](19_1_Verifying_Your_Lightning_Setup.md) -* [Seção 2: Conhecendo a Configuração da c-lightning](19_2_Knowing_Your_lightning_Setup.md) +* [Seção 1: Verificando Nossa Configuração da c-lightning](19_1_Verifying_Your_Lightning_Setup.md) +* [Seção 2: Conhecendo Nossa Configuração da c-lightning](19_2_Knowing_Your_lightning_Setup.md) * [Adendo: Acessando um Segundo Node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md) -* [Seção 3: Criando um Canal na Lightning](19_3_Setting_Up_a_Channel.md) \ No newline at end of file +* [Seção 3: Criando um Canal Lightning](19_3_Setting_Up_a_Channel.md) \ No newline at end of file diff --git a/pt/19_1_Verifying_Your_Lightning_Setup.md b/pt/19_1_Verifying_Your_Lightning_Setup.md index cbf3844..1fb81ba 100644 --- a/pt/19_1_Verifying_Your_Lightning_Setup.md +++ b/pt/19_1_Verifying_Your_Lightning_Setup.md @@ -1,4 +1,4 @@ -# 19.1: Verificando a Configuração da c-lightning +# 19.1: Verificando Nossa Configuração da c-lightning >: information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -258,13 +258,13 @@ Também existe um arquivo de configuração geral (o padrão é `~/.lightning/co Nossa configuração pode não ter nenhum arquivo de configuração: a c-lightning será executada com uma boa configuração padrão, sem eles. -## Resumo: Verificando a Configuração da c-lightning +## Resumo: Verificando Nossa Configuração da c-lightning Antes de começar a brincar com a lightning, devemos nos certificar de que nossos aliases estão configurados, nosso `lightningd` está rodando e nosso node está sincronizado. Também podemos querer configurar algum acesso a configurações alternativas da Lightning, em outras redes. ## O Que Vem Depois? -Vamos continuar "Compreendendo a Configuração da Lightning" na seção [§19.2: Conhecendo a Configuração da c-lightning](19_2_Knowing_Your_lightning_Setup.md). +Vamos continuar "Compreendendo a Configuração da Lightning" na seção [§19.2: Conhecendo Nossa Configuração da c-lightning](19_2_Knowing_Your_lightning_Setup.md). ## Variante: Instalando do Ubuntu ppa diff --git a/pt/19_2_Knowing_Your_lightning_Setup.md b/pt/19_2_Knowing_Your_lightning_Setup.md index 044cf8c..928bc25 100644 --- a/pt/19_2_Knowing_Your_lightning_Setup.md +++ b/pt/19_2_Knowing_Your_lightning_Setup.md @@ -1,4 +1,4 @@ -# 19.2: Conhecendo a Configuração da c-lightning +# 19.2: Conhecendo Nossa Configuração da c-lightning > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -329,12 +329,12 @@ c$ lightning-cli --testnet listconfigs } ``` -## Resumo: Conhecendo a Configuração da c-lightning +## Resumo: Conhecendo Nossa Configuração da c-lightning O diretório `~/.lightning` contém todos os arquivos, enquanto o comando `lightning-cli help` mostra uma variedade de informações dos comandos que podem ser usados para obter mais informações sobre a configuração e o funcionamento da Lightning Network. ## O Que Vem Depois? -Precisaremos de um segundo node para testar o pagamento dos invoices. Se precisarmos de suporte para configurar um, podemos ler o [Adendo: Acessando um Segundo Node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md). +Precisaremos de um segundo node para testar o pagamento dos invoices. Se precisarmos de suporte para configurar um, podemos ler o [Prefácio: Acessando um Segundo Node Lightning](19_2__Interlude_Accessing_a_Second_Lightning_Node.md). Caso contrário, vamos continuar "Compreendendo a Configuração da Lightning" na seção [§19.3: Criando um Canal na Lightning](19_3_Setting_Up_a_Channel.md). \ No newline at end of file diff --git a/pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md b/pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md index 33f330d..a0c9af2 100644 --- a/pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md +++ b/pt/19_2__Interlude_Accessing_a_Second_Lightning_Node.md @@ -1,4 +1,4 @@ -# Adendo: Acessando um Segundo Node Lightning +# Prefácio: Acessando um Segundo Node Lightning > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -315,12 +315,12 @@ c$ lightning-cli --network=testnet listpeers ``` No entanto, este definitivamente não será o caso na nossa primeira interação com a Lightning Network. -## Resumo: Adendo: Acessando um Segundo Node Lightning +## Resumo: Prefácio: Acessando um Segundo Node Lightning Sempre precisaremos de dois nodes Lightning para formar um canal. Se não tivermos outra pessoa que está testando as coisas conosco, precisaremos criar um segundo node, usanda c-lightning ou (como faremos em nossos exemplos) usando a LND. ## O Que Vem Depois? -Embora possivelmente tenhamos criado um LND, a c-lightning permanecerá no centro dos nossos exemplos até que precisemos começar a usar os dois, no [Capítulo 19](19_0_Understanding_Your_Lightning_Setup.md). +Embora possivelmente tenhamos criado um LND, a c-lightning permanecerá no centro dos nossos exemplos até que precisemos começar a usar os dois, no [Capítulo 20](20_0_Using_Lightning.md). -Vamos continuar "Compreendendo a Configuração da Lightning" na seção [§19.3: Criando um Canal na Lightning](19_3_Setting_Up_a_Channel.md). +Vamos continuar "Compreendendo Nossa Configuração da Lightning" na seção [§19.3: Criando um Canal Lightning](19_3_Setting_Up_a_Channel.md). diff --git a/pt/19_3_Setting_Up_a_Channel.md b/pt/19_3_Setting_Up_a_Channel.md index 386c43e..3acb931 100644 --- a/pt/19_3_Setting_Up_a_Channel.md +++ b/pt/19_3_Setting_Up_a_Channel.md @@ -1,4 +1,4 @@ -# 19.3: Criando um Canal na Lightning +# 19.3: Criando um Canal Lightning > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. @@ -176,10 +176,10 @@ Esta transação de financiamento também pode ser encontrada onchain pelo TXID > :book: ***O que é a capacidade do canal?*** Em um canal Lightning, ambos os lados do canal possuem uma parte da capacidade. O valor do seu lado do canal é chamado de *saldo local (local balance)* e o valor do outro lado é chamado de *saldo remoto (remote balance)*. Ambos os saldos podem ser atualizados muitas vezes sem fechar o canal (quando o saldo final é enviado para a blockchain), mas a capacidade do canal não pode mudar sem fechá-lo. A capacidade total de um canal é a soma do saldo de cada participante do canal. -## Resumo: Criando um Canal na Lightning +## Resumo: Criando um Canal Lightning Precisaremos criar um canal com um node remoto para poder receber e enviar dinheiro pela Lightning Network. ## O Que Vem Depois? -Você está pronto para passar para o [Capítulo 20: Usando Lightning](20_0_Using_Lightning.md). \ No newline at end of file +Você está pronto para passar para o [Capítulo 20: Usando a Lightning](20_0_Using_Lightning.md). \ No newline at end of file From 65617c873deeaa8a8b029a71dafb8818ff249408 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:03:20 -0300 Subject: [PATCH 144/155] Revise chapter 20 titles, fix typos --- pt/20_0_Using_Lightning.md | 9 ++++----- pt/20_2_Paying_a_Invoice.md | 2 +- pt/20_3_Closing_a_Channel.md | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pt/20_0_Using_Lightning.md b/pt/20_0_Using_Lightning.md index 748bcde..a8cabca 100644 --- a/pt/20_0_Using_Lightning.md +++ b/pt/20_0_Using_Lightning.md @@ -19,8 +19,7 @@ Os objetivos secundários do capítulo incluem a capacidade de: ## Tabela de Conteúdo -* [Seção 1: Gerando um Invoice](19_1_Generate_a_Payment_Request.md) -* [Seção 2: Pagando um Invoice](19_2_Paying_a_Invoice.md) -* [Seção 3: Fechando um Canal na Lightning](19_3_Closing_a_Channel.md) -* [Seção 4: Expandindo a Lightning Network](19_4_Lightning_Network_Review.md) - +* [Seção 1: Gerando um Invoice](20_1_Generate_a_Payment_Request.md) +* [Seção 2: Pagando um Invoice](20_2_Paying_a_Invoice.md) +* [Seção 3: Fechando um Canal Lightning](20_3_Closing_a_Channel.md) +* [Seção 4: Expandindo a Lightning Network](20_4_Lightning_Network_Review.md) diff --git a/pt/20_2_Paying_a_Invoice.md b/pt/20_2_Paying_a_Invoice.md index 3abb6d5..5aa6676 100644 --- a/pt/20_2_Paying_a_Invoice.md +++ b/pt/20_2_Paying_a_Invoice.md @@ -203,4 +203,4 @@ Depois de recebermos um invoice, é fácil pagar com um único comando na Lightn ## O Que Vem Depois? -Vamos continuar "Usando a Lightning" na seção [§20.3: Fechando um Canal na Lightning](20_3_Closing_a_Channel.md). \ No newline at end of file +Vamos continuar "Usando a Lightning" na seção [§20.3: Fechando um Canal Lightning](20_3_Closing_a_Channel.md). \ No newline at end of file diff --git a/pt/20_3_Closing_a_Channel.md b/pt/20_3_Closing_a_Channel.md index 15b1683..5f66157 100644 --- a/pt/20_3_Closing_a_Channel.md +++ b/pt/20_3_Closing_a_Channel.md @@ -256,4 +256,4 @@ Ao fechar um canal, realizamos uma transação na blockchain encerrando nosso re ## O Que Vem Depois? -Vamos continuar "Usando a Lightning" na seção [§20.4: Expandindo a Rede Lightning](20_4_Lightning_Network_Review.md). \ No newline at end of file +Vamos continuar "Usando a Lightning" na seção [§20.4: Expandindo a Lightning Network](20_4_Lightning_Network_Review.md). \ No newline at end of file From a9a9056681e48583d9d804052274ac6e6c8dc841 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 21 Sep 2021 11:03:42 -0300 Subject: [PATCH 145/155] Revise appendix titles, fix typos --- pt/A1_0_Understanding_Bitcoin_Standup.md | 2 +- pt/A2_0_Compiling_Bitcoin_from_Source.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pt/A1_0_Understanding_Bitcoin_Standup.md b/pt/A1_0_Understanding_Bitcoin_Standup.md index 1e04418..52e615f 100644 --- a/pt/A1_0_Understanding_Bitcoin_Standup.md +++ b/pt/A1_0_Understanding_Bitcoin_Standup.md @@ -26,7 +26,7 @@ Se fornecemos um endereço IP, o acesso `ssh` será limitado a esse endereço, d ## Etapa 5: Configurando o Tor -O Tor é instalado para fornecer serviços protegidos (ocultos) para acessar os comandos RPC do Bitcoin através do nosso servidor. Podemos consultar a seção [§14.1: Verificando a Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) para obter mais informações sobre a configuração do Tor. +O Tor é instalado para fornecer serviços protegidos (ocultos) para acessar os comandos RPC do Bitcoin através do nosso servidor. Podemos consultar a seção [§14.1: Verificando Nossa Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) para obter mais informações sobre a configuração do Tor. Se criarmos um cliente autorizado para os serviços ocultos, o acesso será limitado a essa chave, que está em `/var/lib/tor/standup/authorized_clients`. Caso contrário, na seção [§14.2](14_2_Changing_Your_Bitcoin_Hidden_Services.md) explicamos como podemos fazê-la depois. diff --git a/pt/A2_0_Compiling_Bitcoin_from_Source.md b/pt/A2_0_Compiling_Bitcoin_from_Source.md index cc24de8..4ad0c77 100644 --- a/pt/A2_0_Compiling_Bitcoin_from_Source.md +++ b/pt/A2_0_Compiling_Bitcoin_from_Source.md @@ -122,6 +122,6 @@ Se quisermos aumentar a segurança da instalação do Bitcoin a partir da fonte, ## O Que Vem Depois? -Se estávamos no processo de criação de um node de Bitcoin para usar neste curso, devemos continuar com o [Capítulo 3: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). +Se estávamos no processo de criação de um node Bitcoin para usar neste curso, devemos continuar com o [Capítulo 3: Compreendendo Nossa Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). Se estivermos lendo os apêndices, vamos continuar com o [Apêndice 3: Usando o Bitcoin Regtest](A3_0_Using_Bitcoin_Regtest.md). \ No newline at end of file From d5d1fc36b1b13514e286fade94aabf7b1e5faefc Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 22 Sep 2021 16:18:08 -0300 Subject: [PATCH 146/155] Fix link --- pt/15_1_i2p_service.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pt/15_1_i2p_service.md b/pt/15_1_i2p_service.md index 5d288f5..fce8aaf 100644 --- a/pt/15_1_i2p_service.md +++ b/pt/15_1_i2p_service.md @@ -121,4 +121,4 @@ Agora temos um servidor do Bitcoin acessível através da rede I2P no nosso novo Siga em frente para o "Programando com RPC" no [Capítulo Dezesseis: Conversando com o Bitcoind com C](16_0_Talking_to_Bitcoind.md). -Ou, se não formos programadores, podemos pular para o [Capítulo Dezenove: Compreendendo Sua Configuração Lightning](https://github.com/namcios/Learning-Bitcoin-from-the-Command-Line/blob/portuguese-translation/pt/18_0_Understanding_Your_Lightning_Setup.md) para continuarmos nosso aprendizado da linha de comando com a rede Lightning. \ No newline at end of file +Ou, se não formos programadores, podemos pular para o [Capítulo Dezenove: Compreendendo Sua Configuração Lightning](https://github.com/namcios/Learning-Bitcoin-from-the-Command-Line/blob/portuguese-translation/pt/19_0_Understanding_Your_Lightning_Setup.md) para continuarmos nosso aprendizado da linha de comando com a rede Lightning. From 76728baf0c9b19ff17c1554d2336f4fe394e446b Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 22 Sep 2021 17:12:54 -0300 Subject: [PATCH 147/155] Translate 03_4 --- pt/03_4_Receiving_a_Transaction.md | 319 +++++++++++++++++++++++++++++ 1 file changed, 319 insertions(+) create mode 100644 pt/03_4_Receiving_a_Transaction.md diff --git a/pt/03_4_Receiving_a_Transaction.md b/pt/03_4_Receiving_a_Transaction.md new file mode 100644 index 0000000..92a4b04 --- /dev/null +++ b/pt/03_4_Receiving_a_Transaction.md @@ -0,0 +1,319 @@ +# 3.4: Recebendo uma Transação + +Agora estamos prontos para receber dinheiro no endereço que configuramos. + +## Pegando um Pouco de Dinheiro + +Para fazermos qualquer coisa a mais, precisamos de dinheiro. Na testnet, isso é feito por meio de _faucets_. Como o dinheiro é de mentira, basta irmos a um faucet e pedirmos um pouco de dinheiro que ele será enviado para nós. Sugerimos usar o faucet em https://testnet-faucet.mempool.co/, https://bitcoinfaucet.uo1.net/ ou https://testnet.coinfaucet.eu/en/. Se eles não estiverem disponíveis por algum motivo, podemos pesquisar por "bitcoin testnet faucet" na internet e encontrar outros. + +Para usarmos um faucet, geralmente precisamos acessar uma URL e copiar e colar nosso endereço. Observe que este é um daqueles casos em que não seremos capazes de usar variáveis de linha de comando, infelizmente. Posteriormente, será criada uma transação que enviará dinheiro da faucet para nós. + +> :book: ***O que é uma transação?*** Uma transação é uma troca de bitcoins. O proprietário de alguns bitcoins usa sua chave privada para acessar essas moedas e, em seguida, bloqueia a transação usando a chave pública do destinatário. + +> :link: **TESTNET vs MAINNET:** Infelizmente, não existem faucets na vida real. Se estivéssemos usando a mainnet, precisaríamos ir e realmente comprar bitcoins em uma exchange de bitcoins ou em um caixa eletrônico, ou precisaríamos que alguém os enviasse para nós. A vida na testnet é muito mais fácil. + +## Verificando o Nosso Dinheiro + +Depois de solicitarmos nosso dinheiro, devemos ser capazes de verificá-lo com o comando `bitcoin-cli getbalance`: +``` +$ bitcoin-cli getbalance +0.00000000 +``` +Mas espere, não há nenhum saldo ainda!? + + +Bem-vindo ao mundo da latência do Bitcoin. O problema é que nossa transação ainda não foi gravada em bloco! + +> :book: ***O que é um bloco?*** As transações são transmitidas pela rede e reunidas em blocos pelos mineradores. Esses blocos são protegidos com uma prova de trabalho matemática (em inglês, _proof-of-work_, ou PoW), que prova que o poder de computação foi gasto como parte da criação do bloco. É essa prova de trabalho (multiplicada por muitos blocos, cada um construído sobre o último) que mantém o Bitcoin seguro. + +> :book: ***O que é um minerador?*** Um minerador é um participante na rede Bitcoin que trabalha para criar blocos. É um trabalho remunerado: quando um minerador cria um bloco com sucesso, ele recebe uma recompensa única mais as taxas pelas transações em seu bloco. A mineração é um grande negócio. Os mineradores tendem a funcionar em hardware especial, acelerado de maneiras que tornam mais provável que sejam capazes de criar blocos. Eles também tendem a fazer parte de pools de mineração (_mining pools_), onde todos os mineradores concordam em dividir as recompensas quando um deles cria um bloco com sucesso. + +Felizmente, `bitcoin-cli getunconfirmedbalance` ainda deve mostrar nosso saldo atualizado, desde que a transação inicial tenha sido criada: +``` +$ bitcoin-cli getunconfirmedbalance +0.01010000 +``` + +Se ainda estiver mostrando um zero, provavelmente estamos avançando neste tutorial rápido demais. Espere um segundo. As moedas devem aparecer não confirmadas e, em seguida, mover rapidamente para confirmadas. Observe que uma moeda pode passar de um saldo não confirmado para o confirmado quase imediatamente, portanto, devemos nos certificar de verificar os dois. No entanto, se o `getbalance` e o `getunconfirmedbalance` ainda mostrarem zero em dez minutos, então provavelmente há algo errado com a faucet e precisaremos escolher outra. + +### Ganhando Confiança no Nosso Dinheiro + +Podemos usar `bitcoin-cli getbalance" * "[n]`, onde substituimos `[n]` por um inteiro, para ver se um saldo confirmado tem 'n' blocos de profundidade. + +> :book: ***O que é a profundidade do bloco?*** Depois que um bloco é construído e confirmado, outro bloco é construído em cima dele e então outro ... Como este é um processo estocástico, há alguma chance de reversão quando um bloco ainda é novo. Portanto, um bloco deve ser "enterrado" vários blocos ao fundo de uma cadeia antes que possamos nos sentir totalmente confiante em nossos fundos. Cada um desses blocos tende a ser construído em uma média de 10 minutos ... então normalmente leva cerca de uma hora para uma transação confirmada receber seis blocos de profundidade, que é a medida para confiança completa no Bitcoin. + +O seguinte mostra que nossas transações foram confirmadas uma vez, mas não duas vezes: +``` +$ bitcoin-cli getbalance "*" 1 +0.01010000 +$ bitcoin-cli getbalance "*" 2 +0.00000000 +``` + +Obviamente, a cada dez minutos mais ou menos essa profundidade aumentará. + +É claro que, na testnet, ninguém está tão preocupado com a confiabilidade dos nossos fundos. nós poderemos gastar nosso dinheiro assim que for confirmado. + +## Verificando Nossa Carteira + +O comando `bitcoin-cli getwalletinfo` fornece mais informações sobre o saldo da nossa carteira: +``` +$ bitcoin-cli getwalletinfo +{ + "walletname": "", + "walletversion": 169900, + "balance": 0.01010000, + "unconfirmed_balance": 0.00000000, + "immature_balance": 0.00000000, + "txcount": 2, + "keypoololdest": 1592335137, + "keypoolsize": 999, + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", + "keypoolsize_hd_internal": 1000, + "paytxfee": 0.00000000, + "private_keys_enabled": true, + "avoid_reuse": false, + "scanning": false +} +``` + +## Descobrindo o ID da Nossa Transação + +Nosso dinheiro entrou na nossa carteira por meio de uma transação. Podemos descobrir o ID da transação (txid) com o comando `bitcoin-cli listtransactions`: +``` +$ bitcoin-cli listtransactions +[ + { + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 1, + "confirmations": 1, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 73, + "blocktime": 1592600085, + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "walletconflicts": [ + ], + "time": 1592599884, + "timereceived": 1592599884, + "bip125-replaceable": "no" + }, + { + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.00010000, + "label": "", + "vout": 0, + "confirmations": 1, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 72, + "blocktime": 1592600085, + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "walletconflicts": [ + ], + "time": 1592599938, + "timereceived": 1592599938, + "bip125-replaceable": "no" + } +] + +``` +Isto mostra duas transações (`8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9`) e (` ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36`) para uma quantidade específica (`0.01000000` e `0.00010000`), que foram recebidas (`receive`) pelo mesmo endereço em nossa carteira (` mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE`) . À propósito, isso é uma má higiene de chave: devemos usar um novo endereço para cada Bitcoin que recebermos. Nesse caso, ficamos impacientes porque a primeira faucet parecia não estar funcionando. + +Podemos acessar informações semelhantes com o comando `bitcoin-cli listunspent`, mas ele só mostra as transações para o dinheiro que não gastamos. Eles são chamados de UTXOs e serão de vital importância quando estivermos enviando dinheiro de volta para o mundo Bitcoin: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + }, + { + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "vout": 1, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.01000000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + } +] +``` +Observe que os bitcoins não são simplesmente uma bagunça homogênea de dinheiro enfiado no nosso bolso. Cada transação individual que recebemos ou enviamod é colocada no livro razão da blockchain imutável, em um bloco. Podemos ver essas transações individuais quando olhamos para o nosso dinheiro não gasto. Isso significa que os gastos com bitcoins não são tão anônimos quanto se pensa. Embora os endereços sejam bastante privados, as transações podem ser examinadas à medida que entram e saem dos endereços. Isso torna a privacidade vulnerável à análise estatística. Também introduz uma potencial não fungibilidade para bitcoins, já que se pode rastrear uma série de transações, mesmo se não puder rastrear um "bitcoin" específico. + +> :book: ***Why are all of these bitcoin amounts in fractions?*** Bitcoins are produced slowly, and so there are relatively few in circulation. As a result, each bitcoin over on the mainnet is worth quite a bit (~ $9,000 at the time of this writing). This means that people usually work in fractions. In fact, the .0101 in Testnet coins would be worth about $100 if they were on the mainnet. For this reason, names have appeared for smaller amounts of bitcoins, including millibitcoins or mBTCs (one-thousandth of a bitcoin), microbitcoins or bits or μBTCs (one-millionth of a bitcoin), and satoshis (one hundred millionth of a bitcoin). + +>: book: ***Por que todas essas quantidades de bitcoin em frações?*** Os bitcoins são produzidos lentamente e, portanto, há relativamente poucos em circulação. Como resultado, cada bitcoin na rede principal vale um pouco (~ $9.000 no momento em que este livro foi escrito). Isso significa que as pessoas geralmente trabalham em frações. Na verdade, o 0,0101 em moedas Testnet valeria cerca de $100 se eles estivessem na rede principal. Por esse motivo, surgiram nomes para quantidades menores de bitcoins, incluindo milibitcoins ou mBTCs (um milésimo de um bitcoin), microbitcoins ou bits ou μBTCs (um milionésimo de um bitcoin) e satoshis (um centésimo de milionésimo de um bitcoin). + +## Examinando Nossa Transação + +Podemos adquirir maiores informações em uma transação com o comando `bitcoin-cli gettransaction`: +``` +$ bitcoin-cli gettransaction "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9" +{ + "amount": 0.01000000, + "confirmations": 1, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 73, + "blocktime": 1592600085, + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "walletconflicts": [ + ], + "time": 1592599884, + "timereceived": 1592599884, + "bip125-replaceable": "no", + "details": [ + { + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 1 + } + ], + "hex": "0200000000010114d04977d1b0137adbf51dd5d79944b9465a2619f3fa7287eb69a779977bf5800100000017160014e85ba02862dbadabd6d204fcc8bb5d54658c7d4ffeffffff02df690f000000000017a9145c3bfb36b03f279967977ca9d1e35185e39917788740420f00000000001976a9141b72503639a13f190bf79acf6d76255d772360b788ac0247304402201e74bdfc330fc2e093a8eabe95b6c5633c8d6767249fa25baf62541a129359c202204d462bd932ee5c15c7f082ad7a6b5a41c68addc473786a0a9a232093fde8e1330121022897dfbf085ecc6ad7e22fc91593414a845659429a7bbb44e2e536258d2cbc0c270b1b00" +} +``` +O comando `gettransaction` detalhará transações que estão na nossa carteira, como esta, que nos foi enviada. + +Observe que `gettransaction` tem dois argumentos opcionais: +``` +$ bitcoin-cli help gettransaction +gettransaction "txid" ( include_watchonly verbose ) + +Get detailed information about in-wallet transaction + +Arguments: +1. txid (string, required) The transaction id +2. include_watchonly (boolean, optional, default=true for watch-only wallets, otherwise false) Whether to include watch-only addresses in balance calculation and details[] +3. verbose (boolean, optional, default=false) Whether to include a `decoded` field containing the decoded transaction (equivalent to RPC decoderawtransaction) +``` +Configurando esses dois para true ou false, podemos escolher se queremos incluir endereços "watch-only" no resultado (com os quais não nos importamos) ou vermos um resultado mais extenso (o que queremos). + +Aqui estão os dados quando definimos `include_watchonly` como `false` e `verbose` como `true`. +``` +$ bitcoin-cli gettransaction "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9" false true +{ + "amount": 0.01000000, + "confirmations": 3, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 73, + "blocktime": 1592600085, + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "walletconflicts": [ + ], + "time": 1592599884, + "timereceived": 1592599884, + "bip125-replaceable": "no", + "details": [ + { + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 1 + } + ], + "hex": "0200000000010114d04977d1b0137adbf51dd5d79944b9465a2619f3fa7287eb69a779977bf5800100000017160014e85ba02862dbadabd6d204fcc8bb5d54658c7d4ffeffffff02df690f000000000017a9145c3bfb36b03f279967977ca9d1e35185e39917788740420f00000000001976a9141b72503639a13f190bf79acf6d76255d772360b788ac0247304402201e74bdfc330fc2e093a8eabe95b6c5633c8d6767249fa25baf62541a129359c202204d462bd932ee5c15c7f082ad7a6b5a41c68addc473786a0a9a232093fde8e1330121022897dfbf085ecc6ad7e22fc91593414a845659429a7bbb44e2e536258d2cbc0c270b1b00", + "decoded": { + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "hash": "d4ae2b009c43bfe9eba96dcd16e136ceba2842df3d76a67d689fae5975ce49cb", + "version": 2, + "size": 249, + "vsize": 168, + "weight": 669, + "locktime": 1772327, + "vin": [ + { + "txid": "80f57b9779a769eb8772faf319265a46b94499d7d51df5db7a13b0d17749d014", + "vout": 1, + "scriptSig": { + "asm": "0014e85ba02862dbadabd6d204fcc8bb5d54658c7d4f", + "hex": "160014e85ba02862dbadabd6d204fcc8bb5d54658c7d4f" + }, + "txinwitness": [ + "304402201e74bdfc330fc2e093a8eabe95b6c5633c8d6767249fa25baf62541a129359c202204d462bd932ee5c15c7f082ad7a6b5a41c68addc473786a0a9a232093fde8e13301", + "022897dfbf085ecc6ad7e22fc91593414a845659429a7bbb44e2e536258d2cbc0c" + ], + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01010143, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 5c3bfb36b03f279967977ca9d1e35185e3991778 OP_EQUAL", + "hex": "a9145c3bfb36b03f279967977ca9d1e35185e399177887", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N1ev1WKevSsdmAvRqZf7JjvDg223tPrVCm" + ] + } + }, + { + "value": 0.01000000, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1b72503639a13f190bf79acf6d76255d772360b7 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE" + ] + } + } + ] + } +} +``` +Agora podemos ver todas as informações sobre a transação, incluindo todas as entradas ("vin") e todas as saídas ("vout). Uma das coisas interessantes a se notar é que, embora tenhamos recebido 0,01 BTC na transação, outro 0.01010143 foi enviado para outro endereço. Provavelmente era um endereço de troco, um conceito que será explorado na próxima seção. É bastante comum uma transação ter várias entradas e/ou várias saídas. + +Existe outro comando, `getrawtransaction`, que nos permite ver as transações que não estão em nossa carteira. No entanto, requer que tenhamos um node não prunado e `txindex = 1` em nosso arquivo `bitcoin.conf`. A menos que tenhamos uma necessidade séria de informações que não estão em nossa carteira, provavelmente é melhor usarmos um explorador de Bitcoin para esse tipo de coisa ... + +## Opcional: Usando um Explorador de Blocos + +Até mesmo olhar para as informações detalhadas de uma transação pode ser um pouco intimidante. O principal objetivo deste tutorial é ensinar como lidar com transações brutas da linha de comando, mas ficaremos felizes em falar sobre outras ferramentas quando elas forem aplicáveis. Uma dessas ferramentas é um explorador de blocos, que você pode usar para ver as transações de um navegador da web em um formato muito mais amigável. + +Atualmente, nosso explorador de bloco preferido é [https://live.blockcypher.com/](https://live.blockcypher.com/). + +Podemos usá-lo para procurar transações para um endereço: + +[https://live.blockcypher.com/btc-testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE/](https://live.blockcypher.com/btc-testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE/) + +Também podemos usá-lo para ver transações individuais: + +[https://live.blockcypher.com/btc-testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9/](https://live.blockcypher.com/btc-testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9/) + +Um explorador de bloco geralmente não fornece mais informações do que uma linha de comando em uma transação bruta; ele apenas destaca as informações importantes e junta as peças do quebra-cabeça, incluindo as taxas de transação por trás de uma transação - outro conceito que abordaremos nas próximas seções. + +## Resumo: Recebendo uma Transação + +As faucets nos vão dar dinheiro na testnet. O dinheiro vem como transações brutas, que podem ser examinadas com `gettransaction` ou um explorador de blocos. Assim que recebermos uma transação, poderemos vê-la em nosso saldo e em nossa carteira. + +## O Que Vem Depois? + +Para sabermos como os endereços são descritos, para que eles possam ser transferidos ou transformados em partes de uma assinatura múltipla, podemos consultar [§3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md). + +Mas se isso for muito aprofundado, podemos continuar no [Capítulo Quatro: Enviando Transações no Bitcoin](04_0_Sending_Bitcoin_Transactions.md). From f1c4403e1955e1010e7c5ff7a29a380548defc9d Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 22 Sep 2021 17:56:17 -0300 Subject: [PATCH 148/155] Translate 03_5 --- pt/03_5_Understanding_the_Descriptor.md | 151 ++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 pt/03_5_Understanding_the_Descriptor.md diff --git a/pt/03_5_Understanding_the_Descriptor.md b/pt/03_5_Understanding_the_Descriptor.md new file mode 100644 index 0000000..d776868 --- /dev/null +++ b/pt/03_5_Understanding_the_Descriptor.md @@ -0,0 +1,151 @@ +# 3.5: Compreendendo o Descritor + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Cuidado, leitor. + + +Você deve ter notado um campo `desc:` estranho no comando `listunspent` da seção anterior. Aqui está o que está acontecendo (e como ele pode ser usado para transferir endereços). + +> :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v 0.17.0 que continuou a ser expandida através do Bitcoin Core 0.20.0. A maioria dos comandos nesta seção são de 0.17.0, mas o `importmulti` atualizado que suporta descritores é de 0.18.0. + +## Sabendo Sobre Transferência de Endereços + +A maior parte deste curso presume que estejamos trabalhando inteiramente a partir de um único node onde gerenciamos nossa própria carteira, enviando e recebendo pagamentos com os endereços criados por essa carteira. No entanto, não é necessariamente assim que funciona o ecossistema Bitcoin por completo. Nesse caso, é mais provável que movamos endereços entre carteiras e até mesmo configuremos carteiras para vigiar fundos controlados por carteiras diferentes. + +É aí que entram os descritores. Eles são mais úteis se estivermos interagindo com _outro_ software que não seja o Bitcoin Core, e se realmente precisemos nos apoiar neste tipo de função de compatibilidade: consulte [§6.1] (https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/pt/06_1_Sending_a_Transaction_to_a_Multisig.md) para um exemplo do mundo real de como ter a capacidade de descritores é fundamental. + +Mover endereços entre carteiras costumava focar em `xpub` e` xprv`, e esses ainda são suportados. + +> :book: ***O que é xprv?*** Uma chave privada estendida (_xtended private key_). Esta é a combinação de uma chave privada e um código de cadeia. É uma chave privada da qual uma sequência inteira de chaves privadas filhas pode ser derivada. + +> :book: ***O que é xpub?*** Uma chave pública estendida (_xtended public key_). Esta é a combinação de uma chave pública e um código de cadeia. É uma chave pública da qual uma sequência inteira de chaves públicas filhas pode ser derivada. + + +O fato de que podemos ter uma "sequência inteira de chaves filhas" revela o fato de que "xpub" e "xprv" não são chaves padrão como falamos até agora. Em vez disso, são chaves hierárquicas que podem ser usadas para criar famílias inteiras de chaves, baseadas na ideia de carteiras HD. + +> :book: ***O que é uma Carteira HD?*** A maioria das carteiras modernas é construída com base no [BIP32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). Este é um design hierárquico em que uma única semente pode ser usada para gerar uma sequência completa de chaves. A carteira inteira pode então ser restaurada a partir dessa semente, em vez de exigir a restauração de cada chave privada. + +> :book: ***O que é um caminho de derivação?*** Quando você tem chaves hierárquicas, precisa ser capaz de definir chaves individuais como descendentes de uma semente. Por exemplo, `[0]` é a 0ª chave, `[0/1]` é o primeiro filho da 0ª chave, `[1/0/1]` é o primeiro neto do filho zero da 1ª chave. Algumas chaves também contêm um `'` após o número, para mostrar que estão protegidas, o que as protege de um ataque específico que pode ser usado para derivar uma `xprv` de uma `xpub`. Você não precisa se preocupar com os detalhes, a não ser o fato de que esses `'`s causarão problemas de formatação ao trabalhar na linha de comando. + +> :information_source: **NOTA:** um caminho de derivação define uma chave, o que significa que uma chave representa um caminho de derivação. Eles são equivalentes. No caso de um descritor, o caminho de derivação permite ao `bitcoind` saber de onde veio a chave que segue no descritor! + +`xpubs` e `xprvs` provaram ser insuficientes quando os tipos de chaves públicas multiplicadas sob a [expansão SegWit](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_6_Creating_a_Segwit_Transaction.md), portanto a necessidade de "descritores de saída". + +> :book: ***O que é um descritor de saída?*** Uma descrição precisa de como derivar um endereço Bitcoin de uma combinação de uma função com uma ou mais entradas para essa função. + +A introdução de funções nos descritores é o que os torna poderosos, porque eles podem ser usados para transferir todos os tipos de endereços, desde os endereços legados com os quais estamos trabalhando agora até os endereços Segwit e multisig que encontraremos no futuro. Uma função individual corresponde a um determinado tipo de endereço e se correlaciona com regras específicas para gerar esse endereço. + +## Capturando um Descritor + +Descritores são visíveis em vários comandos, como por exemplo `listunspent` e `getaddressinfo`: +``` +$ bitcoin-cli getaddressinfo ms7ruzvL4atCu77n47dStMb3of6iScS8kZ +{ + "address": "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ", + "scriptPubKey": "76a9147f437379bcc66c40745edc1891ea6b3830e1975d88ac", + "ismine": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", + "iswatchonly": false, + "isscript": false, + "iswitness": false, + "pubkey": "03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388", + "iscompressed": true, + "ischange": false, + "timestamp": 1592335136, + "hdkeypath": "m/0'/0'/18'", + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", + "hdmasterfingerprint": "d6043800", + "labels": [ + "" + ] +} +``` +Neste caso, o descritor é `pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk`. + +## Compreendendo um Descritor + +Um descritor é composto de várias partes: +``` +função([caminho-de-derivação]chave)#checksum +``` +Aqui está o que tudo isso significa: +* **Função.** A função que é usada para criar um endereço a partir dessa chave. Nestes casos, é `pkh`, que é o endereço padrão P2PKH legado que você encontrou em [§3.3: Configurando Nossa Carteira](03_3_Setting_Up_Your_Wallet.md). Da mesma forma, um endereço P2WSH SegWit usaria `wsh` e um endereço P2WPKH usaria` wpkh`. +* **Caminho de Derivação.** Descreve qual parte de uma carteira HD está sendo exportada. Neste caso, é uma semente com a impressão digital `d6043800` e então o 18º filho do 0º filho do 0º filho (`0 '/ 0' / 18'`) dessa semente. Também pode haver uma derivação adicional após a chave: `função([caminho-de-derivação]chave/mais-derivação)#checksum` + * É importante notar aqui que, se algum dia recebermos um caminho de derivação sem uma impressão digital, poderemos inventá-lo. Acontece que, se houver um existente, devemos usá-lo, porque se algum dia voltarmos para o dispositivo que criou a impressão digital, precisaremos ter o mesmo. +* **Chave**. A chave ou as chaves que estão sendo transferidas. Isso pode ser algo tradicional como uma `xpub` ou `xprv`, pode ser apenas uma chave pública para um endereço, como neste caso, pode ser um conjunto de endereços para uma multi-assinatura, ou pode ser outra coisa. Estes são os dados principais: a função explica o que fazer com eles. +* **Checksum**. Os descritores são feitos para poderem ser transferidos por humanos. Esta soma de verificação (checksum) garante que o fizemos corretamente. + +Podemos ver [Informações do Suporte do Bitcoin Core ao Descritor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) para maiores informações. + +## Examinando um Descritor + +Podemos examinar um descritor com o comando RPC `getdescriptorinfo`: +``` +$ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk" +{ + "descriptor": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", + "checksum": "4ahsl9pk", + "isrange": false, + "issolvable": true, + "hasprivatekeys": false +} +``` +Observe que ele retorna um checksum. Se algum dia recebermos um descritor sem um checksum, podemos buscá-lo com este comando: +``` +$ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)" +{ + "descriptor": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", + "checksum": "4ahsl9pk", + "isrange": false, + "issolvable": true, + "hasprivatekeys": false +} +``` +Além de nos dar o checksum, esse comando também verifica a validade do descritor e nos dá informações úteis, como se o descritor contém chaves privadas. + +Um dos poderes de um descritor é a capacidade de derivar um endereço de forma padrão. Isto é feito com o RPC `deriveaddresses`. +``` +$ bitcoin-cli deriveaddresses "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk" +[ + "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ" +] +``` +Podemos observar que ele nos retorna o endereço inicial (como deveria). + +## Importando um Descritor + +Mas a coisa realmente importante sobre um descritor é que podemos levá-lo a outra máquina (remota) e importá-lo. Isto é feito com o RPC `importmulti` usando a opção `desc`: +``` +remote$ bitcoin-cli importmulti '[{"desc": "pkh([d6043800/0'"'"'/0'"'"'/18'"'"']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", "timestamp": "now", "watchonly": true}]' +[ + { + "success": true + } +] +``` +Primeiro, podemos notar nosso primeiro uso muito feio de aspas. Toda `'` no caminho de derivação pode ser substituído com `'"'"'`. Devemos esperar fazer isso se estivermos manipulando um descritor que contenha um caminho de derivação. (Outra opção é trocar o `'` com um `h` de "hardened", mas isto irá alterar nosso checksum, então caso tenhamos essa preferência pela facilidade de uso, precisaremos de umm novo checksum com o `getdescriptorinfo`.) + +Segundo, podemos notar que o marcamos como `watchonly`. Isso ocorre porque sabemos que é uma chave pública, então não podemos usá-la para gastar fundos. Se tivéssemos esquecido de colocar esta sinalização, `importmulti` teria dito algo como o seguinte: `Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.`. + +> :book: ***O que é um endereço watch-only?*** Um endereço watch-only nos permite atentar a transações de certo endereço (ou para toda uma família de endereços se tivermos usado uma `xpub`), mas não nos permite gastarmos fundos destes endereços. + +Usando `getaddressbylabel`, podemos ver que nosso endereço foi importado corretamente na nossa máquina remota! +``` +remote$ bitcoin-cli getaddressesbylabel "" +{ + "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ": { + "purpose": "receive" + } +} +``` +## Resumo: Compreendendo o Descritor + +Descritores nos permitem passar chaves públicas e privadas entre carteiras, mas mais do que isso, nos permitem definir endereços de forma correta e precisa, além de derivar endereços de tipos diversos a partir de um formato descritivo e padronizado. + +> :fire: ***Qual é o poder dos descritores?*** Descritores nos permitem importar e exportar chaves e seeds. O que é excelente se queremos movê-las entre carteiras diferentes. Como um desenvolvedor, eles também nos permitem construir o tipo preciso de endereços que queremos criar. Por exemplo, nós os utilizamos na [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2/blob/master/Docs/How-it-works.md) para gerarmos um multisig de três seeds. + +Faremos uso real dos descritores em [§7.3](07_3_Integrating_with_Hardware_Wallets.md), quando estivermos importando endereços de uma hardware wallet. + +## O Que Vem Depois? + +Vamos avançar no "bitcoin-cli" com o [Capítulo Quatro: Enviando Transações no Bitcoin](04_0_Sending_Bitcoin_Transactions.md). From 788d952a99560692d35207802492502c00b2975e Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 23 Sep 2021 16:59:10 -0300 Subject: [PATCH 149/155] reviewed --- pt/03_4_Receiving_a_Transaction.md | 45 ++++++++++++------------- pt/03_5_Understanding_the_Descriptor.md | 38 ++++++++++----------- 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/pt/03_4_Receiving_a_Transaction.md b/pt/03_4_Receiving_a_Transaction.md index 92a4b04..6375acb 100644 --- a/pt/03_4_Receiving_a_Transaction.md +++ b/pt/03_4_Receiving_a_Transaction.md @@ -4,13 +4,13 @@ Agora estamos prontos para receber dinheiro no endereço que configuramos. ## Pegando um Pouco de Dinheiro -Para fazermos qualquer coisa a mais, precisamos de dinheiro. Na testnet, isso é feito por meio de _faucets_. Como o dinheiro é de mentira, basta irmos a um faucet e pedirmos um pouco de dinheiro que ele será enviado para nós. Sugerimos usar o faucet em https://testnet-faucet.mempool.co/, https://bitcoinfaucet.uo1.net/ ou https://testnet.coinfaucet.eu/en/. Se eles não estiverem disponíveis por algum motivo, podemos pesquisar por "bitcoin testnet faucet" na internet e encontrar outros. +Para fazermos qualquer coisa a mais, precisamos de dinheiro. Na Testnet, isso é feito por meio de _faucets_. Como o dinheiro é de mentira, basta irmos a um faucet e pedirmos um pouco de dinheiro que ele será enviado para nós. Sugerimos usar o faucet em https://testnet-faucet.mempool.co/, https://bitcoinfaucet.uo1.net/ ou https://testnet.coinfaucet.eu/en/. Se eles não estiverem disponíveis por algum motivo, podemos pesquisar por "bitcoin testnet faucet" na internet e encontrar outros. -Para usarmos um faucet, geralmente precisamos acessar uma URL e copiar e colar nosso endereço. Observe que este é um daqueles casos em que não seremos capazes de usar variáveis de linha de comando, infelizmente. Posteriormente, será criada uma transação que enviará dinheiro da faucet para nós. +Para usarmos um faucet, geralmente precisamos acessar uma URL e copiar e colar nosso endereço. É importante observamos que este é um daqueles casos em que não seremos capazes de usar variáveis de linha de comando, infelizmente. Posteriormente, será criada uma transação que enviará dinheiro da faucet para nós. -> :book: ***O que é uma transação?*** Uma transação é uma troca de bitcoins. O proprietário de alguns bitcoins usa sua chave privada para acessar essas moedas e, em seguida, bloqueia a transação usando a chave pública do destinatário. +> :book: ***O que é uma transação?*** Uma transação é uma troca de bitcoins. O proprietário de alguns bitcoins usa sua chave privada para acessar essas moedas e, em seguida, bloqueia a transação usando a chave pública do destinatário. -> :link: **TESTNET vs MAINNET:** Infelizmente, não existem faucets na vida real. Se estivéssemos usando a mainnet, precisaríamos ir e realmente comprar bitcoins em uma exchange de bitcoins ou em um caixa eletrônico, ou precisaríamos que alguém os enviasse para nós. A vida na testnet é muito mais fácil. +> :link: **TESTNET vs MAINNET:** Infelizmente, não existem faucets na vida real. Se estivéssemos usando a Mainnet, precisaríamos realmente comprar bitcoins em uma exchange ou em um caixa eletrônico, ou precisaríamos que alguém os enviasse alguns satoshinhos. A vida na Testnet é muito mais fácil. ## Verificando o Nosso Dinheiro @@ -21,12 +21,11 @@ $ bitcoin-cli getbalance ``` Mas espere, não há nenhum saldo ainda!? - -Bem-vindo ao mundo da latência do Bitcoin. O problema é que nossa transação ainda não foi gravada em bloco! +Bem-vindo ao mundo da latência do Bitcoin. O problema é que nossa transação ainda não foi gravada no bloco! > :book: ***O que é um bloco?*** As transações são transmitidas pela rede e reunidas em blocos pelos mineradores. Esses blocos são protegidos com uma prova de trabalho matemática (em inglês, _proof-of-work_, ou PoW), que prova que o poder de computação foi gasto como parte da criação do bloco. É essa prova de trabalho (multiplicada por muitos blocos, cada um construído sobre o último) que mantém o Bitcoin seguro. -> :book: ***O que é um minerador?*** Um minerador é um participante na rede Bitcoin que trabalha para criar blocos. É um trabalho remunerado: quando um minerador cria um bloco com sucesso, ele recebe uma recompensa única mais as taxas pelas transações em seu bloco. A mineração é um grande negócio. Os mineradores tendem a funcionar em hardware especial, acelerado de maneiras que tornam mais provável que sejam capazes de criar blocos. Eles também tendem a fazer parte de pools de mineração (_mining pools_), onde todos os mineradores concordam em dividir as recompensas quando um deles cria um bloco com sucesso. +> :book: ***O que é um minerador?*** Um minerador é um participante na rede Bitcoin que trabalha para criar blocos. É um trabalho remunerado: quando um minerador cria um bloco com sucesso, ele recebe uma recompensa única mais as taxas pelas transações em seu bloco. A mineração é um grande negócio. Os mineradores tendem a utilizar hardwares especiais, projeto de maneiras que tornam mais provável que sejam capazes de criar blocos. Eles também tendem a fazer parte de pools de mineração (_mining pools_), onde todos os mineradores concordam em dividir as recompensas quando um deles cria um bloco com sucesso. Felizmente, `bitcoin-cli getunconfirmedbalance` ainda deve mostrar nosso saldo atualizado, desde que a transação inicial tenha sido criada: ``` @@ -34,13 +33,13 @@ $ bitcoin-cli getunconfirmedbalance 0.01010000 ``` -Se ainda estiver mostrando um zero, provavelmente estamos avançando neste tutorial rápido demais. Espere um segundo. As moedas devem aparecer não confirmadas e, em seguida, mover rapidamente para confirmadas. Observe que uma moeda pode passar de um saldo não confirmado para o confirmado quase imediatamente, portanto, devemos nos certificar de verificar os dois. No entanto, se o `getbalance` e o `getunconfirmedbalance` ainda mostrarem zero em dez minutos, então provavelmente há algo errado com a faucet e precisaremos escolher outra. +Se ainda estiver mostrando um zero, provavelmente estamos avançando neste tutorial rápido demais. Espere alguns segundos. As moedas devem aparecer não confirmadas e, em seguida, serão rapidamente confirmadas. Observe que uma moeda pode passar de um saldo não confirmado para o confirmado quase imediatamente, portanto, devemos nos certificar de verificar ambos. No entanto, se o `getbalance` e o `getunconfirmedbalance` ainda mostrarem zero nos próximos dez minutos, então provavelmente há algo errado com o faucet e precisaremos escolher outra. ### Ganhando Confiança no Nosso Dinheiro -Podemos usar `bitcoin-cli getbalance" * "[n]`, onde substituimos `[n]` por um inteiro, para ver se um saldo confirmado tem 'n' blocos de profundidade. +Podemos usar `bitcoin-cli getbalance" * "[n]`, onde substituímos `[n]` por um inteiro, para ver se um saldo confirmado tem 'n' blocos de profundidade. -> :book: ***O que é a profundidade do bloco?*** Depois que um bloco é construído e confirmado, outro bloco é construído em cima dele e então outro ... Como este é um processo estocástico, há alguma chance de reversão quando um bloco ainda é novo. Portanto, um bloco deve ser "enterrado" vários blocos ao fundo de uma cadeia antes que possamos nos sentir totalmente confiante em nossos fundos. Cada um desses blocos tende a ser construído em uma média de 10 minutos ... então normalmente leva cerca de uma hora para uma transação confirmada receber seis blocos de profundidade, que é a medida para confiança completa no Bitcoin. +> :book: ***O que é a profundidade do bloco?*** Depois que um bloco é construído e confirmado, outro bloco é construído em cima dele e então outro... Como este é um processo estocástico, há alguma chance de reversão quando um bloco ainda é novo. Portanto, um bloco deve ser "enterrado" vários blocos na blockchain antes que possamos nos sentir totalmente confiantes com nossos fundos. Cada um desses blocos tende a ser construído em uma média de 10 minutos, então normalmente leva cerca de uma hora para uma transação confirmada receber seis blocos de profundidade, que é a medida para completa confiança no Bitcoin. O seguinte mostra que nossas transações foram confirmadas uma vez, mas não duas vezes: ``` @@ -52,7 +51,7 @@ $ bitcoin-cli getbalance "*" 2 Obviamente, a cada dez minutos mais ou menos essa profundidade aumentará. -É claro que, na testnet, ninguém está tão preocupado com a confiabilidade dos nossos fundos. nós poderemos gastar nosso dinheiro assim que for confirmado. +É claro que, na Testnet, ninguém está tão preocupado com a confiabilidade dos fundos. Nós poderemos gastar nosso dinheiro assim que for confirmado. ## Verificando Nossa Carteira @@ -122,7 +121,7 @@ $ bitcoin-cli listtransactions ] ``` -Isto mostra duas transações (`8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9`) e (` ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36`) para uma quantidade específica (`0.01000000` e `0.00010000`), que foram recebidas (`receive`) pelo mesmo endereço em nossa carteira (` mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE`) . À propósito, isso é uma má higiene de chave: devemos usar um novo endereço para cada Bitcoin que recebermos. Nesse caso, ficamos impacientes porque a primeira faucet parecia não estar funcionando. +Isto mostra duas transações (`8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9`) e (` ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36`) para uma quantidade específica (`0.01000000` e `0.00010000`), que foram recebidas (`receive`) pelo mesmo endereço em nossa carteira (` mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE`) . À propósito, isso é uma boa prática para as chaves: devemos usar um novo endereço para cada Bitcoin que recebermos. Nesse caso, ficamos impacientes porque a primeira faucet parecia não estar funcionando. Podemos acessar informações semelhantes com o comando `bitcoin-cli listunspent`, mas ele só mostra as transações para o dinheiro que não gastamos. Eles são chamados de UTXOs e serão de vital importância quando estivermos enviando dinheiro de volta para o mundo Bitcoin: ``` @@ -156,11 +155,9 @@ $ bitcoin-cli listunspent } ] ``` -Observe que os bitcoins não são simplesmente uma bagunça homogênea de dinheiro enfiado no nosso bolso. Cada transação individual que recebemos ou enviamod é colocada no livro razão da blockchain imutável, em um bloco. Podemos ver essas transações individuais quando olhamos para o nosso dinheiro não gasto. Isso significa que os gastos com bitcoins não são tão anônimos quanto se pensa. Embora os endereços sejam bastante privados, as transações podem ser examinadas à medida que entram e saem dos endereços. Isso torna a privacidade vulnerável à análise estatística. Também introduz uma potencial não fungibilidade para bitcoins, já que se pode rastrear uma série de transações, mesmo se não puder rastrear um "bitcoin" específico. +Observe que os bitcoins não são simplesmente uma bagunça homogênea de dinheiro enfiado no nosso bolso. Cada transação individual que recebemos ou enviamos é colocada no livro razão da blockchain imutável, em um bloco. Podemos ver essas transações individuais quando olhamos para o nosso dinheiro não gasto. Isso significa que os gastos com bitcoins não são tão anônimos quanto pensamos. Embora os endereços sejam bastante privados, as transações podem ser examinadas à medida que entram e saem dos endereços. Isso torna a privacidade vulnerável à análise estatística. Também introduz uma potencial de não fungibilidade para os bitcoins, já que se pode rastrear uma série de transações, mesmo se não puder rastrear um "bitcoin" específico. -> :book: ***Why are all of these bitcoin amounts in fractions?*** Bitcoins are produced slowly, and so there are relatively few in circulation. As a result, each bitcoin over on the mainnet is worth quite a bit (~ $9,000 at the time of this writing). This means that people usually work in fractions. In fact, the .0101 in Testnet coins would be worth about $100 if they were on the mainnet. For this reason, names have appeared for smaller amounts of bitcoins, including millibitcoins or mBTCs (one-thousandth of a bitcoin), microbitcoins or bits or μBTCs (one-millionth of a bitcoin), and satoshis (one hundred millionth of a bitcoin). - ->: book: ***Por que todas essas quantidades de bitcoin em frações?*** Os bitcoins são produzidos lentamente e, portanto, há relativamente poucos em circulação. Como resultado, cada bitcoin na rede principal vale um pouco (~ $9.000 no momento em que este livro foi escrito). Isso significa que as pessoas geralmente trabalham em frações. Na verdade, o 0,0101 em moedas Testnet valeria cerca de $100 se eles estivessem na rede principal. Por esse motivo, surgiram nomes para quantidades menores de bitcoins, incluindo milibitcoins ou mBTCs (um milésimo de um bitcoin), microbitcoins ou bits ou μBTCs (um milionésimo de um bitcoin) e satoshis (um centésimo de milionésimo de um bitcoin). +>: book: ***Por que todas essas quantidades de bitcoin em frações?*** Os bitcoins são produzidos lentamente e, portanto, há relativamente poucos em circulação. Como resultado, cada bitcoin na rede principal valem relativamente bastante (pouco mais de 9 mil dólares no momento em que este livro foi escrito). Isso significa que as pessoas geralmente trabalham com frações. Na verdade, o 0,0101 em moedas Testnet valeria cerca de $100 se eles estivessem na rede principal. Por esse motivo, surgiram nomes para quantidades menores de bitcoins, incluindo milibitcoins ou mBTCs (um milésimo de um bitcoin), microbitcoins ou bits ou μBTCs (um milionésimo de um bitcoin) e satoshis (um centésimo de milionésimo de um bitcoin). ## Examinando Nossa Transação @@ -194,7 +191,7 @@ $ bitcoin-cli gettransaction "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc ``` O comando `gettransaction` detalhará transações que estão na nossa carteira, como esta, que nos foi enviada. -Observe que `gettransaction` tem dois argumentos opcionais: +Observando o `gettransaction` temos dois argumentos opcionais: ``` $ bitcoin-cli help gettransaction gettransaction "txid" ( include_watchonly verbose ) @@ -206,7 +203,7 @@ Arguments: 2. include_watchonly (boolean, optional, default=true for watch-only wallets, otherwise false) Whether to include watch-only addresses in balance calculation and details[] 3. verbose (boolean, optional, default=false) Whether to include a `decoded` field containing the decoded transaction (equivalent to RPC decoderawtransaction) ``` -Configurando esses dois para true ou false, podemos escolher se queremos incluir endereços "watch-only" no resultado (com os quais não nos importamos) ou vermos um resultado mais extenso (o que queremos). +Configurando esses dois como `true` ou `false`, podemos escolher se queremos incluir endereços "watch-only" no resultado (com os quais não nos importamos) ou vermos um resultado mais extenso (o que queremos). Aqui estão os dados quando definimos `include_watchonly` como `false` e `verbose` como `true`. ``` @@ -290,27 +287,27 @@ $ bitcoin-cli gettransaction "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc ``` Agora podemos ver todas as informações sobre a transação, incluindo todas as entradas ("vin") e todas as saídas ("vout). Uma das coisas interessantes a se notar é que, embora tenhamos recebido 0,01 BTC na transação, outro 0.01010143 foi enviado para outro endereço. Provavelmente era um endereço de troco, um conceito que será explorado na próxima seção. É bastante comum uma transação ter várias entradas e/ou várias saídas. -Existe outro comando, `getrawtransaction`, que nos permite ver as transações que não estão em nossa carteira. No entanto, requer que tenhamos um node não prunado e `txindex = 1` em nosso arquivo `bitcoin.conf`. A menos que tenhamos uma necessidade séria de informações que não estão em nossa carteira, provavelmente é melhor usarmos um explorador de Bitcoin para esse tipo de coisa ... +Existe outro comando, `getrawtransaction`, que nos permite ver as transações que não estão em nossa carteira. No entanto, requer que tenhamos um node não prunado e `txindex = 1` em nosso arquivo `bitcoin.conf`. A menos que tenhamos uma necessidade séria de informações que não estão em nossa carteira, provavelmente é melhor usarmos um explorador de Bitcoin para esse tipo de coisa. ## Opcional: Usando um Explorador de Blocos -Até mesmo olhar para as informações detalhadas de uma transação pode ser um pouco intimidante. O principal objetivo deste tutorial é ensinar como lidar com transações brutas da linha de comando, mas ficaremos felizes em falar sobre outras ferramentas quando elas forem aplicáveis. Uma dessas ferramentas é um explorador de blocos, que você pode usar para ver as transações de um navegador da web em um formato muito mais amigável. +Até mesmo olhar para as informações detalhadas de uma transação pode ser um pouco intimidante. O principal objetivo deste tutorial é ensinar como lidar com transações brutas da linha de comando, mas ficaremos felizes em falar sobre outras ferramentas quando elas forem aplicáveis. Uma dessas ferramentas é um explorador de blocos, que podemos usar para ver as transações de um navegador web em um formato muito mais amigável. -Atualmente, nosso explorador de bloco preferido é [https://live.blockcypher.com/](https://live.blockcypher.com/). +Atualmente, nosso explorador de bloco preferido é [https://mempool.space/](https://mempool.space/). Podemos usá-lo para procurar transações para um endereço: -[https://live.blockcypher.com/btc-testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE/](https://live.blockcypher.com/btc-testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE/) +[https://mempool.space/pt/testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE](https://mempool.space/pt/testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE) Também podemos usá-lo para ver transações individuais: -[https://live.blockcypher.com/btc-testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9/](https://live.blockcypher.com/btc-testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9/) +[https://mempool.space/pt/testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9](https://mempool.space/pt/testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9) Um explorador de bloco geralmente não fornece mais informações do que uma linha de comando em uma transação bruta; ele apenas destaca as informações importantes e junta as peças do quebra-cabeça, incluindo as taxas de transação por trás de uma transação - outro conceito que abordaremos nas próximas seções. ## Resumo: Recebendo uma Transação -As faucets nos vão dar dinheiro na testnet. O dinheiro vem como transações brutas, que podem ser examinadas com `gettransaction` ou um explorador de blocos. Assim que recebermos uma transação, poderemos vê-la em nosso saldo e em nossa carteira. +As faucets nos vão dar dinheiro na Testnet. O dinheiro vem como transações brutas, que podem ser examinadas com `gettransaction` ou um explorador de blocos. Assim que recebermos uma transação, poderemos vê-la em nosso saldo e em nossa carteira. ## O Que Vem Depois? diff --git a/pt/03_5_Understanding_the_Descriptor.md b/pt/03_5_Understanding_the_Descriptor.md index d776868..6f963a0 100644 --- a/pt/03_5_Understanding_the_Descriptor.md +++ b/pt/03_5_Understanding_the_Descriptor.md @@ -2,33 +2,31 @@ > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Cuidado, leitor. +Você deve ter notado o estranho campo `desc:` no comando `listunspent` da seção anterior. Aqui está o que está acontecendo (e como ele pode ser usado para transferir endereços). -Você deve ter notado um campo `desc:` estranho no comando `listunspent` da seção anterior. Aqui está o que está acontecendo (e como ele pode ser usado para transferir endereços). +> :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.17.0 que continuou a ser expandida através do Bitcoin Core 0.20.0. A maioria dos comandos nesta seção são de 0.17.0, mas o `importmulti` atualizado que suporta descritores é de 0.18.0. -> :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v 0.17.0 que continuou a ser expandida através do Bitcoin Core 0.20.0. A maioria dos comandos nesta seção são de 0.17.0, mas o `importmulti` atualizado que suporta descritores é de 0.18.0. - -## Sabendo Sobre Transferência de Endereços +## Entendendo Sobre a Transferência de Endereços A maior parte deste curso presume que estejamos trabalhando inteiramente a partir de um único node onde gerenciamos nossa própria carteira, enviando e recebendo pagamentos com os endereços criados por essa carteira. No entanto, não é necessariamente assim que funciona o ecossistema Bitcoin por completo. Nesse caso, é mais provável que movamos endereços entre carteiras e até mesmo configuremos carteiras para vigiar fundos controlados por carteiras diferentes. -É aí que entram os descritores. Eles são mais úteis se estivermos interagindo com _outro_ software que não seja o Bitcoin Core, e se realmente precisemos nos apoiar neste tipo de função de compatibilidade: consulte [§6.1] (https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/pt/06_1_Sending_a_Transaction_to_a_Multisig.md) para um exemplo do mundo real de como ter a capacidade de descritores é fundamental. +É aí que entram os descritores. Eles são mais úteis se estivermos interagindo com _outro_ software que não seja o Bitcoin Core, e se realmente precisamos do apoio deste tipo de função de compatibilidade: podemos consultar a seção [§6.1](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/pt/06_1_Sending_a_Transaction_to_a_Multisig.md) para um exemplo do mundo real de como usar a capacidade total dos descritores é fundamental. -Mover endereços entre carteiras costumava focar em `xpub` e` xprv`, e esses ainda são suportados. +Mover endereços entre carteiras costumava focar em `xpub` e `xprv`, e eles ainda possuem suporte. > :book: ***O que é xprv?*** Uma chave privada estendida (_xtended private key_). Esta é a combinação de uma chave privada e um código de cadeia. É uma chave privada da qual uma sequência inteira de chaves privadas filhas pode ser derivada. > :book: ***O que é xpub?*** Uma chave pública estendida (_xtended public key_). Esta é a combinação de uma chave pública e um código de cadeia. É uma chave pública da qual uma sequência inteira de chaves públicas filhas pode ser derivada. +O fato de que podemos ter uma "sequência inteira de chaves filhas" revela o fato de que "xpub" e "xprv" não são chaves padrão como falamos até agora. Em vez disso, são chaves hierárquicas que podem ser usadas para criar molhos inteiros de chaves, baseadas na ideia de carteiras HD. -O fato de que podemos ter uma "sequência inteira de chaves filhas" revela o fato de que "xpub" e "xprv" não são chaves padrão como falamos até agora. Em vez disso, são chaves hierárquicas que podem ser usadas para criar famílias inteiras de chaves, baseadas na ideia de carteiras HD. +> :book: ***O que é uma Carteira HD?*** A maioria das carteiras modernas é construída com base no [BIP32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). Este é um design hierárquico em que uma única seed pode ser usada para gerar uma sequência completa de chaves. A carteira inteira pode então ser restaurada a partir dessa seed, em vez de exigir a restauração de cada chave privada. -> :book: ***O que é uma Carteira HD?*** A maioria das carteiras modernas é construída com base no [BIP32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). Este é um design hierárquico em que uma única semente pode ser usada para gerar uma sequência completa de chaves. A carteira inteira pode então ser restaurada a partir dessa semente, em vez de exigir a restauração de cada chave privada. - -> :book: ***O que é um caminho de derivação?*** Quando você tem chaves hierárquicas, precisa ser capaz de definir chaves individuais como descendentes de uma semente. Por exemplo, `[0]` é a 0ª chave, `[0/1]` é o primeiro filho da 0ª chave, `[1/0/1]` é o primeiro neto do filho zero da 1ª chave. Algumas chaves também contêm um `'` após o número, para mostrar que estão protegidas, o que as protege de um ataque específico que pode ser usado para derivar uma `xprv` de uma `xpub`. Você não precisa se preocupar com os detalhes, a não ser o fato de que esses `'`s causarão problemas de formatação ao trabalhar na linha de comando. +> :book: ***O que é um caminho de derivação?*** Quando temos chaves hierárquicas, precisamos ser capazes de definir chaves individuais como descendentes de uma semente. Por exemplo, `[0]` é a 0ª chave, `[0/1]` é o primeiro filho da 0ª chave, `[1/0/1]` é o primeiro neto do filho zero da 1ª chave. Algumas chaves também contêm um `'` após o número, para mostrar que estão protegidas, o que as protege de um ataque específico que pode ser usado para derivar uma `xprv` de uma `xpub`. Não precisamos nos preocupar com os detalhes, a não ser o fato de que esses `'`s causarão problemas de formatação ao trabalhar na linha de comando. > :information_source: **NOTA:** um caminho de derivação define uma chave, o que significa que uma chave representa um caminho de derivação. Eles são equivalentes. No caso de um descritor, o caminho de derivação permite ao `bitcoind` saber de onde veio a chave que segue no descritor! -`xpubs` e `xprvs` provaram ser insuficientes quando os tipos de chaves públicas multiplicadas sob a [expansão SegWit](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_6_Creating_a_Segwit_Transaction.md), portanto a necessidade de "descritores de saída". +`xpubs` e `xprvs` provaram ser insuficientes quando os tipos de chaves públicas multiplicadas sob a [expansão SegWit](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_6_Creating_a_Segwit_Transaction.md), portanto essa é a necessidade de "descritores de saída". > :book: ***O que é um descritor de saída?*** Uma descrição precisa de como derivar um endereço Bitcoin de uma combinação de uma função com uma ou mais entradas para essa função. @@ -68,12 +66,12 @@ Um descritor é composto de várias partes: ``` função([caminho-de-derivação]chave)#checksum ``` -Aqui está o que tudo isso significa: -* **Função.** A função que é usada para criar um endereço a partir dessa chave. Nestes casos, é `pkh`, que é o endereço padrão P2PKH legado que você encontrou em [§3.3: Configurando Nossa Carteira](03_3_Setting_Up_Your_Wallet.md). Da mesma forma, um endereço P2WSH SegWit usaria `wsh` e um endereço P2WPKH usaria` wpkh`. -* **Caminho de Derivação.** Descreve qual parte de uma carteira HD está sendo exportada. Neste caso, é uma semente com a impressão digital `d6043800` e então o 18º filho do 0º filho do 0º filho (`0 '/ 0' / 18'`) dessa semente. Também pode haver uma derivação adicional após a chave: `função([caminho-de-derivação]chave/mais-derivação)#checksum` - * É importante notar aqui que, se algum dia recebermos um caminho de derivação sem uma impressão digital, poderemos inventá-lo. Acontece que, se houver um existente, devemos usá-lo, porque se algum dia voltarmos para o dispositivo que criou a impressão digital, precisaremos ter o mesmo. -* **Chave**. A chave ou as chaves que estão sendo transferidas. Isso pode ser algo tradicional como uma `xpub` ou `xprv`, pode ser apenas uma chave pública para um endereço, como neste caso, pode ser um conjunto de endereços para uma multi-assinatura, ou pode ser outra coisa. Estes são os dados principais: a função explica o que fazer com eles. -* **Checksum**. Os descritores são feitos para poderem ser transferidos por humanos. Esta soma de verificação (checksum) garante que o fizemos corretamente. +Vamos explicar o que tudo isso significa: +* **Função.** A função que é usada para criar um endereço a partir dessa chave. Nestes casos, é `pkh`, que é o endereço padrão P2PKH legado que encontramos em [§3.3: Configurando Nossa Carteira](03_3_Setting_Up_Your_Wallet.md). Da mesma forma, um endereço P2WSH SegWit usaria `wsh` e um endereço P2WPKH usaria `wpkh`; +* **Caminho de Derivação.** Descreve qual parte de uma carteira HD está sendo exportada. Neste caso, é uma seed com a impressão digital `d6043800` e então o 18º filho do 0º filho do 0º filho (`0 '/ 0' / 18'`) dessa seed. Também pode haver uma derivação adicional após a chave: `função([caminho-de-derivação]chave/mais-derivação)#checksum`. + * É importante notar aqui que, se algum dia recebermos um caminho de derivação sem uma impressão digital, poderemos inventá-lo. Acontece que, se houver um existente, devemos usá-lo, porque se algum dia voltarmos para o dispositivo que criou a impressão digital, precisaremos ter o mesmo; +* **Chave**. A chave ou as chaves que estão sendo transferidas. Isso pode ser algo tradicional como uma `xpub` ou `xprv`, pode ser apenas uma chave pública para um endereço, como neste caso, pode ser um conjunto de endereços para uma multi-assinatura, ou pode ser outra coisa. Estes são os dados principais: a função explica o que fazer com eles; +* **Checksum**. Os descritores são feitos para poderem ser transferidos por humanos. Esta soma de verificação (checksum) garante que o fizemos corretamente; Podemos ver [Informações do Suporte do Bitcoin Core ao Descritor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) para maiores informações. @@ -90,7 +88,7 @@ $ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b2 "hasprivatekeys": false } ``` -Observe que ele retorna um checksum. Se algum dia recebermos um descritor sem um checksum, podemos buscá-lo com este comando: +Observe que ele retorna um checksum. Se algum dia recebermos um descritor sem um checksum, podemos encontrá-lo com este comando: ``` $ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)" { @@ -123,7 +121,7 @@ remote$ bitcoin-cli importmulti '[{"desc": "pkh([d6043800/0'"'"'/0'"'"'/18'"'"'] } ] ``` -Primeiro, podemos notar nosso primeiro uso muito feio de aspas. Toda `'` no caminho de derivação pode ser substituído com `'"'"'`. Devemos esperar fazer isso se estivermos manipulando um descritor que contenha um caminho de derivação. (Outra opção é trocar o `'` com um `h` de "hardened", mas isto irá alterar nosso checksum, então caso tenhamos essa preferência pela facilidade de uso, precisaremos de umm novo checksum com o `getdescriptorinfo`.) +Primeiro, podemos notar nosso primeiro uso muito feio de aspas. Toda `'` no caminho de derivação pode ser substituído com `'"'"'`. Devemos esperar fazer isso se estivermos manipulando um descritor que contenha um caminho de derivação. (Outra opção é trocar o `'` com um `h` de "hardened", mas isto irá alterar nosso checksum, então caso tenhamos essa preferência pela facilidade de uso, precisaremos de um novo checksum com o `getdescriptorinfo`.) Segundo, podemos notar que o marcamos como `watchonly`. Isso ocorre porque sabemos que é uma chave pública, então não podemos usá-la para gastar fundos. Se tivéssemos esquecido de colocar esta sinalização, `importmulti` teria dito algo como o seguinte: `Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.`. @@ -144,7 +142,7 @@ Descritores nos permitem passar chaves públicas e privadas entre carteiras, mas > :fire: ***Qual é o poder dos descritores?*** Descritores nos permitem importar e exportar chaves e seeds. O que é excelente se queremos movê-las entre carteiras diferentes. Como um desenvolvedor, eles também nos permitem construir o tipo preciso de endereços que queremos criar. Por exemplo, nós os utilizamos na [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2/blob/master/Docs/How-it-works.md) para gerarmos um multisig de três seeds. -Faremos uso real dos descritores em [§7.3](07_3_Integrating_with_Hardware_Wallets.md), quando estivermos importando endereços de uma hardware wallet. +Faremos uso real dos descritores na seção [§7.3](07_3_Integrating_with_Hardware_Wallets.md), quando estivermos importando endereços de uma hardware wallet. ## O Que Vem Depois? From c4384baea5b3cbe222c2317f063c7d366880a9b1 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 29 Sep 2021 08:42:17 -0300 Subject: [PATCH 150/155] Fix links to --- pt/04_2__Interlude_Using_JQ.md | 2 +- pt/10_2_Building_the_Structure_of_P2SH.md | 2 +- pt/16_1_Accessing_Bitcoind_with_C.md | 6 +++--- pt/16_2_Programming_Bitcoind_with_C.md | 2 +- pt/16_3_Receiving_Bitcoind_Notifications_with_C.md | 2 +- pt/17_1_Setting_Up_Libwally.md | 2 +- pt/17_2_Using_BIP39_in_Libwally.md | 2 +- pt/17_3_Using_BIP32_in_Libwally.md | 2 +- pt/17_4_Using_PSBTs_in_Libwally.md | 4 ++-- pt/17_5_Using_Scripts_in_Libwally.md | 2 +- pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md | 4 ++-- pt/18_1_Accessing_Bitcoind_with_Go.md | 10 +++++----- pt/18_2_Accessing_Bitcoind_with_Java.md | 6 +++--- pt/18_3_Accessing_Bitcoind_with_NodeJS.md | 6 +++--- pt/18_4_Accessing_Bitcoind_with_Python.md | 6 +++--- pt/18_5_Accessing_Bitcoind_with_Rust.md | 4 ++-- pt/18_6_Accessing_Bitcoind_with_Swift.md | 4 ++-- 17 files changed, 33 insertions(+), 33 deletions(-) diff --git a/pt/04_2__Interlude_Using_JQ.md b/pt/04_2__Interlude_Using_JQ.md index 0ec4618..ba5165c 100644 --- a/pt/04_2__Interlude_Using_JQ.md +++ b/pt/04_2__Interlude_Using_JQ.md @@ -397,7 +397,7 @@ alias btcunspent="bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .v ## 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```. +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. diff --git a/pt/10_2_Building_the_Structure_of_P2SH.md b/pt/10_2_Building_the_Structure_of_P2SH.md index 49ee5de..112d864 100644 --- a/pt/10_2_Building_the_Structure_of_P2SH.md +++ b/pt/10_2_Building_the_Structure_of_P2SH.md @@ -68,7 +68,7 @@ Para completar nossa serialização, traduzimos o código hexadecimal em binári ## Executando o Script de Conversão de Inteiros -Um script completo para alterar um número inteiro entre -2147483647 e 2147483647 para uma representação de magnitude assinada do tipo _little-endian_ em hexadecimal pode ser encontrado no [diretório de código src](src/10_2_integer2lehex.sh). Podemos baixar o ```integeer2lehex.sh```. +Um script completo para alterar um número inteiro entre -2147483647 e 2147483647 para uma representação de magnitude assinada do tipo _little-endian_ em hexadecimal pode ser encontrado no [diretório de código src](../src/10_2_integer2lehex.sh). Podemos baixar o ```integeer2lehex.sh```. > :warning: **AVISO:** Este script não foi verificado de forma consistente. Se formos utilizá-lo para criar scripts de bloqueio reais, precisamos nos certificar de verificar e testar os resultados. diff --git a/pt/16_1_Accessing_Bitcoind_with_C.md b/pt/16_1_Accessing_Bitcoind_with_C.md index b6e3aec..0801110 100644 --- a/pt/16_1_Accessing_Bitcoind_with_C.md +++ b/pt/16_1_Accessing_Bitcoind_with_C.md @@ -26,7 +26,7 @@ $ sudo apt-get install git $ git clone https://github.com/gitmarek/libbitcoinrpc ``` -> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. +> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. ### Compilando o libbitcoinrpc @@ -155,7 +155,7 @@ bitcoinrpc_global_cleanup(); ### Testando o Código de Teste -O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). +O código de teste pode ser encontrado [no diretório src com o nome 16_1_testbitcoin.c](../src/16_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). Podemos compilar e executar o código da seguinte maneira: ``` @@ -223,7 +223,7 @@ printf("Block Count: %d\n",blocks); ### Testando o Código de Informação -Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). +Vamos recuperar o código de teste que está no [diretório src](../src/16_1_getmininginfo.c). ``` $ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo $ ./getmininginfo diff --git a/pt/16_2_Programming_Bitcoind_with_C.md b/pt/16_2_Programming_Bitcoind_with_C.md index 67458a9..03c1158 100644 --- a/pt/16_2_Programming_Bitcoind_with_C.md +++ b/pt/16_2_Programming_Bitcoind_with_C.md @@ -330,7 +330,7 @@ O código inteiro, com um _pouco_ mais verificação de erros, está disponível ## Testando o Código -O código completo pode ser encontrado no [diretório src/](src/16_2_sendtoaddress.c). +O código completo pode ser encontrado no [diretório src/](../src/16_2_sendtoaddress.c). Compile-o como de costume: ``` diff --git a/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md index 4f081a8..f6f810a 100644 --- a/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md +++ b/pt/16_3_Receiving_Bitcoind_Notifications_with_C.md @@ -121,7 +121,7 @@ Claro, quando terminar o processo, precisamos limpar tudo: ### Testando o Código de Notificação -O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: +O código-fonte completo está no [diretório src/](../src/16_3_chainlistener.c) como de costume. Precisamos compilá-lo: ``` $ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq ``` diff --git a/pt/17_1_Setting_Up_Libwally.md b/pt/17_1_Setting_Up_Libwally.md index 57f5810..685c5ab 100644 --- a/pt/17_1_Setting_Up_Libwally.md +++ b/pt/17_1_Setting_Up_Libwally.md @@ -129,7 +129,7 @@ Em ambos os casos, o argumento é para flags, mas atualmente está definido como ## Testando um Programa de Teste da Libwally -O diretório src contém o arquivo [testwally.c](src/17_1_testwally.c), que apenas mostra como funcionam as funções de inicialização e de limpeza. +O diretório src contém o arquivo [testwally.c](../src/17_1_testwally.c), que apenas mostra como funcionam as funções de inicialização e de limpeza. Podemos compilá-lo da seguinte maneira: ``` diff --git a/pt/17_2_Using_BIP39_in_Libwally.md b/pt/17_2_Using_BIP39_in_Libwally.md index 10967ab..90451b1 100644 --- a/pt/17_2_Using_BIP39_in_Libwally.md +++ b/pt/17_2_Using_BIP39_in_Libwally.md @@ -82,7 +82,7 @@ Se dizermos tudo certo, devemos obter uma seed de 64 bytes. (Essa é a variável ## Testando o Código Mnemônico -O código completo para gerar entropia, gerar um mnemônico BIP39, validar o mnemônico e gerar uma seed pode ser encontrado no [diretório src/](src/17_2_genmnemonic.c). Podemos fazer o download e compilar: +O código completo para gerar entropia, gerar um mnemônico BIP39, validar o mnemônico e gerar uma seed pode ser encontrado no [diretório src/](../src/17_2_genmnemonic.c). Podemos fazer o download e compilar: ``` $ cc genmnemonic.c -lwallycore -lsodium -o genmnemonic ``` diff --git a/pt/17_3_Using_BIP32_in_Libwally.md b/pt/17_3_Using_BIP32_in_Libwally.md index d85b510..f9f0d99 100644 --- a/pt/17_3_Using_BIP32_in_Libwally.md +++ b/pt/17_3_Using_BIP32_in_Libwally.md @@ -115,7 +115,7 @@ Há também uma função `wally_bip32_key_to_address`, que pode ser usada para g ## Testando o Código HD -O código para esses exemplos HD pode, como de costume, ser encontrado no [diretório src/](src/17_3_genhd.c). +O código para esses exemplos HD pode, como de costume, ser encontrado no [diretório src/](../src/17_3_genhd.c). Podemos compilá-lo e testá-lo: ``` diff --git a/pt/17_4_Using_PSBTs_in_Libwally.md b/pt/17_4_Using_PSBTs_in_Libwally.md index 4bff407..048d92c 100644 --- a/pt/17_4_Using_PSBTs_in_Libwally.md +++ b/pt/17_4_Using_PSBTs_in_Libwally.md @@ -116,7 +116,7 @@ Obviamente, há muito mais coisas que poderemos observar nos PSBTs. Na verdade, ### Testando Nosso Leitor PSBT -Novamente, o código para este leitor PSBT (extremamente rudimentar e específico) está no [diretório src/](src/17_4_examinepsbt.c). +Novamente, o código para este leitor PSBT (extremamente rudimentar e específico) está no [diretório src/](../src/17_4_examinepsbt.c). Podemos compilá-lo normalmente: ``` @@ -289,7 +289,7 @@ Mas o que temos ainda não é um PSBT legal, por falta de entradas. Podemos cri ``` ### Testando nosso PSBT Criado -Neste ponto, devemos ter um PSBT vazio, mas funcionando, que pode ser visto compilando e executando [o programa](src/17_4_createemptypsbt.c). +Neste ponto, devemos ter um PSBT vazio, mas funcionando, que pode ser visto compilando e executando [o programa](../src/17_4_createemptypsbt.c). ``` $ cc createemptypsbt.c -lwallycore -o createemptypsbt $ ./createemptypsbt diff --git a/pt/17_5_Using_Scripts_in_Libwally.md b/pt/17_5_Using_Scripts_in_Libwally.md index b8df034..d88d846 100644 --- a/pt/17_5_Using_Scripts_in_Libwally.md +++ b/pt/17_5_Using_Scripts_in_Libwally.md @@ -112,7 +112,7 @@ Mostraremos como fazer uso disso na seção §17.7. ## Testando Nosso Script de Substituição -Podemos pegar o código de teste do [diretório src/](src/17_5_replacewithscript.c) e compilá-lo: +Podemos pegar o código de teste do [diretório src/](../src/17_5_replacewithscript.c) e compilá-lo: ``` $ cc replacewithscript.c -lwallycore -o replacewithscript ``` diff --git a/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md b/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md index df3e176..ddfd2e6 100644 --- a/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md +++ b/pt/17_7_Integrating_Libwally_and_Bitcoin-CLI.md @@ -33,7 +33,7 @@ $ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') $ recipient=tb1qycsmq3jas5wkhf8xrfn8k7438cm5pc8h9ae2k0 $ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.0009 }''') ``` -Embora tenhamos colocado um destinatário e uma quantia na saída, isto é irrelevante, porque nós o reescreveremos. Um código mais elaborado poderia ler as informações `vout` existentes antes de reescrever, mas estamos mantendo as coisas muito próximas do nosso [código original](src/17_5_replacewithscript.c). +Embora tenhamos colocado um destinatário e uma quantia na saída, isto é irrelevante, porque nós o reescreveremos. Um código mais elaborado poderia ler as informações `vout` existentes antes de reescrever, mas estamos mantendo as coisas muito próximas do nosso [código original](../src/17_5_replacewithscript.c). Aqui está a única alteração necessária, para permitir que especifiquemos os satoshis no `vout`, sem ter que codificá-lo, como no original: ``` @@ -182,7 +182,7 @@ Infelizmente, nem todas as interações entre a Libwally e o `bitcoin-cli` são ## Importando Chaves Privadas -Felizmente, podemos fazer quase a mesma coisa importando uma chave privada gerada na Libwally. Dê uma olhada no [genhd-for-import.c](src/17_7_genhd_for_import.c), uma versão simplificada do programa `genhd` da seção [§17.3](17_3_Using_BIP32_in_Libwally.md) que também usa a biblioteca `jansson` da seção [§16.1](16_1_Accessing_Bitcoind_with_C.md) para saída regularizada. +Felizmente, podemos fazer quase a mesma coisa importando uma chave privada gerada na Libwally. Dê uma olhada no [genhd-for-import.c](../src/17_7_genhd_for_import.c), uma versão simplificada do programa `genhd` da seção [§17.3](17_3_Using_BIP32_in_Libwally.md) que também usa a biblioteca `jansson` da seção [§16.1](16_1_Accessing_Bitcoind_with_C.md) para saída regularizada. O código atualizado também contém uma alteração importante, pois ele solicita uma impressão digital da Libwally para que se possa criar um caminho de derivação de maneira adequada: ``` diff --git a/pt/18_1_Accessing_Bitcoind_with_Go.md b/pt/18_1_Accessing_Bitcoind_with_Go.md index 1a3b43e..a61705e 100644 --- a/pt/18_1_Accessing_Bitcoind_with_Go.md +++ b/pt/18_1_Accessing_Bitcoind_with_Go.md @@ -160,7 +160,7 @@ No entanto, uma peculiaridade com hashes no `rpcclient` é que normalmente eles ### Executando Nosso Código -Podemos baixar o código completo do [diretório src](src/18_1_blockinfo.go). +Podemos baixar o código completo do [diretório src](../src/18_1_blockinfo.go). Podemos então, executar: ``` @@ -185,7 +185,7 @@ Devido às limitações do `btcd` no `rpcclient`, não podemos fazer uso da fun ``` O `client.GetBalance("*")` requer a entrada `"*"` devido a uma peculiaridade do `btcd`. O asterisco significa que desejamos obter o saldo de todas as nossas carteiras. -Se executarmos [o código src](src/18_1_getbalance.go), deveremos obter uma saída semelhante a esta: +Se executarmos [o código src](../src/18_1_getbalance.go), deveremos obter uma saída semelhante a esta: ``` $ go run getbalance.go 0.000689 BTC @@ -281,7 +281,7 @@ Só depois disso usamos o RPC `getreceivedbyaddress` no nosso endereço decodifi fmt.Println(wallet) ``` -Ao executar [o código](src/18_1_getamountreceived.go), devemos obter uma saída semelhante a esta: +Ao executar [o código](../src/18_1_getamountreceived.go), devemos obter uma saída semelhante a esta: ``` $ go run getamountreceived.go 0.0085 BTC @@ -333,7 +333,7 @@ func main() { fmt.Println(sent) } ``` -Quando executamos [o código](src/18_1_sendtransaction.go), o txid da transação nos será retornado: +Quando executamos [o código](../src/18_1_sendtransaction.go), o txid da transação nos será retornado: ``` $ go run sendtransaction.go @@ -382,7 +382,7 @@ func main() { ``` > **NOTA:** Novamente, vamos querer trocar o txid por um que realmente será reconhecido pelo nosso sistema. -Ao executar [o código](src/18_1_lookuptransaction.go), ele imprimirá os detalhes associados a uma transação, como seu valor e quantas vezes foi confirmada: +Ao executar [o código](../src/18_1_lookuptransaction.go), ele imprimirá os detalhes associados a uma transação, como seu valor e quantas vezes foi confirmada: ``` $ go run lookuptransaction.go diff --git a/pt/18_2_Accessing_Bitcoind_with_Java.md b/pt/18_2_Accessing_Bitcoind_with_Java.md index 7b01aad..06487f0 100644 --- a/pt/18_2_Accessing_Bitcoind_with_Java.md +++ b/pt/18_2_Accessing_Bitcoind_with_Java.md @@ -154,7 +154,7 @@ PubKey: 0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65 ### Executando Nosso Código -O código para esses exemplos pode ser encontrado no [diretório src/](src/18_2_App-getinfo.java) e deve ser instalado na estrutura de diretório padrão criada neste caso como `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. Ele pode então ser compilado e executado. +O código para esses exemplos pode ser encontrado no [diretório src/](../src/18_2_App-getinfo.java) e deve ser instalado na estrutura de diretório padrão criada neste caso como `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. Ele pode então ser compilado e executado. ``` $ mvn compile @@ -277,7 +277,7 @@ System.out.println("Sent signedRawTx (txID): " + sentRawTransactionID); ### Executando Nosso Código -Agora podemos executar [o código da transação](src/18_2_App-sendtx.java) como `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. +Agora podemos executar [o código da transação](../src/18_2_App-sendtx.java) como `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. ``` $ mvn compile @@ -316,7 +316,7 @@ Para fazer isso, podemos usar a classe `BitcoinAcceptor` do `JavaBitcoindRpcClie acceptor.run(); ``` -Veja [o diretório src/](src/18_2_App-listen.java) para o código completo. Cada vez que uma transação é enviada ou um novo bloco é gerado, devemos ver a saída em nosso console: +Veja [o diretório src/](../src/18_2_App-listen.java) para o código completo. Cada vez que uma transação é enviada ou um novo bloco é gerado, devemos ver a saída em nosso console: ``` Transaction: {account=Tests, address=mhopuJzgmTwhGfpNLCJ9CRknugY691oXp1, category=receive, amount=5.0E-4, label=Tests, vout=1, confirmations=0, trusted=false, txid=361e8fcff243b74ebf396e595a007636654f67c3c7b55fd2860a3d37772155eb, walletconflicts=[], time=1513132887, timereceived=1513132887, bip125-replaceable=unknown} diff --git a/pt/18_3_Accessing_Bitcoind_with_NodeJS.md b/pt/18_3_Accessing_Bitcoind_with_NodeJS.md index 152ea62..89ae123 100644 --- a/pt/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/pt/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -109,7 +109,7 @@ O resultado das funções BCRPC é um objeto JSON contendo informações sobre q ### Executando Nosso Código -Podemos encontrar o código `getinfo` no [diretório src/](src/18_3_getinfo.js). +Podemos encontrar o código `getinfo` no [diretório src/](../src/18_3_getinfo.js). ``` $ node getinfo.js 1831094 @@ -162,7 +162,7 @@ agent.getWalletInfo(function (err, walletInfo) { }); ``` -O código está disponível como [walletinfo.js](src/18_3_walletinfo.js). +O código está disponível como [walletinfo.js](../src/18_3_walletinfo.js). ``` $ node walletinfo.js 0.008498 @@ -260,7 +260,7 @@ Devemos obter uma saída semelhante a esta: } ``` -O código completo está disponível no [sendtx.js](src/18_3_sendtx.js). +O código completo está disponível no [sendtx.js](../src/18_3_sendtx.js). ## Resumo: Acessando o Bitcoind com NodeJS diff --git a/pt/18_4_Accessing_Bitcoind_with_Python.md b/pt/18_4_Accessing_Bitcoind_with_Python.md index f343cc9..8eac58d 100644 --- a/pt/18_4_Accessing_Bitcoind_with_Python.md +++ b/pt/18_4_Accessing_Bitcoind_with_Python.md @@ -128,7 +128,7 @@ print("---------------------------------------------------------------\n") ### Executando nosso código -Podemos usar [o código que está no src/](src/18_4_getinfo.py) e executá-lo com `python3`: +Podemos usar [o código que está no src/](../src/18_4_getinfo.py) e executá-lo com `python3`: ``` $ python3 getinfo.py @@ -244,7 +244,7 @@ pprint(utxo_tx_details) print("---------------------------------------------------------------\n") ``` -Este código está disponível no arquivo [walletinfo.py](src/18_4_walletinfo.py). +Este código está disponível no arquivo [walletinfo.py](../src/18_4_walletinfo.py). ``` $ python3 walletinfo.py --------------------------------------------------------------- @@ -422,7 +422,7 @@ send_tx = rpc_client.sendrawtransaction(signed_tx['hex']) ``` ### Executando Nosso Código -[Este código](src/18_4_sendtx.py) está cheio de instruções com `print` para demonstrar todos os dados disponíveis a cada momento: +[Este código](../src/18_4_sendtx.py) está cheio de instruções com `print` para demonstrar todos os dados disponíveis a cada momento: ``` $ python3 sendtx.py Creating a Transaction diff --git a/pt/18_5_Accessing_Bitcoind_with_Rust.md b/pt/18_5_Accessing_Bitcoind_with_Rust.md index 20b4d37..d13ceb3 100644 --- a/pt/18_5_Accessing_Bitcoind_with_Rust.md +++ b/pt/18_5_Accessing_Bitcoind_with_Rust.md @@ -134,7 +134,7 @@ Aqui está o código completo para recuperar um hash de bloco, transformando-o e ### Executando Nosso Código -Podemos acessar o [código src](src/18_5_main-getinfo.rs) e executá-lo. Infelizmente, a informação do "Block" sairá um pouco feia porque este exemplo não inclui uma biblioteca para embelezá-la. +Podemos acessar o [código src](../src/18_5_main-getinfo.rs) e executá-lo. Infelizmente, a informação do "Block" sairá um pouco feia porque este exemplo não inclui uma biblioteca para embelezá-la. ``` $ cargo run @@ -289,7 +289,7 @@ println!("{:?}", txid_sent); ### Executando Nosso Código -Agora podemos executar o código completo do [src](src/18_5_main-sendtx.rs). +Agora podemos executar o código completo do [src](../src/18_5_main-sendtx.rs). ``` diff --git a/pt/18_6_Accessing_Bitcoind_with_Swift.md b/pt/18_6_Accessing_Bitcoind_with_Swift.md index 471c376..460e70d 100644 --- a/pt/18_6_Accessing_Bitcoind_with_Swift.md +++ b/pt/18_6_Accessing_Bitcoind_with_Swift.md @@ -191,7 +191,7 @@ makeCommand(method: method,param: param) { result in ### Executando Nosso Código -O código completo está disponível no [diretório src/](src/18_6_getinfo.playground). Carregue-o no playground Xcode e, em seguida, "Editor -> Executar Playground" e devemos obter resultados como: +O código completo está disponível no [diretório src/](../src/18_6_getinfo.playground). Carregue-o no playground Xcode e, em seguida, "Editor -> Executar Playground" e devemos obter resultados como: ``` { bestblockhash = 00000000000000069725608ebc5b59e520572a8088cbc57ffa5ba87b7f300ac7; @@ -384,7 +384,7 @@ Enviar nossa transação é igualmente simples: } ``` -O código para este remetente de transação pode ser encontrado no [diretório src/](src/18_6_sendtx.playground). +O código para este remetente de transação pode ser encontrado no [diretório src/](../src/18_6_sendtx.playground). ## Usando o Swift de Outras Maneiras From 86b7e7b45a8abc5a440430612d9211b94e149d17 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 4 Oct 2021 19:05:13 -0300 Subject: [PATCH 151/155] Translate CONTRIBUTING.md --- pt/CONTRIBUTING.md | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 pt/CONTRIBUTING.md diff --git a/pt/CONTRIBUTING.md b/pt/CONTRIBUTING.md new file mode 100644 index 0000000..e9692b9 --- /dev/null +++ b/pt/CONTRIBUTING.md @@ -0,0 +1,64 @@ +# Contribuindo + +Nós adoramos a sua contribuição! Queremos deixar o processo de contribuir para este repositório o mais fácil e transparente possível, independente se é para: +- Reportar um bug +- Discutir o estado atual do código +- Enviar uma correção +- Propor novas funcionalidades +- Se tornar um mantenedor + +## Nós Desenvolvemos com o Github +Usamos o GitHub para hospedar o código, rastrear issues e solicitações de recursos e aceitar Pull Requests. + +## Reporte Bugs usando os [issues](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) do GitHub + +Se você encontrar bugs, erros ou inconsistências no código ou nos documentos deste projeto, informe-nos [abrindo um novo issue](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues/new), mas considere pesquisar os problemas existentes primeiro para verificar se o problema já foi relatado. Se tiver, nunca é demais adicionar um rápido "+1" ou "Eu também tenho esse problema". Isso ajuda a priorizar os problemas e solicitações mais comuns. + +### Escreva Relatórios de Bug com Detalhes, Contexto e Código de Amostra + +[Este é um exemplo](http://stackoverflow.com/q/12488905/180626) de um bom relatório de bug por @briandk. Aqui está [outro exemplo de craig.hockenberry](http://www.openradar.me/11905408). + +**Ótimos relatórios de bug** tendem a ter: + +- Um resumo e/ou contexto rápido +- Passos para reproduzir + - Seja específico! + - Forneça um código de amostra, se puder. [O relatório de bug do StackOverflow](http://stackoverflow.com/q/12488905/180626) inclui código de amostra que *qualquer pessoa* com uma configuração básica de R pode executar para reproduzir o que eu estava vendo +- O que você esperava que acontecesse +- O que realmente acontece +- Observações (possivelmente incluindo por que você acha que isso pode estar acontecendo ou coisas que você tentou que não funcionaram) + +As pessoas *adoram* relatórios de bug completos. Sem brincadeira. + +## Envie Alterações de Código por meio de Pull Requests + +Pull Requests simples para corrigir erros de digitação, documentar ou corrigir pequenos bugs são sempre bem-vindas. + +Pedimos que melhorias mais significativas para o projeto sejam propostas, antes que alguém comece a programar, como um [issue](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) ou como uma [Pull Request de rascunho](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/pulls), que é um [novo recurso interessante](https://github.blog/2019-02-14-introducing-draft-pull-requests/) que dá a outros contribuidores a chance de apontar a direção certa, dar feedback sobre o design e talvez discutir se o trabalho relacionado já está em andamento. + +### Use um Estilo de Programação Consistente + +* Recuamos usando dois espaços (soft tabs) +* SEMPRE colocamos espaços após os itens da lista e parâmetros do método ([1, 2, 3], não [1,2,3]), ao redor dos operadores (x + = 1, não x + = 1) e ao redor de setas hash. +* Este é um software de código aberto. Considere as pessoas que lerão seu código e faça com que ele tenha uma boa aparência para elas. É como dirigir um carro: talvez você adore fazer zerinhos quando está sozinho, mas com os passageiros o objetivo é tornar a viagem o mais suave possível. + +### Use [Github Flow](https://guides.github.com/introduction/flow/index.html) para Pull Requests + +Usamos [Github Flow](https://guides.github.com/introduction/flow/index.html). Ao enviar Pull Requests, por favor: + +1. Faça um fork do repo e crie seu branch a partir do `master`. +2. Se você adicionou um código que deve ser testado, adicione testes. +3. Se você alterou APIs, atualize a documentação. +4. Certifique-se de que o conjunto de testes seja aprovado. +5. Certifique-se de que seu código passe por um lint. +6. Emita essa Pull Request! + +### Envie Sob a Licença de Patente BSD-2-Clause Plus + +Resumindo, quando você envia alterações de código, seus envios são considerados disponíveis sob a mesma licença [CC-BY](../ LICENSE-CC-BY-4.0.md) que cobre o projeto. Também pedimos que todos os contribuidores de código do GPG assinem o [Contrato de Licença de Contribuidor (CLA.md)](../CLA.md) para proteger futuros usuários deste projeto. Sinta-se à vontade para entrar em contato com os mantenedores se isso for um problema. + +## Referências + +Partes deste documento CONTRIBUTING.md foram adotadas a partir das melhores práticas de uma série de projetos de código aberto, incluindo: +* [Rascunho do Facebook](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) +* [Contribuição de IPFS](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) \ No newline at end of file From e7b38b6fd1d6401b967c3b4f2bd0e77d3100522c Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 4 Oct 2021 19:05:31 -0300 Subject: [PATCH 152/155] Update README.md --- pt/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pt/README.md b/pt/README.md index 9e71b7b..711375c 100644 --- a/pt/README.md +++ b/pt/README.md @@ -13,7 +13,7 @@ _Este tutorial assume que você tenha um mínimo de background em como utilizar * [Espanhol](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/spanish-translation/es) - em progresso -Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuindo](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master#contributing) abaixo. +Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuindo](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master/pt#contribuindo) abaixo. ## Índice @@ -156,11 +156,11 @@ Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuin v2.0.1 do **Aprendendo Bitcoin pela Linha de Comando** é uma beta. Pode ainda estar sendo sujeito a revisões ou edições de terceiros, mas já pode ser utilizado para o aprendizado. -Nós também estamos considerando o que poderíamos incluir em uma [v3.0](TODO-30.md) do curso. Se você gostaria de apoiar um trabalho desse tipo, torne-se um [Patrocinador no GitHub](https://github.com/sponsors/BlockchainCommons) ou nos apoie pelo nosso [Servidor BTCPay](https://btcpay.blockchaincommons.com/), e nos informe que **Aprendendo Bitcoin** foi o motivo. +Nós também estamos considerando o que poderíamos incluir em uma [v3.0](../TODO-30.md) do curso. Se você gostaria de apoiar um trabalho desse tipo, torne-se um [Patrocinador no GitHub](https://github.com/sponsors/BlockchainCommons) ou nos apoie pelo nosso [Servidor BTCPay](https://btcpay.blockchaincommons.com/), e nos informe que **Aprendendo Bitcoin** foi o motivo. ## Origem, Autores, Copyright & Licenças -A não ser que indicado o contrário (ou neste [/README.md](./README.md) ou nos comentários nos cabeçalhos dos aquivos), os conteúdos deste repositório são Copyright © 2020 por Blockchain Commons, LLC, e licenciados sob [CC-BY](./LICENSE-CC-BY-4.0.md). +A não ser que indicado o contrário (ou neste [/README.md](./README.md) ou nos comentários nos cabeçalhos dos aquivos), os conteúdos deste repositório são Copyright © 2020 por Blockchain Commons, LLC, e licenciados sob [CC-BY](../LICENSE-CC-BY-4.0.md). ## Apoio Financeiro @@ -170,9 +170,9 @@ Para apoiar financeiramente o desenvolvimento futuro de `$projectname` e outros ## Contribuindo -Nós encorajamos contribuições públicas por meio de issues e pull requests! Por favor revise [CONTRIBUTING.md](./CONTRIBUTING.md) para detalhes sobre o nosso processo de desenvolvimento. Todas as contribuições para este repositório requerem um [Contrato de Licença do Contribuidor](./CLA.md) assinado por GPG. +Nós encorajamos contribuições públicas por meio de issues e pull requests! Por favor revise [CONTRIBUTING.md](./CONTRIBUTING.md) para detalhes sobre o nosso processo de desenvolvimento. Todas as contribuições para este repositório requerem um [Contrato de Licença do Contribuidor](../CLA.md) assinado por GPG. -Se você gostaria de providenciar uma tradução de Aprendendo Bitcoin para outra língua, por favor veja também [TRANSLATING.md](./TRANSLATING.md). +Se você gostaria de providenciar uma tradução de Aprendendo Bitcoin para outra língua, por favor veja também [TRANSLATING.md](../TRANSLATING.md). ### Discussões @@ -182,7 +182,7 @@ O melhor lugar para conversar sobre a Blockchain Commons e seus projetos é na n ### Outras Questões & Problemas -Como uma comunidade open-source e de desenvolvimento aberto, a Blockchain Commons não tem os recursos para fornecer apoio direto dos nossos projetos. Por favor considere a área de discussões como um local onde você pode receber respostas a perguntas. Alternativamente, por favor use o campo de [issues](./issues) deste repositório. Infelizmente, não podemos fazer promessas em relação ao tempo de resposta. +Como uma comunidade open-source e de desenvolvimento aberto, a Blockchain Commons não tem os recursos para fornecer apoio direto dos nossos projetos. Por favor considere a área de discussões como um local onde você pode receber respostas a perguntas. Alternativamente, por favor use o campo de [issues](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) deste repositório. Infelizmente, não podemos fazer promessas em relação ao tempo de resposta. Se a sua empresa requer apoio para usar os nossos projetos, por favor nos contacte diretamente para opcões. Nós podemos ser capazes de te oferecer um contrato para apoio por um de nossos contribuidores, ou poderemos te indicar outra entidade que possa oferecer o apoio contratual que você precisa. From 65fd8b50598f2c2fa52a9ca1437b8e5b436869eb Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 4 Oct 2021 19:11:09 -0300 Subject: [PATCH 153/155] Fix link --- pt/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pt/CONTRIBUTING.md b/pt/CONTRIBUTING.md index e9692b9..4add5d5 100644 --- a/pt/CONTRIBUTING.md +++ b/pt/CONTRIBUTING.md @@ -55,7 +55,7 @@ Usamos [Github Flow](https://guides.github.com/introduction/flow/index.html). Ao ### Envie Sob a Licença de Patente BSD-2-Clause Plus -Resumindo, quando você envia alterações de código, seus envios são considerados disponíveis sob a mesma licença [CC-BY](../ LICENSE-CC-BY-4.0.md) que cobre o projeto. Também pedimos que todos os contribuidores de código do GPG assinem o [Contrato de Licença de Contribuidor (CLA.md)](../CLA.md) para proteger futuros usuários deste projeto. Sinta-se à vontade para entrar em contato com os mantenedores se isso for um problema. +Resumindo, quando você envia alterações de código, seus envios são considerados disponíveis sob a mesma licença [CC-BY](../LICENSE-CC-BY-4.0.md) que cobre o projeto. Também pedimos que todos os contribuidores de código do GPG assinem o [Contrato de Licença de Contribuidor (CLA.md)](../CLA.md) para proteger futuros usuários deste projeto. Sinta-se à vontade para entrar em contato com os mantenedores se isso for um problema. ## Referências From 519a8b23c219fa3fc1e7b902c524fdefc42ee4c2 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 2 Nov 2021 07:57:21 -1000 Subject: [PATCH 154/155] fixing an old typo --- 04_2__Interlude_Using_JQ.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04_2__Interlude_Using_JQ.md b/04_2__Interlude_Using_JQ.md index f28356a..8169df5 100644 --- a/04_2__Interlude_Using_JQ.md +++ b/04_2__Interlude_Using_JQ.md @@ -357,7 +357,7 @@ To complete the transaction fee calculation, you subtract the .vout .amount (1.0 To do this, you'll need to install `bc`: ``` -$ sudo apt-get intall bc +$ sudo apt-get install bc ``` Putting it all together creates a complete calculator in just five lines of script: From 09911855b059c899d2798417a11cd9de08487148 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Wed, 3 Nov 2021 08:19:27 -1000 Subject: [PATCH 155/155] added translation credited --- pt/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pt/README.md b/pt/README.md index 711375c..442a1b7 100644 --- a/pt/README.md +++ b/pt/README.md @@ -1,5 +1,6 @@ # Aprendendo Bitcoin pela Linha de Comando 2.0.1 ### _por Christopher Allen e Shannon Appelcline_ +### _tradução por Namcios, Korea, Luke Pavsky e hgrams_ ![](https://www.blockchaincommons.com/images/projects/lbtc-screen.png) @@ -222,4 +223,4 @@ As seguintes chaves podem ser utilizadas para comunicar informação confidencia | ----------------- | -------------------------------------------------- | | Christopher Allen | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | -Você pode importar uma chave executando o seguinte comando com a fingerprint daquele indivíduo: `gpg --recv-keys ""` Se certifique de colocar o fingerprint entre aspas caso o mesmo contenha espaços. \ No newline at end of file +Você pode importar uma chave executando o seguinte comando com a fingerprint daquele indivíduo: `gpg --recv-keys ""` Se certifique de colocar o fingerprint entre aspas caso o mesmo contenha espaços.