Files
guides/es/bitcoin-03-tecnico.md
T
2026-05-25 16:46:23 +02:00

101 KiB
Raw Blame History

Bitcoin — Parte 3: Técnico

Hecho desde la comunidad, para la comunidad hispanohablante Bitcoin Txoko


Índice

  ▶ PARTE 3 — TÉCNICO
  ────────────────────────────────────────────────

  01  Transacciones en profundidad .......... 7
      estructura raw · sighash · TXID · vbytes

  02  Scripts ............................... 19
      pila · P2PKH · P2SH · P2TR · OP_CHECKSIGADD

  03  Claves y direcciones .................. 31
      secp256k1 · ECDSA · Schnorr · HD wallets · paths

  04  Bloques en profundidad ................ 45
      cabecera · version bits · bits · merkle · nonce

  05  Mining técnico ........................ 57
      candidato · ancestor feerate · coinbase · Stratum V2

  06  La cadena de bloques técnico .......... 69
      reorganizaciones · 51% · soft fork · UASF · BIPs

  07  SegWit ................................ 81
      maleabilidad · witness · BIP143 · wTXID · guerra

  08  Taproot ............................... 95
      Schnorr · MAST · clave modificada · tapscript · activación

  09  La red ................................ 109
      mensajes · handshake · propagación · compact blocks · Tor

  ────────────────────────────────────────────────
  Glosario .................................. 123
  Preguntas frecuentes ...................... 137
  Recursos .................................. 149

Capítulo 1 — Transacciones en profundidad

Nivel: Técnico


Una transacción es datos

En la Parte 1 vimos qué hace una transacción — mover bitcoin de una dirección a otra. Ahora vamos a ver qué es exactamente por dentro.

Una transacción es una cadena de bytes. Nada más. Sin magia, sin formato propietario. Cualquier ordenador que entienda el protocolo puede leerla, verificarla y propagarla.

  ┌─────────────────────────────────────────────────┐
  │  TRANSACCIÓN                                    │
  ├─────────────────────────────────────────────────┤
  │  versión        4 bytes   little-endian         │
  ├─────────────────────────────────────────────────┤
  │  [marker]       1 byte    0x00 (solo SegWit)    │
  │  [flag]         1 byte    0x01 (solo SegWit)    │
  ├─────────────────────────────────────────────────┤
  │  nº inputs      variable  compact size          │
  │  input_0        variable                        │
  │  input_1        variable                        │
  ├─────────────────────────────────────────────────┤
  │  nº outputs     variable  compact size          │
  │  output_0       variable                        │
  │  output_1       variable                        │
  ├─────────────────────────────────────────────────┤
  │  [witness]      variable  (solo SegWit)         │
  ├─────────────────────────────────────────────────┤
  │  locktime       4 bytes   little-endian         │
  └─────────────────────────────────────────────────┘
  campos en [ ] solo presentes en transacciones SegWit

Una transacción real, campo a campo

Aquí una transacción legacy real descompuesta en sus bytes:

  01000000   ← versión (1, little-endian)
  01         ← número de inputs (1)

  ── INPUT ──────────────────────────────────────
  9945a5a4...78 01000000  ← TXID (32 bytes, byte order natural)
                          ← VOUT (4 bytes, little-endian): output 1
  6a         ← tamaño del ScriptSig (106 bytes)
  47304402...ac  ← ScriptSig (firma + clave pública)
  fdffffff   ← sequence

  ── OUTPUTS ─────────────────────────────────────
  02         ← número de outputs (2)

  e99e060000000000  ← amount output 0 (453.241 sats, little-endian)
  19         ← tamaño del ScriptPubKey (25 bytes)
  76a914...88ac  ← ScriptPubKey (P2PKH)

  0046c32300000000  ← amount output 1 (little-endian)
  19         ← tamaño del ScriptPubKey
  76a914...88ac  ← ScriptPubKey (P2PKH)

  00000000   ← locktime (0, sin restricción)

Todo lo que Bitcoin hace — mover valor, establecer condiciones, probar propiedad — está codificado en esa secuencia de bytes. No hay nada más.


El input por dentro

  ┌─────────────────────────────────────────────────┐
  │  INPUT                                          │
  ├─────────────────────────────────────────────────┤
  │  TXID       32 bytes  natural byte order        │
  │  VOUT        4 bytes  little-endian             │
  │  ScriptSig  variable  compact size + script     │
  │  Sequence    4 bytes  little-endian             │
  └─────────────────────────────────────────────────┘

  TXID + VOUT = puntero único a un output concreto
  en toda la blockchain

Un detalle importante: el TXID se almacena en natural byte order — el mismo orden en que aparece en exploradores de bloques. Es una excepción al little-endian que usa el resto de campos.

El campo Sequence tiene dos usos. Si vale 0xFFFFFFFD o menos, señaliza que la transacción puede ser reemplazada por otra con fee más alta — esto es RBF. Con versión 2 de transacción, los valores bajos de sequence activan timelocks relativos — el output no puede gastarse hasta que hayan pasado N bloques desde que fue minado.


El output por dentro

  ┌─────────────────────────────────────────────────┐
  │  OUTPUT                                         │
  ├─────────────────────────────────────────────────┤
  │  Amount       8 bytes  little-endian (satoshis) │
  │  ScriptPubKey variable compact size + script    │
  └─────────────────────────────────────────────────┘

El Amount se expresa siempre en satoshis — nunca en BTC. 1 BTC se almacena como 00e1f50500000000 en little-endian. Amount igual a cero es válido — se usa en outputs OP_RETURN para incrustar datos en la blockchain sin mover valor.


Cómo se firma una transacción

Firmar una transacción es lo que prueba que tienes derecho a gastar un output. El proceso tiene más pasos de lo que parece.

Para firmar, el nodo no usa la transacción tal como está. Construye una versión especial para el hash que se va a firmar — el sighash. En el caso más común (SIGHASH_ALL):

  1. toma la transacción completa
  2. vacía todos los ScriptSig de todos los inputs
  3. pone el ScriptPubKey del output que se va a gastar
     en el ScriptSig del input que se está firmando
  4. añade el sighash type (01000000 para SIGHASH_ALL)
  5. SHA256(SHA256(resultado)) → hash a firmar
  6. ECDSA(clave privada, hash) → firma (r, s)
  7. codifica en DER + append del sighash type byte
  SIGHASH_ALL (01)      firma todos los inputs y outputs
                        la tx completa no puede modificarse

  SIGHASH_NONE (02)     firma inputs · no firma outputs
                        cualquiera puede añadir outputs

  SIGHASH_SINGLE (03)   firma inputs · solo firma output
                        con mismo índice que el input

  SIGHASH_ANYONECANPAY  puede combinarse con los anteriores
  (bit 0x80)            solo firma el propio input
                        otros pueden añadir más inputs

El tipo más común es SIGHASH_ALL. Los otros tipos permiten construcciones más complejas — transacciones donde múltiples personas firman independientemente, o donde el destino queda abierto.


El TXID y el wTXID

  TXID:
  SHA256(SHA256(
    versión + inputs(con ScriptSig) + outputs + locktime
  ))
  → witness NO entra en el cálculo
  → modificar witness no cambia el TXID ← eso resuelve SegWit

  wTXID:
  SHA256(SHA256(
    versión + marker + flag + inputs + outputs + witness + locktime
  ))
  → incluye todos los campos
  → usado para el merkle root del witness commitment
    en la coinbase transaction

La distinción entre TXID y wTXID no es solo técnica. Es la base sobre la que se construye Lightning Network — los canales necesitan TXIDs estables para poder referenciar transacciones de compromiso que todavía no han sido publicadas.


Tamaño, peso y vbytes

Una transacción tiene tres medidas de tamaño distintas y las tres aparecen en exploradores de bloques:

  BYTES      tamaño raw en disco · todos los bytes × 1

  WEIGHT     bytes normales × 4
             bytes de witness × 1
             límite del bloque: 4.000.000 wu

  VBYTES     weight / 4
             usado para comparar fees entre txs legacy y SegWit
             fee rate se expresa en sat/vbyte

  ejemplo transacción P2WPKH típica:
  ┌─────────────────────────────────────────┐
  │ 116 bytes no-witness × 4  = 464 wu      │
  │ 110 bytes witness    × 1 = 110 wu       │
  │ total weight              = 574 wu      │
  │ vbytes                    = 143,5 vb    │
  └─────────────────────────────────────────┘
  misma transacción en legacy: ~190 bytes = 760 wu
  SegWit es ~25% más eficiente en términos de peso

Locktime

  locktime = 0              puede minarse en cualquier bloque
  locktime < 500.000.000    altura de bloque mínima para minar
  locktime ≥ 500.000.000    timestamp Unix mínimo para minar

  condición adicional: al menos un input debe tener
  sequence < 0xFFFFFFFE
  si todos los inputs tienen sequence = 0xFFFFFFFF
  el locktime se ignora

  como un cheque posfechado:
  válido · firmado · pero no cobrable hasta la fecha indicada

Verifica tú mismo

Entra en learnmeabitcoin.com/tools/transaction-decoder y pega cualquier transacción en raw. Verás cada campo desglosado y etiquetado con su valor decodificado.

Para obtener una transacción en raw desde tu propio nodo:

bitcoin-cli getrawtransaction [TXID] true

Busca en el output el campo hex — esa es la transacción en bytes crudos. Luego decódificala en el explorador y relaciona cada fragmento hexadecimal con su campo correspondiente.


Resumen

Una transacción es una secuencia precisa de bytes: versión, inputs, outputs, witness opcional y locktime. Cada input referencia un output anterior con TXID y VOUT. Firmar requiere construir un sighash — una versión especial de la transacción que se hashea y firma con ECDSA. El TXID excluye el witness, lo que hace los identificadores estables ante modificaciones de firma. El tamaño en vbytes aplica el descuento del witness para calcular fees de forma uniforme.

Una transacción no es una orden a ningún banco. Es un dato matemáticamente válido que cualquier nodo del mundo puede verificar de forma completamente independiente.


Los inputs y outputs tienen scripts — código que define las condiciones de gasto. Entender esos scripts es entender cómo Bitcoin bloquea y desbloquea el valor.


Capítulo 2 — Scripts

Nivel: Técnico


Bitcoin no transfiere monedas

Bitcoin no mueve monedas de una dirección a otra. Lo que hace es resolver un problema y crear uno nuevo.

Cada output lleva un candado — un ScriptPubKey que define las condiciones para poder gastarlo. Gastar ese output significa aportar el ScriptSig o datos witness que satisfacen esas condiciones.

  OUTPUT (candado)              INPUT (llave)
  ┌────────────────┐            ┌────────────────┐
  │  ScriptPubKey  │            │  ScriptSig /   │
  │                │            │  Witness       │
  │  condiciones   │◀──cumple───│  datos para    │
  │  de gasto      │            │  desbloquear   │
  └────────────────┘            └────────────────┘

  nodo ejecuta ScriptSig + ScriptPubKey
  si el resultado deja TRUE en la pila → válido

Script: un lenguaje de pila

Script es el lenguaje de programación de Bitcoin. Opera sobre una pila — una estructura de datos donde los elementos se apilan y se sacan en orden inverso (LIFO). Cada opcode empuja datos o ejecuta una operación sobre los elementos de la pila.

