Nivel 5

SegWit por dentro

La actualización que separó las firmas del cálculo del txid. El prerrequisito técnico para Lightning Network.

El problema: Transaction Malleability

Antes de SegWit, las transacciones Bitcoin tenían un problema llamado maleabilidad: era posible modificar una transacción válida de forma que siguiera siendo válida pero con un txid diferente.

¿Cómo? El scriptSig (que contiene la firma) podía modificarse de formas que no invalidaban la firma. Por ejemplo, añadir bytes que no afectan la ejecución del script.

El txid se calculaba sobre toda la transacción, incluyendo el scriptSig. Un cambio en el scriptSig cambiaba el txid.

Por qué importaba la maleabilidad

Imagina este escenario:

  1. Alice crea una transacción que envía bitcoin a Bob (txid: ABC123)
  2. Antes de confirmar, alguien modifica el scriptSig → nuevo txid: DEF456
  3. La versión DEF456 se confirma
  4. Alice busca ABC123 y no lo encuentra
  5. Alice podría pensar que la transacción falló y reenviarla, pagando dos veces

Para usuarios normales era un inconveniente menor. Pero para protocolos de segunda capa como Lightning Network, era fatal: Lightning requiere construir cadenas de transacciones que gastan outputs de transacciones no confirmadas. Si el txid puede cambiar, toda la cadena se invalida.

La solución: Segregated Witness

SegWit (Segregated Witness, BIP 141) resuelve esto separando los datos de firma ("witness") del cálculo del txid.

La idea:

  • Los datos que pueden ser modificados (firmas) van en una estructura separada: el witness
  • El txid se calcula solo sobre los datos "base" (versión, inputs sin scriptSig, outputs, locktime)
  • El witness no afecta el txid

Ahora el txid es inmutable una vez que se conocen los inputs y outputs. La firma puede ir en cualquier formato compatible sin cambiar el txid.

Estructura de transacción SegWit

La serialización incluye un marker (0x00) y flag (0x01) después de la versión, indicando que hay datos witness al final.

Los inputs tienen scriptSig vacío. Los datos de firma van en la sección witness correspondiente a cada input.

La serialización "legacy" (sin witness) se usa para calcular el txid. La serialización completa (con witness) se usa para el wtxid y para transmitir/almacenar.

Weight Units y block weight

SegWit introdujo un nuevo sistema de medición: weight units (WU).

Reglas:

  • 1 byte de datos base (versión, inputs, outputs, locktime) = 4 WU
  • 1 byte de witness = 1 WU

Máximo por bloque: 4.000.000 WU

Esto es equivalente a:

  • Un bloque de 1 MB si es todo datos base (transacciones legacy)
  • Un bloque de ~4 MB si es todo witness (teórico, imposible en práctica)
  • Un bloque típico de 1.5-2 MB con mezcla de transacciones

El diseño incentiva las transacciones SegWit: los datos de firma (witness) son más baratos, resultando en fees menores para los usuarios.

Virtual bytes (vBytes)

Para simplificar el cálculo de fees, se usa la unidad "virtual byte" o vByte: vBytes = weight / 4

Una transacción de 400 WU = 100 vBytes.

Las fees se expresan típicamente en sat/vB (satoshis por virtual byte).

BIP 143: nuevo algoritmo de firma

SegWit también cambió cómo se hashean los datos para firmar (BIP 143).

El antiguo algoritmo tenía problemas:

  • Para firmar cada input, había que hashear la transacción completa
  • En transacciones con muchos inputs, esto era O(n²) en complejidad
  • Permitía ataques donde transacciones especialmente diseñadas tardaban mucho en verificar

BIP 143 usa un nuevo esquema donde los datos comunes se hashean una vez y se reutilizan. Firmar es ahora O(n).

Versiones de witness

El witness program tiene un número de versión:

  • Versión 0 (OP_0): SegWit original (P2WPKH, P2WSH)
  • Versión 1 (OP_1): Taproot (P2TR)
  • Versiones 2-16: reservadas para futuras mejoras

Las direcciones bc1q... son versión 0. Las direcciones bc1p... son versión 1.

Activación

SegWit se activó el 24 de agosto de 2017 (bloque 481.824) mediante un soft fork. Fue una de las actualizaciones más debatidas de la historia de Bitcoin, culminando en el "User Activated Soft Fork" (UASF) donde los usuarios amenazaron con activar SegWit sin apoyo mayoritario de mineros.

La controversia sobre SegWit y el tamaño de bloque resultó en el fork de Bitcoin Cash, que rechazó SegWit y optó por aumentar el límite de bloque en su lugar.

Legado de SegWit

SegWit no solo resolvió la maleabilidad. Habilitó Lightning Network, redujo fees para transacciones SegWit, preparó el camino para Taproot, y estableció un precedente para actualizaciones futuras mediante soft forks con activación por usuarios.