Introdução

Às vezes, o Bitcoin é chamado de dinheiro programável. Devido à sua natureza digital, permite aos utilizadores um grande grau de flexibilidade quando se trata de definir as condições de como os fundos podem ser gastos. 

Falamos de carteiras e moedas quando discutimos Bitcoin. Mas também poderíamos pensar nas carteiras como chaves, nas moedas como cheques e na blockchain como fileiras e mais fileiras de cofres trancados. Cada cofre possui uma fenda fina, de modo que qualquer pessoa pode depositar cheques ou verificar quanto valor o cofre contém. Porém, apenas o porta-chaves poderá acessar o interior.

Quando um porta-chaves quer dar dinheiro a outra pessoa, ele destranca a caixa. Eles emitem um novo cheque que faz referência ao antigo (que é então destruído) e o trancam em uma caixa que o destinatário pode abrir. Para gastar isso, o novo destinatário repete o processo.

Neste artigo, daremos uma olhada mais de perto no Script, a linguagem de programação interpretada pelos nós da rede Bitcoin. O script é o que rege o mecanismo de bloqueio/desbloqueio mencionado para os cofres.


Como funciona o Bitcoin?

Seguindo nossa analogia acima, você poderia dizer que cada transação contém duas partes – uma chave (para destrancar sua caixa) e um cadeado. Você usa sua chave para abrir a caixa que contém o cheque que deseja enviar e, em seguida, adiciona um novo a uma nova caixa com um cadeado diferente. Para gastar na nova caixa, você precisa de outra chave.

Simples o suficiente. Você também pode obter algumas variações nos tipos de bloqueios do sistema. Talvez alguns cofres exijam que você forneça várias chaves, e talvez outros precisem que você prove que conhece um segredo. Existem várias condições que as pessoas podem definir. 

Nossa chave é o que chamamos de scriptSig. O bloqueio é nosso scriptPubKey. Se observarmos esses componentes com mais detalhes, descobriremos que eles são, na verdade, compostos de bits de dados e blocos de código. Quando combinados, eles criam um pequeno programa.

Ao fazer uma transação, você transmite essa combinação para a rede. Cada nó que a recebe verificará o programa, que informa se a transação é válida. Caso contrário, ele será simplesmente descartado e você não poderá gastar os fundos bloqueados.

Os cheques (moedas) que você possui são chamados de saídas de transação não gastas (UTXOs). Os fundos podem ser usados ​​por qualquer pessoa que forneça a chave que cabe na fechadura. Especificamente, a chave é o scriptSig e o bloqueio é o scriptPubKey.

Se os UTXOs estiverem em sua carteira, eles provavelmente terão uma condição que diz que apenas a pessoa que puder provar a propriedade dessa chave pública poderá desbloquear esses fundos. Para desbloqueá-lo, você fornece um scriptSig que inclui uma assinatura digital, usando a chave privada que mapeia para a chave pública especificada no scriptPubKey. Tudo isso ficará mais claro em breve.


Compreendendo a pilha Bitcoin

Script é conhecido como linguagem baseada em pilha. Tudo isto significa que, quando lemos um conjunto de instruções, colocamo-las no que pode ser considerado uma coluna vertical. A lista A, B, C, por exemplo, resultaria em uma pilha com A na parte inferior e C no topo. Quando as instruções nos dizem para fazer algo, operamos em um ou mais elementos começando no topo da pilha.


Elements A, B, and C being added and “popped” from the stack.

Elementos A, B e C sendo adicionados e “retirados” da pilha.


Podemos distinguir entre os dados (coisas como assinaturas, hashes e chaves públicas) e as instruções (ou opcodes). As instruções removem dados e fazem algo com eles. Aqui está um exemplo muito simples de como seria um script:

<xyz> <md5 hasher> <d16fb36f0911f878998c136191af705e> <verifique se for igual>

Em vermelho temos os dados e em azul temos os opcodes. Lemos da esquerda para a direita, então primeiro colocamos a string <xyz> na pilha. O próximo é o opcode <md5 hasher>. Este não existe no Bitcoin, mas digamos que ele remove o elemento superior da pilha (<xyz>) e faz o hash usando o algoritmo MD5. Em seguida, a saída é adicionada de volta à pilha. A saída aqui é d16fb36f0911f878998c136191af705e.