Es deliberadamente limitado — no tiene bucles, no es Turing completo. Eso lo hace predecible y verificable en tiempo constante.

  pila vacía  →  empuja datos  →  ejecuta opcode  →  resultado

  [ ]  →  [firma] [pubkey]  →  OP_CHECKSIG  →  [TRUE]
                                                  ↑
                                           output desbloqueado

P2PKH: ejecución paso a paso

P2PKHPay to Public Key Hash — es el script detrás de las direcciones 1.... Ver su ejecución completa es entender cómo funciona Script.

  ScriptSig:    [firma] [clave pública]
  ScriptPubKey: OP_DUP OP_HASH160 [hash160] OP_EQUALVERIFY OP_CHECKSIG

  ejecución:
  ┌────────────────────────────────────────────────────┐
  │ inicio:      pila = [ ]                            │
  │              ScriptSig empuja datos:               │
  │              pila = [firma] [pubkey]               │
  │                                                    │
  │ OP_DUP:      duplica el tope                       │
  │              pila = [firma] [pubkey] [pubkey]      │
  │                                                    │
  │ OP_HASH160:  SHA256 + RIPEMD160 del tope           │
  │              pila = [firma] [pubkey] [hash(pubkey)]│
  │                                                    │
  │ [hash160]:   empuja el hash del ScriptPubKey       │
  │              pila = [firma] [pubkey] [hash(pk)]    │
  │                              [hash esperado]       │
  │                                                    │
  │ OP_EQUALVERIFY: compara los dos topes              │
  │              si no coinciden → fallo inmediato     │
  │              pila = [firma] [pubkey]               │
  │                                                    │
  │ OP_CHECKSIG: verifica firma contra pubkey          │
  │              pila = [TRUE]                         │
  └────────────────────────────────────────────────────┘
  resultado: TRUE → output desbloqueado

Comparativa de scripts estándar

  tipo      ScriptPubKey                          unlock via
  ──────────────────────────────────────────────────────────
  P2PK      [pubkey] OP_CHECKSIG                  ScriptSig
  P2PKH     OP_DUP OP_HASH160 <20b> OP_EQ...     ScriptSig
  P2MS      OP_M [pubkeys] OP_N OP_CHECKMULTISIG  ScriptSig
  P2SH      OP_HASH160 <20b> OP_EQUAL             ScriptSig
  P2WPKH    OP_0 <20b>                            Witness
  P2WSH     OP_0 <32b>                            Witness
  P2TR      OP_1 <32b>                            Witness
  OP_RETURN OP_RETURN <datos>                     no gastable

P2SH: el script que esconde scripts

P2SH resuelve un problema de tamaño. Antes de P2SH, un multisig 2-de-3 requería que quien pagara incluyera las tres claves públicas en el ScriptPubKey — caro para el remitente, visible para todos.

Con P2SH, el output solo guarda el hash del script. El script real se revela al gastar.

  CREAR OUTPUT:
  redeemScript = OP_2 [pubkey1] [pubkey2] [pubkey3] OP_3 OP_CHECKMULTISIG
  ScriptPubKey = OP_HASH160 hash160(redeemScript) OP_EQUAL
  → 23 bytes · complejidad invisible hasta el gasto

  GASTAR:
  ScriptSig = OP_0 [firma1] [firma2] [redeemScript]
  → se revela el script · se verifica hash · se ejecuta

  ventaja: quien crea el output no paga por la complejidad
  coste lo asume quien gasta

P2MS y el bug de OP_CHECKMULTISIG

El multisig legacy tiene un bug histórico. OP_CHECKMULTISIG extrae un elemento más de la pila de lo necesario — un error off-by-one que Satoshi nunca corrigió para no romper compatibilidad.

  ScriptSig correcto para 2-de-3:
  OP_0 [firma1] [firma2]
    ↑
    dummy value obligatorio
    OP_CHECKMULTISIG lo consume pero no lo usa
    si no está → fallo de script

Este bug tiene implicaciones de privacidad: todo multisig legacy es identificable en la blockchain. Taproot lo resuelve por completo.


P2TR: dos caminos de gasto

P2TR es el script más flexible de Bitcoin. Un output P2TR puede gastarse de dos formas completamente distintas — y la elección del camino no es visible desde fuera hasta que se gasta.

  ScriptPubKey: OP_1 [tweaked pubkey 32 bytes]

  ┌─────────────────────────────────────────────────┐
  │  KEY PATH SPEND          SCRIPT PATH SPEND      │
  │                                                 │
  │  witness:                witness:               │
  │  [firma Schnorr]         [script inputs]        │
  │  (64 bytes)              [leaf script]          │
  │                          [control block]        │
  │                                                 │
  │  1 elemento              3+ elementos           │
  │  indistinguible de       revela el script usado │
  │  pago simple             otros scripts ocultos  │
  └─────────────────────────────────────────────────┘

  el nodo decide qué path usar
  según cuántos elementos hay en el witness

El key path es el caso ideal — una firma Schnorr de 64 bytes, sin revelar ninguna condición adicional. Un canal Lightning cerrado cooperativamente, un multisig donde todos están de acuerdo, un contrato que expira bien — todo se ve igual desde fuera.

El script path se usa cuando el key path no es posible — disputa en un canal, timeout de un contrato, condición alternativa. Revela el script usado pero mantiene ocultos todos los demás.


OP_CHECKSIGADD: multisig nativo en Taproot

El multisig legacy usa OP_CHECKMULTISIG con su bug histórico. Taproot introduce OP_CHECKSIGADD — una forma limpia de construir multisig sin bugs y más eficiente.

  MULTISIG LEGACY (P2MS / P2SH)
  OP_2 [key1] [key2] [key3] OP_3 OP_CHECKMULTISIG
  → bug del dummy value
  → identifica multisig en la blockchain
  → todas las claves visibles al gastar

  MULTISIG TAPROOT (tapscript con OP_CHECKSIGADD)
  [key1] OP_CHECKSIG
  [key2] OP_CHECKSIGADD
  [key3] OP_CHECKSIGADD
  OP_2 OP_EQUAL

  ejecución para 2-de-3 con [sig1] [sig3]:
  key1 OP_CHECKSIG    → válida → [1]
  key2 OP_CHECKSIGADD → inválida → [1]
  key3 OP_CHECKSIGADD → válida → [2]
  OP_2 OP_EQUAL → 2 = 2 → TRUE

La ventaja sobre el legacy: sin dummy value, sin bug, las firmas ausentes son ignoradas en orden. Y si se usa vía key path con agregación de firmas Schnorr, el multisig es completamente invisible desde fuera.


Verifica tú mismo

Entra en mempool.space y busca cualquier transacción reciente. Haz clic sobre cualquier output y verás su ScriptPubKey. Identifica el tipo por su patrón:

  OP_DUP OP_HASH160 ...     → P2PKH  (dirección 1...)
  OP_HASH160 ... OP_EQUAL   → P2SH   (dirección 3...)
  OP_0 + 20 bytes           → P2WPKH (dirección bc1q... corta)
  OP_0 + 32 bytes           → P2WSH  (dirección bc1q... larga)
  OP_1 + 32 bytes           → P2TR   (dirección bc1p...)
  OP_RETURN                 → datos  (no gastable)

Para ver un script path spend de Taproot en acción busca la transacción 797505b104b5fb840931c115ea35d445eb1f64c9279bf23aa5bb4c3d779da0c2 — verás el witness con tres elementos: script inputs, leaf script y control block.


Resumen

Script es un lenguaje de pila que define las condiciones de gasto en Bitcoin. P2PKH evalúa hash de clave y verifica firma. P2SH oculta la complejidad hasta el gasto. P2TR ofrece dos caminos: key path con firma Schnorr invisible, o script path que revela solo la condición usada. OP_CHECKSIGADD reemplaza el multisig legacy sin sus bugs históricos.

Bitcoin no sabe quién eres. Solo sabe si has resuelto el puzzle. Y cuanto más sofisticado es el puzzle, menos revela quién lo resolvió.


Los scripts de bloqueo usan claves públicas y sus hashes. Pero ¿cómo se generan esas claves? ¿Qué matemáticas hay detrás y cómo se organizan en un árbol de derivación?


Capítulo 3 — Claves y direcciones

Nivel: Técnico


Todo empieza con un número aleatorio

Una clave privada es un número entre 1 y 2²⁵⁶ — generado en tu dispositivo, sin servidor, sin registro. El espacio de claves es tan grande que generar la misma clave dos veces es astronómicamente improbable.

Ejemplo de clave privada en hexadecimal:
ef235aacf90d9f4aadd8c92e4b2562e1d9eb97f0df9ba3b508258739cb013db2

La curva elíptica secp256k1

La clave pública se deriva multiplicando la clave privada por el punto generador G de la curva secp256k1 — definida por y² = x³ + 7.

  clave privada k  →  clave pública P = k × G

  k × G no es multiplicación aritmética ordinaria
  es adición repetida de un punto sobre la curva elíptica

  dado P, calcular k es el problema del logaritmo discreto
  computacionalmente inviable con los medios actuales

La clave pública es un punto (x, y) en la curva. En formato comprimido se almacena solo la coordenada x más un prefijo que indica la paridad de y:

  punto en la curva:   (x, y)

  y par:   02 + x (32 bytes) = 33 bytes total
  y impar: 03 + x (32 bytes) = 33 bytes total

  la coordenada y se puede recalcular desde x
  → no hace falta almacenarla completa

Pipeline completo de derivación de dirección

  clave privada (32 bytes)
        │ k × G  (multiplicación en curva elíptica)
        ▼
  clave pública comprimida (33 bytes)
        │ SHA256
        ▼
  hash intermedio (32 bytes)
        │ RIPEMD160
        ▼
  hash160 de clave pública (20 bytes)   ← HASH160
        │
        │ según tipo de dirección:
        ├── P2PKH:  versión 0x00 + hash160 → Base58Check → 1...
        ├── P2SH:   versión 0x05 + hash160 → Base58Check → 3...
        ├── P2WPKH: OP_0 + hash160         → Bech32      → bc1q... (corta)
        └── P2TR:   OP_1 + x-only pubkey   → Bech32m     → bc1p...

P2TR es la excepción — no usa el hash de la clave pública sino la clave pública directamente en formato x-only de 32 bytes, ya modificada con el tweak de Taproot.


Firmas ECDSA

  FIRMAR
  ┌────────────────────────────────────────┐
  │  inputs:  clave privada k              │
  │           hash de la tx H             │
  │           nonce aleatorio r (secreto) │
  │                                        │
  │  r = (r × G).x mod n                  │
  │  s = r⁻¹ × (H + k × r) mod n         │
  │                                        │
  │  output: firma (r, s) en formato DER  │
  └────────────────────────────────────────┘

  VERIFICAR
  ┌────────────────────────────────────────┐
  │  inputs:  clave pública P              │
  │           hash de la tx H             │
  │           firma (r, s)                │
  │                                        │
  │  u1 = H × s⁻¹ mod n                  │
  │  u2 = r × s⁻¹ mod n                  │
  │  punto = u1 × G + u2 × P             │
  │                                        │
  │  válido si punto.x mod n = r          │
  └────────────────────────────────────────┘
  la clave privada nunca sale del dispositivo
  cualquier nodo verifica con la clave pública

