Testemunha (Witness)

A região da transação usada para destravar entradas segwit

Diagrama mostrando a área de testemunha de uma transação sendo usada para destravar as entradas.

A testemunha (witness) é a região de uma transação usada para destravar entradas segwit.

Ela é usada para destravar saídas que têm novos scripts de travamento segregados ("programas de testemunha"), como P2WPKH, P2WSH e P2TR. Se alguma das entradas de uma transação tem um programa de testemunha segwit, você precisa usar a seção de testemunha para destravá-la.

A área de testemunha é uma atualização usada em preferência aos campos ScriptSig. Mas o ScriptSig ainda é usado para destravar scripts legados (P2PK, P2PKH, P2MS, P2SH).

Witness (testemunha) é só outra palavra para as assinaturas nas transações.
Pieter Wuille, SF Bitcoin Developers

Estrutura

Como você destrava uma entrada usando a testemunha?

Diagrama mostrando a estrutura da testemunha em uma transação bruta.

A testemunha contém um campo de testemunha para cada entrada da transação.

Cada campo de testemunha começa com um campo de itens da pilha (stack items), indicando o número de itens que ele contém; depois, para cada item, há um campo de tamanho seguido do item em si.

Então, basicamente, cada campo de testemunha contém um monte de elementos de dados necessários para destravar a entrada.

Um campo de testemunha é funcionalmente igual ao campo ScriptSig, mas, em vez de usar OP_CODES para empurrar itens para a pilha, você usa campos compact size antes de cada item. Portanto, você não pode usar nenhum OP_CODE dentro dele para operações lógicas; tudo o que você pode fazer é empurrar dados para a pilha — que é tudo o que é necessário para destravar os tipos de script de travamento mais comuns.

Então os dados de testemunha são uma alternativa simplificada ao Script, que contém apenas dados em vez de opcodes.

A testemunha só pode empurrar dados para a pilha. Por exemplo, no ScriptSig você poderia usar 0x58 (OP_8) para empurrar o número 8 para a pilha; mas, para fazer o mesmo na testemunha, você precisaria usar o byte 0x08 diretamente.

Tabela

Campo de Testemunha
CampoExemploTamanhoFormatoDescrição
Itens da Pilha02variávelCompact SizeO número de itens a empilhar como parte do código de destravamento.
Item
Estrutura de cada item da pilha
CampoExemploTamanhoFormatoDescrição
Tamanho47variávelCompact SizeO tamanho do item de pilha seguinte.
Item3044...01variávelBytesO dado a ser empilhado.

Esta estrutura se repete para cada item de pilha.

Esta estrutura se repete para cada entrada.

Se você está destravando entradas legadas e segwit na mesma transação, precisa definir o campo de testemunha das entradas legadas como 00 (nenhum item), pois cada entrada precisa ter o seu próprio campo de testemunha.

Exemplos

Como é um campo de testemunha?

Aqui estão alguns exemplos de campos de testemunha reais sendo usados para destravar entradas na blockchain.

P2WPKH

Hex

024730440220537f470c1a18dc1a9d233c0b6af1d2ce18a07f3b244e4d9d54e0e60c34c55e67022058169cd11ac42374cda217d6e28143abd0e79549f7b84acc6542817466dc9b3001210301c1768b48843933bd7f0e8782716e8439fc44723d3745feefde2d57b761f503

Bytes separados

02 47 30 44 02 20 53 7f 47 0c 1a 18 dc 1a 9d 23 3c 0b 6a f1 d2 ce 18 a0 7f 3b 24 4e 4d 9d 54 e0 e6 0c 34 c5 5e 67 02 20 58 16 9c d1 1a c4 23 74 cd a2 17 d6 e2 81 43 ab d0 e7 95 49 f7 b8 4a cc 65 42 81 74 66 dc 9b 30 01 21 03 01 c1 76 8b 48 84 39 33 bd 7f 0e 87 82 71 6e 84 39 fc 44 72 3d 37 45 fe ef de 2d 57 b7 61 f5 03

Decodificado

{
  "witness": [
    {
      "stackitems": "02",
      "0": { "size": "47", "item": "30440220537f470c...466dc9b3001" },
      "1": { "size": "21", "item": "0301c1768b48843933bd7f0e8782716e8439fc44723d3745feefde2d57b761f503" }
    }
  ]
}

Transação: 65d8bd45f01bd6209d8695d126ba6bb4f2936501c12b9a1ddc9e38600d35aaa2 (Entrada 0)

Esta transação contém uma entrada que tem uma trava P2WPKH. Para destravá-la, você precisa fornecer uma assinatura seguida de uma chave pública no campo de testemunha.

