P2SH-P2WSH

Nested P2WSH — um P2WSH moderno embrulhado em um P2SH legado

BIP 141: Segregated Witness

Diagrama mostrando a estrutura do código de travamento e destravamento do P2SH-P2WSH.

O P2SH-P2WSH (também conhecido como Nested P2WSH) é um tipo de script de travamento que embrulha um P2WSH moderno dentro de um P2SH legado.

Ele permite enviar bitcoins para um endereço legado iniciado em 3 (P2SH), mas também aproveitar os custos de taxa de transação mais baratos que vêm de gastar uma saída P2WSH moderna.

Portanto, o P2SH-P2WSH fornece um trampolim até que carteiras e exchanges suportem o envio direto para endereços iniciados em bc1q.

Não há razão para usar P2SH-P2WSH se você tem a opção de usar P2WSH diretamente. O P2SH-P2WSH só é útil se você não conseguir enviar para um endereço bc1q a partir da sua carteira ou exchange, mas conseguir enviar para um endereço iniciado em 3.

Propósito

Por que o P2SH-P2WSH existe?

Diagrama mostrando o P2SH-P2WSH sendo usado para enviar bitcoins de uma carteira/exchange que não suporta o envio para P2WSH.

Um P2SH-P2WSH serve ao mesmo propósito que um P2SH-P2WPKH.

Você pode enviar bitcoins para um endereço iniciado em 3 (P2SH), mas depois destravá-los como se tivesse usado um P2WSH moderno.

Isso permite aproveitar o desconto oferecido ao destravar uma saída pela Testemunha, mesmo que a carteira ou exchange que você está usando não permita enviar para um endereço bc1q (P2WSH) diretamente.

Isso torna o destravamento de um P2SH-P2WSH mais complexo do ponto de vista técnico, mas lhe dá o benefício de taxas de transação mais baratas caso o P2WSH não seja uma opção.

Uso

Como o P2SH-P2WSH funciona?

Um P2SH-P2WSH (também conhecido como Nested P2WSH) usa tanto o campo ScriptSig quanto o de Testemunha para ser destravado.

ScriptPubKey (trava)

Diagrama mostrando a estrutura do ScriptPubKey de um P2SH-P2WSH.

O ScriptPubKey é um script de travamento P2SH padrão. Por exemplo:

ASM

OP_HASH160
OP_PUSHBYTES_20
257014cec2f75c19367b2a6a0e08b9f304108e3b
OP_EQUAL

Hex

a914257014cec2f75c19367b2a6a0e08b9f304108e3b87

Transação: c57007980fabfd7c44895d8fc2c28c6ead93483b7c2bfec682ce0a3eaa4008ce (Saída 0)

O hash do script é o HASH160 de um ScriptPubKey P2WSH. Por exemplo:

P2WSH ScriptPubKey: 0020973cfd44e60501c38320ab1105fb3ee3916d2952702e3c8cb4cbb7056aa6b47f
HASH160:            257014cec2f75c19367b2a6a0e08b9f304108e3b

O ScriptPubKey P2WSH original será revelado no ScriptSig que vem a seguir.

O fato de o P2SH-P2WSH usar um ScriptPubKey P2SH padrão é o que o torna retrocompatível. A maioria das carteiras e exchanges deve suportar o envio para um P2SH (endereço iniciado em 3).

ScriptSig (destrava)

Diagrama mostrando a estrutura do ScriptSig de um P2SH-P2WSH.

O ScriptSig contém um empilhamento de dados de 34 bytes de um ScriptPubKey P2WSH.

ASM

OP_PUSHBYTES_34
0020973cfd44e60501c38320ab1105fb3ee3916d2952702e3c8cb4cbb7056aa6b47f

Hex

220020973cfd44e60501c38320ab1105fb3ee3916d2952702e3c8cb4cbb7056aa6b47f

Transação: 55c7c71c63b87478cd30d401e7ca5344a2e159dc8d6990df695c7e0cb2f82783 (Entrada 0)

Esse empilhamento de dados é um ScriptPubKey P2WSH completo. Em outras palavras, é o ScriptPubKey que você teria usado se estivesse usando P2WSH diretamente.

Para a execução desse tipo de script continuar com sucesso, o HASH160 desse empilhamento de dados precisa corresponder ao hash do script no ScriptPubKey.

Ícone Ferramenta HASH160

HASH160

SHA-256 + RIPEMD-160. Usado para encurtar uma chave pública ou script antes de converter em um endereço.

Uma chave pública ou script, por exemplo

0 bytes
SHA-256
RIPEMD-160

RIPEMD-160(SHA-256(dados))

0 bytes