El nonce r debe ser diferente en cada firma. Si se reutiliza el mismo nonce para dos transacciones distintas, la clave privada queda expuesta matemáticamente. Es una de las vulnerabilidades más graves en la práctica.


Schnorr: lineal y agregable

Taproot introduce firmas Schnorr como alternativa a ECDSA. La diferencia clave es la linealidad — varias firmas pueden combinarse matemáticamente en una sola.

  ECDSA (r, s):  no lineal · no agregable · 71-72 bytes DER
  Schnorr (R, s): lineal · agregable · 64 bytes

  agregación Schnorr para multisig:
  claves:   P1, P2, P3
  nonces:   R1, R2, R3  →  R = R1 + R2 + R3
  firmas:   s1, s2, s3  →  s = s1 + s2 + s3

  resultado: una firma (R, s) de 64 bytes
  indistinguible de un pago simple de una sola persona

HD wallets: un árbol de claves desde una semilla

Una HD wallet (Hierarchical Deterministic) deriva todas sus claves desde una única semilla maestra. La semilla se genera desde la seed phrase mediante PBKDF2, y desde ella se deriva la clave maestra con HMAC-SHA512.

  seed phrase (12/24 palabras)
        │ PBKDF2 (2048 iteraciones)
        ▼
  seed (512 bits)
        │ HMAC-SHA512
        ▼
  clave maestra privada (m) + chain code
        │
        │ derivación de hijos
        ▼
  árbol de claves extendidas (xprv/xpub)

Cada clave extendida tiene dos variantes: privada (xprv) para firmar, pública (xpub) para derivar direcciones de recepción sin exponer claves privadas. Eso permite, por ejemplo, generar todas las direcciones de recepción en un servidor sin poner las claves privadas en ese servidor.


Derivation paths: la dirección exacta de cada clave

La estructura estándar, definida por BIP44, es:

  m / purpose' / coin_type' / account' / change / index

  cada segmento:
  m           clave maestra
  purpose'    esquema de derivación (hardened)
  coin_type'  tipo de moneda (hardened)
  account'    cuenta separada (hardened)
  change      0 = recepción · 1 = cambio (normal)
  index       índice de la dirección (normal, empieza en 0)

  ' = hijo hardened (índice + 2.147.483.648)
    solo derivable desde clave privada
    protege la clave maestra si un xpub se compromete

Los paths estándar para Bitcoin según tipo de dirección:

  BIP44  m/44'/0'/0'/0/0  →  P2PKH      dirección 1...
  BIP49  m/49'/0'/0'/0/0  →  P2SH-P2WPKH dirección 3...
  BIP84  m/84'/0'/0'/0/0  →  P2WPKH     dirección bc1q...
  BIP86  m/86'/0'/0'/0/0  →  P2TR       dirección bc1p...

Un path anotado carácter a carácter

  m / 84' / 0' / 0' / 0 / 5

  m    → clave maestra privada
  84'  → purpose: BIP84 (P2WPKH, bc1q)
         hardened: solo derivable con clave privada
  0'   → coin type: Bitcoin mainnet
         hardened
  0'   → cuenta número 0
         hardened · "pot" separado de fondos
  0    → external chain (recepción)
         normal: xpub puede derivar estas claves
         (útil para watch-only wallets)
  5    → sexta dirección generada (índice empieza en 0)
         la que se entrega al pagador

Si el índice change fuera 1 en lugar de 0, sería la sexta dirección de cambio — la que la wallet usa para devolverte el cambio de tus propias transacciones.


Gap limit

Las wallets no derivan claves infinitamente. Siguen el gap limit — por defecto 20 direcciones consecutivas sin uso. Si al escanear la blockchain las 20 siguientes direcciones están vacías, la wallet asume que no hay más fondos en esa rama.

  índices:  0  1  2  3  4  5  6  7  ...  25  26
  uso:      ✓  ✓  ✗  ✓  ✗  ✗  ✗  ✗  ...  ✗   ✗

  gap de 20 consecutivas sin uso → wallet detiene la búsqueda
  si saltaste índices al generar claves manualmente
  → fondos en índices > gap pueden no aparecer al recuperar

Verifica tú mismo

Entra en iancoleman.io/bip39 — sin conexión a internet — y genera una seed phrase de prueba. Cambia el path a m/84'/0'/0' y observa cómo se derivan las claves y direcciones bc1q. Cambia el índice de change de 0 a 1 y observa cómo aparecen las direcciones de cambio.

Luego prueba m/86'/0'/0' para ver las direcciones Taproot bc1p derivadas del mismo seed.


Resumen

La clave privada es un número aleatorio. La clave pública es un punto en secp256k1. ECDSA firma con clave privada y verifica con clave pública — el nonce nunca debe repetirse. Schnorr permite agregar firmas en una sola. Las HD wallets derivan todo desde una semilla mediante árboles de claves extendidas. Los derivation paths son la dirección exacta de cada clave en ese árbol — purpose, coin, account, change e index.

La seed phrase no es una contraseña. Es una llave maestra que genera un universo de claves. Entender su estructura es entender exactamente qué se pierde cuando se pierde.


Las claves y sus derivaciones definen quién puede gastar qué. Esos gastos se agrupan en bloques. ¿Qué hay exactamente dentro de un bloque a nivel técnico?


Capítulo 4 — Bloques en profundidad

Nivel: Técnico


Un bloque es una cabecera y una lista de transacciones

  ┌─────────────────────────────────────────────────┐
  │  CABECERA DE BLOQUE (80 bytes exactos)          │
  ├──────────────┬──────────────────────────────────┤
  │  versión     │  4 bytes  little-endian          │
  │  prev block  │ 32 bytes  natural byte order     │
  │  merkle root │ 32 bytes  natural byte order     │
  │  time        │  4 bytes  little-endian          │
  │  bits        │  4 bytes  little-endian          │
  │  nonce       │  4 bytes  little-endian          │
  └──────────────┴──────────────────────────────────┘
  hash(cabecera) = SHA256(SHA256(80 bytes))
  debe ser < target para ser válido

Los 80 bytes exactos de la cabecera no son un detalle arbitrario. Los nodos ligeros (SPV) solo descargan cabeceras — 80 bytes por bloque en lugar de 1-2 MB. Con más de 880.000 bloques, eso es la diferencia entre ~70 MB y ~1,5 TB.


El campo versión y la señalización de soft forks

El campo versión empezó siendo un entero simple. Desde BIP9 en 2015 se interpreta como un campo de bits donde cada bit puede asignarse a una propuesta de upgrade diferente.

  versión en bits (32 bits):
  0b 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     │ │ │
     │ │ └── bits 0-28: señalización de upgrades
     │ └──── bit 29: reservado
     └────── bits 30-31: deben ser 001 (BIP9)

  0x20000000  versión por defecto · sin señalizar nada
  0x20000002  señalizando SegWit  (bit 1 activo)
  0x20000004  señalizando Taproot (bit 2 activo)

  los mineros también usan bits no asignados como extranonce
  → versiones "raras" en bloques recientes son normales

El campo bits: target en formato compacto

El campo bits es una representación compacta del target en 4 bytes. Su estructura:

  bits: 1705dd01  (ejemplo)
        ──┬─────
          │
  primer byte:  17 (hex) = 23 (decimal) = exponente
  siguientes 3: 05dd01 = coeficiente

  target = coeficiente × 256^(exponente - 3)
         = 0x05dd01 × 256^(23-3)
         = 0x05dd01 × 256^20
         = 000000000000000005dd01000000000000000000000000000000000000000000

  el hash del bloque debe ser menor que ese número
  → cuantos más ceros al inicio, más difícil

El target completo tiene 32 bytes pero el campo bits solo almacena 4 — pierde precisión. Esa pérdida de precisión es deliberada e irrelevante en la práctica: la diferencia entre el target exacto y el aproximado es mínima comparada con el espacio de búsqueda de hashes.


El árbol de Merkle

El merkle root resume todas las transacciones del bloque en 32 bytes. Su construcción:

  transacciones:    tx_A   tx_B   tx_C   tx_D

  nivel 1 (hojas):  H(A)   H(B)   H(C)   H(D)
                      │       │       │       │
  nivel 2:          H(AB)           H(CD)
                        │               │
  merkle root:             H(ABCD)

  si el número de txs es impar:
  el último hash se duplica antes de combinar
  H(CC) en lugar de un par faltante

Modificar cualquier transacción cambia su hash, lo que cambia el hash del nivel superior, lo que cambia el merkle root, lo que invalida la cabecera. La integridad de todas las transacciones queda comprometida en esos 32 bytes de la cabecera.


Prueba de Merkle para nodos ligeros

El árbol de Merkle tiene una segunda utilidad crucial: permite demostrar que una transacción concreta está en un bloque sin descargar todas las transacciones.

  ¿está tx_C en el bloque?

  solo necesitas:
  H(C) + H(D) + H(AB) + merkle root del bloque

  verificación:
  H(C) + H(D) → H(CD)
  H(AB) + H(CD) → H(ABCD)
  ¿H(ABCD) = merkle root de la cabecera? → SÍ

  datos transferidos: 3 hashes × 32 bytes = 96 bytes
  en lugar de descargar el bloque completo (~1 MB)

Esto es la base del SPV — Simplified Payment Verification — que usan las wallets móviles. Confían en los hashes de bloque sin verificar todas las transacciones.


Nonce y extranonce

El nonce es el campo que los mineros modifican para variar el hash de la cabecera sin tocar las transacciones.

  nonce: 4 bytes → 2^32 = 4.294.967.296 valores posibles

  hashrate actual de la red: ~800 EH/s
  = 800 × 10^18 hashes por segundo

  4.294.967.296 intentos se agotan en:
  4.294.967.296 / (800 × 10^18) ≈ 0,000000005 segundos

  el nonce se agota casi instantáneamente
  → necesidad del extranonce en la coinbase tx

  flujo cuando se agota el nonce:
  ┌──────────────────────────────────────┐
  │  1. nonce de 0 a 0xFFFFFFFF → agotado│
  │  2. incrementar extranonce           │
  │     en ScriptSig de coinbase tx      │
  │  3. cambia TXID de coinbase          │
  │  4. cambia merkle root               │
  │  5. nueva cabecera de 80 bytes       │
  │  6. nuevo espacio de 4.294.967.296   │
  └──────────────────────────────────────┘

El timestamp y sus límites

El campo time de la cabecera tiene reglas específicas que los nodos verifican:

  time válido:
  > mediana de los últimos 11 bloques (MTP)
  < tiempo del nodo + 2 horas

  no puede ser anterior a los 11 bloques previos
  no puede ser más de 2 horas en el futuro

  consecuencia: el timestamp de un bloque no es exacto
  puede estar hasta 2 horas adelantado
  puede retroceder respecto al bloque anterior
  solo la mediana de 11 bloques es confiable

Verifica tú mismo

Entra en mempool.space y busca cualquier bloque reciente. Haz clic en “Details” para ver la cabecera raw. Identifica los seis campos e intenta decodificar el campo bits — extrae el exponente (primer byte) y el coeficiente (siguientes 3 bytes) y calcula el target aproximado.

Busca también el bloque génesis — altura 0. Su campo previous block son 32 bytes de ceros. No hay nada antes que él.

Desde tu propio nodo:

bitcoin-cli getblockheader [hash] true

Resumen