Esse código de destravamento é funcionalmente igual ao script de destravamento encontrado dentro do ScriptSig de um P2PKH legado. Ou seja, ele apenas contém uma assinatura e uma chave pública.

Porém, enquanto o ScriptSig de um P2PKH usa OP_CODES para empurrar a assinatura e a chave pública para a pilha, a testemunha apenas usa campos compact size para indicar o tamanho da assinatura e da chave pública.

Exemplo de ScriptSig P2PKH

Os campos ScriptSig legados usam os opcodes OP_PUSHBYTES_XX para empurrar dados para a pilha. Mas, como você pode ver, o dado de fato em um campo de testemunha P2WPKH é o mesmo que em um ScriptSig P2PKH:

ASM

OP_PUSHBYTES_72
3045022100c233c3a8a510e03ad18b0a24694ef00c78101bfd5ac075b8c1037952ce26e91e02205aa5f8f88f29bb4ad5808ebc12abfd26bd791256f367b04c6d955f01f28a772401
OP_PUSHBYTES_33
03f0609c81a45f8cab67fc2d050c21b1acd3d37c7acfd54041be6601ab4cef4f31

Hex

483045022100c233c3a8a510e03ad18b0a24694ef00c78101bfd5ac075b8c1037952ce26e91e02205aa5f8f88f29bb4ad5808ebc12abfd26bd791256f367b04c6d955f01f28a7724012103f0609c81a45f8cab67fc2d050c21b1acd3d37c7acfd54041be6601ab4cef4f31

Transação: 40e331b67c0fe7750bb3b1943b378bf702dce86124dc12fa5980f975db7ec930 (Entrada 0)

P2WSH

Hex

04004730440220415899bbee08e42376d06e8f86c92b4987613c2816352fe09cd1479fd639f18c02200db57f508f69e266d76c23891708158bda18690c165a41b0aa88303b97609f780147304402203973de2303e8787767090dd25c8a4dc97ce1aa7eb4c0962f13952ed4e856ff8e02203f1bb425def789eea8be46407d10b3c8730407176aef4dc2c29865eb5e5542bf0169522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae

Bytes separados

04 00 47 30 44 02 20 41 58 99 bb ee 08 e4 23 76 d0 6e 8f 86 c9 2b 49 87 61 3c 28 16 35 2f e0 9c d1 47 9f d6 39 f1 8c 02 20 0d b5 7f 50 8f 69 e2 66 d7 6c 23 89 17 08 15 8b da 18 69 0c 16 5a 41 b0 aa 88 30 3b 97 60 9f 78 01 47 30 44 02 20 39 73 de 23 03 e8 78 77 67 09 0d d2 5c 8a 4d c9 7c e1 aa 7e b4 c0 96 2f 13 95 2e d4 e8 56 ff 8e 02 20 3f 1b b4 25 de f7 89 ee a8 be 46 40 7d 10 b3 c8 73 04 07 17 6a ef 4d c2 c2 98 65 eb 5e 55 42 bf 01 69 52 21 03 84 8e 30 85 69 b6 44 37 2a 5e b2 66 65 f1 a8 c3 4c a3 93 c1 30 b3 76 db 2f ae 75 c4 35 00 01 3c 21 03 ce c1 ee 61 5c 17 e0 6d 4f 4b 0a 08 61 7d ff b8 e5 68 93 6b df f1 8f b0 57 83 2a 58 ad 4d 1b 75 21 03 ee d7 ae 80 c3 4d 70 f5 ba 93 f9 39 65 f6 9f 3c 69 1d a0 f4 60 7f 24 2f 4f d6 c7 a4 87 89 23 3e 53 ae

Decodificado

{
  "witness": [
    {
      "stackitems": "04",
      "0": { "size": "00", "item": "" },
      "1": { "size": "47", "item": "30440220415899bb...97609f7801" },
      "2": { "size": "47", "item": "304402203973de23...5e5542bf01" },
      "3": { "size": "69", "item": "522103848e3085...89233e53ae" }
    }
  ]
}

Transação: b38a88b073743bcc84170071cff4b68dec6fb5dc0bc8ffcb3d4ca632c2c78255 (Entrada 0)

Esta transação contém uma entrada que tem uma trava P2WSH.

O último item neste campo de testemunha é o Witness Script (equivalente ao Redeem Script em um P2SH), que neste exemplo é um script de travamento P2MS. Você pode conferir isso decodificando os bytes hex do empilhamento de dados final para ver o Script de fato que ele contém:

