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