Un bloque es una cabecera de 80 bytes más transacciones. El campo versión señaliza soft forks mediante bits individuales. El campo bits codifica el target en 4 bytes con el esquema exponente-coeficiente. El merkle root compromete todas las transacciones en 32 bytes y permite pruebas de inclusión eficientes para nodos ligeros. El nonce se agota casi instantáneamente — el extranonce en la coinbase es el mecanismo real de variación.

Un bloque válido es la prueba de que alguien gastó energía real buscando exactamente ese hash. Eso es lo que hace que falsificarlo sea prohibitivamente caro.


Sabemos cómo está estructurado un bloque. Lo que falta es ver cómo se construye uno desde cero — qué decisiones toma un minero antes de empezar a hacer hashes.


Capítulo 5 — Mining técnico

Nivel: Técnico


Antes de minar hay que construir

Un bloque candidato es el bloque que un minero intenta añadir a la blockchain. No hay un único bloque candidato que todos los mineros compartan — cada minero construye el suyo desde su propia mempool. Puede haber diferencias menores entre candidatos, pero la mayoría de transacciones se solapan.

  MEMPOOL (transacciones sin confirmar)
  ordenadas por ancestor feerate (sat/vbyte)
        │
        │ minero selecciona
        ▼
  ┌─────────────────────────────────────┐
  │  BLOQUE CANDIDATO                   │
  ├─────────────────────────────────────┤
  │  1. coinbase tx (recompensa)        │ ← siempre primera
  │  2. tx con ancestor feerate mayor   │
  │  3. siguiente por feerate           │
  │  ...                                │
  │  N. última tx que cabe              │ ← límite 4M weight units
  └─────────────────────────────────────┘
  padres siempre antes que hijos
  tx inválida en el bloque → bloque rechazado por la red

Ancestor feerate: el orden real de selección

Un minero no selecciona transacciones solo por su feerate individual. Si una transacción de fee baja tiene un hijo con fee muy alta, el minero las evalúa juntas — el ancestor feerate es la fee combinada de la transacción y todos sus ancestros pendientes dividida entre su tamaño combinado.

  tx_padre:  2 sat/vbyte · 100 vbytes · fee: 200 sats
  tx_hijo:   18 sat/vbyte · 100 vbytes · fee: 1800 sats

  ancestor feerate del hijo:
  (200 + 1800) / (100 + 100) = 10 sat/vbyte

  el minero los incluye juntos como paquete
  el hijo arrastra al padre aunque el padre tenga fee baja
  → técnica de fee bumping: CPFP (Child Pays For Parent)

La coinbase transaction por dentro

  ┌─────────────────────────────────────────────────┐
  │  COINBASE TX                                    │
  ├─────────────────────────────────────────────────┤
  │  INPUT:                                         │
  │    TXID: 0000...0000 (32 bytes ceros)           │
  │    VOUT: 0xFFFFFFFF  (índice especial)          │
  │    ScriptSig: altura de bloque (BIP34)          │
  │               + extranonce del minero           │
  │               + datos arbitrarios (hasta 100b)  │
  ├─────────────────────────────────────────────────┤
  │  OUTPUT principal:                              │
  │    subsidio: 3,125 BTC (tras halving 2024)      │
  │    + suma de fees de todas las txs del bloque   │
  ├─────────────────────────────────────────────────┤
  │  OUTPUT witness commitment (SegWit):            │
  │    OP_RETURN + merkle root de wTXIDs            │
  └─────────────────────────────────────────────────┘
  única tx sin inputs reales · bitcoin creado desde cero
  no puede gastarse hasta 100 bloques después (coinbase maturity)

El output de witness commitment es obligatorio en bloques con transacciones SegWit — compromete todos los wTXIDs del bloque en un OP_RETURN de la coinbase, sellando los datos witness de todas las transacciones.


El cálculo del nuevo target

Cada 2016 bloques cada nodo recalcula el target de forma independiente:

  nuevo target = target actual × (tiempo real / tiempo esperado)

  tiempo esperado = 2016 bloques × 10 min = 20.160 minutos

  ejemplo:
  bloques minados en 12 días (17.280 min) en lugar de 14:
  nuevo target = target × (17.280 / 20.160)
               = target × 0,857
               → target más bajo → más difícil

  ejemplo contrario, minados en 16 días (23.040 min):
  nuevo target = target × (23.040 / 20.160)
               = target × 1,142
               → target más alto → más fácil

  límite de ajuste: máximo ×4 o ÷4 en un solo periodo
  evita oscilaciones bruscas si el hashrate cambia radicalmente

Todos los nodos calculan exactamente el mismo resultado porque comparten la misma blockchain. No hay coordinación — es aritmética determinista sobre datos compartidos.


Pool mining vs solo mining: la matemática real

  POOL MINING                    SOLO MINING
  ┌─────────────────────┐        ┌─────────────────────┐
  │ hashrate pool:      │        │ Bitaxe S21:         │
  │ ~100 EH/s           │        │ ~4 TH/s             │
  │                     │        │                     │
  │ bloque cada ~10 min │        │ prob. bloque/día:   │
  │ recompensa dividida │        │ 4×10¹²/             │
  │ entre participantes │        │ (800×10¹⁸ × 600)   │
  │ según hashrate      │        │ ≈ 1 en 120.000.000  │
  │ aportado            │        │ días (~330.000 años)│
  └─────────────────────┘        └─────────────────────┘
  ingresos predecibles           lotería matemáticamente justa
  varianza mínima                varianza máxima

La lotería es honesta porque cada hash tiene exactamente la misma probabilidad de ser válido independientemente de quién lo genere. El protocolo no discrimina por tamaño.


Stratum: el protocolo de los pools

Los pools se comunican con sus mineros mediante el protocolo Stratum. El pool distribuye trabajo a cada minero con un rango de nonces asignado — así miles de mineros pueden trabajar en paralelo sin repetir intentos.

  pool → minero:  "trabaja en este bloque candidato
                   con nonces en el rango X-Y"

  minero → pool:  "encontré un hash por debajo
                   del target del pool" (share)

  pool verifica el share → acumula trabajo del minero
  si algún share es válido para la red → bloque encontrado
  → recompensa distribuida proporcionalmente a shares aportados

El pool tiene su propio target más fácil que el de la red — así puede medir la contribución de cada minero aunque ninguno encuentre un bloque real. Los shares son la unidad de trabajo del pool.


Stratum V2: soberanía en la selección de transacciones

En el Stratum clásico, el pool decide qué transacciones entran en el bloque candidato. Los mineros solo hacen hashes — no controlan el contenido del bloque.

Stratum V2 cambia esto. Permite que el minero construya su propio bloque candidato con las transacciones que él elige, y solo use el pool para combinar hashrate y distribuir recompensas. Es un cambio relevante para la descentralización y la resistencia a la censura — un pool que quiera censurar transacciones ya no puede hacerlo si sus mineros usan Stratum V2 con selección propia.


Verifica tú mismo

Entra en mempool.space y observa el bloque candidato actual en la sección de mining. Verás las transacciones ordenadas por feerate y el peso total acumulado.

Desde tu propio nodo puedes construir un bloque candidato y ver exactamente qué transacciones seleccionaría:

bitcoin-cli getblocktemplate '{"rules": ["segwit"]}'

El resultado incluye la lista completa de transacciones candidatas, el target actual en hex, el valor del subsidio y el coinbase que debes construir.


Resumen

Un bloque candidato requiere coinbase tx válida, transacciones válidas ordenadas de padres a hijos, y peso total dentro del límite de 4M weight units. El orden de selección usa ancestor feerate — no feerate individual. El target se recalcula cada 2016 bloques con aritmética determinista. Los pools distribuyen trabajo mediante Stratum y miden contribuciones con shares. Stratum V2 devuelve la selección de transacciones al minero individual.

La minería no es solo encontrar un hash. Es construir el bloque correcto antes de empezar a buscarlo.


Los mineros añaden bloques. Pero ¿qué pasa cuando dos mineros encuentran un bloque válido casi al mismo tiempo, o cuando alguien con mucho hashrate intenta reescribir la historia?


Capítulo 6 — La cadena de bloques técnico

Nivel: Técnico


La cadena más larga gana

Todos los nodos siguen una regla simple: la cadena válida con más trabajo acumulado es la cadena correcta. No la más larga en número de bloques — la que representa más prueba de trabajo total.

  bloque 0 ── bloque 1 ── bloque 2 ── bloque 3 ── bloque 4
                                          │
                                     bloque 3'
                                     (descartado)

  bloque 3' puede tener un hash válido
  pero la cadena que construye sobre él
  tiene menos trabajo acumulado
  todos los nodos convergen hacia la cadena más larga

Reorganizaciones

Una reorganización ocurre cuando un nodo recibe una cadena alternativa con más trabajo acumulado que su cadena activa. El nodo descarta sus bloques actuales y adopta la nueva cadena.

  situación: dos bloques válidos minados casi simultáneamente

  nodo A:  ... ── bloque 99 ── [bloque 100a] ← adopta primero
  nodo B:  ... ── bloque 99 ── [bloque 100b] ← adopta primero

  se mina bloque 101 encima de 100a:

  cadena con 100a:  ... ── 99 ── 100a ── 101  (más larga)
  cadena con 100b:  ... ── 99 ── 100b          (descartada)

  nodo B reorganiza: descarta 100b · adopta 100a + 101
  txs en 100b que no estaban en 100a → vuelven a mempool

Las reorganizaciones naturales de un bloque ocurren aproximadamente cada 45 días. Las de más de un bloque son extremadamente raras en condiciones normales — señal casi segura de un ataque activo o un fallo grave.


El ataque del 51%: qué puede y qué no puede hacer

  CON 51% DEL HASHRATE PUEDES:
  ┌─────────────────────────────────────────────────┐
  │  · revertir transacciones propias recientes     │
  │    (doble gasto)                                │
  │  · excluir transacciones de tus bloques         │
  │    (censura temporal)                           │
  │  · ganar todas las recompensas de bloque        │
  │    durante el ataque                            │
  └─────────────────────────────────────────────────┘

  CON 51% DEL HASHRATE NO PUEDES:
  ┌─────────────────────────────────────────────────┐
  │  · crear bitcoin de la nada                     │
  │  · robar bitcoin de wallets ajenas              │
  │  · cambiar las reglas del protocolo             │
  │  · gastar outputs que no te pertenecen          │
  │  · alterar transacciones antiguas con           │
  │    muchas confirmaciones (coste prohibitivo)    │
  └─────────────────────────────────────────────────┘

Los nodos verifican las reglas del protocolo independientemente del hashrate. Un bloque con bitcoin creado de la nada o con una firma inválida es rechazado por todos los nodos aunque tenga un hash perfecto. El hashrate solo decide el orden de las transacciones — no su validez.


La matemática del doble gasto

La probabilidad de que un atacante con fracción q del hashrate consiga revertir una transacción con z confirmaciones decrece exponencialmente:

  q = fracción del hashrate del atacante
  z = número de confirmaciones a revertir

  q = 0.10 (10% hashrate):
  z=1  → probabilidad éxito: ~20%
  z=3  → ~1%
  z=6  → ~0.1%

  q = 0.30 (30% hashrate):
  z=1  → ~45%
  z=3  → ~18%
  z=6  → ~5%

  q = 0.40 (40% hashrate):
  z=5  → ~55%  ← todavía posible con menos del 51%

  con < 50% hashrate: posible pero requiere suerte
  con > 50% hashrate: es cuestión de tiempo
  nunca ha ocurrido en Bitcoin mainnet

