En este artículo, echaremos un vistazo más de cerca a Script de Bitcoin, el lenguaje de programación interpretado por los nodos en la red. El script es lo que gobierna el mecanismo de bloqueo / desbloqueo mencionado para las cajas fuertes. A veces se hace referencia a Bitcoin como dinero programable. Debido a su naturaleza digital, permite a los usuarios un gran grado de flexibilidad a la hora de establecer condiciones sobre cómo se pueden gastar los fondos.
Hablamos de billeteras y monedas cuando hablamos de Bitcoin. Pero también podríamos pensar en las carteras como llaves, las monedas como cheques y la cadena de bloques como fila tras fila de cajas fuertes cerradas. Cada caja fuerte tiene una ranura delgada, de modo que cualquiera puede depositar cheques o mirar hacia adentro para ver cuánto valor tiene la caja fuerte. Sin embargo, solo el poseedor de la llave podrá acceder al interior.
Cuando el poseedor de una llave quiere dar dinero a otra persona, abre su caja. Extienden un nuevo cheque que hace referencia al anterior (que luego se destruye) y lo guardan en una caja que el destinatario puede abrir. Para gastar eso, el nuevo destinatario repite el proceso.
¿Cómo Funciona el Script de Bitcoin?
Siguiendo nuestra analogía anterior, se podría decir que hay dos partes en cada transacción: una llave (para desbloquear su caja) y un candado. Utiliza su llave para abrir la caja que contiene el cheque que desea enviar y luego agrega una nueva a una nueva caja con un candado diferente. Para gastar desde la nueva caja, necesita otra clave.
Suficientemente simple. También puede obtener un poco de variación en los tipos de bloqueos del sistema. Tal vez algunas cajas fuertes requieran que proporciones varias claves, y tal vez otras necesiten que demuestres que conoces un secreto. Hay un montón de condiciones que la gente puede establecer.
Nuestra clave es lo que llamamos scriptSig. El candado es nuestro scriptPubKey. Si observamos esos componentes con un poco más de detalle, veremos que en realidad están formados por bits de datos y bloques de código. Cuando se combinan, crean un programa pequeño.
Cuando realiza una transacción, está transmitiendo esa combinación a la red. Cada nodo que lo reciba comprobará el programa, que le indicará si la transacción es válida. De lo contrario, simplemente se descartará y no podrá gastar los fondos bloqueados.
Los cheques (monedas) que tiene se denominan salidas de transacciones no gastadas (UTXO). Los fondos pueden ser utilizados por cualquier persona que pueda proporcionar la llave que se ajusta a la cerradura. Si las UTXO están en su billetera, probablemente tendrán una condición que dice que solo la persona que puede demostrar la propiedad de esta clave pública puede desbloquear estos fondos. Para desbloquearlo, proporciona un scriptSig que incluye una firma digital, utilizando la clave privada que se asigna a la clave pública especificada en el scriptPubKey. Todo esto se aclarará en breve.
Entendiendo el Script de Bitcoin
El script es lo que se conoce como lenguaje basado en pilas. Todo esto significa que, cuando leemos un conjunto de instrucciones, las colocamos en lo que se puede pensar como una columna vertical. La lista A, B, C, por ejemplo, daría como resultado una pila con A en la parte inferior y C en la parte superior. Cuando las instrucciones nos dicen que hagamos algo, operamos en uno o más elementos comenzando en la parte superior de la pila.
Podemos distinguir entre los datos (cosas como firmas, hash y claves públicas) y las instrucciones (o códigos de operación). Las instrucciones eliminan datos y hacen algo con ellos. Aquí hay un ejemplo muy simple de cómo podría verse un script: <xyz> <md5 hasher> <d16fb36f0911f878998c136191af705e> <comprobar si es igual>
En rojo, tenemos los datos y en azul, tenemos los códigos de operación. Leemos de izquierda a derecha, por lo que primero colocamos la cadena <xyz> en la pila. El siguiente es el código de operación <md5 hasher>. Este no existe en Bitcoin, pero digamos que elimina el elemento superior de la pila (<xyz>) y lo codifica usando el algoritmo MD5. Luego, la salida se vuelve a agregar a la pila. La salida aquí resulta ser d16fb36f0911f878998c136191af705e.
¡Qué casualidad! Nuestro siguiente elemento para agregar es <d16fb36f0911f878998c136191af705e>, por lo que ahora nuestra pila tiene dos elementos idénticos. Por último, <comprobar si es igual> saca dos elementos de la parte superior y comprueba si son iguales. Si es así, agrega <1> a la pila. Si no, agrega <0>.
Llegamos al final de nuestra lista de instrucciones. Nuestro script podría haber fallado de dos maneras: si el elemento restante era cero o si uno de los operadores provocó que fallara cuando no se cumplieron algunas condiciones. No teníamos tales operadores en este ejemplo, y terminamos con un elemento distinto de cero (<1>), por lo que nuestro script era válido. Estas reglas también son válidas para las transacciones reales de Bitcoin. Eso fue solo un programa inventado. Veamos algunos reales ahora.
Script de Bitcoin. Pago con Clave Pública (P2PK)
Pay-to-Pubkey (P2PK) es increíblemente sencillo. Implica bloquear fondos a una clave pública en particular. Si desea recibir fondos de esta manera, debe proporcionar al remitente su clave pública, en lugar de una dirección de Bitcoin. La primera transacción entre Satoshi Nakamoto y Hal Finney en 2009 fue P2PK. La estructura se utilizó mucho en los primeros días de Bitcoin, pero hoy en día, Pay-to-Pubkey-Hash (P2PKH) la ha reemplazado en gran medida.
El script de bloqueo para una transacción P2PK sigue el formato de <clave pública> OP_CHECKSIG. Suficientemente simple. Es posible que haya adivinado que OP_CHECKSIG verifica una firma con la clave pública proporcionada. Como tal, nuestro scriptSig será una simple <firma>. Recuerde, el scriptSig es la llave de la cerradura.
No hay nada más sencillo que esto. Se agrega una firma a la pila, seguida de una clave pública. OP_CHECKSIG los muestra a ambos y verifica la firma con la clave pública. Si coinciden, agrega un <1> a la pila. De lo contrario, agrega un <0>.
Por las razones que explicaremos en la siguiente sección, P2PK ya no se usa realmente.
Script de Bitcoin. Pago a Pubkey-Hash (P2PKH)
Pay-to-Pubkey-Hash (P2PKH) es ahora el tipo de transacción más común. A menos que esté haciendo todo lo posible para descargar software arcaico, es probable que su billetera lo haga de forma predeterminada. El scriptPubKey en P2PKH es el siguiente: OP_DUP OP_HASH160 <hash de clave pública> OP_EQUALVERIFY OP_CHECKSIG
Antes de presentar el scriptSig, analicemos lo que harán los nuevos códigos de operación:
- OP_DUP: Muestra el primer elemento y lo duplica. Luego, vuelve a agregar ambos a la pila. Normalmente, esto se hace para que podamos realizar una operación en el duplicado sin afectar al original.
- OP_HASH160: Esto hace estallar el primer elemento y lo codifica dos veces. La primera ronda se procesará con el algoritmo SHA-256. La salida SHA-256 luego se hash con el algoritmo RIPEMD-160. La salida resultante se vuelve a agregar a la pila.
- OP_EQUALVERIFY: Combina otros dos operadores: OP_EQUAL y OP_VERIFY. OP_EQUAL muestra dos elementos y comprueba si son idénticos. Si es así, agrega un 1 a la pila. Si no es así, agrega un 0. OP_VERIFY muestra el elemento superior y verifica si es Verdadero (es decir, distinto de cero). Si no es así, la transacción falla. Combinado, OP_EQUALVERIFY hace que la transacción falle si los dos elementos superiores no coinciden.
Esta vez, el scriptSig se ve así: <firma> <clave pública>. Debe proporcionar una firma y la clave pública correspondiente para desbloquear las salidas P2PKH.
Hay algo que destacar. En un script de bloqueo P2PKH, la clave pública no es visible; solo podemos ver su hash. Si vamos a un explorador de blockchain y observamos una salida P2PKH que no se ha gastado, no podemos determinar la clave pública. Solo se revela cuando el receptor decide transferir los fondos.
Esto tiene algunos beneficios. La primera es que el hash de clave pública es simplemente más fácil de pasar que una clave pública completa. Satoshi lo lanzó en 2009 por esta misma razón. El hash de clave pública es lo que hoy conocemos como dirección de Bitcoin.
El segundo beneficio es que los hash de clave pública podrían proporcionar una capa adicional de seguridad contra la computación cuántica. Debido a que nuestra clave pública no se conoce hasta que gastamos los fondos, es aún más difícil para otros calcular la clave privada. Tendrían que revertir las dos rondas de hash (RIPEMD-160 y SHA-256) para obtenerlo.
Script de Bitcoin. Pago a script-Hash (P2SH)
Pay-to-Script-Hash (P2SH) fue un desarrollo muy interesante para Bitcoin. Permite al remitente bloquear fondos en el hash de un script; no necesitan saber qué hace realmente el script. Toma el siguiente hash SHA-256: e145fe9ed5c23aa71fdb443de00c7d9b4a69f8a27a2e4fbb1fe1d0dbfb6583f1
No es necesario que conozca la entrada del hash para bloquear los fondos. El gastador, sin embargo, debe proporcionar el script que se utilizó para realizar el hash y debe satisfacer las condiciones de ese script. El hash anterior se creó a partir del siguiente script: <multiplicar por 2> <4> <comprobar si es igual>
Si desea gastar las monedas vinculadas a ese scriptPubKey, no solo proporciona esos comandos. También necesita un scriptSig que haga que el script completado se evalúe como True. En este ejemplo, ese es un elemento que <multiplica por 2> para dar un resultado de <4>. Por supuesto, eso significa que nuestro scriptSig es solo <2>. En la vida real, el scriptPubKey para una salida P2SH es: OP_HASH160 <redeemScript hash> OP_EQUAL
No hay nuevos operadores aquí. Pero tenemos <redeemScript hash> como nuevo elemento. Como sugiere el nombre, es un hash del script que debemos proporcionar para canjear los fondos (llamado redeemScript ). El scriptSig cambiará dependiendo de lo que haya en el redeemScript. Sin embargo, en general, encontrará que es una combinación de firmas y las claves públicas adjuntas, seguidas del código canjeador (obligatorio): <firma> <clave pública> <redeemScript>
Nuestra evaluación difiere un poco de la ejecución de la pila que hemos visto hasta ahora. Sucede en dos partes. El primero simplemente verifica que haya proporcionado el hash correcto. Notarás que no hacemos nada con los elementos que preceden al redeemScript. No se utilizan en este momento. Hemos llegado al final de este miniprograma y el elemento superior es distinto de cero. Eso significa que es válido.
Sin embargo, aún no hemos terminado. Los nodos de red reconocen esta estructura como P2SH, por lo que en realidad tienen los elementos de scriptSig esperando en otra pila. Ahí es donde se utilizará la firma y la clave pública.
Hasta ahora, hemos tratado el redeemScript como un elemento. Pero ahora, se interpretará como instrucciones, que podrían ser cualquier cosa. Tomemos el ejemplo de un script de bloqueo P2PKH, al que debemos proporcionar la <firma> y la <clave pública> que coinciden con un <hash de clave pública> dentro del <redeemScript>.
Una vez que se haya expandido su código redeemScript, puede ver que tenemos una situación que se parece exactamente a una transacción P2PKH normal. A partir de ahí, simplemente ejecútelo como lo haría con uno normal.
Hemos demostrado lo que se llama un script P2SH (P2PKH) aquí, pero es poco probable que encuentre uno de esos en la naturaleza. Nada le impide hacer uno, pero no le brinda beneficios adicionales y termina ocupando más espacio en un bloque (y, por lo tanto, cuesta más).
P2SH generalmente es útil para cosas como transacciones de múltiples firmas o compatibles con SegWit. Las transacciones multifirma pueden tener un tamaño muy grande, ya que pueden requerir varias claves. Antes de la implementación de Pay-to-Script-Hash, un remitente tendría que enumerar todas las claves públicas posibles en su script de bloqueo.
Pero con P2SH, no importa cuán complejas sean las condiciones de gasto. El hash de redeemScript siempre tiene un tamaño fijo. Por lo tanto, los costos se transfieren a los usuarios que desean desbloquear el script de bloqueo.
La compatibilidad con SegWit es otro caso en el que P2SH resulta útil (entraremos en detalles sobre cómo difiere la estructura de la transacción en la siguiente sección). SegWit fue una bifurcación suave que resultó en un cambio en los formatos de bloque / transacción. Debido a que es una actualización opcional, no todo el software de billetera reconoce los cambios.
Eso no importa si los clientes envuelven el hash del script SegWit en P2SH. Como ocurre con todas las transacciones de este tipo, no es necesario que sepan cuál será el código de desbloqueo de redeemScript.
Script de Bitcoin. Transacciones SegWit (P2WPKH y P2WSH)
Para comprender el formato de transacción en SegWit, solo necesita saber que ya no solo tenemos un scriptSig y un scriptPubKey. Ahora, también tenemos un nuevo campo llamado testigo. Los datos que usamos para mantener en el scriptSig se mueven al testigo, por lo que el scriptSig está vacío.
Si ha encontrado direcciones que comienzan con ‘bc1’, esas son las que llamamos SegWit-native (a diferencia de las compatibles con SegWit, que comienzan con un ‘3’ ya que son direcciones P2SH).
Pago-a-Testigo-Pubkey-Hash (P2WPKH)
Pay-to-Witness-Pubkey-Hash (P2WPKH) es la versión SegWit de P2PKH. Nuestro testigo se ve así: <firma> <clave pública>. Observará que es lo mismo que el scriptSig de P2PKH. Aquí, el scriptSig está vacío. Mientras tanto, scriptPubKey se parece a lo siguiente: <OP_0> <hash de clave pública>
Eso se ve un poco extraño, ¿no? ¿Dónde están los códigos de operación que nos permiten comparar la firma, la clave pública y su hash? No mostramos operadores adicionales aquí, porque los nodos que reciben la transacción saben qué hacer con ella en función de la longitud de <hash de clave pública>. Calcularán la longitud y comprenderán que debe ejecutarse con el mismo estilo que una buena transacción P2PKH antigua.
Los nodos no actualizados no saben cómo interpretar la transacción de esa manera, pero no importa. Según las viejas reglas, no hay testigos, por lo que leen un scriptSig vacío y algunos datos. Evalúan esto y lo marcan como válido; en lo que a ellos respecta, cualquiera podría gastar el resultado. Esta es la razón por la que SegWit se considera una horquilla blanda compatible con versiones anteriores.
Pago-a-Testigo-Script-Hash (P2WSH)
Pay-to-Witness-Script Hash (P2WSH) es el nuevo P2SH. Si ha llegado hasta aquí, probablemente pueda averiguar cómo se verá, pero lo revisaremos de todos modos. Nuestro testimonio es lo que normalmente pondríamos en el scriptSig. En un P2WSH que envuelve una transacción P2PKH, por ejemplo, podría verse así: <firma 1> <clave pública>. Aquí está nuestro scriptPubKey: <OP_0> <script hash>
Se mantienen las mismas reglas. Los nodos SegWit leen la longitud del hash del script y determinan que es una salida P2WSH, que se evalúa de manera similar a P2SH. Mientras tanto, los nodos antiguos simplemente lo ven como una salida que cualquiera puede gastar.
Pensamientos Finales
En este artículo, hemos aprendido un poco sobre los componentes básicos de Bitcoin. Resumámoslos rápidamente:
Script de Bitcoin | Descripción |
---|---|
Pago con clave pública (P2PK) | Bloquea fondos en una clave pública en particular |
Pago a Pubkey-Hash (P2PKH) | Bloquea fondos en un hash de clave pública en particular (es decir, una dirección) |
Pago a script-Hash (P2SH) | Bloquea los fondos en el hash de un script que el destinatario puede proporcionar |
Pago-a-Testigo-Pubkey-Hash (P2WPKH) | La versión SegWit de P2PK |
Pago-a-Testigo-Script-Hash (P2WSH) | La versión SegWit de P2SH |
Una vez que profundiza en el Script de Bitcoin, comienza a comprender por qué tiene tanto potencial. Las transacciones pueden estar formadas por muchos componentes diferentes. Al manipular estos bloques de construcción, los usuarios tienen una gran flexibilidad cuando se trata de establecer condiciones sobre cómo y cuándo se pueden gastar los fondos.