Dados on-chain e SQL · Aula 2 de 9
Transações Bitcoin brutas e tipos de script
14 min de leitura
Exploradores mostram uma transação Bitcoin como listas organizadas de endereços e valores, mas essa visualização é uma decodificação de bytes brutos, e parte do que ela mostra nem sequer está na transação. Ler a estrutura bruta informa ao investigador o que está registrado na blockchain e o que uma ferramenta derivou, por que a taxa não pode ser calculada apenas com a transação e quais campos contêm as impressões digitais de carteira nas quais heurísticas posteriores se baseiam. Ler os formatos de endereço informa qual tipo de script está em uso, o que restringe as possibilidades de software de carteira e sua época, e o que se tornará público quando as moedas forem gastas.
A serialização, campo a campo
Uma transação é armazenada e retransmitida como uma sequência de bytes. Desde o SegWit (BIP 141, ativado em agosto de 2017), existem duas formas: a forma legada e a forma estendida do BIP 144, usada quando pelo menos uma entrada contém dados de testemunha.
| Campo | Tamanho | Observações |
|---|---|---|
| version | 4 bytes | Inteiro little-endian, geralmente 1 ou 2 |
| marker, flag | 2 bytes | 00 01, presentes apenas na forma SegWit |
| contagem de entradas | variável | Inteiro CompactSize |
| entradas | variável | Cada uma: txid anterior (32), índice da saída (4), comprimento do scriptSig e scriptSig, sequence (4) |
| contagem de saídas | variável | Inteiro CompactSize |
| saídas | variável | Cada uma: valor em satoshis (8), comprimento do scriptPubKey e scriptPubKey |
| witness | variável | Apenas na forma SegWit: para cada entrada, uma contagem de itens e os itens |
| locktime | 4 bytes | Primeira altura de bloco ou instante em que a transação é válida |
Os inteiros são little-endian: o byte menos significativo vem primeiro. Um inteiro CompactSize ocupa um byte para valores abaixo de 253; caso contrário, usa um byte de prefixo (fd, fe ou ff) seguido de 2, 4 ou 8 bytes. Veja uma transação SegWit com uma entrada e duas saídas dividida em seus campos, com valores longos truncados:
02000000 versão 2
00 01 marcador e sinalizador SegWit
01 contagem de entradas 1
ab09…1d7c txid anterior, ordem interna de bytes (32 bytes)
01000000 índice da saída anterior 1
00 comprimento do scriptSig 0 (entrada SegWit nativa)
fdffffff sequence 0xfffffffd
02 contagem de saídas 2
40420f0000000000 valor 1.000.000 sat
16 0014 3c1e…9d02 script, 22 bytes: P2WPKH
0c6a070000000000 valor 485.900 sat
16 0014 77b4…e051 script, 22 bytes: P2WPKH
02 47 3044…01 21 02a1…5f testemunha: 2 itens, assinatura (71 bytes), chave pública (33 bytes)
00000000 locktime 0
Leia o primeiro valor invertendo seus bytes: 40 42 0f 00 … torna-se 0x0f4240, que equivale a 1.000.000 satoshis (0,01 BTC). Observe o que está ausente: nenhum endereço do remetente, nenhum valor de entrada e nenhuma taxa.
Entradas e outpoints
Uma entrada não contém moedas; ela aponta para uma saída anterior, chamada de outpoint e escrita como txid:vout. O txid de 32 bytes dentro da entrada é armazenado na ordem interna de bytes, o inverso do que os exploradores exibem: ab09…1d7c nos bytes é 7c1d…09ab na tela. Esquecer essa inversão é uma causa clássica de "transação não encontrada".
O valor e o script que está sendo gasto ficam na saída anterior, portanto, para saber quem pagou e quanto, é preciso consultar cada outpoint. O scriptSig (scripts legados) ou a testemunha (scripts SegWit) da entrada fornece os dados que satisfazem as condições da saída anterior, geralmente assinaturas e chaves públicas. Uma entrada coinbase, que cria novas moedas, tem um txid anterior composto inteiramente por zeros e índice 0xffffffff.
Sequence, version, locktime e impressões digitais de carteira
Os campos ao redor das entradas e saídas parecem padronizados, mas contêm informações:
- Sequence. Valores abaixo de
0xfffffffesinalizam a possibilidade de substituição conforme o BIP 125, sendo0xfffffffda escolha comum. Desde o Bitcoin Core 28.0 (2024), os nós aceitam substituições por padrão, independentemente de a transação original ter sinalizado essa possibilidade; por isso, hoje o valor importa principalmente como uma impressão digital. Bloqueios temporais relativos (BIP 68) usam o mesmo campo. - Version. Quase sempre 1 ou 2; a versão 2 é necessária para bloqueios temporais relativos, e as carteiras diferem quanto à versão que usam.
- Locktime. Interpretado como uma altura de bloco abaixo de 500.000.000 e como um timestamp Unix caso contrário; zero significa nenhuma restrição. Muitas carteiras o definem como a altura atual para desestimular mineradores a reescrever blocos recentes para capturar taxas (anti-fee-sniping); assim, um locktime de 880.213 em uma transação confirmada em 880.214 revela algo sobre o software que a criou.
Esses valores, juntamente com os tipos de script usados, a ordem das saídas e a codificação das assinaturas, formam uma impressão digital de carteira. Uma impressão digital não prova nada; uma combinação consistente entre transações é um dos sinais que a Aula 4.2 usa para distinguir um pagamento de um troco.
Scripts de saída e formatos de endereço
Cada saída contém um valor em satoshis e um scriptPubKey, a condição para gastá-la. Scripts padrão seguem modelos fixos, de modo que o tipo pode ser identificado pelos primeiros bytes. Um endereço é uma codificação de um script padrão, não um campo da transação: os decodificadores o derivam, e o formato revela o tipo.
| Tipo | Padrão do scriptPubKey | Bytes | Definido em | Codificação | Endereço | type do Bitcoin Core |
|---|---|---|---|---|---|---|
| P2PKH | 76 a9 14 {20} 88 ac | 25 | original | Base58Check, versão 0x00 | 1…, até 34 caracteres | pubkeyhash |
| P2SH | a9 14 {20} 87 | 23 | BIP 16 | Base58Check, versão 0x05 | 3…, 34 caracteres | scripthash |
| P2WPKH | 00 14 {20} | 22 | BIP 141 | bech32 | bc1q…, 42 caracteres | witness_v0_keyhash |
| P2WSH | 00 20 {32} | 34 | BIP 141 | bech32 | bc1q…, 62 caracteres | witness_v0_scripthash |
| P2TR | 51 20 {32} | 34 | BIP 341 | bech32m | bc1p…, 62 caracteres | witness_v1_taproot |
| OP_RETURN | 6a … | varia | — | nenhuma | nenhum | nulldata |
Em P2PKH, 76 a9 14 … 88 ac é OP_DUP OP_HASH160 {push 20 bytes} OP_EQUALVERIFY OP_CHECKSIG. Saídas SegWit começam com um opcode de versão (00 para a versão 0, 51 para a versão 1, Taproot), seguido de uma operação de inserção do programa na pilha. Uma saída OP_RETURN é comprovadamente não gastável e contém dados, não valor. Redes de teste usam outros prefixos (m ou n para P2PKH, 2 para P2SH, tb1 para SegWit), portanto é fácil identificar um endereço de rede de teste isolado em um conjunto de dados. Alguns scripts antigos, como as primeiras saídas de pagamento para chave pública e multisig sem encapsulamento, não têm endereço padrão algum; repositórios de dados podem deixar a coluna de endereço vazia, e um filtro por address IS NOT NULL os descarta silenciosamente.
Base58Check
Endereços legados usam um byte de versão, acrescentam a carga útil de 20 bytes (um HASH160 de uma chave pública ou script), adicionam uma soma de verificação dos primeiros 4 bytes de SHA-256(SHA-256(versão ‖ carga útil)) e escrevem os 25 bytes em um alfabeto de 58 caracteres sem 0, O, I e l. Cada byte zero inicial torna-se um 1 inicial, razão pela qual todo endereço P2PKH começa com ele. A codificação diferencia maiúsculas de minúsculas, e a soma de verificação rejeita quase todo erro de digitação. O byte de versão é a chave de classificação: 0x00 significa P2PKH, 0x05 significa P2SH e qualquer outro valor indica outra rede ou moeda.
Bech32 e bech32m
Endereços SegWit nativos usam bech32 (BIP 173): uma parte legível por humanos (bc para a rede principal, tb para a rede de teste), o separador 1 e uma parte de dados em um alfabeto de 32 caracteres que exclui 1, b, i e o. O primeiro caractere dos dados é a versão da testemunha (q = 0, p = 1), seguido pelo programa e por uma soma de verificação de 6 caracteres. Um programa de 20 bytes resulta em 42 caracteres (P2WPKH); um de 32 bytes, em 62 (P2WSH). Bech32 usa apenas minúsculas (maiúsculas são permitidas para códigos QR, mas a mistura de maiúsculas e minúsculas deve ser rejeitada), tem no máximo 90 caracteres, e sua soma de verificação detecta qualquer erro que afete até quatro caracteres.
Ela tem uma falha: quando uma sequência termina em p, inserir ou excluir caracteres q imediatamente antes dele pode manter a soma de verificação válida. Os comprimentos rígidos de programa da versão 0 tornam isso praticamente inofensivo, mas versões posteriores permitem outros comprimentos; por isso, o BIP 350 introduziu bech32m, idêntico exceto pela constante da soma de verificação (0x2bc830a3 em vez de 1). A versão 0 mantém bech32; as versões 1 a 16, incluindo Taproot, usam bech32m, e os decodificadores devem rejeitar a soma de verificação incorreta para cada uma. Em pipelines, nunca classifique com base em "começa com bc1": leia o quarto caractere e o comprimento. Analisadores escritos antes de 2021 podem rejeitar endereços bc1p válidos, e um pipeline que descarta linhas que não consegue analisar subestima a atividade Taproot sem aviso.
Dados de testemunha, peso e tamanho
O SegWit move as assinaturas para uma testemunha separada. O que ela contém depende do tipo que está sendo gasto:
- P2WPKH: uma assinatura DER com um byte sighash (geralmente 71 ou 72 bytes) e uma chave pública comprimida de 33 bytes.
- P2WSH: os itens que satisfazem as condições, seguidos do próprio script de testemunha, de modo que a política de gasto só se torna visível quando a saída é gasta.
- Caminho de chave P2TR: uma assinatura Schnorr de 64 bytes (BIP 340), ou 65 bytes com um tipo sighash não padrão. Um gasto por caminho de script revela um script (BIP 342) e um bloco de controle.
- SegWit encapsulado em P2SH: o scriptSig contém apenas um script de resgate curto, como
0014…, e as assinaturas ficam na testemunha.
Os bytes de testemunha recebem um desconto. O BIP 141 define peso como tamanho base × 3 + tamanho total, em que o tamanho base exclui o marcador, o sinalizador e a testemunha; o tamanho virtual (vsize) é o peso ÷ 4, arredondado para cima, e as taxas por unidade são expressas por vbyte. No exemplo, a forma base tem 113 bytes, e a seção de testemunha, contando o marcador e o sinalizador, acrescenta 109, totalizando 222 bytes. O peso é 113 × 3 + 222 = 561, e 561 ÷ 4, arredondado para cima, resulta em 141 vbytes.
A visualização decodificada e a taxa
O getrawtransaction do Bitcoin Core com verbosidade 2 retorna a transação decodificada, além de cada saída gasta (prevout) e da taxa, quando o nó tem os dados de desfazimento do bloco (a Aula 2.1 aborda as chamadas ao nó):
{
"txid": "4f3a…c21e", "hash": "9b07…e4d2",
"version": 2, "size": 222, "vsize": 141, "weight": 561, "locktime": 0,
"vin": [{
"txid": "7c1d…09ab", "vout": 1,
"scriptSig": {"asm": "", "hex": ""},
"txinwitness": ["3044…01", "02a1…5f"],
"prevout": {"value": 0.01500000, "height": 868120,
"scriptPubKey": {"type": "witness_v0_keyhash", "address": "bc1q…7k3f"}},
"sequence": 4294967293
}],
"vout": [
{"value": 0.01000000, "n": 0,
"scriptPubKey": {"type": "witness_v0_keyhash", "address": "bc1q…m2d8"}},
{"value": 0.00485900, "n": 1,
"scriptPubKey": {"type": "witness_v0_keyhash", "address": "bc1q…x9qa"}}
],
"fee": 0.00014100
}
A taxa nunca é escrita na transação; ela é a diferença entre entradas e saídas. Aqui, o único outpoint vale 1.500.000 sat, as saídas totalizam 1.000.000 + 485.900 = 1.485.900 sat, portanto a taxa é de 14.100 sat, e 14.100 ÷ 141 = 100 sat/vB. O decoderawtransaction simples retorna a mesma estrutura sem prevout e fee, porque não consegue ver as saídas anteriores. Os valores chegam em BTC como números JSON; converta-os em satoshis inteiros antes de qualquer operação aritmética (Aula 2.6). Uma transação coinbase não tem taxa: suas saídas reivindicam o subsídio mais todas as demais taxas. A Aula 2.9 mostra o mesmo cálculo em SQL sobre tabelas de entradas e saídas.
txid versus wtxid
O txid é o SHA-256 duplo da transação serializada sem marcador, sinalizador e testemunha; o wtxid calcula o hash da forma SegWit completa, e o Bitcoin Core o mostra como hash. Sem dados de testemunha, os dois são idênticos. Excluir a testemunha corrigiu a maleabilidade por terceiros: alterar a codificação de uma assinatura costumava mudar o txid de uma transação que, fora isso, era idêntica. Agora, mudanças na testemunha alteram apenas o wtxid, de modo que cadeias de transações não confirmadas podem referenciar umas às outras com segurança. Os blocos se comprometem com os wtxids por meio de um compromisso de testemunha na coinbase. Em relatórios, identifique as transações pelo txid na ordem de bytes de exibição.
O que os scripts revelam sobre carteiras e custódia
Os formatos de endereço acompanham o histórico das carteiras:
1…: carteiras antigas, serviços exclusivamente legados, algumas carteiras de exchanges em uso há muito tempo; atividade P2PKH nova hoje frequentemente aponta para software antigo ou personalizado.3…: ambíguo até ser gasto: multisig ou uma carteira de chave única usando SegWit aninhado, um padrão comum por volta de 2017–2019. No gasto, o script de resgate esclarece isso:0014mais 20 bytes é P2WPKH aninhado,0020mais 32 bytes é P2WSH aninhado, e um script terminado emae(OP_CHECKMULTISIG) é multisig clássico.bc1q…: o tipo padrão de recebimento da maioria das carteiras amplamente usadas nos últimos anos; P2WSH de 62 caracteres geralmente significa multisig ou outro script personalizado.bc1p…: carteiras que adotaram Taproot após sua ativação no bloco 709.632 em novembro de 2021, além de ferramentas de inscrições e tokens.
Os tipos de script também se misturam dentro das transações: se todas as entradas forem P2WPKH e as saídas forem uma P2WPKH e uma P2SH, a saída que corresponde às entradas tem maior probabilidade de ser troco (uma heurística, não um fato; veja a Aula 4.2).
Multisig clássico
O multisig clássico oculta sua política enquanto os fundos permanecem não gastos (apenas um hash está na blockchain) e a publica no primeiro gasto. Uma entrada P2WSH 2-de-3:
witness[0] (vazio) -- elemento fictício exigido por OP_CHECKMULTISIG
witness[1] 3044…01 -- primeira assinatura (DER, byte sighash 01)
witness[2] 3045…01 -- segunda assinatura
witness[3] 5221…21…21…53ae -- OP_2 <key1> <key2> <key3> OP_3 OP_CHECKMULTISIG
52 é OP_2 (duas assinaturas exigidas), cada 21 insere uma chave de 33 bytes na pilha, 53 é OP_3 e ae é OP_CHECKMULTISIG. Um gasto revela o limiar, todas as três chaves públicas e quais duas assinaram. Custodiantes frequentemente usam políticas distintas (2-de-3, 3-de-5), e a mesma chave pública aparecendo em muitos scripts multisig vincula esses endereços a um único detentor de chave com muito mais confiabilidade do que heurísticas comportamentais. Muitas carteiras ordenam as chaves lexicograficamente (BIP 67), o que por si só constitui uma pequena impressão digital.
Taproot
O Taproot combina assinaturas Schnorr com chaves de 32 bytes "somente x" (BIP 340), uma chave de saída Q = P + t·G em que P é uma chave interna e o ajuste t estabelece um compromisso com P e com a raiz de Merkle de uma árvore opcional de scripts (BIP 341), e regras de script que substituem OP_CHECKMULTISIG por OP_CHECKSIGADD (BIP 342).
| Gasto | Testemunha | O que um analista descobre |
|---|---|---|
| Multisig P2WSH 2-de-3 | Duas assinaturas mais o script completo | Limiar, todas as chaves, quais chaves assinaram |
| Caminho de chave P2TR | Uma assinatura de 64 bytes (65 com sighash explícito) | Nada sobre a política |
| Caminho de script P2TR | Script da folha, suas entradas, bloco de controle de 33 + 32m bytes | A única condição usada, sua profundidade m, a chave interna |
No caminho de chave, uma carteira de chave única, um grupo n-de-n usando agregação de chaves (MuSig2) e um esquema de limiar têm a mesma aparência. O caminho de script revela apenas a folha usada, embora o comprimento do caminho de Merkle revele algo sobre o tamanho da árvore. O Taproot remove os indícios de multisig sempre que o caminho de chave é usado; ele não oculta valores, o grafo ou os aspectos temporais, e o próprio formato bc1p ainda distingue seus usuários. Gastos por caminho de script também contêm inscrições: desde 2023, testemunhas grandes com um invólucro OP_FALSE OP_IF … OP_ENDIF incorporam imagens e dados de tokens, um padrão a ser excluído da análise de pagamentos.
Foco no exame: espere decodificar ou classificar, não apenas memorizar: ordem e tamanhos dos campos, valores little-endian e CompactSize; outpoints e ordem de bytes invertida do txid; modelos de scriptPubKey, BIPs, prefixos e comprimentos (1,3,bc1qcom 42 e 62,bc1pcom 62); bytes de versão Base58Check e bech32 versus bech32m; o fato de que endereços, valores de entrada e taxas são derivados, não armazenados; cálculos de peso e vsize; taxa a partir das saídas anteriores; txid versus wtxid e maleabilidade; como um P2SH gasto é esclarecido, o que um gasto multisig revela e o que gastos Taproot por caminho de chave e por caminho de script ocultam.