Cuantas más confirmaciones tiene una transacción, más trabajo habría que rehacer para revertirla. Para transacciones con 6 confirmaciones y hashrate de red actual, el coste energético de un ataque exitoso sería de cientos de millones de dólares.


Soft fork vs hard fork: la diferencia técnica precisa

  HARD FORK                        SOFT FORK
  expande reglas                   restringe reglas
  (antes inválido → ahora válido)  (antes válido → ahora inválido)

  nodos sin actualizar:            nodos sin actualizar:
  rechazan nuevos bloques          aceptan nuevos bloques
  → cadena se divide               → siguen la cadena más larga

  ┌─────────────────────┐          ┌─────────────────────┐
  │ dos cadenas         │          │ una sola cadena      │
  │ incompatibles       │          │ compatible           │
  │ para siempre        │          │ nodos viejos siguen  │
  └─────────────────────┘          └─────────────────────┘

La distinción es más sutil de lo que parece. Un soft fork restringe lo que es válido — los nodos antiguos ven los nuevos bloques como válidos aunque no entiendan las nuevas restricciones. Un hard fork expande lo que es válido — los nodos antiguos ven bloques que violan sus reglas y los rechazan.

Todos los upgrades de Bitcoin hasta hoy han sido soft forks. El único hard fork conocido fue accidental — en 2013, un cambio de base de datos entre versiones creó una división temporal que se resolvió haciendo que los mineros retrocedieran a la versión anterior.


El proceso BIP y la activación

  1. propuesta  → BIP escrito · publicado en GitHub
                  discusión pública abierta

  2. implementación → código en Bitcoin Core
                      revisión por pares

  3. señalización → mineros activan bit en campo versión
                    BIP9: ventanas de 2016 bloques

  4. umbral     → 90-95% de bloques señalizando
                  en una ventana de tiempo

  5. lock-in    → upgrade comprometido para activarse
                  no puede revertirse

  6. activación → en altura de bloque específica
                  todos los nodos aplican las nuevas reglas

  SegWit (BIP141):  propuesto dic 2015 → activado ago 2017
  Taproot (BIP341): propuesto ene 2020 → activado nov 2021

UASF: cuando los usuarios toman el control

En 2017, durante la guerra de los bloques, un sector de la comunidad lanzó el movimiento UASFUser Activated Soft Fork. La idea: si los mineros no señalizaban SegWit, los nodos actualizados empezarían a rechazar bloques que no lo activaran a partir de una fecha determinada.

  mecanismo normal (MASF):
  mineros señalizan → umbral → lock-in → activación

  UASF:
  nodos anuncian fecha límite
  "a partir del bloque X solo aceptamos bloques SegWit"
  → mineros que no activan SegWit quedan fuera de la cadena válida
  → incentivo económico para activar

  resultado 2017: mineros cedieron antes de la fecha límite
  SegWit se activó · sin división de cadena

El UASF demostró empíricamente que el poder en Bitcoin no está en quien mina sino en quien verifica. Los nodos tienen la última palabra sobre qué cadena es válida — los mineros solo construyen bloques que esos nodos aceptarán o rechazarán.


Verifica tú mismo

Desde tu propio nodo puedes ver el historial de reorganizaciones que ha observado:

bitcoin-cli getchaintips

El resultado muestra todas las cadenas conocidas — la activa y los stale blocks que tu nodo ha visto. El campo branchlen indica cuántos bloques tiene cada rama alternativa.

Para seguir el estado de BIPs activos y propuestos: github.com/bitcoin/bips


Resumen

La cadena válida es siempre la de mayor trabajo acumulado. Las reorganizaciones naturales son infrecuentes y de un bloque. Un atacante con 51% puede revertir transacciones propias recientes pero no puede crear bitcoin, robar fondos ajenos ni cambiar las reglas del protocolo — eso lo deciden los nodos. Los soft forks restringen reglas y son compatibles hacia atrás. El UASF de 2017 demostró que los usuarios que ejecutan nodos tienen más poder que los mineros.

El hashrate decide el orden. Los nodos deciden las reglas. Esa distinción es la base de la descentralización real de Bitcoin.


Sabemos cómo se construyen y evolucionan los bloques. Queda una pieza fundamental: SegWit — la actualización que hizo posible Lightning Network y que sigue siendo la base de la mayoría de transacciones modernas.


Capítulo 7 — SegWit

Nivel: Técnico


Un problema que casi mata a Lightning antes de nacer

En 2015, Joseph Poon y Thaddeus Dryja publicaron el whitepaper de Lightning Network. La idea era brillante — pagos instantáneos off-chain usando la blockchain solo como árbitro de última instancia.

Pero había un problema que hacía Lightning matemáticamente imposible con el protocolo tal como existía en ese momento.


La maleabilidad de transacciones

Cada transacción tiene un TXID calculado hasheando todos sus datos — incluyendo las firmas en el ScriptSig. Las firmas ECDSA tienen una propiedad matemática incómoda: dado un par (r, s) válido, el par (r, -s mod n) también es válido para el mismo mensaje.

  firma original:    (r, s)
  firma modificada:  (r, -s mod n)

  ambas firmas son válidas para la misma transacción
  mismo efecto económico · bitcoin llega igual
  pero los datos de la tx son diferentes → TXID diferente

  TXID original:   aaa...
  TXID modificado: bbb...

  cualquier nodo intermedio podía modificar el ScriptSig
  antes de propagar la transacción
  sin invalidarla · pero cambiando su TXID

Para Lightning esto es fatal. Un canal requiere construir transacciones de compromiso que referencian el TXID de la transacción de financiación — que todavía no ha sido minada. Si ese TXID puede cambiar antes de ser minada, las transacciones de compromiso quedan invalidadas. Lightning era imposible.


La solución: segregar el testigo

SegWit resuelve la maleabilidad moviendo las firmas fuera del cuerpo principal de la transacción al campo witness — y excluyendo ese campo del cálculo del TXID.

  LEGACY                          SEGWIT
  ┌──────────────────────┐        ┌──────────────────────┐
  │ versión              │        │ versión              │
  │ inputs               │        │ marker 0x00          │
  │   ScriptSig [firma]  │        │ flag   0x01          │
  │ outputs              │        │ inputs               │
  │ locktime             │        │   ScriptSig vacío    │
  └──────────────────────┘        │ outputs              │
                                  │ witness [firma]      │
  TXID = hash(todo)               │ locktime             │
  firma dentro → TXID mutable     └──────────────────────┘

                                  TXID = hash(sin witness)
                                  firma fuera → TXID estable

Con el witness excluido del TXID, modificar la firma no cambia el identificador de la transacción. Lightning pasa de ser imposible a ser construible.


El nuevo sighash para SegWit: BIP143

SegWit también cambió cómo se calcula el sighash — los datos que se firman al gastar un output SegWit. El algoritmo legacy tenía un problema de escalado cuadrático: al firmar una transacción con N inputs, cada firma requería hashear la transacción completa N veces.

BIP143 introduce un nuevo algoritmo de sighash para P2WPKH y P2WSH que resuelve esto:

  LEGACY SIGHASH (O(n²)):
  para cada input a firmar:
    hashear toda la transacción modificada
    → con N inputs: N hasheados de tx completa

  BIP143 SIGHASH (O(n)):
  componentes precalculados una sola vez:
  · hash de todos los outpoints (TXID+VOUT)
  · hash de todas las sequences
  · hash de todos los outputs
  cada firma usa estos hashes precalculados
  → escala linealmente con el número de inputs

Para hardware wallets esto es especialmente importante — firmar transacciones grandes con el algoritmo legacy requería descargar y verificar la transacción completa múltiples veces. BIP143 lo hace eficiente.


El descuento del witness y el aumento efectivo de bloque

  datos normales:   1 byte = 4 weight units (wu)
  datos witness:    1 byte = 1 weight unit  (wu)
  límite del bloque: 4.000.000 wu

  transacción P2PKH típica (legacy):
  ┌──────────────────────────────────────────┐
  │ 150 bytes no-witness × 4  =  600 wu      │
  │ 106 bytes ScriptSig  × 4  =  424 wu      │
  │ total:                       1.024 wu    │
  └──────────────────────────────────────────┘

  transacción P2WPKH equivalente (SegWit):
  ┌──────────────────────────────────────────┐
  │ 150 bytes no-witness × 4  =  600 wu      │
  │ 107 bytes witness    × 1  =  107 wu      │
  │ total:                       707 wu      │
  └──────────────────────────────────────────┘
  ~31% más eficiente · fees ~31% más baratas

  aumento efectivo del bloque:
  un bloque típico es ~60% datos de firma
  400.000 bytes no-witness × 4 = 1.600.000 wu
  600.000 bytes witness    × 1 =   600.000 wu
  total:                         2.200.000 wu
  → caben 4.000.000 / 2.200.000 × 1 MB ≈ 1,8 MB de txs

SegWit no aumentó el límite de bloque a 4 MB. Aumentó la capacidad efectiva para transacciones típicas a aproximadamente 1,8 MB.


El wTXID y el witness commitment

Con el witness excluido del TXID surge un nuevo problema: alguien podría modificar los datos witness de una transacción ya minada sin cambiar su TXID.

La solución es el wTXID — un identificador que incluye todos los campos de la transacción, witness incluido:

  TXID  = SHA256(SHA256(versión + inputs + outputs + locktime))
  wTXID = SHA256(SHA256(versión + marker + flag +
                        inputs + outputs + witness + locktime))

  los mineros calculan un merkle root de todos los wTXIDs
  y lo incluyen en un output OP_RETURN de la coinbase tx
  → witness commitment

  si alguien modifica el witness de cualquier tx:
  su wTXID cambia → el merkle root de wTXIDs cambia
  → el witness commitment de la coinbase no coincide
  → bloque inválido

SegWit como soft fork

El truco que hizo posible implementar SegWit sin un hard fork es elegante. Para los nodos antiguos que no entienden SegWit, los nuevos scripts P2WPKH y P2WSH parecen outputs gastables por cualquiera — su ScriptPubKey tiene una estructura que los nodos legacy interpretan como siempre válida.

  P2WPKH ScriptPubKey: OP_0 <20 bytes>

  nodo legacy:  "OP_0 empuja datos · resultado no vacío · válido"
                acepta el bloque · no verifica el witness
                (no sabe que existe el campo witness)

  nodo SegWit:  "P2WPKH · verifica firma en el witness"
                aplica las reglas completas

  los nodos legacy siguen la cadena más larga
  que construyen los nodos actualizados
  sin saber que están siguiendo reglas nuevas

La guerra de los bloques

SegWit llegó en medio del conflicto más intenso de la historia de Bitcoin. Un sector — principalmente grandes mineros y algunas empresas — quería aumentar el límite de bloque directamente mediante hard fork. Otro defendía SegWit como solución técnicamente superior y compatible hacia atrás.

En agosto de 2017, después del UASF que forzó la mano de los mineros, SegWit se activó. Quienes no aceptaron el resultado lanzaron Bitcoin Cash — un hard fork con bloques de 8 MB.

