From 267f1aa16fcdf99f65fcddaed7a2f2316b27d9bd Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Wed, 4 Aug 2021 19:09:40 -0300 Subject: [PATCH 1/4] Chapter 12 translated. --- pt/12_0_Expanding_Bitcoin_Scripts.md | 20 +++ pt/12_1_Using_Script_Conditionals.md | 199 +++++++++++++++++++++++++ pt/12_2_Using_Other_Script_Commands.md | 85 +++++++++++ 3 files changed, 304 insertions(+) create mode 100644 pt/12_0_Expanding_Bitcoin_Scripts.md create mode 100644 pt/12_1_Using_Script_Conditionals.md create mode 100644 pt/12_2_Using_Other_Script_Commands.md diff --git a/pt/12_0_Expanding_Bitcoin_Scripts.md b/pt/12_0_Expanding_Bitcoin_Scripts.md new file mode 100644 index 0000000..2354278 --- /dev/null +++ b/pt/12_0_Expanding_Bitcoin_Scripts.md @@ -0,0 +1,20 @@ +# Capítulo 12: Expandindo os Scripts do Bitcoin + +Ainda há um pouco mais sobre os Scripts do Bitcoin que precisamos saber. As condicionais fornecem acesso total ao controle de fluxo, enquanto uma variedade de outros opcodes podem expandir nossas possibilidades. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Decidir como usar os condicionais no script; + * Decidir como usar outros opcodes no script. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Compreender toda a gama de possibilidades do script; + * Identificar como aprender mais sobre os opcodes. + +## Tabela de conteúdo + +* [Seção 1: Usando condicionais no script](12_1_Using_Script_Conditionals.md) +* [Seção 2: Usando outros comandos no script](12_2_Using_Other_Script_Commands.md) \ No newline at end of file diff --git a/pt/12_1_Using_Script_Conditionals.md b/pt/12_1_Using_Script_Conditionals.md new file mode 100644 index 0000000..aab7ad9 --- /dev/null +++ b/pt/12_1_Using_Script_Conditionals.md @@ -0,0 +1,199 @@ +# 12.1: Usando condicionais no script + +Há um aspecto importante na criação de Script de Bitcoin que é crucial para expandir o seu verdadeiro poder. Os condicionais permitem que criemos vários caminhos de execução. + +## Entendendo as Verificações + +Já vimos um condicional dentro do script, o ```op_verify``` (0x69). Ele retira o item superior na pilha e verifica se é verdade. Se não for _ele termina a execução do script_. + +A verificação é geralmente incorporada em outros opcodes. Já vimos o ```OP_EQUALVERIFY``` (0xad), o ```OP_CHECKLOCKTIMEVERIFY``` (0xb1) e o ```OP_CHECKSEQUENCEVERIFY``` (0xb2). Cada um desses opcodes faz nossa ação central (equal, checklocktime ou checkscence) e então faz uma verificação posteriormente. Os outros opcodes de verificação que ainda não vimos são: ```OP_NUMEQUALVERIFY``` (0x9d), ```OP_CHECKSIGVERIFY``` (0xad), e ```OP_CHECKMULTISIGVERIFY``` (0xaf). + +Então, como o ```OP_VERIFY``` é um condicional? É o tipo mais poderoso de condicional. Usando o ```OP_VERIFY```, _SE_ uma condição é verdadeira, o script continua executando, _SENÃO_ o script para a execução. É assim que verificamos as condições que são absolutamente necessárias para que um script tenha sucesso. Por exemplo, o script P2PKH (```OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG```) tem duas condições necessárias: (1) a chave pública fornecida precisa corresponder ao hash da chave pública e; (2) a assinatura fornecida precisa corresponder a essa chave pública. Um ```OP_EQUALVERIFY``` é usado para a comparação do hash da chave pública e a chave pública do hash porque é uma condição absolutamente necessária. Não _QUEREMOS_ que o script continue caso venha a falhar. + +Podemos notar que não há ```OP_VERIFY``` no final deste (ou da maioria dos demais) script, apesar da condição final também ser necessária. Isso porque o Bitcoin efetivamente faz um ```OP_VERIFY``` no final de cada roteiro, para garantir que o resultado final da pilha seja verdadeiro. Não podemos fazer um ```OP_VERIFY``` antes do final do script, porque precisamos deixar algo na pilha para ser testado! + +## Entendendo o If/Then (Se/Então) + +O outro condicional principal no script do Bitcoin é o clássico ```OP_IF``` (0x63) / ```OP_ELSE``` (0x67) / ```OP_ENDIF``` (0x68). Este é o controle típico do fluxo: Se o ```OP_IF``` detectar uma afirmação verdadeira, executa o bloco abaixo dele, caso contrário, se houver um ```OP_ELSE```, executa-o e; o ```OP_ENDIF``` marca o final do bloco. + +> :warning: **AVISO:** Estes condicionais tecnicamente são opcodes também, mas como são pequenos números, vamos deixar o prefixo do ```OP_``` desligado para manter a brevidade e a clareza. Assim, vamos escrever ```IF```, ```ELSE```, e ```ENDIF``` ao invés de ```OP_IF```, ```OP_ELSE```, e ```OP_ENDIF```. + +### Entendendo a Ordem do If/Then + +Existem duas grandes sacadas nos condicionais. Eles dificultam a leitura e determinam os scripts se não tivermos cuidado. + +Primeiro, o ```IF``` condicional verifica a verdade do que é _antes dele_ (em outras palavras, o que está na pilha), não o que está depois dele. + +Segundo, o ```IF``` condicional tende a estar no script de bloqueio e o que é verificado tende a estar no script de desbloqueio. + +Claro, podemos dizer, é assim que funciona o Script do Bitcoin. Condicionais usam notação polonesa reversa e adotam o paradigma padrão de desbloqueio/bloqueio, assim como todos os scripts do bitcoin. Isso é tudo verdade, mas também vai ao contrário da maneira padrão que lemos IF/ELSE condicionais em outras linguagens de programação. Assim, é fácil lermos inconscientemente errado os condicionais do Bitcoin. + +Vamos observar o seguinte código: `IF OP_DUP OP_HASH160 ELSE OP_DUP OP_HASH160 ENDIF OP_EQUALVERIFY OP_CHECKSIG`. + +Olhando para os condicionais na notação do prefixo podemos ler isso da seguinte maneira: +``` +IF (OP_DUP) THEN + OP_HASH160 + OP_PUSHDATA +ELSE + OP_DUP + OP_HASH160 + OP_PUSHDATA +ENDIF + OP_EQUALVERIFY + OP_CHECKSIG +``` +Então, podemos pensar, se o ```OP_DUP``` é verdadeiro, então nós vamos fazer o primeiro bloco, senão, o segundo. Mas isso não faz sentido! Por que o ```OP_DUP``` não daria verdadeiro?! + +E, de fato, não faz nenhum sentido, porque acidentalmente lemos a declaração usando a notação errada. A leitura correta é: +``` +IF + OP_DUP + OP_HASH160 + OP_PUSHDATA +ELSE + OP_DUP + OP_HASH160 + OP_PUSHDATA +ENDIF + OP_EQUALVERIFY + OP_CHECKSIG +``` +A declaração que avaliará para é ```True``` ou ```False``` é colocada na pilha _antes_ de executar o ```IF```, então o bloco correto do código será executado com base nesse resultado. + +Este exemplo específico de código é destinado a uma simples multisig 1-de-2. O proprietário da `````` colocaria ``` TRUE``` no script de desbloqueio, enquanto o proprietário da `````` colocaria ``` FALSE``` no script de desbloqueio. Aquele que for rastreado como ```TRUE``` ou ```FALSE``` é o que é verificado pela instrução ```IF```/```ELSE```. Ele conta ao script qual o hash da chave pública é para verificar, então o ```OP_EQUALVERIFY``` e o ```OP_CHECKSIG``` no final fazem o verdadeiro trabalho. + +### Executando um If/Then com Multisig + +Com uma compreensão central dos condicionais do Bitcoin, estamos prontos para executar scripts utilizando-os. Nós vamos começar, criando uma ligeira variante da multisig 1-de-2 do exemplo, onde nossos usuários não precisam lembrar se eles são ```TRUE``` ou ```FALSE```. Ao invés disso, se necessário, o script verifica os hashes de chave pública, apenas exigindo um único sucesso: +``` +OP_DUP OP_HASH160 OP_EQUAL +IF + OP_CHECKSIG +ELSE + OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +ENDIF +``` +Precisamos lembrar da notação polonesa reversa! Aquela instrução ```IF``` está referindo-se ao ```OP_EQUAL``` antes dela, não ao `OP_CHECKSIG` posterior! + +#### Executando a Parte Verdadeira + +Veja como é executado se desbloquearmos com ``` ```: +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Primeiro, colocamos as constantes na pilha: +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Em seguida, nós executamos os primeiros, comandos óbvios, ```OP_DUP``` e ```OP_HASH160``` e colocamos outra constante: +``` +Script: OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_DUP +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Em seguida, executamos o ```OP_EQUAL```, que é o que vai alimentar o ```IF```: +``` +Script: IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_EQUAL +Stack: [ True ] +``` +Agora, o ```IF``` executa, e desde que seja um ```TRUE```, ele só executa o primeiro bloco, eliminando todo o resto: +``` +Script: OP_CHECKSIG +Running: True IF +Stack: [ ] +``` +E o ```OP_CHECKSIG``` acabará sendo ```TRUE``` também: +``` +Script: +Running: OP_CHECKSIG +Stack: [ True ] +``` + +#### Executando a Parte Falsa + +Veja como ele iria executar se fossemos desbloquear com ``` ```: +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Primeiro, colocamos as constantes na pilha: +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Em seguida, executamos os primeiros, comandos óbvios, ```OP_DUP``` e ```OP_HASH160``` e adicionamos outra constante: +``` +Script: OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_DUP +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Em seguida, executamos o ```OP_EQUAL```, que é o que vai alimentar o ```IF```: +``` +Script: IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_EQUAL +Stack: [ False ] +``` +Uhul! O resultado foi ```FALSE``` porque o `````` não é igual ao ``````. Agora, quando o ```IF``` for executado, ele vai pular para a instrução ```ELSE```: +``` +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: False IF +Stack: [ ] +``` +Depois, passamos por todo o imbróglio, começando com outro ```OP_DUP```, mas eventualmente o testando usando outro ```pubKeyHash```: +``` +Script: OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: OP_DUP +Stack: [ ] + +Script: OP_EQUALVERIFY OP_CHECKSIG +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] + +Script:OP_CHECKSIG +Running: OP_EQUALVERIFY +Stack: [ ] + +Script: +Running: OP_CHECKSIG +Stack: [ True ] +``` +Isso provavelmente não é tão eficiente quanto um verdadeiro multisig do Bitcoin, mas é um bom exemplo de como os resultados adicionados a pilha devido a testes anteriores podem ser usados para alimentar futuros condicionais. Neste caso, é o fracasso da primeira assinatura que diz a condicional que deve ir verificar a segunda. + +## Entendendo os Demais Condicionais + +Existem alguns outros condicionais para ser analisados. O maior deles é o ```OP_NOTIF``` (0x64), que é o oposto de ```OP_IF```. Ele executa o próximo bloco se o item superior for ```FALSE```. Um ```ELSE``` pode ser colocado junto, que como usual é executado se o primeiro bloco não for executado. Podemos ainda terminar com o ```OP_ENDIF```. + +Há também um ```OP_IFDUP``` (0x73), que duplica o item de pilha superior somente se o resultado não for 0. + +Essas opções são usadas com muito menos frequência do que a construção usando ```IF```/```ELSE```/```ENDIF```. + +## Resumo: Usando condicionais no script + +Os condicionais no script do Bitcoin permitem deter o script (usando o ```OP_VERIFY```) ou para escolher diferentes ramos de execução (usando ```OP_IF```). No entanto, a ler o ```OP_IF``` pode ser um pouco complicado. Precisamos lembrar de que é o item adicionado a pilha _antes_ do operador ```OP_IF``` ser executado que controla a sua execução. Esse item normalmente fará parte do script de desbloqueio (ou será um resultado direto de itens do script de desbloqueio). + +> :fire: ***Qual é o poder dos condicionais?*** Os condicionais do script são o principal bloco de construção no script do Bitcoin. Eles transformam os scripts simples e estáticos do Bitcoin em scripts de bitcoin complexos e dinâmicos que podem avaliar de maneira diferente com base em diferentes momentos, diferentes circunstâncias ou diferentes entradas de usuário. Em outras palavras, eles são o último pilar dos contratos inteligentes. + +## O Que Vem Depois? + +Vamos continuar "Expandindo os Scripts do Bitcoin" na seção [§12.2: Usando outros comandos no script](12_2_using_other_script_commands.md). \ No newline at end of file diff --git a/pt/12_2_Using_Other_Script_Commands.md b/pt/12_2_Using_Other_Script_Commands.md new file mode 100644 index 0000000..d44c1fb --- /dev/null +++ b/pt/12_2_Using_Other_Script_Commands.md @@ -0,0 +1,85 @@ +# 12.2: Usando outros comandos no script + +Já temos em mãos a maioria dos opcodes do script do Bitcoin que iremos usar na maioria dos nossos scripts. No entanto, o script do Bitcoin oferece muito mais opções, o que pode vir a ser exatamente o que precisamos para criar o nosso instrumento financeiro dos nossos sonhos. + +Devemos consultar a [página do script do Bitcoin](https://en.bitcoin.it/wiki/script) para termos uma lista mais completa de todos esses e muitos outros comandos. Esta seção destaca apenas os opcodes mais notáveis. + +## Entendendo os Opcodes Aritméticos + +Os opcodes aritméticos manipulam ou testam números. + +Manipulam um número: + +* OP_1ADD (0x8b) - Adiciona uma unidade; +* OP_1SUB (0x8C) - Subtrai uma unidade; +* OP_NEGATE (0x8f) - Inverte o sinal do número; +* OP_ABS (0x90) - O número fica positivo; +* OP_NOT (0x91) - Troca 1 por 0, senão 0. + +É legal saber sobre o ```OP_0NOTEQUAL``` (0x92). + +Manipulam dois números matematicamente: + +* OP_ADD (0x93) - Adiciona dois números; +* OP_SUB (0x94) - Subtrai dois números; +* OP_MIN (0xA3) - Retorna o menor entre dois números; +* OP_MAX (0xA4) - Retorna o maior entre dois números. + +Manipulam dois números logicamente: + +* OP_BOOLAND (0x9a) - 1 se ambos os números não são 0, senão 0; +* OP_BOOLOR (0x9B) - 1 se qualquer número não é 0, senão 0. + +Testa dois números: + +* OP_NUMEQUAL (0x9C) - 1 se ambos os números forem iguais, senão 0; +* OP_LESSTHAN (0x9f) - 1 se o primeiro número for menor que o segundo, senão 0; +* OP_GREATERTHAN (0xA0) - 1 se o primeiro número for maior que o segundo, senão 0; +* OP_LESSTHANOREQUAL (0xA1) - 1 se o primeiro número for menor ou igual ao segundo, senão 0; +* OP_GREATERTHANOREQUAL (0xA2) - 1 se o primeiro número for maior ou igual a segundo, senão 0. + +É legal saber também: O ```OP_NUMEQUALVERIFY``` (0x9d) e o ```OP_NUMNOTEQUAL``` (0x9e) + +Testa três números: + +* OP_WITHIN (0xA5) - 1 se um número estiver no intervalo de dois outros números. + +## Entendendo a Opcodes de Pilha + +Há um número chocante de opcodes de pilha, mas além de ```OP_DROP```, ```OP_DUP```, e às vezes, ```OP_SWAP``` geralmente não serão necessários se tivermos cuidado com a ordem da pilha. No entanto, aqui estão alguns dos mais interessantes: + +* OP_DEPTH (0x74) - Aumenta o tamanho da pilha; +* OP_DROP (0x75) - Retira o item superior da pilha; +* OP_DUP (0x76) - Duplica o item superior da pilha; +* OP_PICK (0x79) - Duplica o enésimo item da pilha começando pelo topo; +* OP_ROLL (0x7a) - Move o enésimo item para o topo da pilha; +* OP_SWAP(0x7C) - Troca os dois principais itens da pilha. + +É legal saber também: O `OP_TOALTSTACK` (0x6b), `OP_FROMALTSTACK` (0x6c), `OP_2DROP` (0x6d), `OP_2DUP` (0x6e), `OP_3DUP` (0x6f), `OP_2OVER` (0x70), `OP_2ROT` (0x71), `OP_2SWAP` (0x72), `OP_IFDUP` (0x73), `OP_NIP` (0x77), `OP_OVER` (0x78), `OP_ROT` (0x7b), e o `OP_TUCK` (0x7d). + +## Entendendo os Opcodes Criptográficos + +Finalmente, uma variedade de opcodes para dar suporte ao hashing e a verificação da assinatura: + +Hash: + +* OP_RIPEMD160 (0xa6) — RIPEMD-160; +* OP_SHA1 (0xa7) — SHA-1; +* OP_SHA256 (0xa8) - SHA-256; +* OP_HASH160 (0xa9) — SHA-256 + RIPEMD-160; +* OP_HASH256 (0xaa) — SHA-256 + SHA-256. + +Verifica as assinaturas: + +* Op_checksig (0xac) - Verifica uma assinatura; +* Op_checkmultisig (0xae) - Verifica uma multisig M-DE-N. + +É legal saber também: O `OP_CODESEPARATOR` (0xab), `OP_CHECKSIGVERIFY` (0xad), e o `OP_CHECKMULTISIGVERIFY` (0xaf). + +## Resumo: Usando outros comandos no script + +O script do Bitcoin inclui uma ampla gama de opcodes aritméticos, de pilha e criptográficos. A maioria desses opcodes adicionais provavelmente não serão tão comuns quanto os discutidos nas seções anteriores, mas, no entanto, estão disponíveis, para sabermos que existem caso precisemos utilizá-los para escrever nosso script! + +## O Que Vem Depois? + +Vamos avançar do "Expandindo os Scripts do Bitcoin" para o [Capítulo 13: Projetando Scripts Reais no Bitcoin](13_0_Designing_real_bitcoin_scripts.md). \ No newline at end of file From e612796ff86c7e161eea859735404240b62135ab Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 10:19:16 -0300 Subject: [PATCH 2/4] Review 12_0 --- pt/12_0_Expanding_Bitcoin_Scripts.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pt/12_0_Expanding_Bitcoin_Scripts.md b/pt/12_0_Expanding_Bitcoin_Scripts.md index 2354278..ec48dfc 100644 --- a/pt/12_0_Expanding_Bitcoin_Scripts.md +++ b/pt/12_0_Expanding_Bitcoin_Scripts.md @@ -2,7 +2,7 @@ Ainda há um pouco mais sobre os Scripts do Bitcoin que precisamos saber. As condicionais fornecem acesso total ao controle de fluxo, enquanto uma variedade de outros opcodes podem expandir nossas possibilidades. -## Objetivos deste capítulo +## Objetivos Deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: @@ -11,10 +11,10 @@ Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: Os objetivos secundários do capítulo incluem a capacidade de: - * Compreender toda a gama de possibilidades do script; + * Compreender toda a gama de possibilidades de programação; * Identificar como aprender mais sobre os opcodes. -## Tabela de conteúdo +## Tabela de Conteúdo -* [Seção 1: Usando condicionais no script](12_1_Using_Script_Conditionals.md) -* [Seção 2: Usando outros comandos no script](12_2_Using_Other_Script_Commands.md) \ No newline at end of file +* [Seção 1: Usando Condicionais no Script](12_1_Using_Script_Conditionals.md) +* [Seção 2: Usando Outros Comandos no Script](12_2_Using_Other_Script_Commands.md) \ No newline at end of file From a0e422b75e53d6286687a70654272df6bc2a1a2c Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 10:40:21 -0300 Subject: [PATCH 3/4] Review 12_1 --- pt/12_1_Using_Script_Conditionals.md | 50 ++++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/pt/12_1_Using_Script_Conditionals.md b/pt/12_1_Using_Script_Conditionals.md index aab7ad9..88ce03a 100644 --- a/pt/12_1_Using_Script_Conditionals.md +++ b/pt/12_1_Using_Script_Conditionals.md @@ -1,32 +1,32 @@ -# 12.1: Usando condicionais no script +# 12.1: Usando Condicionais no Script Há um aspecto importante na criação de Script de Bitcoin que é crucial para expandir o seu verdadeiro poder. Os condicionais permitem que criemos vários caminhos de execução. ## Entendendo as Verificações -Já vimos um condicional dentro do script, o ```op_verify``` (0x69). Ele retira o item superior na pilha e verifica se é verdade. Se não for _ele termina a execução do script_. +Já vimos um condicional dentro do script, o ```op_verify``` (0x69). Ele retira o item superior na pilha e verifica se é verdade. Se não for, _ele termina a execução do script_. -A verificação é geralmente incorporada em outros opcodes. Já vimos o ```OP_EQUALVERIFY``` (0xad), o ```OP_CHECKLOCKTIMEVERIFY``` (0xb1) e o ```OP_CHECKSEQUENCEVERIFY``` (0xb2). Cada um desses opcodes faz nossa ação central (equal, checklocktime ou checkscence) e então faz uma verificação posteriormente. Os outros opcodes de verificação que ainda não vimos são: ```OP_NUMEQUALVERIFY``` (0x9d), ```OP_CHECKSIGVERIFY``` (0xad), e ```OP_CHECKMULTISIGVERIFY``` (0xaf). +A verificação é geralmente incorporada em outros opcodes. Já vimos o ```OP_EQUALVERIFY``` (0xad), o ```OP_CHECKLOCKTIMEVERIFY``` (0xb1) e o ```OP_CHECKSEQUENCEVERIFY``` (0xb2). Cada um desses opcodes faz nossa ação central (equal, checklocktime ou checksequence) e então faz uma verificação posteriormente. Os outros opcodes de verificação que ainda não vimos são: ```OP_NUMEQUALVERIFY``` (0x9d), ```OP_CHECKSIGVERIFY``` (0xad), e ```OP_CHECKMULTISIGVERIFY``` (0xaf). -Então, como o ```OP_VERIFY``` é um condicional? É o tipo mais poderoso de condicional. Usando o ```OP_VERIFY```, _SE_ uma condição é verdadeira, o script continua executando, _SENÃO_ o script para a execução. É assim que verificamos as condições que são absolutamente necessárias para que um script tenha sucesso. Por exemplo, o script P2PKH (```OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG```) tem duas condições necessárias: (1) a chave pública fornecida precisa corresponder ao hash da chave pública e; (2) a assinatura fornecida precisa corresponder a essa chave pública. Um ```OP_EQUALVERIFY``` é usado para a comparação do hash da chave pública e a chave pública do hash porque é uma condição absolutamente necessária. Não _QUEREMOS_ que o script continue caso venha a falhar. +Então, como o ```OP_VERIFY``` é um condicional? É o tipo mais poderoso de condicional. Usando o ```OP_VERIFY```, _se_ uma condição é verdadeira, o script continua executando, _senão_ o script pára a execução. É assim que verificamos as condições que são absolutamente necessárias para que um script tenha sucesso. Por exemplo, o script P2PKH (```OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG```) tem duas condições necessárias: (1) a chave pública fornecida precisa corresponder ao hash da chave pública e; (2) a assinatura fornecida precisa corresponder à essa chave pública. Um ```OP_EQUALVERIFY``` é usado para a comparação do hash da chave pública e a chave pública do hash porque é uma condição absolutamente necessária. Não _queremos_ que o script continue caso isto falhe. -Podemos notar que não há ```OP_VERIFY``` no final deste (ou da maioria dos demais) script, apesar da condição final também ser necessária. Isso porque o Bitcoin efetivamente faz um ```OP_VERIFY``` no final de cada roteiro, para garantir que o resultado final da pilha seja verdadeiro. Não podemos fazer um ```OP_VERIFY``` antes do final do script, porque precisamos deixar algo na pilha para ser testado! +Podemos notar que não há ```OP_VERIFY``` no final deste script (ou da maioria dos demais), apesar da condição final também ser necessária. Isso porque o Bitcoin efetivamente faz um ```OP_VERIFY``` no final de cada script, para garantir que o resultado final da pilha seja verdadeiro. Não podemos fazer um ```OP_VERIFY``` antes do final do script, porque precisamos deixar algo na pilha para ser testado! -## Entendendo o If/Then (Se/Então) +## Compreendendo o If/Then (Se/Então) -O outro condicional principal no script do Bitcoin é o clássico ```OP_IF``` (0x63) / ```OP_ELSE``` (0x67) / ```OP_ENDIF``` (0x68). Este é o controle típico do fluxo: Se o ```OP_IF``` detectar uma afirmação verdadeira, executa o bloco abaixo dele, caso contrário, se houver um ```OP_ELSE```, executa-o e; o ```OP_ENDIF``` marca o final do bloco. +O outro condicional principal no script do Bitcoin é o clássico ```OP_IF``` (0x63) / ```OP_ELSE``` (0x67) / ```OP_ENDIF``` (0x68). Este é o controle típico de fluxo: se o ```OP_IF``` detectar uma afirmação verdadeira, ele executa o bloco abaixo dele, caso contrário, se houver um ```OP_ELSE```, ele o executa; e o ```OP_ENDIF``` marca o final do bloco. > :warning: **AVISO:** Estes condicionais tecnicamente são opcodes também, mas como são pequenos números, vamos deixar o prefixo do ```OP_``` desligado para manter a brevidade e a clareza. Assim, vamos escrever ```IF```, ```ELSE```, e ```ENDIF``` ao invés de ```OP_IF```, ```OP_ELSE```, e ```OP_ENDIF```. -### Entendendo a Ordem do If/Then +### Compreendendo a Ordem do If/Then Existem duas grandes sacadas nos condicionais. Eles dificultam a leitura e determinam os scripts se não tivermos cuidado. -Primeiro, o ```IF``` condicional verifica a verdade do que é _antes dele_ (em outras palavras, o que está na pilha), não o que está depois dele. +Primeiro, o condicional ```IF``` verifica a verdade do que é _antes dele_ (em outras palavras, o que está na pilha), e não o que está depois dele. -Segundo, o ```IF``` condicional tende a estar no script de bloqueio e o que é verificado tende a estar no script de desbloqueio. +Segundo, o condicional ```IF``` tende a estar no script de bloqueio e o que é verificado tende a estar no script de desbloqueio. -Claro, podemos dizer, é assim que funciona o Script do Bitcoin. Condicionais usam notação polonesa reversa e adotam o paradigma padrão de desbloqueio/bloqueio, assim como todos os scripts do bitcoin. Isso é tudo verdade, mas também vai ao contrário da maneira padrão que lemos IF/ELSE condicionais em outras linguagens de programação. Assim, é fácil lermos inconscientemente errado os condicionais do Bitcoin. +Claro, podemos dizer, é assim que funciona o Script do Bitcoin. Condicionais usam notação polonesa reversa e adotam o paradigma padrão de desbloqueio/bloqueio, assim como todos os scripts do bitcoin. Isso é tudo verdade, mas também é o contrário da maneira padrão de ler-se condicionais IF/ELSE em outras linguagens de programação. Assim, é fácil lermos errado, inconscientemente, os condicionais do Bitcoin. Vamos observar o seguinte código: `IF OP_DUP OP_HASH160 ELSE OP_DUP OP_HASH160 ENDIF OP_EQUALVERIFY OP_CHECKSIG`. @@ -43,7 +43,7 @@ ENDIF OP_EQUALVERIFY OP_CHECKSIG ``` -Então, podemos pensar, se o ```OP_DUP``` é verdadeiro, então nós vamos fazer o primeiro bloco, senão, o segundo. Mas isso não faz sentido! Por que o ```OP_DUP``` não daria verdadeiro?! +Então, podemos pensar, se o ```OP_DUP``` é verdadeiro, então nós vamos fazer o primeiro bloco, senão, o segundo. Mas isso não faz sentido! Por que o ```OP_DUP``` não executaria com sucesso?! E, de fato, não faz nenhum sentido, porque acidentalmente lemos a declaração usando a notação errada. A leitura correta é: ``` @@ -59,13 +59,13 @@ ENDIF OP_EQUALVERIFY OP_CHECKSIG ``` -A declaração que avaliará para é ```True``` ou ```False``` é colocada na pilha _antes_ de executar o ```IF```, então o bloco correto do código será executado com base nesse resultado. +A declaração que avaliará para ```True``` ou ```False``` é colocada na pilha _antes_ de executar o ```IF```, então o bloco correto do código será executado com base naquele resultado. -Este exemplo específico de código é destinado a uma simples multisig 1-de-2. O proprietário da `````` colocaria ``` TRUE``` no script de desbloqueio, enquanto o proprietário da `````` colocaria ``` FALSE``` no script de desbloqueio. Aquele que for rastreado como ```TRUE``` ou ```FALSE``` é o que é verificado pela instrução ```IF```/```ELSE```. Ele conta ao script qual o hash da chave pública é para verificar, então o ```OP_EQUALVERIFY``` e o ```OP_CHECKSIG``` no final fazem o verdadeiro trabalho. +Este exemplo específico de código é destinado a um simples multisig 1-de-2. O proprietário da `````` colocaria ``` TRUE``` no script de desbloqueio, enquanto o proprietário da `````` colocaria ``` FALSE``` no script de desbloqueio. Aquele que for rastreado como ```TRUE``` ou ```FALSE``` é o que é verificado pela instrução ```IF```/```ELSE```. Ele conta ao script qual o hash da chave pública é para verificar, então o ```OP_EQUALVERIFY``` e o ```OP_CHECKSIG``` no final fazem o verdadeiro trabalho. ### Executando um If/Then com Multisig -Com uma compreensão central dos condicionais do Bitcoin, estamos prontos para executar scripts utilizando-os. Nós vamos começar, criando uma ligeira variante da multisig 1-de-2 do exemplo, onde nossos usuários não precisam lembrar se eles são ```TRUE``` ou ```FALSE```. Ao invés disso, se necessário, o script verifica os hashes de chave pública, apenas exigindo um único sucesso: +Com uma compreensão central dos condicionais do Bitcoin, estamos prontos para executar scripts os utilizando. Nós vamos começar criando uma ligeira variante do multisig 1-de-2 do exemplo, onde nossos usuários não precisam lembrar se eles são ```TRUE``` ou ```FALSE```. Ao invés disso, se necessário, o script verifica os hashes de chave pública, apenas exigindo um único sucesso: ``` OP_DUP OP_HASH160 OP_EQUAL IF @@ -74,7 +74,7 @@ ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF ``` -Precisamos lembrar da notação polonesa reversa! Aquela instrução ```IF``` está referindo-se ao ```OP_EQUAL``` antes dela, não ao `OP_CHECKSIG` posterior! +Precisamos lembrar da notação polonesa reversa! Aquela instrução ```IF``` está se referindo ao ```OP_EQUAL``` antes dela, não ao `OP_CHECKSIG` posterior! #### Executando a Parte Verdadeira @@ -88,7 +88,7 @@ Primeiro, colocamos as constantes na pilha: Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF Stack: [ ] ``` -Em seguida, nós executamos os primeiros, comandos óbvios, ```OP_DUP``` e ```OP_HASH160``` e colocamos outra constante: +Em seguida, nós executamos os primeiros comandos óbvios, ```OP_DUP``` e ```OP_HASH160```, e colocamos outra constante: ``` Script: OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF Running: OP_DUP @@ -107,7 +107,7 @@ Script: IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CH Running: OP_EQUAL Stack: [ True ] ``` -Agora, o ```IF``` executa, e desde que seja um ```TRUE```, ele só executa o primeiro bloco, eliminando todo o resto: +Agora, o ```IF``` executa, e desde que haja um ```TRUE```, ele só executa o primeiro bloco, eliminando todo o resto: ``` Script: OP_CHECKSIG Running: True IF @@ -122,7 +122,7 @@ Stack: [ True ] #### Executando a Parte Falsa -Veja como ele iria executar se fossemos desbloquear com ``` ```: +Veja como ele iria executar se fôssemos desbloquear com ``` ```: ``` Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF Stack: [ ] @@ -132,7 +132,7 @@ Primeiro, colocamos as constantes na pilha: Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF Stack: [ ] ``` -Em seguida, executamos os primeiros, comandos óbvios, ```OP_DUP``` e ```OP_HASH160``` e adicionamos outra constante: +Em seguida, executamos os primeiros comandos óbvios, ```OP_DUP``` e ```OP_HASH160```, e adicionamos outra constante: ``` Script: OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF Running: OP_DUP @@ -178,7 +178,7 @@ Script: Running: OP_CHECKSIG Stack: [ True ] ``` -Isso provavelmente não é tão eficiente quanto um verdadeiro multisig do Bitcoin, mas é um bom exemplo de como os resultados adicionados a pilha devido a testes anteriores podem ser usados para alimentar futuros condicionais. Neste caso, é o fracasso da primeira assinatura que diz a condicional que deve ir verificar a segunda. +Isso provavelmente não é tão eficiente quanto um verdadeiro multisig do Bitcoin, mas é um bom exemplo de como os resultados adicionados à pilha devido a testes anteriores podem ser usados para alimentar condicionais futuros. Neste caso, é o fracasso da primeira assinatura que diz ao condicional que deve ir verificar a segunda. ## Entendendo os Demais Condicionais @@ -188,12 +188,12 @@ Há também um ```OP_IFDUP``` (0x73), que duplica o item de pilha superior somen Essas opções são usadas com muito menos frequência do que a construção usando ```IF```/```ELSE```/```ENDIF```. -## Resumo: Usando condicionais no script +## Resumo: Usando Condicionais no Script -Os condicionais no script do Bitcoin permitem deter o script (usando o ```OP_VERIFY```) ou para escolher diferentes ramos de execução (usando ```OP_IF```). No entanto, a ler o ```OP_IF``` pode ser um pouco complicado. Precisamos lembrar de que é o item adicionado a pilha _antes_ do operador ```OP_IF``` ser executado que controla a sua execução. Esse item normalmente fará parte do script de desbloqueio (ou será um resultado direto de itens do script de desbloqueio). +Os condicionais no script do Bitcoin permitem parar o script (usando o ```OP_VERIFY```) ou escolher diferentes ramos de execução (usando ```OP_IF```). No entanto, ler o ```OP_IF``` pode ser um pouco complicado. Precisamos lembrar de que é o item adicionado à pilha _antes_ do operador ```OP_IF``` ser executado que controla a sua execução. Esse item normalmente fará parte do script de desbloqueio (ou será um resultado direto de itens do script de desbloqueio). -> :fire: ***Qual é o poder dos condicionais?*** Os condicionais do script são o principal bloco de construção no script do Bitcoin. Eles transformam os scripts simples e estáticos do Bitcoin em scripts de bitcoin complexos e dinâmicos que podem avaliar de maneira diferente com base em diferentes momentos, diferentes circunstâncias ou diferentes entradas de usuário. Em outras palavras, eles são o último pilar dos contratos inteligentes. +> :fire: ***Qual é o poder dos condicionais?*** Os condicionais do script são o principal bloco de construção no Bitcoin Script. Eles transformam os scripts simples e estáticos do Bitcoin em scripts de Bitcoin complexos e dinâmicos que podem avaliar de maneira diferente com base em diferentes momentos, diferentes circunstâncias ou diferentes entradas de usuário. Em outras palavras, eles são o último pilar dos contratos inteligentes. ## O Que Vem Depois? -Vamos continuar "Expandindo os Scripts do Bitcoin" na seção [§12.2: Usando outros comandos no script](12_2_using_other_script_commands.md). \ No newline at end of file +Vamos continuar "Expandindo os Scripts do Bitcoin" na seção [§12.2: Usando Outros Comandos no Script](12_2_using_other_script_commands.md). \ No newline at end of file From 4f380e5180b40f841f139172414108378ff31ca3 Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 10 Aug 2021 10:53:32 -0300 Subject: [PATCH 4/4] Review 12_2 --- pt/12_2_Using_Other_Script_Commands.md | 34 +++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/pt/12_2_Using_Other_Script_Commands.md b/pt/12_2_Using_Other_Script_Commands.md index d44c1fb..88055ae 100644 --- a/pt/12_2_Using_Other_Script_Commands.md +++ b/pt/12_2_Using_Other_Script_Commands.md @@ -1,8 +1,8 @@ -# 12.2: Usando outros comandos no script +# 12.2: Usando Outros Comandos no Script -Já temos em mãos a maioria dos opcodes do script do Bitcoin que iremos usar na maioria dos nossos scripts. No entanto, o script do Bitcoin oferece muito mais opções, o que pode vir a ser exatamente o que precisamos para criar o nosso instrumento financeiro dos nossos sonhos. +Provavelmente já temos em mãos a maioria dos opcodes do Bitcoin Script que iremos usar na maioria dos nossos scripts. No entanto, o Bitcoin Script oferece muito mais opções, o que pode vir a ser exatamente o que precisamos para criar o instrumento financeiro dos nossos sonhos. -Devemos consultar a [página do script do Bitcoin](https://en.bitcoin.it/wiki/script) para termos uma lista mais completa de todos esses e muitos outros comandos. Esta seção destaca apenas os opcodes mais notáveis. +Devemos consultar a [página do script do Bitcoin](https://en.bitcoin.it/wiki/script) para termos uma lista mais completa de todos esses e muitos outros comandos. Esta seção destaca apenas os opcodes mais notáveis. ## Entendendo os Opcodes Aritméticos @@ -13,10 +13,10 @@ Manipulam um número: * OP_1ADD (0x8b) - Adiciona uma unidade; * OP_1SUB (0x8C) - Subtrai uma unidade; * OP_NEGATE (0x8f) - Inverte o sinal do número; -* OP_ABS (0x90) - O número fica positivo; +* OP_ABS (0x90) - Torna o número positivo; * OP_NOT (0x91) - Troca 1 por 0, senão 0. -É legal saber sobre o ```OP_0NOTEQUAL``` (0x92). +Veja também: ```OP_0NOTEQUAL``` (0x92). Manipulam dois números matematicamente: @@ -38,15 +38,15 @@ Testa dois números: * OP_LESSTHANOREQUAL (0xA1) - 1 se o primeiro número for menor ou igual ao segundo, senão 0; * OP_GREATERTHANOREQUAL (0xA2) - 1 se o primeiro número for maior ou igual a segundo, senão 0. -É legal saber também: O ```OP_NUMEQUALVERIFY``` (0x9d) e o ```OP_NUMNOTEQUAL``` (0x9e) +Veja também: ```OP_NUMEQUALVERIFY``` (0x9d) e ```OP_NUMNOTEQUAL``` (0x9e) Testa três números: * OP_WITHIN (0xA5) - 1 se um número estiver no intervalo de dois outros números. -## Entendendo a Opcodes de Pilha +## Compreendendo os Opcodes de Pilha -Há um número chocante de opcodes de pilha, mas além de ```OP_DROP```, ```OP_DUP```, e às vezes, ```OP_SWAP``` geralmente não serão necessários se tivermos cuidado com a ordem da pilha. No entanto, aqui estão alguns dos mais interessantes: +Há um número chocante de opcodes de pilha, mas além de ```OP_DROP```, ```OP_DUP```, e às vezes ```OP_SWAP```, eles geralmente não serão necessários se tivermos cuidado com a ordem da pilha. No entanto, aqui estão alguns dos mais interessantes: * OP_DEPTH (0x74) - Aumenta o tamanho da pilha; * OP_DROP (0x75) - Retira o item superior da pilha; @@ -55,11 +55,11 @@ Há um número chocante de opcodes de pilha, mas além de ```OP_DROP```, ```OP_D * OP_ROLL (0x7a) - Move o enésimo item para o topo da pilha; * OP_SWAP(0x7C) - Troca os dois principais itens da pilha. -É legal saber também: O `OP_TOALTSTACK` (0x6b), `OP_FROMALTSTACK` (0x6c), `OP_2DROP` (0x6d), `OP_2DUP` (0x6e), `OP_3DUP` (0x6f), `OP_2OVER` (0x70), `OP_2ROT` (0x71), `OP_2SWAP` (0x72), `OP_IFDUP` (0x73), `OP_NIP` (0x77), `OP_OVER` (0x78), `OP_ROT` (0x7b), e o `OP_TUCK` (0x7d). +Veja também: `OP_TOALTSTACK` (0x6b), `OP_FROMALTSTACK` (0x6c), `OP_2DROP` (0x6d), `OP_2DUP` (0x6e), `OP_3DUP` (0x6f), `OP_2OVER` (0x70), `OP_2ROT` (0x71), `OP_2SWAP` (0x72), `OP_IFDUP` (0x73), `OP_NIP` (0x77), `OP_OVER` (0x78), `OP_ROT` (0x7b), e `OP_TUCK` (0x7d). -## Entendendo os Opcodes Criptográficos +## Compreendendo os Opcodes Criptográficos -Finalmente, uma variedade de opcodes para dar suporte ao hashing e a verificação da assinatura: +Finalmente, uma variedade de opcodes para dar suporte ao hashing e à verificação de assinatura: Hash: @@ -71,15 +71,15 @@ Hash: Verifica as assinaturas: -* Op_checksig (0xac) - Verifica uma assinatura; -* Op_checkmultisig (0xae) - Verifica uma multisig M-DE-N. +* OP_CHECKSIG (0xac) - Verifica uma assinatura; +* OP_CHECKMULTISIG (0xae) - Verifica um multisig m-de-n. -É legal saber também: O `OP_CODESEPARATOR` (0xab), `OP_CHECKSIGVERIFY` (0xad), e o `OP_CHECKMULTISIGVERIFY` (0xaf). +Veja também: `OP_CODESEPARATOR` (0xab), `OP_CHECKSIGVERIFY` (0xad), e `OP_CHECKMULTISIGVERIFY` (0xaf). -## Resumo: Usando outros comandos no script +## Resumo: Usando Outros Comandos no Script -O script do Bitcoin inclui uma ampla gama de opcodes aritméticos, de pilha e criptográficos. A maioria desses opcodes adicionais provavelmente não serão tão comuns quanto os discutidos nas seções anteriores, mas, no entanto, estão disponíveis, para sabermos que existem caso precisemos utilizá-los para escrever nosso script! +O Bitcoin Script inclui uma ampla gama de opcodes aritméticos, de pilha e criptográficos. A maioria desses opcodes adicionais provavelmente não serão tão comuns quanto os discutidos nas seções anteriores, mas, no entanto, estão disponíveis caso precisemos utilizá-los para escrever nosso script! ## O Que Vem Depois? -Vamos avançar do "Expandindo os Scripts do Bitcoin" para o [Capítulo 13: Projetando Scripts Reais no Bitcoin](13_0_Designing_real_bitcoin_scripts.md). \ No newline at end of file +Vamos avançar "Expandindo os Scripts do Bitcoin" com o [Capítulo 13: Projetando Scripts Reais no Bitcoin](13_0_Designing_real_bitcoin_scripts.md). \ No newline at end of file