O fato de o ScriptSig conter outro ScriptPubKey P2WSH dentro dele é o motivo pelo qual isso às vezes é chamado de "Nested P2WSH" (P2WSH aninhado).

Testemunha

Diagrama mostrando a estrutura do campo de testemunha de um P2SH-P2WSH.

O campo de testemunha contém os dados necessários para destravar o ScriptPubKey P2WSH aninhado dentro do ScriptSig.

ASM

00
3044022047ebba593cba4048da04316b9fb6c076d95d17175d7560edc93868a7d170767502203d0ce939ae462ca685a15f5fd3a64b7a1793cb10473665d5bedd3322c55a2b1001
3044022022a8a0ae1f80934abb38d4f8c3febf6f5c5c43e7e70460aa71f9a895aaea4d950220023b8f4d2fd90abdbe6f80c9bcb2b38c7326e5e9e0f3b1ea25a5499d240cacb201
522103591da02bf7c80dc5d0edee4bbbfad7e58320785e3e54d4dab117152361f7002c21027ea2bc65ce49dcd748e4e41a0c8881be388b9182ad5e47579a0de0119803827b2103c5fdaf887f76119a73a7f738d5d4a451ff07bbbc83422c529452d8a36ae59e3953ae

Dividido

{
  "stackitems": "04",
  "0": {
    "size": "00",
    "item": ""
  },
  "1": {
    "size": "47",
    "item": "3044022047ebba593cba4048da04316b9fb6c076d95d17175d7560edc93868a7d170767502203d0ce939ae462ca685a15f5fd3a64b7a1793cb10473665d5bedd3322c55a2b1001"
  },
  "2": {
    "size": "47",
    "item": "3044022022a8a0ae1f80934abb38d4f8c3febf6f5c5c43e7e70460aa71f9a895aaea4d950220023b8f4d2fd90abdbe6f80c9bcb2b38c7326e5e9e0f3b1ea25a5499d240cacb201"
  },
  "3": {
    "size": "69",
    "item": "522103591da02bf7c80dc5d0edee4bbbfad7e58320785e3e54d4dab117152361f7002c21027ea2bc65ce49dcd748e4e41a0c8881be388b9182ad5e47579a0de0119803827b2103c5fdaf887f76119a73a7f738d5d4a451ff07bbbc83422c529452d8a36ae59e3953ae"
  }
}

Hex

0400473044022047ebba593cba4048da04316b9fb6c076d95d17175d7560edc93868a7d170767502203d0ce939ae462ca685a15f5fd3a64b7a1793cb10473665d5bedd3322c55a2b1001473044022022a8a0ae1f80934abb38d4f8c3febf6f5c5c43e7e70460aa71f9a895aaea4d950220023b8f4d2fd90abdbe6f80c9bcb2b38c7326e5e9e0f3b1ea25a5499d240cacb20169522103591da02bf7c80dc5d0edee4bbbfad7e58320785e3e54d4dab117152361f7002c21027ea2bc65ce49dcd748e4e41a0c8881be388b9182ad5e47579a0de0119803827b2103c5fdaf887f76119a73a7f738d5d4a451ff07bbbc83422c529452d8a36ae59e3953ae

Transação: 55c7c71c63b87478cd30d401e7ca5344a2e159dc8d6990df695c7e0cb2f82783 (Entrada 0)

A estrutura do campo de testemunha de um P2SH-P2WSH é exatamente a mesma de um P2WSH direto.

Em primeiro lugar, o hash SHA-256 do Witness Script precisa corresponder ao hash de script de 32 bytes no ScriptPubKey P2WSH (que está dentro do ScriptSig). Por exemplo:

Witness Script: 522103591da02bf7c80dc5d0edee4bbbfad7e58320785e3e54d4dab117152361f7002c21027ea2bc65ce49dcd748e4e41a0c8881be388b9182ad5e47579a0de0119803827b2103c5fdaf887f76119a73a7f738d5d4a451ff07bbbc83422c529452d8a36ae59e3953ae
SHA-256:        973cfd44e60501c38320ab1105fb3ee3916d2952702e3c8cb4cbb7056aa6b47f

A partir daqui, a Testemunha é executada como em um P2WSH normal.

Neste exemplo, o Witness Script é um script de travamento multisig 2-de-3, e as entradas de script antes dele são as assinaturas necessárias para destravá-lo. Mas, como você pode usar qualquer script de travamento personalizado que quiser como Witness Script, esse campo de testemunha poderia ter uma aparência completamente diferente e exigir um número (e tamanho) diferente de entradas de script.

Ícone Ferramenta Script

Script

Decodifique e codifique um script.

0 bytes

