P2TR
Pay To Taproot
BIP 341: Taproot — Regras de gasto do SegWit versão 1
O P2TR (Pay To Taproot) é um script de travamento que trava uma saída a uma chave pública e a múltiplos scripts de travamento personalizados opcionais*.
Ele é, na prática, um híbrido dos scripts de travamento P2WPKH e P2WSH, mas a trava em si é pequena e contém uma única chave pública (graças a uma matemática e criptografia engenhosas).
Nesta página vou dar uma visão geral de como são os scripts de travamento P2TR.
O P2TR foi introduzido na atualização Taproot.
*Os scripts de travamento personalizados usam uma variante do script chamada tapscript.
Uso
Como o P2TR funciona?
Os detalhes técnicos de um P2TR são um pouco complexos, então vou apenas mostrar a estrutura do ScriptPubKey e da Testemunha para que você veja como são e tenha uma ideia de como funcionam.
Confira a página Taproot para um guia completo de como construir e gastar um P2TR.
ScriptPubKey
ASM
OP_1
OP_PUSHBYTES_32
0f0c8db753acbd17343a39c2f3f4e35e4be6da749f9e35137ab220e7b238a667 Hex
51200f0c8db753acbd17343a39c2f3f4e35e4be6da749f9e35137ab220e7b238a667 Transação: a7115c7267dbb4aab62b37818d431b784fe731f4d2f9fa0939a9980d581690ec (Saída 0)
Um script de travamento P2TR começa com o opcode de versão OP_1 seguido do empilhamento de dados de uma chave pública.
Porém, essa chave pública é um pouco "diferente" por dois motivos:
- É uma chave pública ajustada (tweaked). É como qualquer outra chave pública normal, mas foi ajustada para incluir um compromisso com todos os scripts personalizados adicionais que você gostaria de usar para destravar a saída P2TR. Esse valor de ajuste (tweak) é basicamente o hash de todos os scripts personalizados, e você usa esse ajuste sobre uma chave pública inicial para criar a chave pública ajustada.
- As chaves públicas no P2TR têm apenas 32 bytes de comprimento. São, portanto, um pouco mais curtas que as chaves públicas comprimidas de 33 bytes encontradas em scripts de travamento mais antigos (por exemplo, o P2PK). Isso porque elas não incluem o byte inicial (ou seja, 0x02 ou 0x03) que indica se a coordenada y é par ou ímpar. Então é o mesmo que uma chave pública comprimida padrão, mas sem o primeiro byte.
Mas, como eu disse, embora isso seja chamado de chave pública ajustada, ela parece e se comporta como qualquer outra chave pública.
A chave pública ajustada é chamada de taproot, daí o nome Pay To Taproot.
- O opcode de versão
OP_1indica que este é um script de travamento P2TR (o P2WPKH e o P2WSH começam comOP_0). - Um script de travamento P2TR contém uma chave pública crua, em vez de um hash de chave pública (como nos P2PKH e P2WPKH).
Veja a construção do P2TR no Taproot para detalhes.
ScriptSig
Uma saída P2TR não é destravada pelo campo ScriptSig.
Em vez disso, ela é destravada pelo campo de Testemunha.
Testemunha
Esta é a parte interessante.
Uma saída P2TR pode ser destravada de duas formas, e a estrutura do campo de testemunha varia conforme o método que você escolhe usar.
1. Gasto por Caminho de Chave (Key Path Spend)
Método padrão
ASM
b693a0797b24bae12ed0516a2f5ba765618dca89b75e498ba5b745b71644362298a45ca39230d10a02ee6290a91cebf9839600f7e35158a447ea182ea0e022ae01 Dividido
{
"stackitems": "01",
"0": {
"size": "41",
"item": "b693a0797b24bae12ed0516a2f5ba765618dca89b75e498ba5b745b71644362298a45ca39230d10a02ee6290a91cebf9839600f7e35158a447ea182ea0e022ae01"
}
} Hex
0141b693a0797b24bae12ed0516a2f5ba765618dca89b75e498ba5b745b71644362298a45ca39230d10a02ee6290a91cebf9839600f7e35158a447ea182ea0e022ae01 Transação: 091d2aaadc409298fd8353a4cd94c319481a0b4623fb00872fe240448e93fcbe (Entrada 0)
Em um gasto por caminho de chave, a testemunha contém apenas um único item de assinatura.
Essa assinatura é criada primeiro ajustando a chave privada usada para criar a chave pública inicial.
Se a assinatura corresponder à chave pública ajustada no ScriptPubKey, a saída é destravada e pode ser gasta.
- O P2TR usa assinaturas Schnorr em vez de ECDSA.
- As assinaturas no P2TR também são um pouco mais curtas por não usarem a codificação DER.
- O byte de tipo de hash no final da assinatura é opcional.
Veja o gasto por caminho de chave no Taproot para detalhes.
2. Gasto por Caminho de Script (Script Path Spend)
Método(s) alternativo(s)
ASM
01769105cbcbdcaaee5e58cd201ba3152477fda31410df8b91b4aee2c4864c7700615efb425e002f146a39ca0a4f2924566762d9213bd33f825fad83977fba7f01
206d4ddc0e47d2e8f82cbe2fc2d0d749e7bd3338112cecdc76d8f831ae6620dbe0ac
c0924c163b385af7093440184af6fd6244936d1288cbb41cc3812286d3f83a3329 Dividido
{
"stackitems": "03",
"0": {
"size": "41",
"item": "01769105cbcbdcaaee5e58cd201ba3152477fda31410df8b91b4aee2c4864c7700615efb425e002f146a39ca0a4f2924566762d9213bd33f825fad83977fba7f01"
},
"1": {
"size": "22",
"item": "206d4ddc0e47d2e8f82cbe2fc2d0d749e7bd3338112cecdc76d8f831ae6620dbe0ac"
},
"2": {
"size": "21",
"item": "c0924c163b385af7093440184af6fd6244936d1288cbb41cc3812286d3f83a3329"
}
} Transação: 797505b104b5fb840931c115ea35d445eb1f64c9279bf23aa5bb4c3d779da0c2 (Entrada 0)
Um gasto por caminho de script é quando você gasta a saída P2TR usando um dos scripts de travamento personalizados codificados na chave pública ajustada.
Essa testemunha é obviamente um pouco mais complexa do que em um gasto por caminho de chave. Mesmo assim, ela pode ser dividida em 3 partes:
- Entradas de Script (Script Inputs) — Os primeiros itens da testemunha são os elementos de dados necessários para destravar o script personalizado.
- Leaf Script — O penúltimo item da testemunha é o script de travamento personalizado que você escolheu. É um dos scripts personalizados que você usou ao construir a chave pública ajustada.
- Control Block — O último item da testemunha contém os dados que provam que o script personalizado que você está usando era um dos scripts originais usados para criar a chave pública ajustada.
Então, em um gasto por caminho de script, a testemunha geralmente contém 3 ou mais itens. Sempre haverá pelo menos 2 itens (o leaf script e o control block), e então você pode ter múltiplas entradas de script no início (por exemplo, uma assinatura).
A saída será destravada se:
- Os dados no control block confirmarem que o leaf script foi codificado na chave pública ajustada.
- As entradas de script satisfizerem as condições do leaf script.
Veja a execução do gasto por caminho de script para detalhes.
- O fato de um gasto por caminho de script conter mais de 1 item é o que o diferencia de um gasto por caminho de chave.
- A testemunha de um gasto por caminho de script se parece com a testemunha de um P2WSH, exceto por incluir um control block adicional no final.
Veja o gasto por caminho de script no Taproot para detalhes.
Execução
Como você esperaria, a execução do ScriptPubKey + testemunha de um P2TR é diferente da execução de outros scripts no Bitcoin.
O método de execução varia conforme quantos itens há na testemunha.
Aqui está uma visão geral dos passos:
- O primeiro passo é sempre remover o annex opcional da testemunha.
A. Gasto por Caminho de Chave
Se restar apenas 1 item na testemunha, a execução de gasto por caminho de chave é usada.
- Verificar que o item na testemunha é uma assinatura válida para a chave pública ajustada no ScriptPubKey.
As saídas P2TR usam assinaturas Schnorr em vez de ECDSA. Esse passo também usa o algoritmo de assinatura do Taproot para criar a mensagem a ser validada.
Se a assinatura não tiver um byte de tipo de hash anexado (ou seja, tem 64 bytes em vez de 65 bytes), o byte de tipo de hash é definido como SIGHASH_DEFAULT, que corresponde a SIGHASH_ALL (o tipo de hash mais comumente usado).
B. Gasto por Caminho de Script
Se restarem 2 ou mais itens na testemunha, a execução de gasto por caminho de script é usada.
- Verificar que o leaf script foi de fato codificado na chave pública ajustada no ScriptPubKey. Isso é feito usando os dados no control block.
Detalhes
Aqui estão alguns passos mais detalhados de como a chave pública ajustada é calculada a partir dos dados da testemunha.
Isso provavelmente não fará muito sentido a menos que você já esteja familiarizado com a construção de um P2TR, mas resolvi cobrir os passos em mais detalhes aqui mesmo assim.
- Calcular o leaf hash. O primeiro passo é calcular o leaf hash. Ele é calculado usando o leaf script e a leaf version (que está codificada no primeiro byte do control block).
- Calcular a raiz de Merkle. Em seguida, use o leaf hash do passo anterior junto com o caminho de Merkle no control block para calcular a raiz de Merkle.
- Calcular o tweak. O tweak é calculado fazendo o hash da raiz de Merkle do passo anterior junto com a chave pública inicial fornecida no control block.
- Calcular a chave pública ajustada. Em seguida, você usa o tweak do passo anterior para calcular a chave pública ajustada. Ela é calculada primeiro criando um novo ponto ao multiplicar o ponto gerador pelo tweak, e então somando esse ponto à chave pública inicial (convertida em ponto) dentro do control block.
- Verificar a chave pública ajustada. Verifique que a chave pública ajustada que acabamos de calcular corresponde à chave pública ajustada no ScriptPubKey. Se corresponder, isso confirma que o leaf script em uso foi codificado na chave pública ajustada original.
- Executar o leaf script junto com as entradas de script fornecidas na testemunha. Se esse script for válido, a saída é destravada e pode ser gasta.
A maior parte da execução do gasto por caminho de script envolve usar o control block para confirmar que o leaf script fornecido foi de fato codificado na chave pública ajustada.
Depois disso, você simplesmente executa as entradas de script + o leaf script (assim como você faria em um P2WSH padrão).
Cada leaf script usa tapscript, que é uma leve variação do script padrão.
Benefícios
Há três benefícios principais em usar o P2TR em vez de outros scripts de travamento:
- Flexibilidade. O P2TR permite travar uma saída a uma simples chave pública e/ou múltiplos scripts de travamento personalizados. Isso significa que a saída pode ser travada usando múltiplas condições de gasto. Você normalmente usa um dos scripts adicionais se o método "padrão" de destravar pela chave pública não for o preferido (por qualquer motivo).
- Privacidade. Se você gasta a saída pelo método padrão da chave pública, quaisquer condições de gasto adicionais não são reveladas (na verdade, você nem saberia se elas existem). Além disso, se você destravar a saída usando um dos scripts personalizados adicionais, os outros scripts na árvore não serão revelados.
- Eficiência.
- Todas as condições de gasto de uma saída P2TR podem ser condensadas em uma única chave pública ajustada de 32 bytes, o que economiza espaço em comparação a ter múltiplos scripts de travamento personalizados colocados diretamente em uma saída.
- As saídas P2TR usam assinaturas Schnorr em vez de ECDSA, o que significa que quaisquer assinaturas necessárias para destravar a saída podem ser somadas. Como resultado, isso torna muito mais eficiente usar P2TR para scripts de travamento multiassinatura em comparação com outras opções como P2MS, P2SH ou P2WSH (todos os quais usam ECDSA).
No entanto, se você quiser apenas travar uma saída a uma chave pública sem nenhuma condição de gasto adicional, é perfeitamente aceitável ficar com o P2WPKH, mais simples.
De forma parecida, se você quiser usar apenas um único script de travamento personalizado (em vez de ter vários para escolher), é perfeitamente aceitável ficar com o P2WSH, mais simples.
Mas não há nada de errado em usar o P2TR para esses tipos simples de travas, se você preferir.
Endereço
Um script de travamento P2TR tem seu próprio formato de endereço.
Ele pode ser convertido em um endereço codificando todo o ScriptPubKey em Bech32.
O ScriptPubKey de um P2TR tem a seguinte estrutura: 5120<chave pública ajustada de 32 bytes>
Endereço (Bech32)
Um endereço P2TR sempre começa com bc1p e tem 62 caracteres de comprimento.
O endereço de um P2TR é codificado usando bech32m em vez de bech32. É basicamente o mesmo que o bech32, mas com uma pequena mudança na forma como o checksum é calculado.
História
O P2TR foi adicionado ao Bitcoin em 2021 como parte da atualização Taproot.
Ele combina a funcionalidade das atualizações MAST e assinaturas Schnorr previamente propostas em um único mecanismo de travamento, e é por isso que ele foi introduzido como parte de uma grande atualização via soft fork do software.
Resumo
O P2TR é como um mecanismo de travamento "tudo em um" que oferece a mesma funcionalidade de todos os scripts de travamento anteriores combinados. A inclusão das assinaturas Schnorr é um bônus interessante.
Então, se você só pudesse usar um único tipo de script de travamento no Bitcoin daqui para frente, escolheria o P2TR.
Claro, toda essa funcionalidade significa que ele é naturalmente mais complexo de construir e gastar do que os mecanismos de travamento mais simples P2WPKH e P2WSH. No entanto, uma vez que você pega o jeito, vai perceber que é um script de travamento extremamente versátil.
Então vale a pena aprender a usá-lo.