Que coincidência! Nosso próximo elemento a ser adicionado é <d16fb36f0911f878998c136191af705e>, então agora nossa pilha tem dois elementos idênticos. Por último, <check if equal> destaca dois elementos do topo e verifica se eles são iguais. Se estiverem, adiciona <1> à pilha. Caso contrário, adiciona <0>. 

Chegamos ao final da nossa lista de instruções. Nosso script poderia ter falhado de duas maneiras – se o elemento restante fosse zero ou se um dos operadores causasse sua falha quando algumas condições não fossem atendidas. Não tínhamos nenhum desses operadores neste exemplo e terminamos com um elemento diferente de zero (<1>), portanto nosso script era válido. Essas regras também são válidas para transações reais de Bitcoin.

Esse foi apenas um programa inventado. Vejamos alguns reais agora.


Pague para Pubkey (P2PK)

Pay-to-Pubkey (P2PK) é incrivelmente simples. Envolve bloquear fundos para uma chave pública específica. Se você quisesse receber fundos dessa maneira, você forneceria ao remetente sua chave pública, em vez de um endereço Bitcoin. 

A primeira transação entre Satoshi Nakamoto e Hal Finney em 2009 foi P2PK. A estrutura foi muito utilizada nos primeiros dias do Bitcoin, mas hoje em dia, Pay-to-Pubkey-Hash (P2PKH) a substituiu em grande parte. 

O script de bloqueio para uma transação P2PK segue o formato de <chave pública> OP_CHECKSIG. Simples o suficiente. Você deve ter adivinhado que OP_CHECKSIG verifica uma assinatura na chave pública fornecida. Como tal, nosso scriptSig será uma simples <signature>. Lembre-se, o scriptSig é a chave da fechadura.


A signature gets added to the stack, followed by a public key. OP_CHECKSIG pops them both and verifies the signature against the public key. If they match, it adds a <1> to the stack. Otherwise, it adds a <0>


Não pode ser muito mais simples do que isso. Uma assinatura é adicionada à pilha, seguida por uma chave pública. OP_CHECKSIG exibe ambos e verifica a assinatura em relação à chave pública. Se corresponderem, adiciona <1> à pilha. Caso contrário, adiciona um <0>.

Por motivos que discutiremos na próxima seção, o P2PK não é mais usado.


Pagamento para Pubkey-Hash (P2PKH)

Pay-to-Pubkey-Hash (P2PKH) é agora o tipo de transação mais comum. A menos que você esteja se esforçando para baixar software arcaico, sua carteira provavelmente estará fazendo isso por padrão.

O scriptPubKey em P2PKH é o seguinte:

OP_DUP OP_HASH160 <hash de chave pública> OP_EQUALVERIFY OP_CHECKSIG

Antes de apresentarmos o scriptSig, vamos detalhar o que os novos opcodes farão:


OP_DUP

OP_DUP exibe o primeiro elemento e o duplica. Em seguida, ele adiciona ambos de volta à pilha. Normalmente, isso é feito para que possamos realizar uma operação na duplicata sem afetar o original.


OP_HASH160

Isso exibe o primeiro elemento e faz o hash duas vezes. A primeira rodada fará hash com o algoritmo SHA-256. A saída SHA-256 é então hash com o algoritmo RIPEMD-160. A saída resultante é adicionada de volta à pilha.


OP_EQUALVERIFY

OP_EQUALVERIFY combina dois outros operadores – OP_EQUAL e OP_VERIFY. OP_EQUAL exibe dois elementos e verifica se eles são idênticos. Se estiverem, adiciona 1 à pilha. Caso contrário, adiciona 0. OP_VERIFY exibe o elemento superior e verifica se é True (ou seja, diferente de zero). Se não for, a transação falhará. Combinado, OP_EQUALVERIFY faz com que a transação falhe se os dois elementos superiores não corresponderem.

Desta vez, o scriptSig fica assim:

<assinatura> <chave pública>

Você precisa fornecer uma assinatura e a chave pública correspondente para desbloquear as saídas P2PKH.


We’re just adding an extra step to check that the public key matches the hash in the script


Você pode ver o que está acontecendo no GIF acima. Não é muito diferente de um script P2PK. Estamos apenas adicionando uma etapa extra para verificar se a chave pública corresponde ao hash no script.

Há algo a ser observado, no entanto. Em um script de bloqueio P2PKH, a chave pública não é visível – só podemos ver seu hash. Se formos a um explorador de blockchain e observarmos uma saída P2PKH que não foi gasta, não poderemos determinar a chave pública. Só é revelado quando o destinatário decide transferir os fundos.

