mirror of
https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line.git
synced 2025-06-07 16:06:26 +00:00
Merge pull request #302 from KoreaComK/chapter-09
Chapter 09 Translated by @koreacomk reviewed by @namcios
This commit is contained in:
commit
1baf06366d
27
pt/09_0_Introducing_Bitcoin_Scripts.md
Normal file
27
pt/09_0_Introducing_Bitcoin_Scripts.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Capítulo 9: Apresentando Scripts no 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
|
||||
|
||||
Depois de trabalhar neste capítulo, um desenvolvedor será capaz de:
|
||||
|
||||
* 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 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 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)
|
142
pt/09_1_Understanding_the_Foundation_of_Transactions.md
Normal file
142
pt/09_1_Understanding_the_Foundation_of_Transactions.md
Normal file
@ -0,0 +1,142 @@
|
||||
# 9.1: Compreendendo a Base de Transações
|
||||
|
||||
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
|
||||
|
||||
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 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.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 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 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 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
|
||||
|
||||
Agora podemos examinar nossa transação profundamente usando ```decoderawtransaction``` 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 pelo ```scriptSig``` da transação que reutiliza aquele UTXO.
|
||||
|
||||
### Lendo os Scripts na Transação
|
||||
|
||||
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 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 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.
|
||||
|
||||
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 em Bitcoin Script para bloquear uma transação P2PKH.
|
||||
|
||||
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
|
||||
|
||||
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",
|
||||
"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 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
|
||||
|
||||
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.
|
||||
|
||||
## O Que Vem Depois?
|
||||
|
||||
Vamos continuar "Apresentando os Scripts no Bitcoin" na seção [§9.2: Executando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md).
|
125
pt/09_2_Running_a_Bitcoin_Script.md
Normal file
125
pt/09_2_Running_a_Bitcoin_Script.md
Normal file
@ -0,0 +1,125 @@
|
||||
# 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 (_stack_).
|
||||
|
||||
## 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.
|
||||
|
||||
### Compreendendo a Ordem
|
||||
|
||||
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 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
|
||||
|
||||
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" (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).
|
||||
```
|
||||
Script:
|
||||
Running: 1 2 OP_ADD
|
||||
Stack: [ 3 ]
|
||||
```
|
||||
|
||||
## 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:
|
||||
```
|
||||
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 Bitcoin Script
|
||||
|
||||
É basicamente programar no Bitcoin ... além de algumas complexidades de como essa linguagem de programação interage com o próprio Bitcoin.
|
||||
|
||||
### Compreendendo scriptSig e scriptPubKey
|
||||
|
||||
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, 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:
|
||||
```
|
||||
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: 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 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
|
||||
|
||||
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 no 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.
|
||||
|
||||
## O Que Vem Depois?
|
||||
|
||||
Vamos continuar "Apresentando Scripts no Bitcoin" na seção [§9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md).
|
209
pt/09_3_Testing_a_Bitcoin_Script.md
Normal file
209
pt/09_3_Testing_a_Bitcoin_Script.md
Normal file
@ -0,0 +1,209 @@
|
||||
# 9.3: Testando um Script no 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.
|
||||
|
||||
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 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.
|
||||
```
|
||||
$ 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 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
|
||||
|
||||
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``` 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
|
||||
|
||||
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]'
|
||||
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 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 pode tornar mais fácil observarmos o que está acontecendo e onde estamos no processo.
|
||||
|
||||
## Testando um Script Online
|
||||
|
||||
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
|
||||
|
||||
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 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.
|
||||
|
||||
## 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?
|
||||
|
||||
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).
|
389
pt/09_4_Scripting_a_P2PKH.md
Normal file
389
pt/09_4_Scripting_a_P2PKH.md
Normal file
@ -0,0 +1,389 @@
|
||||
# 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
|
||||
|
||||
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 ```<signature>``` (e um ```[ALL]```) e uma ```<pubkey>```:
|
||||
```
|
||||
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 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
|
||||
{
|
||||
"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 `<pubKeyHash>` preso no meio.
|
||||
|
||||
Executando-o 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, isso produz o seguinte:
|
||||
```
|
||||
Script: <signature> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> 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: <signature> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
Stack: [ ]
|
||||
|
||||
Script: <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
Stack: [ <signature> ]
|
||||
|
||||
Script: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
Stack: [ <signature> <pubKey> ]
|
||||
|
||||
Script: OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
Running: <pubKey> OP_DUP
|
||||
Stack: [ <signature> <pubKey> <pubKey> ]
|
||||
```
|
||||
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 ```<pubKey>``` fora da pilha, cria um hash e coloca o resultado de volta nela.
|
||||
```
|
||||
Script: <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
Running: <pubKey> OP_HASH160
|
||||
Stack: [ <signature> <pubKey> <pubKeyHash> ]
|
||||
```
|
||||
Então, colocamos o ```<pubKeyHash>``` que estava no script de bloqueio na pilha:
|
||||
```
|
||||
Script: OP_EQUALVERIFY OP_CHECKSIG
|
||||
Stack: [ <signature> <pubKey> <pubKeyHash> <pubKeyHash> ]
|
||||
```
|
||||
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 ```<pubKeyHash>``` são iguais, teremos o seguinte resultado:
|
||||
```
|
||||
Script: OP_CHECKSIG
|
||||
Running: <pubKeyHash> <pubKeyHash> OP_EQUALVERIFY
|
||||
Stack: [ <signature> <pubKey> ]
|
||||
```
|
||||
Neste momento, provamos que a `<pubkey>` 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: <signature> <pubKey> OP_CHECKSIG
|
||||
Stack: [ True ]
|
||||
```
|
||||
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
|
||||
|
||||
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 ```<signature>``` e a ```<pubKey>```. Podemos analisar as informações da transação bruta do UTXO para conhecer o script de bloqueio, incluindo o ```<pubKeyHash>```.
|
||||
|
||||
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
|
||||
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 ```<signature>``` e a ```<pubKey>``` 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 ```<pubKey>```:
|
||||
|
||||
```
|
||||
#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 ```<pubKeyHash>``` 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 de sua criptografia.
|
||||
|
||||
### Como Procurar uma Pub Key e uma Assinatura Manualmente
|
||||
|
||||
E se quiséssemos gerar a ```<signature>``` e a ```<PubKey>```, 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 ````<pubKey>````. 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" o UTXO é a melhor solução para isso neste momento.
|
||||
|
||||
## Resumo: Programando um P2PKH
|
||||
|
||||
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?
|
||||
|
||||
Vamos continuar "Apresentando Scripts no Bitcoin" na seção [§9.4: Programando um P2WPKH](09_4_Scripting_a_P2WPKH.md).
|
119
pt/09_5_Scripting_a_P2WPKH.md
Normal file
119
pt/09_5_Scripting_a_P2WPKH.md
Normal file
@ -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. Cautela, leitor.
|
||||
|
||||
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
|
||||
|
||||
É 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 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 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.
|
||||
|
||||
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 "testemunhas".
|
||||
|
||||
### 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 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 à 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_ 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?
|
||||
|
||||
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).
|
Loading…
x
Reference in New Issue
Block a user