Lo que reveló la guerra de los bloques. El conflicto demostró empíricamente algo que hasta entonces era solo teoría: los mineros no controlan Bitcoin. Cuando los grandes pools amenazaron con no activar SegWit, la comunidad respondió con el UASF — nodos que rechazarían bloques sin SegWit a partir de una fecha. Los mineros cedieron. El poder no está en quien mina. Está en quien verifica.


Verifica tú mismo

Busca en mempool.space cualquier transacción con dirección bc1q. En la vista de detalles observa el campo witness — verás las firmas completamente separadas del cuerpo de la transacción. Compara el campo size con el campo vsize — la diferencia es el descuento del witness aplicado.

Para ver el witness commitment en una coinbase transaction, busca cualquier bloque reciente, entra en la primera transacción y localiza el output OP_RETURN — contiene el merkle root de los wTXIDs de todas las transacciones del bloque.


Resumen

SegWit resolvió la maleabilidad de transacciones moviendo las firmas al campo witness y excluyéndolo del cálculo del TXID. Sin esa corrección Lightning era imposible. BIP143 introdujo un nuevo algoritmo de sighash que escala linealmente. El descuento del witness hace las transacciones ~31% más baratas y aumenta la capacidad efectiva del bloque a ~1,8 MB. El wTXID commitment protege los datos witness en la coinbase. Se implementó como soft fork sin romper compatibilidad.

A veces la solución más elegante es mover unas firmas de sitio. Lo que cambia cuando lo haces puede ser todo.


SegWit preparó el terreno. Taproot construyó encima — firmas más eficientes, privacidad mejorada, contratos complejos que se ven como pagos simples.


Capítulo 8 — Taproot

Nivel: Técnico


La pregunta que Taproot responde

Cuando Alice y Bob abren un canal Lightning y lo cierran cooperativamente, la transacción de cierre aparece en la blockchain como lo que es — una transacción multisig con datos de canal. Cualquier analista puede identificarla.

¿Y si esa transacción de cierre pudiera ser indistinguible de un pago ordinario de una sola persona? ¿Y si un multisig 2-de-3, un contrato con timelock, un canal Lightning — todos pudieran verse exactamente igual desde fuera cuando se resuelven de forma cooperativa?

Eso es Taproot.


Schnorr: la firma que ECDSA no podía ser

Las firmas Schnorr llevan más tiempo que ECDSA — fueron propuestas en 1990. Satoshi eligió ECDSA en 2009 porque las patentes de Schnorr no expiraron hasta 2008, demasiado tarde para incluirlo en el diseño original. Para 2021 esos problemas habían desaparecido.

La diferencia técnica clave es la linealidad:

  ECDSA (r, s):
  firma = función no lineal de clave privada + hash + nonce
  dos firmas NO pueden combinarse matemáticamente
  multisig requiere revelar todas las claves y firmas

  Schnorr (R, s):
  firma = nonce × G + clave privada × hash
  ecuación lineal → firmas son sumables

  agregación de claves y firmas:
  P_agg = P1 + P2 + P3          (suma de claves públicas)
  s_agg = s1 + s2 + s3          (suma de firmas parciales)
  R_agg = R1 + R2 + R3          (suma de nonces públicos)

  resultado: una firma (R_agg, s_agg) de 64 bytes
  verificable contra P_agg
  indistinguible de firma de una sola persona

Además las firmas Schnorr son más compactas — 64 bytes frente a los 71-72 bytes de DER de ECDSA. Y el byte de sighash type al final es opcional en Taproot, lo que ahorra otro byte en el caso más común.


MAST: ocultar lo que no usas

Antes de Taproot, P2SH y P2WSH revelaban el script completo al gastarlo — todas las condiciones, incluso las que no se usaron. Con MAST solo se revela la condición que se ejerció.

  contrato con tres condiciones:
  A: Alice firma sola (caso normal)
  B: Bob firma después de 30 días (timeout)
  C: Alice y Bob firman juntos (cooperativo)

  árbol de Merkle de scripts:
  ┌──────────────────────────────────────────────┐
  │              merkle root                     │
  │             /           \                    │
  │         H(AB)           H(C)                 │
  │        /     \                               │
  │      H(A)   H(B)                             │
  └──────────────────────────────────────────────┘

  si se usa condición A:
  witness revela: script_A + H(B) + H(C)
  → B y C permanecen ocultas para siempre
  → un observador externo no sabe que B y C existían

  si se usa condición C (cooperativa):
  → key path spend · solo una firma Schnorr
  → nadie sabe que A y B existían

La clave modificada: el corazón de Taproot

El mecanismo que une todo es la tweaked public key — una clave pública que parece ordinaria pero que contiene un compromiso con todos los scripts alternativos.

  clave interna: P  (tu clave pública normal)
  merkle root:   M  (hash raíz del árbol de scripts)

  tweak = hash_taptweak(P || M)
  clave modificada Q = P + tweak × G

  ┌─────────────────────────────────────────────────┐
  │  Q parece una clave pública normal de 32 bytes  │
  │  pero contiene un compromiso criptográfico      │
  │  con todos los scripts del árbol               │
  │  nadie sabe qué hay dentro hasta que se gasta   │
  └─────────────────────────────────────────────────┘

  ScriptPubKey P2TR: OP_1 [Q 32 bytes]
  dirección resultante: bc1p...

Si no hay scripts alternativos — solo quieres un pago simple — el merkle root es vacío y el tweak se aplica igualmente. El output sigue siendo P2TR pero sin MAST.


Key path vs script path: ejecución completa

  KEY PATH SPEND
  ┌─────────────────────────────────────────────────┐
  │  witness: [firma Schnorr 64 bytes]              │
  │                                                 │
  │  verificación:                                  │
  │  1. ¿un solo elemento en witness? → key path    │
  │  2. firma válida para Q (clave modificada)?     │
  │     → output desbloqueado                       │
  │                                                 │
  │  nota: el firmante usa la clave privada         │
  │  modificada internamente para firmar            │
  │  p_tweaked = p + tweak (mod n)                  │
  └─────────────────────────────────────────────────┘

  SCRIPT PATH SPEND
  ┌─────────────────────────────────────────────────┐
  │  witness: [script inputs] [leaf script]         │
  │           [control block]                       │
  │                                                 │
  │  verificación:                                  │
  │  1. ¿dos o más elementos? → script path         │
  │  2. extraer clave interna P del control block   │
  │  3. recalcular tweak desde P + merkle path      │
  │  4. reconstruir Q y verificar que coincide      │
  │     con el ScriptPubKey                         │
  │  5. ejecutar leaf script con script inputs      │
  │     → si TRUE → output desbloqueado             │
  └─────────────────────────────────────────────────┘

  el nodo decide qué path usar según
  cuántos elementos hay en el witness

Tapscript: Script con mejoras

Los scripts dentro de un Taproot script path spend usan tapscript — una variante de Script con algunas diferencias importantes:

  SCRIPT estándar vs TAPSCRIPT
  ┌───────────────────────────────────────────────┐
  │  OP_CHECKMULTISIG: eliminado en tapscript     │
  │  → sustituido por OP_CHECKSIGADD              │
  │                                               │
  │  OP_CHECKSIG en tapscript:                    │
  │  → usa Schnorr en lugar de ECDSA              │
  │  → falla si firma inválida pero firma vacía   │
  │    se permite (facilita multisig variable)    │
  │                                               │
  │  opcodes reservados para upgrades futuros:    │
  │  OP_SUCCESS opcodes → siempre TRUE            │
  │  permite añadir nuevos opcodes como soft fork │
  │  sin invalidar scripts existentes             │
  └───────────────────────────────────────────────┘

Los OP_SUCCESS opcodes son especialmente importantes para la gobernanza futura — permiten añadir nuevas funcionalidades a tapscript mediante soft fork sin complicaciones de compatibilidad.


La activación de Taproot

  oct 2020   BIPs 340/341/342 publicados
             (Schnorr, Taproot, Tapscript)
      │
      ▼
  ene-abr 2021  debate sobre mecanismo de activación
                Speedy Trial vs UASF (LOT=true)
      │
      ▼
  may 2021   Speedy Trial comienza
             mineros señalizan bit 2 en campo versión
      │
      ▼
  12 jun 2021  umbral 90% alcanzado en bloque 687.284
               lock-in confirmado · no puede revertirse
      │
      ▼
  14 nov 2021  bloque 709.632
               Taproot activado
               sin división · sin guerra de bloques

El debate sobre Speedy Trial fue intenso — algunos argumentaban que daba demasiado poder a los mineros sobre el calendario de activación. El resultado fue un compromiso: Speedy Trial con ventanas cortas de 2016 bloques, tres meses máximo. Si los mineros no alcanzaban el umbral en ese tiempo, el proceso se reiniciaba.

Lo que reveló la activación de Taproot. A diferencia de 2017, Taproot se activó sin división ni guerra. La comunidad había aprendido. El mérito técnico era claro, el proceso fue transparente, y el debate sobre el mecanismo de activación — aunque intenso — se resolvió con consenso real. Bitcoin puede evolucionar sin romperse cuando el cambio tiene mérito genuino y el proceso respeta a todos los participantes.


Verifica tú mismo

Busca en mempool.space una transacción con dirección bc1p. Observa el ScriptPubKey — verás OP_1 seguido de 32 bytes. Esos 32 bytes son la clave modificada Q.

Para ver un key path spend busca una transacción donde el witness tenga un solo elemento de 64 bytes — es una firma Schnorr pura.

Para ver un script path spend busca la transacción 797505b104b5fb840931c115ea35d445eb1f64c9279bf23aa5bb4c3d779da0c2 — el witness tiene tres elementos: script inputs, leaf script y control block.

Consulta taproot.watch para ver la adopción de Taproot en tiempo real.


Resumen

Taproot combina tres innovaciones. Schnorr permite firmas de 64 bytes agregables — un multisig es indistinguible de un pago simple en el key path. MAST organiza scripts alternativos en un árbol de Merkle y solo revela el usado. La clave modificada compromete todos los scripts en una clave pública que parece ordinaria. Tapscript sustituye OP_CHECKMULTISIG por OP_CHECKSIGADD y añade OP_SUCCESS para upgrades futuros. Se activó en noviembre de 2021 sin división.

La privacidad perfecta no es que nadie sepa que hiciste algo complejo. Es que nadie sepa que era complejo.


Hemos recorrido toda la pila técnica. Queda una última pieza: cómo todo esto viaja de nodo en nodo hasta llegar a cualquier parte del mundo en segundos.


Capítulo 9 — La red

Nivel: Técnico


Sin servidor central

Cuando pulsas enviar en tu wallet, tu transacción no va a ningún servidor central. Va a un nodo. Ese nodo la verifica y la reenvía a otros nodos. En cuestión de segundos, tu transacción ha llegado a miles de ordenadores distribuidos por todo el mundo.

Todo esto ocurre mediante un protocolo P2P bien definido — mensajes binarios con estructura precisa que cualquier implementación puede entender y verificar.


La estructura de un mensaje

