O pagamento-para-hash-de-script (P2SH) foi apresentado em 2012 como um novo tipo poderoso de transação que simplifica e muito o uso de scripts complexos de transação. Para explicar a necessidade do P2SH, vamos dar uma olhada em um exemplo prático.
Em [ch01_intro_what_is_bitcoin], nós apresentamos o Mohammed, um importador de eletrônicos que mora em Dubai. A companhia do Mohammed usa a funcionalidade de múltiplas assinaturas do bitcoin para suas contas corporativas. Os scripts de múltiplas assinaturas são um dos usos mais comuns das capacidades avançadas de scripting do bitcoin e são uma funcionalidade muito poderosa. A companhia do Mohammed usa um script de múltiplas-assinaturas para todos os pagamentos de clientes, conhecidos em termos de contabilidade como "contas recebíveis", ou CR. Com o esquema de múltiplas assinaturas, quaisquer pagamentos feitos pelos consumidores são travados de uma maneira que eles exigem pelo menos duas assinaturas para serem liberados, do Mohammed para um de seus sócios ou do seu advogado que possui uma chave de backup. Um esquema de múltiplas assinaturas desse tipo oferece controle de governança corporativa e protege contra roubo, desvio de fundos ou perdas.
O script resultante é bastante longo e se parece com isso:
2 <Chave Pública do Mohammed> <Chave Pública do Parceiro1> <Chave Pública do Parceiro2> <Chave Pública do Parceiro3> <Chave Pública do Advogado> 5 OP_CHECKMULTISIG
Apesar de os scripts de múltiplas assinaturas serem uma funcionalidade poderosa, eles podem ser difíceis de se usar. Em relação ao script anterior, o Mohammed teria que comunicar esse script para cada um de seus consumidores antes do pagamento. Cada consumidor teria que usar um software de
carteira bitcoin especial com a habilidade de criar scripts de transação customizados, e cada consumidor teria que entender como criar uma transação usando scripts customizados. Além disso, a transação resultante seria cerca de cinco vezes maior do que uma transação de pagamento simples, pois esse script contém chaves públicas muito longas. O fardo dessa transação extra-grande teria que ser carregado pelo consumidor na forma de taxas. Finalmente, um script grande de transação como esse seria carregado no conjunto UTXO na RAM de cada nodo completo, até que ele fosse gasto. Todos esses problemas fazem com que o uso de scripts de outputs complexos sejam difíceis na prática.
O pagamento-para-hash-de-script (P2SH) foi desenvolvido para resolver essas dificuldades práticas e para fazer a utilização de scripts complexos de uma maneira tão fácil quanto um pagamento para um endereço bitcoin. Com pagamentos P2SH, o script de travamento complexo é substituído pela sua impressão digital, que é um hash criptográfico. Quando uma transação tentanto gastar o UTXO é apresentada mais tarde, ela deve conter o script que corresponde ao hash, além do script de destravamento. Em termos simples, P2SH significa "pagar para um script que corresponde a esse hash, um script que será apresentado mais tarde quando esse output for gasto".
Nas transações P2SH, o script de travamento que é substituído por um hash é chamado de script de
resgate ("redeem script"), pois ele é apresentado ao sistema na hora do resgate ao invés de ser
apresentado como um script de travamento. Script complexo sem P2SH demonstra o script sem P2SH e
Script complexo como P2SH demonstra o mesmo script codificado com P2SH.
Table 4. Script complexo sem P2SH
Script de Travamento 2 ChavePub1 ChavePub2 ChavePub3 ChavePub4 ChavePub5 5 OP_CHECKMULTISIG
Script de Destravamento Ass1 Ass2
Table 5. Script complexo como P2SH
Script de Resgate 2 ChavePub1 ChavePub2 ChavePub3 ChavePub4 ChavePub5 5 OP_CHECKMULTISIG
Script de Travamento OP_HASH160 <hash de 20 bytes do script de resgate> OP_EQUAL
Script de Destravamento Ass1 Ass2 script de resgate
Como você pode ver nas tabelas, com P2SH, o complexo script que detalha as condições para gastar o output (o script de resgate) não é apresentado ao script de travamento. Ao invés disso, somente um hash disso está no script de travamento e o próprio scrit de resgate é apresentado depois, como parte do script de destravamento quando o output é gasto. Isso passa o fardo das taxas e da complexidade do pagador para o recipiente (que gasta) da transação.
Vamos dar uma olhada na companhia do Mohammed, um script complexo de múltiplas assinaturas e os scripts P2SH resultantes.
Primeiro, o script de múltiplas assinaturas que a companhia de Mohammed usa para todos os pagamentos que recebe de seus clientes:
2 <Chave Pública do Mohammed> <Chave Pública do Parceiro1> <Chave Pública do Parceiro2> <Chave Pública do Parceiro3> <Chave Pública do Advogado> 5 OP_CHECKMULTISIG
Se os marcadores forem substituídos por chaves públicas de verdade (demonstradas aqui como números de 520 bits começando com 04), você verá que esse script se torna muito longo:
2 04C16B8698A9ABF84250A7C3EA7EEDEF9897D1C8C6ADF47F06CF73370D74DCCA01CDCA79DCC5C395D7EEC6984 D83F1F50C900A24DD47F569FD4193AF5DE762C58704A2192968D8655D6A935BEAF2CA23E3FB87A3495E7AF308 EDF08DAC3C1FCBFC2C75B4B0F4D0B1B70CD2423657738C0C2B1D5CE65C97D78D0E34224858008E8B49047E632 48B75DB7379BE9CDA8CE5751D16485F431E46117B9D0C1837C9D5737812F393DA7D4420D7E1A9162F0279CFC1 0F1E8E8F3020DECDBC3C0DD389D99779650421D65CBD7149B255382ED7F78E946580657EE6FDA162A187543A9 D85BAAA93A4AB3A8F044DADA618D087227440645ABE8A35DA8C5B73997AD343BE5C2AFD94A5043752580AFA1E CED3C68D446BCAB69AC0BA7DF50D56231BE0AABF1FDEEC78A6A45E394BA29A1EDF518C022DD618DA774D207D1 37AAB59E0B000EB7ED238F4D800 5 OP_CHECKMULTISIG
Todo esse script pode, no entanto, ser representado por um hash criptográfico de 20 bytes, ao aplicar- se primeito o algoritmo de hashing SHA256 e então aplicando-se o algoritmo RIPEMD160 no resultado. O hash de 20 bytes do script anterior é:
54c557e07dde5bb6cb791c7a540e0a4796f5e97e
Uma transação P2SH trava o output nesse hash, e não no script maior, através do script de travamento:
OP_HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e OP_EQUAL
o qual, como você pode ver, é muito menor. Ao invés de "pagar para esse script de múltiplas assinaturas de 5 chaves", a transação equivalente P2SH é "pagar para um script com esse hash". Um cliente fazendo um pagamento à companhia do Mohammed precisa apenas incluir no seu pagamento esse script de travamento muito menor. Quando o Mohammed quiser gastar esse UTXO, eles precisam apresentar o script de resgate original (aqueles cujo hash travou o UTXO) e as assinaturas necessárias para destravá-lo, dessa maneira:
<Sig1> <Sig2> <2 PK1 PK2 PK3 PK4 PK5 5 OP_CHECKMULTISIG>
Os dois scripts são combinados em dois estágios. Primeiro, o script de resgate é verificado em relação ao script de travamento, para garantir que os hashes correspondem:
Se o hash do script de resgate corresponder, o script de destravemento é executado por conta própria, para destavar o script de resgate:
<Sig1> <Sig2> 2 PK1 PK2 PK3 PK4 PK5 5 OP_CHECKMULTISIG
Endereços Pay-to-script-hash
Outra parte importante da funcionalidade P2SH é a habilidade de codificar um hash de script como um endereço, que foi definido na BIP0013. Os endereços P2SH são codificações Base58Check do hash de 20 bytes de um script, da mesma maneira que endereços bitcoin são codificações Base58Check do hash de 20 bytes de uma chave pública. Os endereços P2SH usam o prefixo de versão "5", que resulta em endereços codificados em Base58Check que iniciam com um "3". Por exemplo, o script complexo do Mohammed, "hashado" e codificado em Base58Check, como um endereço P2SH se torna 39RF6JqABiHdYHkfChV6USGMe6Nsr66Gzw. Agora, o Mohammed pode fornecer o seu "endereço" para seus consumidores e eles podem usá-lo em quase qualquer carteira bitcoin para fazer um pagamento simples, como se ele fosse um endereço bitcoin. O prefixo 3 lhes dá a dica de que esse é um tipo especial de endereço, um que corresponde a um script, ao invés de uma chave pública, mas fora isso ele funciona exatamente da mesma maneira que um pagamento para um endereço bitcoin.
Os endereços P2SH escondem toda essa complexidade, de maneira que a pessoa que está fazendo o pagamento não enxerga o script.
Benefícios do pay-to-script-hash
A funcionalidade pagar-para-hash-de-script oferece os seguintes benefícios em comparação ao uso direto de scripts complexos para travar outputs:
• Scripts complexos são substituídos por impressões digitais menores no output da transação, tornando a transação menor.
• Os scripts podem ser codificados como um endereço, de maneira que o pagador e a carteira do pagador não precisem fazer modificações complexas para implementar o P2SH.
• O P2SH faz com que o fardo de se construir o script seja do recipiente, e não do pagador
• O P2SH passa o fardo do armazenamento de dados para o script longo do output (que está no conjunto UTXO) para o input (armazenado na blockchain)
• O P2SH faz com que o fardo do armazenamento de dados para o script longo deixe de estar no tempo presente (pagamento) e passe a estar no tempo futuro (quando ele é gasto).
• O P2SH faz com que o custo da taxa de transação de um script longo deixe de ser do pagador e passe a ser do recipiente, que tem que incluir o longo script de resgate para poder gastá-lo.
Script de Resgate e validação isStandard
Antes da versão 0.9.2 do cliente Bitcoin Core, o pagamento-para-hash-de-script era limitado a tipos padrões de scripts de transação bitcoin, pela função isStandard(). Isso significa que o script de resgate
apresentado na transação de gasto poderia ser de apenas um dos tipos padrões: P2PK, P2PKH ou de múltiplas assinaturas, excluindo o OP_RETURN e o próprio P2SH.
A partir da versão 0.9.2 do cliente Bitcoin Core, as transações P2SH podem conter qualquer script válido, tornando o padrão P2SH muito mais flexível e permitindo a experimentação de muitos tipos novos e complexos de transações.
Note que você não consegue colocar um P2SH dentro de um script de resgate P2SH, porque a especificação P2SH não é recursiva. Você também não consegue usar o OP_RETURN em um script de resgate porque, por definição, o OP_RETURN não pode ser resgatado.
Como o script de regaste não é apresentado para a rede até que você tente gastar o output P2SH, se você travar um output com o hash de uma transação inválida, ela será processada independente disso. Entretanto, você não será capaz de gastá-lo, pois a transação de gasto, que inclui o script de resgate, não será aceita, pois o script é inválido. Isso cria um risco, porque você pode travar um bitcoin em um P2SH que não poderá ser gasto mais tarde. A rede irá aceitar a oneração P2SH mesmo que ela corresponda a um script de resgate inválido, pois o hash do script não dá nenhuma indicação do script que ele representa.
WARNING
Os scripts de travamento P2SH contém o hash de um script de resgate, que não dá dicas do conteúdo do script de resgate. A transação P2SH será considerada válida e será aceita mesmo se o script de resgate for inválido. Dessa maneira, você pode travar bitcoins acidentalmente, que não poderão ser gastos mais tarde.