Entendiendo el Bitcoin Script
¿Qué es el Bitcoin Script?
Cada vez que envías Bitcoin, en realidad no estás moviendo una moneda de un sitio a otro. Estás creando una salida y adjuntándole un pequeño programa. Ese programa define las condiciones exactas bajo las cuales esas monedas podrán gastarse más adelante. El lenguaje que se usa para escribir estos programas se llama Bitcoin Script.
Satoshi Nakamoto lo describió de la mejor manera, llamando a un script una especie de predicado: una pequeña ecuación que se resuelve como verdadero o falso. Si quien gasta consigue que la ecuación dé verdadero, las monedas se mueven. Si no, permanecen bloqueadas. Ese es todo el trabajo de Script. Es un mecanismo de bloqueo, no un ordenador de propósito general.
El Bitcoin Script es deliberadamente pequeño y limitado. No es Turing completo, lo que significa que no tiene bucles, no tiene recursión y no tiene forma de ejecutar un programa sin fin. No es una función que falte. Es una decisión de seguridad fundamental. Un lenguaje que no puede ejecutarse para siempre siempre puede ser comprobado de forma rápida y barata por cada nodo de la red, y eso es parte de lo que permite que personas corrientes verifiquen Bitcoin con hardware modesto.
Esto contrasta de forma deliberada con las redes que usan un lenguaje de contratos Turing completo. Esa mayor expresividad ha producido repetidamente comportamientos inesperados, fondos congelados y exploits que han drenado valor por cientos de millones de Euro o Dólar. En esas plataformas, los tokens también pueden ser congelados o confiscados por el emisor o por una organización que los controle. Bitcoin eligió un lenguaje más pequeño y predecible precisamente para que nadie tenga ese tipo de interruptor sobre tus monedas.
Si todavía no has leído cómo la red comprueba una transacción, Cómo se verifican las transacciones de Bitcoin es un buen complemento para este artículo.
La pila: cómo razona Script
El Bitcoin Script es un lenguaje basado en pila. Una pila es un simple montón de datos en el que solo puedes añadir un elemento arriba (un "push") o quitar un elemento de arriba (un "pop"). Lo último que pones es lo primero que quitas. Los ordenadores manejan este tipo de memoria de forma muy eficiente, aunque a los humanos nos resulte algo extraño.
Por culpa de la pila, Script no se escribe como solemos escribir las operaciones matemáticas. En lugar de escribir 9 más 12, escribes primero los dos números y después la operación: 9 12 OP_ADD. Los dos números se colocan en la pila, y luego OP_ADD los retira a ambos, los suma y vuelve a colocar el resultado.
Los comandos como OP_ADD se llaman opcodes, abreviatura de operation code. Son los verbos del lenguaje. Hay alrededor de 80 opcodes activos, que abarcan operaciones matemáticas simples, comparaciones, hashing criptográfico y comprobación de firmas. Cada uno retira algunos elementos de la pila, hace su trabajo y puede volver a colocar un resultado.
Aquí tienes un ejemplo completo, aunque algo tonto, de un script que funciona:
9 12 OP_ADD 21 OP_EQUAL
Leyendo de izquierda a derecha: coloca 9, coloca 12, luego OP_ADD los sustituye por 21. Ahora coloca otro 21. Por último OP_EQUAL retira los dos valores, ve que coinciden y coloca un 1. Queda un solo 1 en la pila, así que el script es válido. En términos sencillos, esta salida está bloqueada detrás del acertijo "dame dos números que sumen 21", y cualquiera que sepa aritmética básica podría desbloquearla.
Scripts de bloqueo y scripts de desbloqueo
En Bitcoin ese único script está en realidad dividido en dos mitades que viven en lugares distintos.
El script de bloqueo, técnicamente el scriptPubKey, va adjunto a una salida. Establece las condiciones para gastar. En el ejemplo anterior, la parte de bloqueo es OP_ADD 21 OP_EQUAL, la regla que hay que cumplir.
El script de desbloqueo, técnicamente el scriptSig, lo aporta más tarde quien quiere gastar esa salida. Proporciona los valores de entrada que satisfacen la regla. En el ejemplo, la parte de desbloqueo es 9 12, la respuesta al acertijo.
Así que enviar Bitcoin a alguien significa en realidad crear una salida cuyo script de bloqueo solo esa persona puede satisfacer. La versión clásica bloquea las monedas a una clave, de modo que solo quien posea la clave privada correspondiente puede producir un script de desbloqueo válido.
Hay un detalle que confunde a casi todo el mundo. Aunque el script de desbloqueo lo aporta quien gasta después de que la salida ya exista, cuando un nodo ejecuta la validación completa coloca primero el script de desbloqueo, y luego el script de bloqueo. El script de desbloqueo deja los datos en la pila, y el script de bloqueo después los comprueba.
How Locking and Unlocking Fit Together
Unlocking Script
scriptSig
Provided by the spender.
Locking Script
scriptPubKey
Attached to the output.
During validation the unlocking script runs first, then the locking script.
If the combined script leaves a single TRUE on the stack, the output is unlocked.
Cómo se valida un script
Un nodo valida una transacción combinando los scripts de desbloqueo y de bloqueo y ejecutándolos de izquierda a derecha. El resultado es binario.
Un script es válido si, al terminar, queda exactamente un elemento distinto de cero en la pila. En la práctica eso significa un único OP_1, o cualquier valor que cuente como "verdadero".
Un script es no válido si al final la pila está vacía, si lo único que queda es un cero, si queda más de un elemento, o si el script se interrumpe antes de tiempo. No hay un "quizá". O se cumplen las condiciones, o las monedas no se mueven.
Esta claridad de pasa o no pasa es lo que hace que Bitcoin sea verificable. Cada nodo ejecuta los mismos scripts y llega a la misma respuesta, sin ambigüedad y sin depender de información externa.
Pay-to-Public-Key: el bloqueo original
El primer tipo de script estándar es Pay-to-Public-Key (P2PK). El script de bloqueo contiene simplemente una clave pública seguida del opcode OP_CHECKSIG. Para gastar, el propietario aporta una firma en el script de desbloqueo.
Bloqueo: <ClavePublica> OP_CHECKSIG
Desbloqueo: <Firma>
OP_CHECKSIG retira la firma y la clave pública, verifica que la firma fue producida por la clave privada correspondiente y coloca un 1 si todo cuadra. P2PK aparece en muchos de los primerísimos bloques, incluidas las salidas coinbase del bloque génesis.
Hoy casi nadie usa P2PK. El problema es práctico: para pagar a alguien necesitarías su clave pública completa, que es larga, ilegible y fácil de copiar mal. Satoshi resolvió esto con el siguiente patrón.
Pay-to-Public-Key-Hash: el caballo de batalla
Pay-to-Public-Key-Hash (P2PKH) guarda en el script de bloqueo solo un hash de la clave pública, no la clave en sí. Piensa en el hash como una breve huella de la clave. La clave pública real solo se revela más tarde, en el script de desbloqueo, cuando se gastan las monedas.
El hash se obtiene ejecutando SHA-256 y después RIPEMD-160, una combinación que Bitcoin envuelve en un único opcode llamado OP_HASH160. El resultado es de solo 160 bits, mucho más corto que la clave pública. A partir de ese hash, con cierta codificación y un checksum, una wallet construye la conocida dirección de Bitcoin. Un detalle en el que merece la pena detenerse: las direcciones no existen realmente dentro de la blockchain. Son una comodidad creada por las wallets por encima de estos hashes. Lo que el protocolo ve es el hash.
El compromiso es que la clave pública ya no es visible en la salida, y sin embargo OP_CHECKSIG la necesita para verificar la firma. Así que quien gasta debe aportar tanto la clave pública como la firma, y el script comprueba primero que la clave aportada realmente produce el hash guardado en el bloqueo.
Bloqueo: OP_DUP OP_HASH160 <HashClavePublica> OP_EQUALVERIFY OP_CHECKSIG
Desbloqueo: <Firma> <ClavePublica>
Para profundizar en el propio paso de hashing, consulta ¿Qué es un hash?.
Recorrido paso a paso de un script P2PKH
Aquí tienes el script P2PKH completo ejecutándose paso a paso. El script de desbloqueo va primero.
- La firma y la clave pública se colocan en la pila.
OP_DUPduplica el elemento de arriba, la clave pública, porque el script necesita una copia para aplicar el hash y otra copia para verificar la firma más adelante.OP_HASH160toma la copia superior de la clave pública y le aplica el hash, dejando en la pila un nuevo hash de la clave pública.- El hash esperado del script de bloqueo se coloca en la pila, y
OP_EQUALVERIFYcompara los dos hashes. Si difieren, el script falla de inmediato. Si coinciden, ambos se retiran y la ejecución continúa. - Lo que queda es ahora, de hecho, un script P2PK: una firma y una clave pública.
OP_CHECKSIGverifica la firma frente a la clave y coloca un 1.
Queda un solo 1 en la pila, así que la salida queda desbloqueada. La mecánica es idéntica tanto si las monedas se bloquearon con el P2PKH legacy como con su equivalente moderno de SegWit, P2WPKH. Solo cambia el lugar donde se almacenan los datos de la firma.
P2PKH Script Execution
Step through how a node unlocks a Pay-to-Public-Key-Hash output.
Stack (top to bottom)
Operation
Initial State
The script is ready. The unlocking script runs first, then the locking script.
Scripts multifirma
Uno de los trucos más útiles de Script es exigir más de una firma para gastar. Un script multisig estándar, de tipo P2MS, codifica una regla "m de n": de entre n claves públicas listadas, cualquier conjunto de m firmas válidas desbloquea los fondos.
Un multisig 2 de 3, por ejemplo, necesita 2 firmas de un conjunto de 3 claves. Es la base de la custodia compartida, donde ninguna clave por sí sola puede mover el dinero. Sustenta las configuraciones multifirma que tratamos en nuestros artículos de seguridad.
Bloqueo: OP_2 <ClavePub1> <ClavePub2> <ClavePub3> OP_3 OP_CHECKMULTISIG
Desbloqueo: <Firma1> <Firma2>
OP_CHECKMULTISIG comprueba tanto que esté presente el número requerido de firmas válidas como que cada una pertenezca a una de las claves listadas. Escrito directamente así, sin embargo, el multisig tiene la misma incomodidad que P2PK. Quien envía tiene que conocer cada clave pública y el script exacto, la salida se vuelve grande y cara, y tu configuración de seguridad queda expuesta on-chain a la vista de todos. El siguiente patrón resuelve todo eso de golpe.
Pay-to-Script-Hash: ocultar la complejidad
Pay-to-Script-Hash (P2SH) te permite bloquear las monedas al hash de un script en lugar de al script en sí. Tu script personalizado completo, llamado redeem script, permanece oculto hasta que gastas.
Al enviar a una salida P2SH, el script de bloqueo contiene solo el hash. Quien envía no necesita conocer tu estructura multisig ni tus condiciones personalizadas. Simplemente paga a una dirección corta que empieza por el dígito 3. Tu redeem script, junto con los datos que lo satisfacen, se aporta solo más tarde en el script de desbloqueo.
Bloqueo: OP_HASH160 <HashScript> OP_EQUAL
Desbloqueo: <Firma1> <Firma2> <RedeemScript>
La validación ocurre en dos fases. Primero el script exterior confirma que el redeem script aportado produce el hash que hay en el bloqueo. Después el redeem script se desempaqueta y se ejecuta como un script por derecho propio, frente a las firmas aportadas. Solo si ambas fases pasan se mueven las monedas. P2SH te da tres ventajas juntas: salidas más pequeñas y baratas, una dirección estandarizada y limpia, y tus condiciones mantenidas en privado hasta el momento en que gastas.
Los principales tipos de script
Aunque puedes construir casi cualquier script de bloqueo que quieras, la mayoría de los nodos solo retransmiten un pequeño conjunto de patrones estándar. La tabla siguiente presenta los tipos de script que han dado forma a Bitcoin, desde la era legacy hasta SegWit y Taproot, con sus prefijos de dirección y el lugar donde cada uno almacena los datos de desbloqueo.
La distinción entre legacy y SegWit importa. Los scripts legacy (P2PK, P2PKH, P2MS, P2SH) ponen sus datos de desbloqueo en el scriptSig. Los scripts SegWit (P2WPKH, P2WSH, P2TR) los ponen en cambio en un campo aparte llamado witness, que es lo que solucionó la maleabilidad de las transacciones y rebajó las comisiones.
Standard Script Types
| Type | Pattern | Address | Unlocking | Era |
|---|---|---|---|---|
P2PK Pay to Public Key | <PubKey> OP_CHECKSIG | none | scriptSig | Legacy |
P2PKH Pay to Public Key Hash | OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG | 1... | scriptSig | Legacy |
P2MS Bare Multisig | OP_m <PubKey> ... <PubKey> OP_n OP_CHECKMULTISIG | none | scriptSig | Legacy |
P2SH Pay to Script Hash | OP_HASH160 <ScriptHash> OP_EQUAL | 3... | scriptSig | Legacy |
P2WPKH Pay to Witness Public Key Hash | OP_0 <PubKeyHash> | bc1q... | witness | SegWit |
P2WSH Pay to Witness Script Hash | OP_0 <ScriptHash> | bc1q... | witness | SegWit |
P2TR Pay to Taproot | OP_1 <TaprootOutputKey> | bc1p... | witness | Taproot |
P2PK
Pay to Public Key
Pattern
<PubKey> OP_CHECKSIG
Address
noneUnlocking
scriptSigP2PKH
Pay to Public Key Hash
Pattern
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Address
1...Unlocking
scriptSigP2MS
Bare Multisig
Pattern
OP_m <PubKey> ... <PubKey> OP_n OP_CHECKMULTISIG
Address
noneUnlocking
scriptSigP2SH
Pay to Script Hash
Pattern
OP_HASH160 <ScriptHash> OP_EQUAL
Address
3...Unlocking
scriptSigP2WPKH
Pay to Witness Public Key Hash
Pattern
OP_0 <PubKeyHash>
Address
bc1q...Unlocking
witnessP2WSH
Pay to Witness Script Hash
Pattern
OP_0 <ScriptHash>
Address
bc1q...Unlocking
witnessP2TR
Pay to Taproot
Pattern
OP_1 <TaprootOutputKey>
Address
bc1p...Unlocking
witnessP2PK and bare P2MS have no standard address format. Multisig is almost always wrapped in P2SH or P2WSH today.
SegWit y Taproot: más allá del Script clásico
La actualización SegWit de 2017 movió los datos de las firmas fuera del cuerpo principal de la transacción y los llevó al campo witness. Esto resolvió un problema de larga data llamado maleabilidad de transacciones, en el que la firma visible podía retocarse para cambiar el identificador de una transacción sin cambiar su significado, y además abarató la inclusión de los datos de firma. P2WPKH y P2WSH son simplemente las versiones SegWit de P2PKH y P2SH, y producen direcciones que empiezan por bc1q.
Resulta interesante que estos nuevos tipos de script apenas usan todo el lenguaje Script. Cada uno sigue un patrón interno fijo que los nodos ejecutan de una manera prefijada, que es exactamente la simplificación de "basta con comprobar una clave y una firma" que el Script clásico hacía posible pero no imponía. El lenguaje completo sigue vivo dentro de P2WSH, donde puedes envolver cualquier script personalizado que necesites.
Pay-to-Taproot (P2TR), activado en noviembre de 2021, es el estándar más reciente y produce direcciones que empiezan por bc1p. Combina las firmas Schnorr con una estructura llamada MAST (Merkelized Abstract Syntax Trees), que permite codificar muchas condiciones de gasto alternativas en un árbol. Lo crucial es que solo se revela la rama que realmente usas al gastar. Una wallet con elaboradas condiciones de respaldo y recuperación puede así gastar de una forma idéntica a un pago corriente de clave única, lo que mejora tanto la privacidad como la eficiencia.
Más allá de las firmas: timelocks y acertijos
Script puede expresar mucho más que "demuestra que posees esta clave". Dos opcodes añaden la dimensión del tiempo. OP_CHECKLOCKTIMEVERIFY (introducido con BIP 65) hace que una salida no se pueda gastar hasta una fecha o una altura de bloque elegidas. OP_CHECKSEQUENCEVERIFY (BIP 112) impone un retraso relativo, medido desde que se recibieron las monedas. Juntos hacen que condiciones como "estos fondos no pueden moverse durante seis meses" sean exigibles por el propio protocolo.
Estos timelocks son los ladrillos de construcciones más avanzadas. Un Hash Time Locked Contract (HTLC), por ejemplo, combina un acertijo de hash con un timelock, de modo que un pago o bien se completa cuando se revela un secreto, o bien se reembolsa tras una fecha límite. Ese patrón es lo que hace posible la Lightning Network.
Script también permite acertijos puros. Un acertijo de hash bloquea las monedas detrás de "aporta datos que produzcan este hash". Existe incluso un acertijo de colisión de hash que paga a quien sea capaz de aportar dos entradas distintas que produzcan el mismo hash, en la práctica una recompensa pública sobre una función de hash rota. Y el opcode especial OP_RETURN te permite adjuntar un pequeño dato a una salida marcándola como permanentemente no gastable, una forma limpia de anclar información en la cadena sin inflar el conjunto de monedas gastables.
Los límites que mantienen seguro a Bitcoin
Script viene con límites estrictos de tamaño, y existen por la misma razón por la que el lenguaje evita los bucles: mantener la verificación rápida e impedir que alguien lo convierta en un arma contra la red.
Los límites duros de validez son claros. Un script completo no puede superar los 10.000 bytes. Puede ejecutar como mucho 201 opcodes, sin contar las operaciones que solo colocan datos en la pila. Ningún elemento individual colocado en la pila puede superar los 520 bytes, y la propia pila no puede contener más de 1.000 elementos a la vez. Incumple cualquiera de estos y el script es no válido, sin más.
También hay una capa más blanda. Un script puede ser perfectamente válido pero no estándar, lo que significa que los nodos se negarán a retransmitirlo por la red aunque un minero todavía pudiera incluirlo en un bloque. Es una medida de seguridad: solo los patrones estándar bien probados circulan libremente, así que un atacante no puede inundar la red con scripts raros y lentos de verificar. En la práctica, una transacción no estándar hay que entregarla directamente a un minero o minarla tú mismo.
Por qué esto importa
Es tentador ver los límites de Script como un Bitcoin que se queda atrás frente a cadenas más "programables". La verdad es la contraria. Cada restricción aquí es un intercambio deliberado de expresividad a cambio de previsibilidad, verificabilidad y seguridad.
Como ningún script puede ejecutarse para siempre, cada nodo puede confirmar la cadena entera sin confiar en nadie. Como el lenguaje es pequeño, la superficie de ataque es pequeña. Como no existe un estado global compartido en el que los contratos puedan intervenir, no hay un único punto en el que alguien pueda intervenir y congelar tus monedas. La misma flexibilidad que permite a otras redes prometer más es también lo que las ha expuesto a exploits catastróficos y lo que permite a las partes que las controlan confiscar o congelar saldos a voluntad.
Bitcoin hizo una apuesta distinta. Un lenguaje modesto y predecible, comprobado de la misma manera por todos, que protege un conjunto de reglas fijo y neutral. Eso es lo que permite a una canoa moverse por aguas abiertas sin pedir permiso, y ese es justo el objetivo. Para el panorama más amplio de cómo se aplican estas reglas en toda la red, consulta El mecanismo de consenso de Bitcoin: un análisis a fondo, y para la estructura que los scripts protegen en última instancia, ¿Qué es una blockchain?.
Datos Clave
El Bitcoin Script no es Turing completo por diseño. No tiene bucles ni recursión, así que cada script termina en un número de pasos limitado y predecible.
Cada salida lleva un script de bloqueo (scriptPubKey). Para gastarla, la transacción debe aportar un script de desbloqueo correspondiente (scriptSig, o el campo witness en SegWit).
Un script es válido cuando la ejecución deja un único valor distinto de cero en la pila. Cualquier otra cosa falla.
Un único script de Bitcoin está limitado a 10.000 bytes y a un máximo de 201 opcodes ejecutados, sin ningún elemento de datos mayor de 520 bytes.
P2WPKH (SegWit nativo, 2017) y P2TR (Taproot, 2021) son los tipos de script estándar modernos y se desbloquean mediante el campo witness en lugar del scriptSig.
Preguntas frecuentes
No, y es intencionado. El Bitcoin Script no es Turing completo, lo que significa que no puede ejecutar bucles ni programas arbitrarios. Esta decisión de diseño elimina categorías enteras de errores y hace que cada transacción sea rápida y barata de verificar, incluso en hardware modesto.
El scriptPubKey es el script de bloqueo adjunto a una salida. Establece las condiciones que deben cumplirse para gastar esas monedas. El scriptSig es el script de desbloqueo que aporta quien gasta. Proporciona los datos, normalmente una firma y una clave pública, que satisfacen esas condiciones.
Sí. El Bitcoin Script admite acertijos, timelocks y condiciones multifirma mucho más allá de una simple comprobación de firma. Los scripts personalizados son válidos y pueden minarse, pero la mayoría de los nodos solo retransmiten un pequeño conjunto de patrones estándar, así que un script no estándar es más difícil de confirmar a menos que esté envuelto en P2SH o P2WSH.
Taproot introdujo Pay-to-Taproot (P2TR), que combina las firmas Schnorr con un árbol de posibles condiciones de gasto llamado MAST. Solo se revela on-chain la rama que realmente usas, así que un contrato complejo parece idéntico a un pago simple, mejorando tanto la privacidad como la eficiencia del espacio en los bloques.
Fuentes
- 1.Greg Walker: Bitcoin Script (learnmeabitcoin.com)
- 2.Antonopoulos: Mastering Bitcoin, Chapter 7, Authorization and Authentication
- 3.Bitcoin Wiki: Script and Opcode List
- 4.BIP 16: Pay to Script Hash
- 5.BIP 141: Segregated Witness
- 6.BIP 341 and BIP 342: Taproot and Tapscript
No es asesoramiento financiero. CanoeBit publica únicamente contenido educativo. Nada de lo aquí escrito constituye una recomendación de compra, venta o tenencia de ningún activo.
Continúa la ruta Cómo funciona Bitcoin
Paso 9 de 11