O Witness Script dentro de um P2WSH é equivalente ao Redeem Script em um P2SH. Ambos se referem aos dados que revelam o verdadeiro script de travamento personalizado que define as condições para destravar a saída.

Os hashes de script usados em P2SH e P2WSH são criados com funções de hash diferentes:

  • O hash de script no P2SH é criado com HASH160.
  • O hash de script no P2WSH é criado com SHA-256.

Portanto, dentro de um P2SH-P2WSH:

  • O hash de script no ScriptPubKey é o HASH160 do empilhamento de dados no ScriptSig.
  • O hash de script no ScriptSig é o hash SHA-256 do Witness Script na Testemunha.

Eu entendo por que isso é confuso. Mas, no fim das contas, você está realizando um travamento no estilo "Pay to Script Hash" duas vezes, já que você tem um P2WSH embrulhado em um P2SH legado, e os hashes de script de cada um são criados com funções de hash diferentes.

Custos

Quão mais barato é usar P2SH-P2WSH em vez do P2SH legado?

A tabela a seguir mostra o número de bytes necessários para destravar um P2SH legado, um P2SH-P2WSH e um P2WSH moderno comparáveis.

Você pode usar qualquer tipo de script de travamento personalizado ao usar um travamento no estilo "Pay to Script Hash", então escolhi exemplos que usam um multisig 2-de-3 como Redeem Script (também conhecido como Witness Script no P2SH-P2WSH e no P2WSH).

Estas são as entradas que usei como exemplos:

  • Esses scripts de travamento no estilo "Pay to Script Hash" são comumente usados para scripts multisig (ou seja, P2MS).
  • Um 2-de-3 é um arranjo popular para multisig, e é por isso que o usei nesses exemplos.
  • As economias descritas abaixo ficam ainda maiores se você estiver usando um script de travamento personalizado mais complexo (por exemplo, um multisig m-de-n grande).
Bytes para destravar cada tipo de script
Tipo de ScriptScriptSig (bytes)Testemunha (bytes)Total (bytes)
P2SH2520252
P2SH-P2WSH35252287
P2WSH0252252

Nota: O tamanho das assinaturas pode variar ligeiramente, mas todas as assinaturas nesses exemplos têm 71 bytes.

Como você pode ver, o P2SH-P2WSH exige mais bytes para destravar do que um P2SH legado ou um P2WSH moderno.

Porém, o cálculo de tamanho de uma transação foi ajustado durante a atualização Segregated Witness para usar bytes virtuais. Essa nova medida de bytes virtuais dá um desconto aos bytes no campo de testemunha, em que cada byte na testemunha ocupa apenas 0,25 byte virtual de espaço.

A tabela a seguir mostra o número de bytes virtuais necessários para destravar os mesmos scripts:

Bytes virtuais para destravar cada tipo de script
Tipo de ScriptScriptSig (bytes virtuais)Testemunha (bytes virtuais)Total (bytes virtuais)
P2SH2520252
P2SH-P2WSH356398
P2WSH06363

Nota: O número de bytes na testemunha foi multiplicado por 0,25.

Então, embora o gasto de um P2SH-P2WSH exija mais bytes no geral, o desconto dado aos bytes no campo de testemunha significa que um P2SH-P2WSH usa menos bytes virtuais em comparação com um P2SH legado.

E, como o valor que você paga em taxas de transação é calculado em sats por byte virtual, sai mais barato gastar um P2SH-P2WSH do que um P2SH legado.

Você obtém os benefícios do segwit (com uma pequena penalidade, o embrulho do P2SH tem um custo), mas consegue receber moedas de remetentes que não suportam endereços segwit nativos.
Pieter Wuille, bitcoin.stackexchange.com

O P2WSH é o mais barato. Mas, se essa não for uma opção, o P2SH-P2WSH é mais barato que o P2SH legado.

Enviando

Há uma pequena diferença na quantidade de espaço usado ao enviar bitcoins para um P2SH, P2SH-P2WSH ou P2WSH.

Esta é a quantidade de bytes necessária para travar uma saída (ou seja, "enviar") para cada um desses padrões de ScriptPubKey:

Bytes para travar (enviar) para cada tipo de script
Tipo de ScriptScriptPubKey (bytes)
P2SH23
P2SH-P2WSH23
P2WSH34

E, como o campo ScriptPubKey não recebe desconto, eles ocupam a mesma quantidade de espaço em termos de bytes virtuais:

Bytes virtuais para travar (enviar) para cada tipo de script
Tipo de ScriptScriptPubKey (bytes virtuais)
P2SH23
P2SH-P2WSH23
P2WSH34