Todos los mensajes entre nodos tienen la misma estructura: un header fijo de 24 bytes seguido de un payload variable.

  HEADER (24 bytes siempre):
  ┌──────────────┬───────┬──────────────────────────┐
  │  magic bytes │ 4 B   │ identifica la red        │
  │  command     │ 12 B  │ tipo de mensaje (ASCII)  │
  │  size        │ 4 B   │ tamaño del payload       │
  │  checksum    │ 4 B   │ primeros 4B del hash     │
  └──────────────┴───────┴──────────────────────────┘

  PAYLOAD (variable):
  datos específicos del tipo de mensaje

Los magic bytes son el delimitador que identifica el inicio de cada mensaje en el stream TCP. Son distintos para cada red:

  Mainnet:  f9beb4d9
  Testnet3: 0b110907
  Regtest:  fabfb5da

  cuando un nodo recibe bytes del socket
  busca f9beb4d9 para saber dónde empieza
  un nuevo mensaje

Cómo se descubren los nodos

  nodo nuevo arranca por primera vez
        │
        ▼
  1. lista de conexiones anteriores (peers.dat)
     si existe → intenta reconectar
        │
        ▼ si no hay conexiones previas
  2. DNS seeds (servidores de confianza que
     devuelven IPs de nodos activos):
     seed.bitcoin.sipa.be      (Pieter Wuille)
     dnsseed.bitcoin.dashjr.org (Luke Dashjr)
     seed.bitcoin.sprovoost.nl  (Sjors Provoost)
        │
        ▼ si DNS falla
  3. lista hardcodeada en Bitcoin Core
     (chainparamsseeds.h)
        │
        ▼
  conecta con varios nodos
  solicita sus listas de peers (mensaje getaddr)
  guarda nuevas IPs en peers.dat
  → ya integrado en la red

El objetivo es solo conectar con un nodo fiable. Desde ahí ese nodo comparte sus peers y el grafo de conexiones crece orgánicamente.


El handshake

Antes de intercambiar transacciones o bloques, dos nodos deben establecer la conexión mediante un handshake de cuatro mensajes:

  Nodo A                              Nodo B
     │                                   │
     │──── version ──────────────────────▶│
     │     (protocolo, altura, servicios, │
     │      IP, timestamp, user agent)    │
     │                                   │
     │◀─── version ──────────────────────│
     │                                   │
     │◀─── verack ───────────────────────│
     │                                   │
     │──── verack ───────────────────────▶│
     │                                   │
     │  canal abierto · listos para      │
     │  intercambiar txs y bloques       │

El mensaje version contiene la versión del protocolo, la altura del bloque más reciente conocido por el nodo, los servicios que ofrece y su dirección IP. El verack es un acknowledgement sin payload — solo el header con el comando verack.

El orden importa. Si se envían los mensajes fuera de orden el nodo remoto rechaza la conexión. Demasiados handshakes fallidos pueden resultar en un ban temporal de la IP.


Cómo viaja una transacción: inv / getdata / tx

Los nodos no envían transacciones completas a todos sus peers de forma proactiva — eso desperdiciaría ancho de banda. En su lugar usan un mecanismo de tres mensajes:

  tu wallet emite tx
        │
        ▼
  Nodo A recibe tx · verifica · añade a mempool
        │
        │ inv [tipo: MSG_TX, hash: TXID]
        ▼     "tengo esta transacción, ¿la quieres?"
  Nodo B recibe inv
        │
        │ getdata [tipo: MSG_TX, hash: TXID]
        ▼         "sí, dámela"
  Nodo A responde
        │
        │ tx [datos completos de la transacción]
        ▼
  Nodo B verifica · propaga a sus vecinos
  · · ·
  en segundos: miles de nodos tienen la tx

Para transacciones SegWit el tipo en el mensaje getdata cambia de MSG_TX (01000000) a MSG_WITNESS_TX (01000040) — así el nodo receptor obtiene los datos witness completos.


Compact blocks: propagación rápida de bloques

Cuando se mina un bloque nuevo, propagarlo rápido es crítico — cuanto más tarde llega a otros mineros, más tiempo trabajan en vano sobre la cadena antigua.

El mecanismo compact blocks (BIP152) resuelve esto:

  PROPAGACIÓN TRADICIONAL        COMPACT BLOCKS
  ┌────────────────────┐         ┌────────────────────┐
  │ bloque completo    │         │ header             │
  │ 1-4 MB             │         │ + short IDs (6B)   │
  │ esperar descarga   │         │ de cada tx         │
  │ antes de verificar │         │ ~20 KB total       │
  └────────────────────┘         └────────┬───────────┘
                                          │
                               nodo reconstruye bloque
                               desde su propia mempool
                               (ya tiene casi todas las txs)
                                          │
                               solo solicita las txs
                               que le faltan (getblocktxn)
                                          │
                               bloque completo en ms
                                          │
                               verifica y propaga

Los short IDs son hashes truncados a 6 bytes derivados del TXID y un nonce del bloque — suficientes para identificar unívocamente cada transacción en la mempool local.


Mensajes de mantenimiento

Además de txs y bloques, los nodos intercambian mensajes de mantenimiento continuamente:

  ping  → nodo envía nonce aleatorio de 8 bytes
  pong  → nodo responde con el mismo nonce
          si no hay respuesta en tiempo → desconectar

  addr  → lista de IPs de nodos conocidos
  getaddr → solicitar lista de peers

  mempool → solicitar txs pendientes del peer
  feefilter → "solo envíame txs con fee > X sat/vbyte"
              reduce tráfico en nodos con muchos peers

Nodo completo vs nodo ligero (SPV)

  NODO COMPLETO                  NODO LIGERO (SPV)
  ┌────────────────────┐         ┌────────────────────┐
  │ descarga toda la  │         │ solo headers        │
  │ blockchain        │         │ 80 bytes × 880K+    │
  │ verifica cada tx  │         │ bloques ≈ 70 MB     │
  │ independientemente│         │                    │
  │ ~700 GB disco     │         │ verifica txs con   │
  │ ~4-10 GB RAM      │         │ pruebas de Merkle  │
  │                   │         │ confía en nodos    │
  │ no confía en nada │         │ completos para     │
  │ soberanía total   │         │ el estado UTXO     │
  └────────────────────┘         └────────────────────┘

El nodo ligero tiene una limitación importante: no puede verificar que un output no ha sido ya gastado sin consultar a un nodo completo. Sabe que una transacción existe en un bloque (gracias a la prueba de Merkle) pero no sabe si el UTXO que gasta seguía sin gastar en el momento de confirmación.


Tu IP es un dato

  SIN NODO PROPIO                CON NODO PROPIO + TOR
  ┌────────────────────┐         ┌────────────────────┐
  │ wallet consulta    │         │ wallet consulta     │
  │ servidor externo   │         │ tu propio nodo      │
  │                   │         │ nodo usa Tor        │
  │ el servidor sabe:  │         │                    │
  │ · tus direcciones  │         │ nadie sabe:        │
  │ · tu saldo         │         │ · qué direcciones  │
  │ · tu actividad     │         │   son tuyas        │
  │ · tu IP            │         │ · tu IP real       │
  └────────────────────┘         └────────────────────┘

Bitcoin Core tiene soporte nativo para Tor. Configurado correctamente, todas las conexiones salientes usan la red Tor — los peers solo ven una dirección .onion, no tu IP real.


Verifica tú mismo

Entra en bitnodes.io y observa el mapa de nodos activos en tiempo real.

Desde tu propio nodo puedes inspeccionar todas las conexiones activas:

bitcoin-cli getpeerinfo

Para conectarte manualmente a un nodo y ver los mensajes raw, el protocolo está completamente documentado en learnmeabitcoin.com/technical/networking.


Resumen

La red Bitcoin es un protocolo P2P de mensajes binarios sobre TCP. Cada mensaje lleva magic bytes, comando, tamaño y checksum. Los nodos se descubren mediante DNS seeds y listas de peers. El handshake establece la conexión en cuatro mensajes. Las transacciones viajan mediante inv/getdata/tx. Compact blocks acelera la propagación de bloques nuevos reconstruyéndolos desde la mempool local. Los nodos ligeros verifican inclusión pero no estado UTXO. Tor elimina la exposición de IP.

La red no tiene centro. Cada nodo es igual a los demás. Eso es exactamente lo que la hace imposible de apagar.


Con este capítulo concluye la Parte 3 — Técnico.

La guía completa cubre ahora desde los conceptos más básicos hasta los mecanismos criptográficos más profundos del protocolo. Tres partes. Una sola idea: Bitcoin funciona porque cualquiera puede verificarlo.


Glosario

Ancestor feerate — Fee rate combinado de una transacción y todos sus ancestros pendientes en la mempool, dividido entre su tamaño combinado. Es la métrica real que usan los mineros para ordenar transacciones en el bloque candidato.

BIP143 — Propuesta que define el nuevo algoritmo de sighash para transacciones SegWit. Resuelve el escalado cuadrático del algoritmo legacy precalculando componentes compartidos entre todos los inputs.

Bech32 — Formato de codificación de direcciones usado por P2WPKH y P2WSH (direcciones bc1q). Usa un alfabeto de 32 caracteres que evita confusiones entre letras similares y tiene detección de errores mejorada.

Bech32m — Variante de Bech32 usada por P2TR (direcciones bc1p). Usa un polinomio de checksum diferente que mejora la detección de errores para longitudes de datos distintas.

BIP152 — Propuesta que define compact blocks — el mecanismo de propagación de bloques que envía short IDs en lugar del bloque completo, permitiendo que los nodos reconstruyan el bloque desde su mempool.

Compact blocks — Mecanismo de propagación de bloques que envía la cabecera más identificadores cortos de 6 bytes por transacción. El nodo receptor reconstruye el bloque desde su mempool y solo solicita las transacciones que le faltan.

Control block — Elemento del witness en un script path spend de Taproot. Contiene la clave interna, la versión de tapscript y el merkle path necesario para demostrar que el leaf script usado estaba comprometido en la clave modificada.

CPFPChild Pays For Parent. Técnica donde el destinatario de una transacción atascada crea una transacción hijo con fee alta para arrastrar a la transacción padre mediante el ancestor feerate combinado.

Curva elíptica secp256k1 — Curva matemática definida por y² = x³ + 7 usada por Bitcoin para la criptografía de clave pública. La seguridad se basa en la dificultad computacional del logaritmo discreto sobre esta curva.

Derivation path — Ruta que indica la posición exacta de una clave en el árbol de una HD wallet. Formato: m / purpose' / coin_type' / account' / change / index. El apóstrofo indica hijo hardened.

DNS seed — Servidor de nombres mantenido por desarrolladores de confianza que devuelve listas de direcciones IP de nodos Bitcoin activos. Usado por Bitcoin Core para el descubrimiento inicial de peers.

ECDSAElliptic Curve Digital Signature Algorithm. Algoritmo de firma digital usado en Bitcoin desde sus inicios. Las firmas tienen formato DER y tamaño variable de 71-72 bytes. Sustituido por Schnorr en Taproot.

Extranonce — Campo en el ScriptSig de la coinbase transaction que los mineros modifican para ampliar el espacio de búsqueda cuando el nonce de la cabecera se agota.

Extended public key (xpub) — Clave pública extendida que permite derivar todas las claves públicas hijas de una rama sin exponer ninguna clave privada. Usada en watch-only wallets.

Fee rate — Comisión expresada en satoshis por vbyte (sat/vbyte). Métrica estándar para comparar la prioridad de transacciones en la mempool.