Ícone Ferramenta Script

Script

Decodifique e codifique um script.

0 bytes

Todos os itens antes do Witness Script são os elementos de dados necessários para destravá-lo.

Exemplo de ScriptSig P2SH

Novamente, os campos ScriptSig usam os opcodes OP_PUSHBYTES_XX para empurrar dados para a pilha. Este ScriptSig P2SH contém o mesmo tipo de dado que um campo de testemunha P2WSH, embora o P2MS embrulhado dentro deste campo de testemunha exija apenas uma assinatura para ser destravado:

ASM

OP_0
OP_PUSHBYTES_71
3044022100d0ed946330182916da16a6149cd313a4b1a7b41591ee52fb3e79d64e36139d66021f6ccf173040ef24cb45c4db3e9c771c938a1ba2cf8d2404416f70886e360af401
OP_PUSHBYTES_71
5121022afc20bf379bc96a2f4e9e63ffceb8652b2b6a097f63fbee6ecec2a49a48010e2103a767c7221e9f15f870f1ad9311f5ab937d79fcaeee15bb2c722bca515581b4c052ae

Hex

00473044022100d0ed946330182916da16a6149cd313a4b1a7b41591ee52fb3e79d64e36139d66021f6ccf173040ef24cb45c4db3e9c771c938a1ba2cf8d2404416f70886e360af401475121022afc20bf379bc96a2f4e9e63ffceb8652b2b6a097f63fbee6ecec2a49a48010e2103a767c7221e9f15f870f1ad9311f5ab937d79fcaeee15bb2c722bca515581b4c052ae

Transação: 30c239f3ae062c5f1151476005fd0057adfa6922de1b38d0f11eb657a8157b30 (Entrada 11)

Embora os dados de testemunha em si não sejam Script, no caso de scripts de travamento P2WSH o item final do campo de testemunha de fato contém Script.

P2WPKH & P2PKH

Hex

024730440220599640d1dba05cba9bf5284cf080171c736a8fef51e8975501abd995744cbc8e02202fcda9a5423cfa3c75aadb0a4a20f57d1e2f041211658bc1793974b41202bc4e01210214a6f6ff714e38376ab3afb8f10965cf1ed7940284a3bff81dc8c0bd656de43300

Decodificado

{
  "witness": [
    {
      "stackitems": "02",
      "0": { "size": "47", "item": "30440220599640d1...3974b41202bc4e01" },
      "1": { "size": "21", "item": "0214a6f6ff714e38376ab3afb8f10965cf1ed7940284a3bff81dc8c0bd656de433" }
    },
    {
      "stackitems": "00"
    }
  ]
}

Transação: 0c722837427b05e718ab8e15fc0f5f0e7011e82f13dc1b48b65107876c265ef5

Esta transação está destravando duas entradas distintas: a primeira tem um script de travamento P2WPKH (programa de testemunha) mais novo, e a segunda tem um script de travamento P2PKH legado.

Como esta transação está destravando uma saída segwit, as duas entradas precisam ter o seu próprio campo de testemunha.

E, como você pode ver, os campos de testemunha de cada entrada são simplesmente concatenados um após o outro dentro da área de testemunha de uma transação.

É perfeitamente normal combinar entradas legadas e segwit em uma transação. Você só precisa lembrar de definir o campo de testemunha de uma entrada como 00 se ela não exigir o uso de um campo de testemunha para ser destravada.

P2TR

Uma saída P2TR pode ser destravada de duas formas: pelo "caminho da chave" (key path) ou pelo "caminho de script" (script path). A estrutura da testemunha é diferente em cada caso.

1. Gasto pelo Caminho da Chave (Key Path)

Hex

0141b693a0797b24bae12ed0516a2f5ba765618dca89b75e498ba5b745b71644362298a45ca39230d10a02ee6290a91cebf9839600f7e35158a447ea182ea0e022ae01

Bytes separados

01 41 b6 93 a0 79 7b 24 ba e1 2e d0 51 6a 2f 5b a7 65 61 8d ca 89 b7 5e 49 8b a5 b7 45 b7 16 44 36 22 98 a4 5c a3 92 30 d1 0a 02 ee 62 90 a9 1c eb f9 83 96 00 f7 e3 51 58 a4 47 ea 18 2e a0 e0 22 ae 01

Decodificado

{
  "witness": [
    {
      "stackitems": "01",
      "0": { "size": "41", "item": "b693a0797b24bae1...82ea0e022ae01" }
    }
  ]
}

Transação: 091d2aaadc409298fd8353a4cd94c319481a0b4623fb00872fe240448e93fcbe