Então, como você pode ver, é na verdade um pouco mais "caro" enviar para um P2WSH moderno do que enviar para um P2SH legado ou P2SH-P2WSH. Isso se deve ao fato de que o hash de script de um P2WSH é criado com SHA-256 (32 bytes), ao passo que o hash de script de um P2SH é criado com HASH160 (20 bytes).

Mas essa é uma diferença insignificante, e a segurança aprimorada graças à menor chance de uma colisão é a razão por trás da mudança na função de hash usada para criar o hash de script de um P2WSH.

Os pagamentos multisig atualmente usam P2SH, que é protegido pelo algoritmo HASH160 de 160 bits (RIPEMD do SHA256). Porém, se um dos signatários desejar roubar todos os fundos, ele pode encontrar uma colisão entre um endereço válido como parte de um script multisig e um script que simplesmente paga todos os fundos a ele com apenas 80 bits (2⁸⁰) de trabalho, o que já está dentro do âmbito do possível para um atacante com recursos extremamente abundantes.

O Segwit resolve isso usando HASH160 apenas para pagamentos diretos a uma única chave pública (onde esse tipo de ataque é inútil), enquanto usa hashes SHA256 de 256 bits para pagamentos a um hash de script.

bitcoincore.org

Endereço

Como você cria um endereço para um P2SH-P2WSH?

Diagrama mostrando como codificar um P2SH-P2WSH em um endereço.

Os scripts de travamento P2SH-P2WSH têm um endereço iniciado em 3.

Isso porque ele usa o P2SH para o ScriptPubKey, então tem o mesmo formato de endereço que qualquer outro P2SH.

Para criar o endereço, você começa construindo o ScriptPubKey P2WSH que quer usar. Você então faz o hash dele usando HASH160 para criar o hash de script de 20 bytes. Por fim, você codifica esse hash de script em Base58Check usando o prefixo 05 para significar um endereço P2SH (que é o que lhe dá um 3 no início do endereço).

Por exemplo, a codificação em hex do ScriptPubKey P2WSH colocado no ScriptSig no exemplo acima é:

0020973cfd44e60501c38320ab1105fb3ee3916d2952702e3c8cb4cbb7056aa6b47f
Ícone Ferramenta Script

Script

Decodifique e codifique um script.

0 bytes

Se fizermos o hash disso usando HASH160, obtemos:

257014cec2f75c19367b2a6a0e08b9f304108e3b
Ícone Ferramenta HASH160

HASH160

SHA-256 + RIPEMD-160. Usado para encurtar uma chave pública ou script antes de converter em um endereço.

Uma chave pública ou script, por exemplo

0 bytes
SHA-256
RIPEMD-160

RIPEMD-160(SHA-256(dados))

0 bytes

E, se convertermos isso para Base58Check usando o prefixo 05, obtemos:

356yCBhiW9tqg5iiPDhEZ8f8t3JfqkEihA

Ícone Ferramenta Base58Check

Base58Check

Cria um checksum para os dados e depois codifica em base58.

0 bytes
Esperado:
0 caracteres

Não é possível identificar um P2SH-P2WSH apenas pelo endereço. A única forma de identificar que um endereço iniciado em 3 usa Nested P2WSH é quando ele é gasto, pois é aí que ele revela o script de travamento P2WSH embrulhado dentro do ScriptSig.

Resumo

O P2SH-P2WSH é irmão do script de travamento P2SH-P2WPKH.

Em resumo, ele permite enviar bitcoins para um endereço iniciado em 3, mas depois destravá-los como se você tivesse usado um P2WSH nativo.

É um script um tanto curioso, pois o P2WSH é a versão moderna do P2SH, e ambos são usados para scripts de travamento personalizados. E, para conseguir usar o P2WSH enquanto envia para um P2SH, você precisa embrulhar o método moderno (P2WSH) dentro do método legado (P2SH). Então, em outras palavras, você tem um script de travamento personalizado dentro de um script de travamento personalizado.

Meme 'Yo dawg' para o P2SH-P2WSH — 'Yo Dawg, ouvi dizer que você gosta de Bitcoin Script. Então coloquei um script de travamento personalizado dentro do seu script de travamento personalizado, para você poder fazer script enquanto faz script'.

Dito de outra forma, é como o filme A Origem (Inception), mas com Bitcoin Script.

Se você ainda achar isso confuso (não te culpo), eu recomendaria aprender primeiro como o P2SH e o P2WSH funcionam separadamente. Ambos usam um mecanismo de destravamento parecido, mas no P2SH-P2WSH você tem um embrulhado dentro do outro, então você tem 2 camadas de um mesmo tipo de mecanismo de destravamento.

Boa sorte.

Recursos