Gap limit — Número de direcciones consecutivas sin actividad que una wallet HD escanea antes de asumir que no hay más fondos en esa rama. Por defecto 20 en Bitcoin Core.

Handshake — Intercambio inicial de cuatro mensajes (version → version ← verack ← verack →) entre dos nodos Bitcoin para establecer la conexión antes de intercambiar transacciones o bloques.

Hash160 — Resultado de aplicar SHA256 seguido de RIPEMD160 a una clave pública. Produce 20 bytes y es la base de las direcciones P2PKH y P2WPKH.

HD walletHierarchical Deterministic wallet. Wallet que deriva todas sus claves de forma determinista desde una única semilla maestra mediante HMAC-SHA512.

Key path spend — Forma de gastar un output P2TR usando directamente la firma Schnorr de la clave modificada. El witness contiene un único elemento de 64 bytes. Indistinguible de un pago simple desde fuera.

Leaf script — Script individual dentro del árbol MAST de un output Taproot. Se revela solo cuando se usa ese camino de gasto específico.

Locktime — Campo de 4 bytes en una transacción que especifica la altura de bloque o timestamp Unix mínimo a partir del cual puede ser minada.

Magic bytes — Cuatro bytes (f9beb4d9 en mainnet) que preceden cada mensaje en el protocolo P2P de Bitcoin. Permiten identificar el inicio de un nuevo mensaje en el stream TCP.

MASTMerkelized Abstract Syntax Tree. Técnica que organiza múltiples condiciones de gasto en un árbol de Merkle. Solo se revela la condición usada al gastar; las demás permanecen ocultas.

Merkle proof — Conjunto mínimo de hashes necesarios para demostrar que una transacción concreta está incluida en un bloque sin descargar todas las transacciones del bloque.

Natural byte order — Orden en que se almacenan los TXIDs en los campos de input de una transacción. Equivalente a little-endian para este campo específico.

OP_CHECKSIGADD — Opcode de tapscript que verifica una firma y suma 1 al contador de la pila si es válida. Reemplaza OP_CHECKMULTISIG sin su bug histórico del dummy value.

OP_SUCCESS — Clase de opcodes reservados en tapscript que devuelven TRUE inmediatamente. Permiten añadir nuevas funcionalidades en upgrades futuros mediante soft fork sin invalidar scripts existentes.

P2TRPay to Taproot. Script que bloquea un output a una clave modificada de 32 bytes. Permite gasto vía key path (firma Schnorr) o script path (árbol MAST).

P2WPKHPay to Witness Public Key Hash. Script SegWit que bloquea un output al hash de una clave pública, con los datos de desbloqueo en el campo witness.

P2WSHPay to Witness Script Hash. Script SegWit que bloquea un output al hash de un script arbitrario, con el script completo y sus datos de desbloqueo en el witness.

Script path spend — Forma de gastar un output P2TR revelando uno de los leaf scripts alternativos comprometidos en la clave modificada. El witness contiene script inputs, leaf script y control block.

Sequence — Campo de 4 bytes en cada input de una transacción. Señaliza RBF cuando vale 0xFFFFFFFD o menos. Con versión 2 de transacción, valores bajos activan timelocks relativos.

Sighash — Hash que se firma al autorizar el gasto de un input. Se construye hasheando una versión modificada de la transacción según el tipo de sighash (ALL, NONE, SINGLE, ANYONECANPAY).

Sighash type — Byte que especifica qué partes de la transacción cubre la firma. SIGHASH_ALL (0x01) es el más común — cubre todos los inputs y outputs.

Stratum — Protocolo de comunicación entre pools de minería y sus mineros. El pool distribuye trabajo asignando rangos de nonces y recibe shares para medir la contribución de cada minero.

Stratum V2 — Versión actualizada de Stratum que permite al minero individual construir su propio bloque candidato con las transacciones que elige, en lugar de delegar esa decisión al pool.

Tapscript — Variante de Script usada dentro de los leaf scripts de Taproot. Sustituye OP_CHECKMULTISIG por OP_CHECKSIGADD, usa firmas Schnorr y añade OP_SUCCESS para extensibilidad futura.

Tweaked public key — Clave pública modificada usada en P2TR. Se calcula sumando a la clave interna el punto tweak × G, donde tweak es el hash del merkle root de los scripts alternativos.

UASFUser Activated Soft Fork. Mecanismo de activación de soft fork impulsado por los nodos de usuarios en lugar de los mineros. Demostrado en 2017 durante la activación de SegWit.

Version bits (BIP9) — Sistema de señalización de upgrades donde cada bit del campo versión de la cabecera de bloque puede asignarse a una propuesta diferente. Los mineros señalizan activando el bit correspondiente.

wTXIDWitness TXID. Identificador de transacción calculado incluyendo todos los campos — versión, marker, flag, inputs, outputs, witness y locktime. Usado para el witness commitment en la coinbase.

X-only public key — Clave pública de 32 bytes usada en Taproot que omite el byte de prefijo de paridad. Se asume siempre coordenada y par. Ahorra un byte y simplifica la aritmética Schnorr.


Preguntas frecuentes

¿Por qué el TXID se calcula sin el witness? Porque el witness contiene las firmas, y las firmas ECDSA podían modificarse matemáticamente sin invalidar la transacción — la maleabilidad. Si el TXID incluyera el witness, un nodo intermedio podría cambiar el TXID antes de que la transacción fuera minada, rompiendo cualquier protocolo que dependa de referenciar esa transacción por su ID. SegWit resolvió esto excluyendo el witness del cálculo del TXID. El wTXID sí incluye el witness y se usa internamente para el witness commitment en la coinbase.

¿Qué pasa si reutilizo el mismo nonce en dos firmas ECDSA distintas? La clave privada queda expuesta matemáticamente. Con dos firmas (r, s1) y (r, s2) firmadas con el mismo nonce sobre mensajes distintos H1 y H2, cualquiera puede calcular la clave privada con álgebra básica. Ha ocurrido en la práctica — wallets con generadores de números aleatorios defectuosos han perdido fondos exactamente por este motivo. Schnorr es más robusto en este aspecto porque usa nonces deterministas derivados de la clave privada y el mensaje.

¿Qué diferencia hay entre TXID y wTXID? El TXID se calcula hasheando versión, inputs, outputs y locktime — sin el witness. El wTXID incluye también marker, flag y witness. Para transacciones legacy sin witness, TXID y wTXID son idénticos. Para transacciones SegWit son distintos. Los mineros construyen dos árboles de Merkle: uno de TXIDs para la cabecera del bloque, y otro de wTXIDs cuyo root se incluye en un output OP_RETURN de la coinbase como witness commitment.

¿Por qué el campo bits en la cabecera del bloque pierde precisión respecto al target real? Porque el target completo tiene 32 bytes y el campo bits solo 4 — el primer byte es el exponente y los tres siguientes son el coeficiente. La precisión que se pierde es mínima en la práctica: la diferencia entre el target aproximado y el exacto es infinitesimal comparada con el espacio de búsqueda de 2²⁵⁶ hashes posibles. El campo bits existe como conveniencia — los nodos podrían calcular el target internamente sin él.

¿Puede un minero incluir transacciones inválidas en su bloque candidato? Puede incluirlas en el candidato que construye — nadie se lo impide técnicamente. Pero si mina ese bloque y lo propaga, todos los nodos de la red lo rechazarán. El minero habrá gastado energía real encontrando un hash válido para un bloque que nadie acepta. El incentivo económico es el mecanismo de seguridad — minar bloques inválidos es simplemente caro y sin recompensa.

¿Qué es CPFP y en qué se diferencia de RBF? CPFP — Child Pays For Parent — es una técnica donde el destinatario de una transacción atascada crea una transacción hijo que gasta el output de la padre con una fee muy alta. Los mineros evalúan el ancestor feerate combinado del paquete padre-hijo, lo que arrastra a la transacción padre aunque su fee individual sea baja. RBF — Replace by Fee — lo hace el remitente original, reemplazando su propia transacción sin confirmar por una nueva con fee más alta. RBF requiere que la transacción original haya señalizado con sequence < 0xFFFFFFFE. CPFP no requiere ninguna señalización previa.

¿Qué es el gap limit y por qué importa al recuperar una wallet? Las wallets HD derivan claves en secuencia pero no escanean infinitamente. El gap limit — por defecto 20 en Bitcoin Core — define cuántas direcciones consecutivas sin actividad escanea la wallet antes de asumir que no hay más fondos en esa rama. Si en algún momento generaste claves saltando índices, o usaste un path de derivación no estándar, los fondos en índices por encima del gap podrían no aparecer al recuperar. La solución es aumentar el gap limit en el software de recuperación o conocer exactamente qué paths y qué índices usaste.

¿Por qué Taproot usa claves x-only de 32 bytes en lugar de 33? Las claves públicas comprimidas estándar tienen 33 bytes — 32 de coordenada x más un byte de prefijo (02 o 03) que indica si la coordenada y es par o impar. En Taproot ese byte de prefijo se omite porque se asume siempre que y es par — si la clave tiene y impar, se usa su negación, que tiene y par. Esto ahorra un byte por clave y simplifica la aritmética en las verificaciones de firma Schnorr.

¿Qué son los OP_SUCCESS opcodes en tapscript y para qué sirven? Son opcodes reservados que en tapscript hacen que el script devuelva TRUE inmediatamente sin ejecutar nada más. Esto los hace seguros para reasignar en upgrades futuros mediante soft fork: si se añade una nueva funcionalidad a un OP_SUCCESS opcode, los scripts que lo usan pasan de “siempre TRUE” a ejecutar la nueva lógica. Los nodos sin actualizar siguen viendo TRUE y aceptan el bloque. Los nodos actualizados ejecutan las nuevas reglas. Es el mecanismo de extensibilidad más limpio que tiene Bitcoin para añadir nuevos opcodes.

¿Por qué un nodo ligero SPV no puede verificar completamente una transacción? Porque solo descarga cabeceras de bloque — no las transacciones. Puede verificar que una transacción específica está incluida en un bloque usando una prueba de Merkle. Pero no puede verificar que el UTXO que esa transacción gasta no había sido ya gastado previamente — para eso necesitaría el UTXO set completo, que solo mantienen los nodos completos. Un SPV confía en que la cadena más larga es válida y en que los nodos completos a los que consulta son honestos.

¿Qué información revela el campo version del mensaje de handshake? Revela la versión del protocolo que soporta el nodo, la altura del último bloque conocido, los servicios que ofrece — si es nodo completo, si soporta SegWit, si tiene filtros de bloom activos — su dirección IP y puerto, y su user agent que incluye la versión del software. Todo esto antes de que se haya intercambiado una sola transacción. Es información relevante para quienes monitorean la red y pueden correlacionar IPs con wallets si no se usa Tor.

¿Puede cambiarse el límite de 21 millones mediante soft fork? No. Aumentar el límite de emisión requiere un hard fork — es una expansión de reglas, no una restricción. Crearía bloques que los nodos sin actualizar considerarían inválidos porque la coinbase reclamaría más bitcoin del permitido. En la práctica, cualquier propuesta de cambiar los 21 millones sería rechazada por la inmensa mayoría de nodos y usuarios que tienen incentivo económico directo en que ese límite no cambie. Es la regla más inviolable del protocolo — no por imposibilidad técnica sino por imposibilidad económica y política.


Recursos