Isso tem alguns benefícios. A primeira é que o hash da chave pública é simplesmente mais fácil de transmitir do que uma chave pública completa. Satoshi o lançou em 2009 exatamente por esse motivo. O hash de chave pública é o que hoje conhecemos como endereço Bitcoin.

O segundo benefício é que os hashes de chave pública podem fornecer uma camada adicional de segurança contra a computação quântica. Como a nossa chave pública não é conhecida até gastarmos os fundos, é ainda mais difícil para outros calcularem a chave privada. Eles teriam que reverter as duas rodadas de hash (RIPEMD-160 e SHA-256) para obtê-lo.


➠ Quer começar a usar criptomoedas? Compre Bitcoin na Binance!


Pagamento para hash de script (P2SH)

Pay-to-Script-Hash (P2SH) foi um desenvolvimento muito interessante para o Bitcoin. Ele permite que o remetente bloqueie fundos no hash de um script – ele não precisa saber o que o script realmente faz. Pegue o seguinte hash SHA-256:

e145fe9ed5c23aa71fdb443de00c7d9b4a69f8a27a2e4fbb1fe1d0dbfb6583f1

Você não precisa saber a entrada do hash para bloquear fundos nele. O gastador, entretanto, precisa fornecer o script que foi usado para fazer o hash e precisa satisfazer as condições desse script.

O hash acima foi criado a partir do seguinte script:

<multiplicar por 2> <4> <verificar se é igual>

Se quiser gastar as moedas vinculadas a esse scriptPubKey, você não fornece apenas esses comandos. Você também precisa de um scriptSig que faça com que o script concluído seja avaliado como True. Neste exemplo, esse é um elemento que você <multiplica por 2> para obter um resultado de <4>. Claro, isso significa que nosso scriptSig é apenas <2>.

Na vida real, o scriptPubKey para uma saída P2SH é:

OP_HASH160 <redeemScript hash> OP_EQUAL

Não há novos operadores aqui. Mas temos <redeemScript hash> como um novo elemento. Como o nome sugere, é um hash do script que precisamos fornecer para resgatar os fundos (chamado redeemScript). O scriptSig mudará dependendo do que estiver no redeemScript. Geralmente, porém, você descobrirá que é uma combinação de assinaturas e chaves públicas anexadas, seguida pelo redeemScript (obrigatório):

<assinatura> <chave pública> <redeemScript>

Nossa avaliação difere um pouco da execução da pilha que vimos até agora. Acontece em duas partes. A primeira simplesmente verifica se você forneceu o hash correto. 


We’ve reached the end of this mini-program, and the top element is non-zero. That means it’s valid


Você notará que não fazemos nada com os elementos que precedem o redeemScript. Eles não são usados ​​neste momento. Chegamos ao final deste miniprograma e o elemento superior é diferente de zero. Isso significa que é válido.

Ainda não terminamos. Os nós da rede reconhecem essa estrutura como P2SH, portanto, na verdade, eles têm os elementos do scriptSig aguardando em outra pilha. É aí que a assinatura e a chave pública serão usadas.

Até agora, tratamos o redeemScript como um elemento. Mas agora serão interpretados como instruções, que podem ser qualquer coisa. Vejamos o exemplo de um script de bloqueio P2PKH, para o qual devemos fornecer a <signature> e a <public key> que corresponda a um <public key hash> dentro do <redeemScript>.


Once your redeemScript has been expanded, you can see that we have a situation that looks exactly like a regular P2PKH transaction.


Depois que seu redeemScript for expandido, você poderá ver que temos uma situação que se parece exatamente com uma transação P2PKH normal. A partir daí, basta executá-lo como faria normalmente.

Demonstramos o que é chamado de script P2SH (P2PKH) aqui, mas é improvável que você encontre um desses por aí. Nada impede você de fazer um, mas não traz nenhum benefício adicional e acaba ocupando mais espaço em um bloco (e, portanto, custa mais).

P2SH geralmente é útil para coisas como transações multiassinaturas ou compatíveis com SegWit. As transações multisig podem ser muito grandes, pois podem exigir várias chaves. Antes da implementação do Pay-to-Script-Hash, um remetente teria que listar todas as chaves públicas possíveis em seu script de bloqueio. 