Em um gasto pelo caminho da chave em P2TR, a testemunha contém um único item de assinatura.

Essa assinatura corresponde à chave pública ajustada (tweaked) colocada no ScriptPubKey do P2TR.

Este é o método "padrão" para destravar uma saída P2TR.

2. Gasto pelo Caminho de Script (Script Path)

Hex

034101769105cbcbdcaaee5e58cd201ba3152477fda31410df8b91b4aee2c4864c7700615efb425e002f146a39ca0a4f2924566762d9213bd33f825fad83977fba7f0122206d4ddc0e47d2e8f82cbe2fc2d0d749e7bd3338112cecdc76d8f831ae6620dbe0ac21c0924c163b385af7093440184af6fd6244936d1288cbb41cc3812286d3f83a3329

Bytes separados

03 41 01 76 91 05 cb cb dc aa ee 5e 58 cd 20 1b a3 15 24 77 fd a3 14 10 df 8b 91 b4 ae e2 c4 86 4c 77 00 61 5e fb 42 5e 00 2f 14 6a 39 ca 0a 4f 29 24 56 67 62 d9 21 3b d3 3f 82 5f ad 83 97 7f ba 7f 01 22 20 6d 4d dc 0e 47 d2 e8 f8 2c be 2f c2 d0 d7 49 e7 bd 33 38 11 2c ec dc 76 d8 f8 31 ae 66 20 db e0 ac 21 c0 92 4c 16 3b 38 5a f7 09 34 40 18 4a f6 fd 62 44 93 6d 12 88 cb b4 1c c3 81 22 86 d3 f8 3a 33 29

Decodificado

{
  "witness": [
    {
      "stackitems": "03",
      "0": { "size": "41", "item": "01769105cbcbdcaa...77fba7f01" },
      "1": { "size": "22", "item": "206d4ddc0e47d2e8f82cbe2fc2d0d749e7bd3338112cecdc76d8f831ae6620dbe0ac" },
      "2": { "size": "21", "item": "c0924c163b385af7093440184af6fd6244936d1288cbb41cc3812286d3f83a3329" }
    }
  ]
}

Transação: 797505b104b5fb840931c115ea35d445eb1f64c9279bf23aa5bb4c3d779da0c2

Em um gasto pelo caminho de script em P2TR, a testemunha contém 2 ou mais itens. Esses itens podem ser divididos em 3 seções:

  1. Entradas do Script (opcional) — Os itens no início do campo de testemunha são usados para destravar o item de leaf script seguinte. Normalmente é uma única assinatura, mas pode ser composto por vários itens de pilha (dependendo do que for necessário para destravar o leaf script).
  2. Leaf Script — É o penúltimo item do campo de testemunha e vem depois das entradas do script. É um script de travamento completo que foi usado como uma das travas personalizadas adicionais da saída.
  3. Control Block — É o último item do campo de testemunha. Ele contém informações que provam que o leaf script fazia parte da árvore de scripts usada para criar a chave pública ajustada colocada no ScriptPubKey original.

Este é o método "secundário" para destravar uma saída P2TR. O método de gasto pelo caminho de script é usado como alternativa ao método de gasto pelo caminho da chave acima.

Esta estrutura de testemunha para um gasto pelo caminho de script em P2TR é igual à estrutura de testemunha de um P2WSH, mas com um control block adicional no fim.

Limites

Qual é o tamanho máximo de um campo de testemunha?

Diagrama mostrando os limites do campo de testemunha de uma transação para scripts de travamento padrão.

Assim como o Script, os dados de testemunha de uma transação têm certos limites de tamanho para scripts de travamento padrão P2WPKH, P2WSH e P2TR:

O Witness Script em um P2WSH (o item final da pilha) pode ter até 3.600 bytes. Esse é o empilhamento de dados do script de travamento de fato.

Uma transação pode exceder esses limites e ainda será considerada válida, mas também será considerada não padrão e, portanto, não será retransmitida pelos nós. Esses limites podem ser encontrados em policy.h.

Benefícios

Por que usar a testemunha em vez do ScriptSig?

Há dois benefícios em usar a testemunha em vez do campo ScriptSig para destravar entradas.

1. Os dados de testemunha pesam menos

Cada byte dentro da testemunha carrega menos peso do que cada byte dentro do ScriptSig:

Peso por byte: ScriptSig vs Testemunha
ScriptSig1 byte = 4 unidades de peso
Testemunha1 byte = 1 unidade de peso

Ou, em termos de bytes virtuais, isso é:

