Nivel 5

Bitcoin Script

El lenguaje que define las condiciones para gastar bitcoin. Simple por diseño, poderoso en la práctica.

Qué es Bitcoin Script

Bitcoin tiene su propio lenguaje de programación llamado Script. Cada UTXO está bloqueado por un script (scriptPubKey) que define las condiciones para gastarlo. Para gastar, el input proporciona datos (scriptSig o witness) que satisfacen esas condiciones.

Script no es como los lenguajes de programación convencionales. Es intencionalmente limitado para minimizar la superficie de ataque y garantizar que la ejecución siempre termine.

Características del lenguaje

Basado en pila (stack-based)

Script usa una pila de datos. Los valores se empujan (push) a la pila y los operadores (opcodes) actúan sobre los valores en la pila.

No hay variables con nombres. No hay memoria direccionable. Solo la pila.

No Turing-completo

Script no tiene bucles. No puedes escribir while o for. Cada script tiene un número finito y predecible de operaciones.

Esto es intencional: garantiza que la validación siempre termine y previene ataques de denegación de servicio donde un script malicioso consume recursos indefinidamente.

Determinista

Dado el mismo estado inicial, un script siempre produce el mismo resultado. No hay aleatoriedad ni acceso a información externa.

Ejecución de scripts

Históricamente, la ejecución combinaba scriptSig y scriptPubKey:

  1. Los datos del scriptSig se ejecutan (típicamente solo pushes a la pila)
  2. El scriptPubKey se ejecuta sobre la pila resultante
  3. Si la pila termina con un valor TRUE (no cero) en el tope, el gasto es válido

En SegWit, el witness reemplaza al scriptSig pero el concepto es similar.

Opcodes principales

Manipulación de pila

  • OP_DUP: Duplica el elemento en el tope de la pila
  • OP_DROP: Elimina el elemento en el tope
  • OP_SWAP: Intercambia los dos elementos superiores
  • OP_PICK: Copia el n-ésimo elemento al tope
  • OP_ROLL: Mueve el n-ésimo elemento al tope

Operaciones lógicas y aritméticas

  • OP_EQUAL: Compara dos elementos, empuja TRUE si son iguales
  • OP_EQUALVERIFY: Como OP_EQUAL pero falla si no son iguales
  • OP_ADD, OP_SUB: Suma y resta
  • OP_NOT, OP_BOOLAND, OP_BOOLOR: Operaciones booleanas

Criptografía

  • OP_HASH160: Aplica RIPEMD160(SHA256(x)) al tope de la pila
  • OP_SHA256: Aplica SHA256
  • OP_CHECKSIG: Verifica una firma contra una clave pública
  • OP_CHECKMULTISIG: Verifica múltiples firmas contra múltiples claves
  • OP_CHECKSIGADD: Versión Tapscript para multisig eficiente

Control de flujo

  • OP_IF, OP_ELSE, OP_ENDIF: Ejecución condicional
  • OP_VERIFY: Falla si el tope no es TRUE
  • OP_RETURN: Marca el output como no gastable

Timelocks

  • OP_CHECKLOCKTIMEVERIFY (OP_CLTV): Verifica locktime absoluto
  • OP_CHECKSEQUENCEVERIFY (OP_CSV): Verifica timelock relativo

Ejemplo: ejecución de P2PKH

Script de bloqueo (scriptPubKey): OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

Datos de desbloqueo (scriptSig): <signature> <pubKey>

Ejecución paso a paso: Pila inicial: (vacía)

Push <signature> Pila: [signature] Push <pubKey> Pila: [signature, pubKey] OP_DUP Pila: [signature, pubKey, pubKey] OP_HASH160 Pila: [signature, pubKey, hash(pubKey)] Push <pubKeyHash> Pila: [signature, pubKey, hash(pubKey), pubKeyHash] OP_EQUALVERIFY Compara hash(pubKey) con pubKeyHash Si son iguales, elimina ambos y continúa Si no, FALLO inmediato Pila: [signature, pubKey] OP_CHECKSIG Verifica que signature es válida para pubKey Empuja TRUE o FALSE Pila: [TRUE]

Resultado: TRUE → gasto válido

Limitaciones y por qué existen

Sin bucles: Previene scripts que nunca terminan.

Sin acceso al estado: Los scripts no pueden leer el saldo de otras direcciones ni información de bloques anteriores. Esto mantiene la validación simple y paralelizable.

Tamaño limitado: Los scripts tienen límite de tamaño y de operaciones. Previene ataques de complejidad.

Opcodes deshabilitados: Satoshi deshabilitó varios opcodes originales (OP_CAT, OP_MUL, etc.) por precaución ante posibles vulnerabilidades. Algunos están siendo reconsiderados para futuras actualizaciones.

Script en la práctica

La mayoría de usuarios nunca escriben Script directamente. Las wallets generan los scripts estándar (P2PKH, P2WPKH, P2TR) automáticamente.

Pero entender Script es esencial para:

  • Desarrollar protocolos avanzados
  • Auditar transacciones complejas
  • Comprender las posibilidades y límites de Bitcoin
Experimenta con Script

Puedes probar scripts en /herramientas/script-interpreter. Escribe opcodes, observa la pila, y entiende la ejecución paso a paso.