Bitcoin Script y opcodes

El pequeño lenguaje de pila que bloquea cada moneda.

Las monedas no se guardan en cuentas. Cada UTXO lleva un pequeño programa, el script de bloqueo (scriptPubKey), que dice qué se necesita para gastarla. Quien gasta aporta un script de desbloqueo (scriptSig, o el witness para SegWit). Un nodo los ejecuta y, si el resultado es «true», el gasto es válido.

Una máquina de pila

Script se lee de izquierda a derecha. Los datos se empujan a una pila, y cada opcode saca elementos, trabaja con ellos y empuja resultados. No hay bucles, lo que significa que todo script termina y su coste es predecible. Esto es deliberado: Script no es Turing-completo.

Recorrido por P2PKH

El script de bloqueo clásico «pay to public key hash» es:

OP_DUP OP_HASH160 <20-byte pubkey hash> OP_EQUALVERIFY OP_CHECKSIG

Quien gasta aporta <signature> <public key>. El intérprete:

  1. empuja la firma y la clave pública,
  2. duplica la clave pública (OP_DUP),
  3. hashea la copia con SHA-256 y luego RIPEMD-160 (OP_HASH160),
  4. comprueba que coincida con el hash del script de bloqueo (OP_EQUALVERIFY),
  5. verifica la firma digital contra la clave y la transacción (OP_CHECKSIG).

Si todos los pasos pasan, queda un «true» en la pila y la moneda se puede gastar.

Qué cubre la firma

OP_CHECKSIG no firma bytes arbitrarios. Comprueba un hash de partes seleccionadas de la transacción, elegidas por el flag sighash. Suele ser todo, para que nadie pueda cambiar las salidas después de que firmes.

Límites por seguridad

Los scripts legacy tienen límites duros: como máximo 10.000 bytes, como máximo 201 opcodes que no son push, y como máximo 1.000 elementos en la pila. Opcodes como OP_CAT se desactivaron en 2010 tras encontrarse fallos. Tapscript (BIP342) eliminó los límites de 10.000 bytes y 201 opcodes y se apoya en un presupuesto de firmas ligado al tamaño del witness.

Más allá de las firmas únicas

Las mismas herramientas expresan multifirma (OP_CHECKMULTISIG, o OP_CHECKSIGADD en Tapscript), bloqueos por hash (OP_SHA256 <hash> OP_EQUAL) y bloqueos temporales (OP_CHECKLOCKTIMEVERIFY, OP_CHECKSEQUENCEVERIFY). Combinarlos da bóvedas, planes de herencia y canales Lightning. Escribir esos scripts a mano es propenso a errores, por eso existe Miniscript.