Mas com o P2SH, não importa quão complexas sejam as condições de despesa. O hash do redeemScript é sempre de tamanho fixo. Os custos são, portanto, repassados ​​ao(s) usuário(s) que desejam desbloquear o script de bloqueio.

A compatibilidade do SegWit é outro caso em que o P2SH é útil (entraremos em detalhes sobre como a estrutura da transação difere na próxima seção). SegWit foi um soft fork que resultou em uma mudança nos formatos de bloco/transação. Por ser uma atualização opcional, nem todos os softwares de carteira reconhecem as alterações. Não importa se os clientes agrupam o hash do script SegWit em P2SH. Assim como acontece com todas as transações desse tipo, eles não precisam saber qual será o resgate do desbloqueio. 


Transações SegWit (P2WPKH e P2WSH)

Para uma introdução mais abrangente ao SegWit, consulte Guia para iniciantes em testemunhas segregadas.

Para entender o formato da transação no SegWit, basta saber que não temos mais apenas um scriptSig e um scriptPubKey. Agora, também temos um novo campo chamado testemunha. Os dados que mantíamos no scriptSig são movidos para a testemunha, portanto o scriptSig fica vazio.

Se você encontrar endereços que começam com 'bc1', eles são o que chamamos de nativos do SegWit (em oposição a apenas compatíveis com o SegWit, que começam com '3', pois são endereços P2SH).


Pagar para testemunhar-Pubkey-Hash (P2WPKH)

Pay-to-Witness-Pubkey-Hash (P2WPKH) é a versão SegWit do P2PKH. Nosso testemunho é assim:

<assinatura> <chave pública>

Você notará que este é o mesmo que o scriptSig do P2PKH. Aqui, o scriptSig está vazio. Enquanto isso, o scriptPubKey se parece com o seguinte:

<OP_0> <hash de chave pública>

Isso parece um pouco estranho, não é? Onde estão os opcodes que nos permitem comparar a assinatura, a chave pública e seu hash?

Não estamos mostrando operadores adicionais aqui, porque os nós que recebem a transação sabem o que fazer com ela com base no comprimento do <hash de chave pública>. Eles calcularão a duração e entenderão que ela deve ser executada no mesmo estilo de uma boa e velha transação P2PKH.

Os nós não atualizados não sabem como interpretar a transação dessa maneira, mas isso não importa. De acordo com as regras antigas, não há testemunha, então eles leem um scriptSig vazio e alguns dados. Eles avaliam isso e marcam-no como válido – no que lhes diz respeito, qualquer um poderia gastar o resultado. É por isso que o SegWit é considerado um soft fork compatível com versões anteriores.


Hash de script pago para testemunha (P2WSH)

Hash de script pago para testemunhar (P2WSH) é o novo P2SH. Se você chegou até aqui, provavelmente pode descobrir como ficará, mas analisaremos isso de qualquer maneira. Nosso testemunho é o que normalmente colocaríamos no scriptSig. Em um P2WSH que envolve uma transação P2PKH, por exemplo, pode ser algo assim:

<assinatura 1> <chave pública>

Aqui está nosso scriptPubKey:

<OP_0> <script hash>

As mesmas regras se aplicam. Os nós SegWit leem o comprimento do hash do script e determinam que é uma saída P2WSH, que é avaliada de forma semelhante ao P2SH. Enquanto isso, os nós antigos apenas veem isso como uma saída que qualquer um pode gastar.


Pensamentos finais

Neste artigo, aprendemos um pouco sobre os blocos de construção do Bitcoin. Vamos resumi-los rapidamente:


Tipo de roteiro

Descrição

Pague para Pubkey (P2PK)

Bloqueia fundos para uma chave pública específica

Pagamento para Pubkey-Hash (P2PKH)

Bloqueia fundos para um hash de chave pública específico (ou seja, um endereço)

Pagamento para hash de script (P2SH)

Bloqueia fundos no hash de um script que o destinatário pode fornecer

Pagar para testemunhar-Pubkey-Hash (P2WPKH)

A versão SegWit do P2PK

Hash de script pago para testemunha (P2WSH)

A versão SegWit do P2SH


Depois de se aprofundar no Bitcoin, você começará a entender por que ele tem tanto potencial. As transações podem ser compostas de muitos componentes diferentes. Ao manipular estes blocos de construção, os utilizadores têm uma grande flexibilidade quando se trata de definir condições sobre como e quando os fundos podem ser gastos.


➠ Dúvidas sobre o roteiro? Vá para a Ask Academy!