Bytes virtuais por byte: ScriptSig vs Testemunha
ScriptSig1 byte = 1 vbyte
Testemunha1 byte = 0,25 vbytes

Por exemplo, o código de destravamento típico dentro de um ScriptSig para um P2PKH legado contém 106 bytes, o que é igual a 424 unidades de peso ou 106 vbytes:

47304402205aea7d8d4896c5057a96f1b9fc76dd2b00f30ab0df46149047b5f4294f88796202205ce938d9f14f5238192b369d79861ade5a25884ece7afe9b9dde8a6a683c4af7012102af26f51735ff252de2972f06f2bb47456108c2e8a6554187cf3bb4a0c657590f

Transação: 842c4626a8ef8eebe46ed8d591b643c5d7be84ea1aa199fb76e5d78fe8d6819f (Entrada 0)

Porém, o código de destravamento típico dentro de um campo de testemunha para um P2WPKH segwit contém 107 bytes, o que é igual a 107 unidades de peso ou 26,75 vbytes:

0247304402202a11945f55d174686cd48e9b3e0db3bfbe5fb9557a76fa546c6772c434f03f14022010be503e37c1cb6e0519ce9f8532c89fa2cbec6667d93a4f3bdef43fb047dba30121032704e02eb63d8ea323b0386bf3b47c0d9058f36c9c486ac102a34b929d862abb

Transação: 7a466b5ed43e5022121918d9e9fdef923a7a5e2d01c9abd6a4998e30e77d2ad3 (Entrada 0)

Como resultado, o código de destravamento de scripts de travamento segwit ocupa menos espaço dentro de um bloco. Isso significa que você não precisa pagar tanto em taxas de transação, em termos de sats por vbyte, para conseguir minerar a transação.

Usar a testemunha dá a você um desconto na quantia que precisa pagar em taxas de transação em comparação com usar o ScriptSig.

2. A testemunha previne a maleabilidade de transações

Diagrama mostrando os dados de testemunha não sendo incluídos na criação do TXID.

O campo ScriptSig geralmente contém uma assinatura, e esse campo entra no cálculo do TXID. Porém, a testemunha não faz parte do TXID, então as assinaturas que ficam nela não entram mais no cálculo do TXID.

Isso é importante porque assinaturas podem ser modificadas mantendo a transação válida, o que significava que o TXID de uma transação podia mudar antes de ela ser minerada. Ao usar a testemunha para destravar entradas, você tem a confiança de que o TXID permanecerá o mesmo depois que a transação for enviada à rede. Essa mudança foi a força motriz por trás da atualização Segregated Witness.

TXID

Crie um TXID a partir dos dados de uma transação bruta.

0 bytes

Bytes da transação efetivamente usados no hash (sem marker, flag nem testemunha):

Usado internamente dentro dos dados da transação bruta

0 bytes

Usado externamente ao buscar transações em exploradores de blocos

0 bytes

Valor Reservado de Testemunha

O espaço para comprometer novos dados ao bloco

Diagrama mostrando novos dados sendo comprometidos ao bloco por meio do valor reservado de testemunha no campo de testemunha de uma transação coinbase.

A testemunha da entrada de uma transação coinbase contém um valor reservado de testemunha (witness reserved value): um espaço de 32 bytes reservado para um commitment de novos dados em uma futura atualização do bitcoin.

Como a entrada de uma coinbase não referencia nenhuma saída anterior, não há nada a destravar — então os campos de destravamento dessa entrada (ScriptSig e testemunha) ficam "sobrando". Por isso, a testemunha dessa entrada foi reservada como espaço para armazenar dados extras em uma potencial atualização futura: se uma nova atualização adicionasse dados às transações, todos esses dados poderiam ser hasheados e armazenados no valor reservado de testemunha, e qualquer um poderia ver que os dados foram de fato incluídos como parte do bloco.

No momento, o valor reservado de testemunha não é usado, então normalmente fica como um valor vazio de 32 bytes: 0000000000000000000000000000000000000000000000000000000000000000.

Terminologia

Por que se chama testemunha?

O termo "witness" (testemunha) foi cunhado por Pieter Wuille, o desenvolvedor por trás da atualização Segregated Witness:

A única coisa com que nos importamos é que o remetente autorizou [a transação]. Pode haver várias assinaturas possíveis para uma transação, mas só nos importamos que uma delas exista. Isso é algo chamado de Testemunha (Witness) na matemática; você prova que algo existe dando um exemplo.
Pieter Wuille, SF Bitcoin Developers

Então é só um nome técnico chique para a área de "código de destravamento" das saídas segwit.

Recursos