Datos en cadena y SQL · Lección 2 de 9
Transacciones de Bitcoin en bruto y tipos de scripts
15 min de lectura
Los exploradores muestran una transacción de Bitcoin como listas ordenadas de direcciones e importes, pero esa vista es una decodificación de bytes en bruto, y parte de lo que muestra ni siquiera está en la transacción. Leer la estructura en bruto indica al investigador qué está registrado en la cadena y qué ha derivado una herramienta, por qué no se puede calcular la comisión únicamente a partir de una transacción y qué campos contienen las huellas de la billetera en las que se basan las heurísticas posteriores. Leer los formatos de dirección permite saber qué tipo de script se utiliza, lo que acota el software de billetera y su época, y qué se hará público cuando se gasten las monedas.
La serialización, campo por campo
Una transacción se almacena y se retransmite como una secuencia de bytes. Desde SegWit (BIP 141, activado en agosto de 2017) existen dos formas: la forma heredada y la forma extendida de BIP 144, que se utiliza cuando al menos una entrada contiene datos de testigo.
| Campo | Tamaño | Notas |
|---|---|---|
| versión | 4 bytes | Entero little-endian, normalmente 1 o 2 |
| marcador, indicador | 2 bytes | 00 01, presentes solo en la forma SegWit |
| número de entradas | variable | Entero CompactSize |
| entradas | variable | Cada una: txid anterior (32), índice de salida (4), longitud de scriptSig y scriptSig, secuencia (4) |
| número de salidas | variable | Entero CompactSize |
| salidas | variable | Cada una: valor en satoshis (8), longitud de scriptPubKey y scriptPubKey |
| testigo | variable | Solo en la forma SegWit: para cada entrada, un número de elementos y los elementos |
| locktime | 4 bytes | Altura de bloque o momento más temprano en que la transacción es válida |
Los enteros son little-endian: el byte menos significativo aparece primero. Un entero CompactSize ocupa un byte para valores inferiores a 253; en los demás casos, un byte de prefijo (fd, fe o ff) seguido de 2, 4 u 8 bytes. Aquí se muestra una transacción SegWit de una entrada y dos salidas dividida en sus campos, con los valores largos truncados:
02000000 versión 2
00 01 marcador e indicador SegWit
01 número de entradas 1
ab09…1d7c txid anterior, orden interno de bytes (32 bytes)
01000000 índice de salida anterior 1
00 longitud de scriptSig 0 (entrada SegWit nativa)
fdffffff secuencia 0xfffffffd
02 número de salidas 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 testigo: 2 elementos, firma (71 bytes), clave pública (33 bytes)
00000000 locktime 0
Lea el primer valor invirtiendo sus bytes: 40 42 0f 00 … se convierte en 0x0f4240, que equivale a 1.000.000 satoshis (0,01 BTC). Observe lo que falta: no hay dirección del remitente, importe de la entrada ni comisión.
Entradas y outpoints
Una entrada no contiene monedas; apunta a una salida anterior, denominada outpoint y escrita como txid:vout. El txid de 32 bytes dentro de la entrada se almacena en orden interno de bytes, el inverso del que muestran los exploradores: ab09…1d7c en los bytes es 7c1d…09ab en pantalla. Olvidar esta inversión es una causa clásica de «transacción no encontrada».
El importe y el script que se gasta se encuentran en la salida anterior, por lo que, para saber quién pagó y cuánto, hay que consultar cada outpoint. El scriptSig (scripts heredados) o el testigo (scripts SegWit) de la entrada proporciona los datos que satisfacen las condiciones de la salida anterior, normalmente firmas y claves públicas. Una entrada coinbase, que crea monedas nuevas, tiene un txid anterior compuesto íntegramente por ceros y el índice 0xffffffff.
Secuencia, versión, locktime y huellas de billetera
Los campos que rodean las entradas y salidas parecen rutinarios, pero contienen información:
- Secuencia. Los valores inferiores a
0xfffffffeseñalan la posibilidad de reemplazo conforme a BIP 125, y0xfffffffdes la opción habitual. Desde Bitcoin Core 28.0 (2024), los nodos aceptan reemplazos de forma predeterminada independientemente de que la transacción original lo señalara, por lo que hoy el valor importa principalmente como huella. Los bloqueos temporales relativos (BIP 68) utilizan el mismo campo. - Versión. Casi siempre 1 o 2; la versión 2 es necesaria para los bloqueos temporales relativos, y las billeteras difieren en cuál utilizan.
- Locktime. Se interpreta como una altura de bloque por debajo de 500.000.000 y como una marca de tiempo Unix en los demás casos; cero significa que no hay restricción. Muchas billeteras lo establecen en la altura actual para disuadir a los mineros de reescribir bloques recientes con el fin de capturar comisiones (anti-fee-sniping), por lo que un locktime de 880.213 en una transacción confirmada en 880.214 aporta información sobre el software que la creó.
Estos valores, junto con los tipos de scripts utilizados, el orden de las salidas y la codificación de las firmas, forman una huella de billetera. Una huella por sí sola no demuestra nada; una combinación coherente entre transacciones es una de las señales que utiliza la lección 4.2 para distinguir un pago del cambio.
Scripts de salida y formatos de dirección
Cada salida contiene un valor en satoshis y un scriptPubKey, la condición para gastarla. Los scripts estándar siguen plantillas fijas, de modo que el tipo puede identificarse a partir de los primeros bytes. Una dirección es una codificación de un script estándar, no un campo de la transacción: los decodificadores la derivan, y el formato revela el tipo.
| Tipo | Patrón de scriptPubKey | Bytes | Definido en | Codificación | Dirección | type de Bitcoin Core |
|---|---|---|---|---|---|---|
| P2PKH | 76 a9 14 {20} 88 ac | 25 | original | Base58Check, versión 0x00 | 1…, hasta 34 caracteres | pubkeyhash |
| P2SH | a9 14 {20} 87 | 23 | BIP 16 | Base58Check, versión 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 … | variable | — | ninguna | ninguna | nulldata |
En P2PKH, 76 a9 14 … 88 ac es OP_DUP OP_HASH160 {insertar 20 bytes} OP_EQUALVERIFY OP_CHECKSIG. Las salidas SegWit comienzan con un código de operación de versión (00 para la versión 0, 51 para la versión 1, Taproot) seguido de una inserción del programa en la pila. Una salida OP_RETURN es demostrablemente no gastable y contiene datos, no valor. Las redes de prueba utilizan otros prefijos (m o n para P2PKH, 2 para P2SH, tb1 para SegWit), por lo que es fácil detectar una dirección de red de prueba aislada en un conjunto de datos. Algunos scripts antiguos, como las primeras salidas de pago a clave pública y los scripts multifirma sin encapsular, no tienen ninguna dirección estándar; los almacenes de datos pueden dejar vacía la columna de dirección, y un filtro basado en address IS NOT NULL los descarta silenciosamente.
Base58Check
Las direcciones heredadas toman un byte de versión, le añaden la carga útil de 20 bytes (un HASH160 de una clave pública o un script), agregan una suma de verificación formada por los primeros 4 bytes de SHA-256(SHA-256(versión ‖ carga útil)) y escriben los 25 bytes en un alfabeto de 58 caracteres sin 0, O, I ni l. Cada byte cero inicial se convierte en un 1 inicial, por lo que todas las direcciones P2PKH comienzan con él. La codificación distingue entre mayúsculas y minúsculas, y la suma de verificación rechaza casi cualquier error tipográfico. El byte de versión es la clave de clasificación: 0x00 significa P2PKH, 0x05 P2SH y cualquier otro valor indica otra red o moneda.
Bech32 y bech32m
Las direcciones SegWit nativas utilizan bech32 (BIP 173): una parte legible por humanos (bc para la red principal, tb para la red de prueba), el separador 1 y una parte de datos en un alfabeto de 32 caracteres que excluye 1, b, i y o. El primer carácter de datos es la versión del testigo (q = 0, p = 1), seguido del programa y una suma de verificación de 6 caracteres. Un programa de 20 bytes da lugar a 42 caracteres (P2WPKH); uno de 32 bytes, a 62 (P2WSH). Bech32 utiliza solo minúsculas (se permiten mayúsculas para códigos QR; la combinación de mayúsculas y minúsculas debe rechazarse), tiene como máximo 90 caracteres y su suma de verificación detecta cualquier error que afecte a un máximo de cuatro caracteres.
Tiene un defecto: cuando una cadena termina en p, insertar o eliminar caracteres q justo antes puede dejar una suma de verificación válida. Las longitudes estrictas de los programas de la versión 0 hacen que esto sea mayormente inocuo, pero las versiones posteriores permiten otras longitudes, por lo que BIP 350 introdujo bech32m, idéntico salvo por la constante de la suma de verificación (0x2bc830a3 en lugar de 1). La versión 0 mantiene bech32; las versiones 1 a 16, incluido Taproot, utilizan bech32m, y los decodificadores deben rechazar la suma de verificación incorrecta para cada una. En las canalizaciones de procesamiento, nunca clasifique según «empieza por bc1»: lea el cuarto carácter y la longitud. Los analizadores escritos antes de 2021 pueden rechazar direcciones bc1p válidas, y una canalización que descarta las filas que no puede analizar contabiliza menos actividad de Taproot de la real sin advertirlo.
Datos de testigo, peso y tamaño
SegWit traslada las firmas a un testigo separado. Su contenido depende del tipo que se gasta:
- P2WPKH: una firma DER con un byte sighash (normalmente 71 o 72 bytes) y una clave pública comprimida de 33 bytes.
- P2WSH: los elementos que satisfacen las condiciones seguidos del propio script de testigo, por lo que la política de gasto solo se hace visible cuando se gasta la salida.
- Ruta de clave de P2TR: una firma Schnorr de 64 bytes (BIP 340), o 65 bytes con un tipo sighash no predeterminado. Un gasto por ruta de script revela un script (BIP 342) y un bloque de control.
- SegWit encapsulado en P2SH: el scriptSig contiene únicamente un script de canje corto, como
0014…, y las firmas se encuentran en el testigo.
Los bytes del testigo reciben un descuento. BIP 141 define el peso como tamaño base × 3 + tamaño total, donde el tamaño base excluye el marcador, el indicador y el testigo; el tamaño virtual (vsize) es el peso ÷ 4, redondeado hacia arriba, y las tasas de comisión se expresan por vbyte. En el ejemplo, la forma base ocupa 113 bytes y la sección del testigo, contando el marcador y el indicador, añade 109, para un total de 222 bytes. El peso es 113 × 3 + 222 = 561, y 561 ÷ 4 redondeado hacia arriba da 141 vbytes.
La vista decodificada y la comisión
getrawtransaction de Bitcoin Core con nivel de detalle 2 devuelve la transacción decodificada, además de cada salida gastada (prevout) y la comisión, cuando el nodo dispone de los datos de reversión del bloque (la lección 2.1 trata las llamadas al nodo):
{
"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
}
La comisión nunca se escribe en la transacción; es la diferencia entre las entradas y las salidas. Aquí, el único outpoint tiene un valor de 1.500.000 sat, las salidas suman 1.000.000 + 485.900 = 1.485.900 sat, por lo que la comisión es de 14.100 sat, y 14.100 ÷ 141 = 100 sat/vB. decoderawtransaction por sí solo devuelve la misma estructura sin prevout ni fee, porque no puede ver las salidas anteriores. Los importes llegan en BTC como números JSON; conviértalos a satoshis enteros antes de realizar cualquier operación aritmética (lección 2.6). Una transacción coinbase no tiene comisión: sus salidas reclaman el subsidio más todas las demás comisiones. La lección 2.9 muestra el mismo cálculo en SQL sobre tablas de entradas y salidas.
txid frente a wtxid
El txid es el doble SHA-256 de la transacción serializada sin marcador, indicador ni testigo; el wtxid calcula el hash de la forma SegWit completa, y Bitcoin Core lo muestra como hash. Sin datos de testigo, ambos son idénticos. Excluir el testigo resolvió la maleabilidad por terceros: alterar la codificación de una firma antes cambiaba el txid de una transacción por lo demás idéntica. Ahora, los cambios en el testigo solo alteran el wtxid, por lo que las cadenas de transacciones no confirmadas pueden referenciarse entre sí de forma segura. Los bloques se comprometen criptográficamente con los wtxid mediante un compromiso de testigo en la coinbase. En los informes, identifique las transacciones por su txid en el orden de bytes de visualización.
Qué revelan los scripts sobre las billeteras y la custodia
Los formatos de dirección reflejan la historia de las billeteras:
1…: billeteras antiguas, servicios que solo admiten formatos heredados, algunas billeteras de exchanges de larga trayectoria; la actividad P2PKH nueva hoy suele apuntar a software antiguo o personalizado.3…: ambiguo hasta que se gasta: multifirma o una billetera de una sola clave que utiliza SegWit anidado, una configuración predeterminada habitual alrededor de 2017–2019. En el momento del gasto, el script de canje resuelve la ambigüedad:0014más 20 bytes es P2WPKH anidado,0020más 32 bytes es P2WSH anidado y un script que termina enae(OP_CHECKMULTISIG) es multifirma clásica.bc1q…: el tipo de recepción predeterminado de la mayoría de las billeteras de uso generalizado en los últimos años; P2WSH de 62 caracteres suele indicar multifirma u otro script personalizado.bc1p…: billeteras que adoptaron Taproot tras su activación en el bloque 709.632 en noviembre de 2021, además de herramientas de inscripciones y tokens.
Los tipos de scripts también se mezclan dentro de las transacciones: si todas las entradas son P2WPKH y las salidas son una P2WPKH y una P2SH, es más probable que la salida que coincide con las entradas sea el cambio (una heurística, no un hecho; véase la lección 4.2).
Multifirma clásica
La multifirma clásica oculta su política mientras los fondos permanecen sin gastar (solo hay un hash en la cadena) y la publica en el primer gasto. Una entrada P2WSH de 2 de 3:
witness[0] (vacío) -- elemento ficticio requerido por OP_CHECKMULTISIG
witness[1] 3044…01 -- primera firma (DER, byte sighash 01)
witness[2] 3045…01 -- segunda firma
witness[3] 5221…21…21…53ae -- OP_2 <key1> <key2> <key3> OP_3 OP_CHECKMULTISIG
52 es OP_2 (se requieren dos firmas), cada 21 inserta una clave de 33 bytes en la pila, 53 es OP_3 y ae es OP_CHECKMULTISIG. Un gasto revela el umbral, las tres claves públicas y cuáles dos firmaron. Los custodios suelen aplicar políticas distintivas (2 de 3, 3 de 5), y la aparición de la misma clave pública en muchos scripts multifirma vincula esas direcciones con un mismo titular de clave de forma mucho más fiable que las heurísticas de comportamiento. Muchas billeteras ordenan las claves lexicográficamente (BIP 67), lo que constituye en sí mismo una pequeña huella.
Taproot
Taproot combina firmas Schnorr con claves de 32 bytes «solo x» (BIP 340), una clave de salida Q = P + t·G donde P es una clave interna y el ajuste t se compromete criptográficamente con P y con la raíz de Merkle de un árbol de scripts opcional (BIP 341), y reglas de scripts que sustituyen OP_CHECKMULTISIG por OP_CHECKSIGADD (BIP 342).
| Gasto | Testigo | Qué averigua un analista |
|---|---|---|
| Multifirma P2WSH de 2 de 3 | Dos firmas más el script completo | Umbral, todas las claves, qué claves firmaron |
| Ruta de clave de P2TR | Una firma de 64 bytes (65 con sighash explícito) | Nada sobre la política |
| Ruta de script de P2TR | Script de la hoja, sus entradas, bloque de control de 33 + 32m bytes | La única condición utilizada, su profundidad m, la clave interna |
En la ruta de clave, una billetera de una sola clave, un grupo de n de n que utiliza agregación de claves (MuSig2) y un esquema de umbral tienen el mismo aspecto. La ruta de script revela solo la hoja utilizada, aunque la longitud de la ruta de Merkle filtra algo de información sobre el tamaño del árbol. Taproot elimina la huella de la multifirma siempre que se utiliza la ruta de clave; no oculta los importes, el grafo ni los tiempos, y el propio formato bc1p sigue distinguiendo a sus usuarios. Los gastos por ruta de script también contienen inscripciones: desde 2023, testigos grandes con una envoltura OP_FALSE OP_IF … OP_ENDIF incorporan imágenes y datos de tokens, un patrón que debe excluirse del análisis de pagos mediante filtros.
Enfoque del examen: prepárese para decodificar o clasificar, no solo para recordar: orden y tamaños de los campos, valores little-endian y CompactSize; outpoints y orden invertido de los bytes del txid; plantillas de scriptPubKey, BIP, prefijos y longitudes (1,3,bc1qde 42 y 62,bc1pde 62); bytes de versión de Base58Check y bech32 frente a bech32m; que las direcciones, los importes de las entradas y las comisiones se derivan, no se almacenan; cálculos de peso y vsize; comisión a partir de las salidas anteriores; txid frente a wtxid y maleabilidad; cómo se resuelve la ambigüedad de un P2SH al gastarlo, qué revela un gasto multifirma y qué ocultan los gastos de Taproot por ruta de clave y por ruta de script.