¿Qué es un OP_CODE?

Las instrucciones e indicaciones que se utilizan en informática para la programación de equipos de computación y máquinas virtuales son conocidas como OP_CODE (Operation Code) o códigos de operación.

Estos códigos indican las operaciones o funciones que deben ser realizadas y ejecutadas por el hardware o software. En el caso de los hardware, la forma de los OP_CODE estará definida según el tipo de arquitectura del conjunto de operaciones (ISA) del ordenador. Es decir, según las instrucciones que posea el dispositivo para la interpretación y ejecución de los códigos de operación. En caso de los software, los OP_CODE están creados con un tipo de ISA, o arquitectura de operaciones, diseñada especialmente para ser interpretada por la máquina virtual o el interpretador de bytes.

Los códigos de operación permiten que un programa de computación pueda emitir una orden al computador y que éste la intérprete y la ejecute.

¿Cómo funciona un OP_CODE?

Para que las máquinas, equipos y ordenadores puedan recibir y ejecutar una orden específica, es necesario emitir instrucciones en un lenguaje que puedan entender. Por ello, estas instrucciones son escritas en un lenguaje de programación que contiene códigos de operación.

Estos códigos están escritos en un idioma que generalmente conocemos, como el inglés, y luego son traducidos por un programa compilador o traductor para que las máquinas lo entiendan en su lenguaje binario. Es decir, las instrucciones mnemónicas escritas en nuestro lenguaje para la interpretación de nosotros los humanos, tienen su equivalente en lenguaje binario para que las máquinas puedan interpretarlas fácilmente. Y así poder actuar sobre la instrucción recibida y ejecutarla de forma correcta.

Ejemplo de un OP_CODE

Un buen ejemplo de OP_CODE lo podemos ver en la siguiente imagen:

En ella podemos ver algunos OP_CODES pertenecientes a las instrucciones capaces de ejecutar un procesador o CPU de computadora (específicamente los x86 de Intel). Como podrás ver es algo críptico de leer y difícilmente se puede programar usando el mismo (aunque algunos desarrollos se hacen en este tipo de lenguaje debido a su velocidad).

La situación en el mundo cripto, no es muy distinta y en Bitcoin por ejemplo, podemos ver algo como esto:

Ciertamente es igual de críptico, pero esta sencilla sentencia es equivalente a una transacción en Bitcoin. Si quieres saber más de la misma, puedes leer nuestro artículo dedicado a Bitcoin Script donde explicamos a profundidad que hacen exactamente estas instrucciones.

Tipos de códigos de operación en el script de Bitcoin

Los OP_CODES para el Bitcoin Script pueden clasificarse según la función e indicaciones que vayan a ejecutar en el sistema. Por ejemplo, estos códigos pueden ser utilizados para eliminar, añadir, mover o girar elementos en la pila, analizar y realizar operaciones aritméticas, validar o invalidar transacciones, entre muchas otras más funciones.

A continuación presentaremos un listado de los códigos de operación clasificados según su tipo y funciones. No obstante es importante señalar que esta lista no es concluyente ni radical, puesto que existen muchos códigos de operación en el script de Bitcoin y aquí sólo se mencionan algunos de ellos.

Códigos de inserción

OP_0 = 0x00 y OP_FALSE = OP_0: ambos códigos empujan o agregan un elemento o una matriz vacía de bytes a la pila. Ninguno de los dos debe ser confundido con NO_OP

OP_PUSHDATA1 = 0x4c, OP_PUSHDATA2 = 0x4d y OP_PUSHDATA4 = 0x4e: En el primer código, el siguiente byte contiene el número de bytes que se insertarán en la pila. En el segundo código los siguientes 2 bytes contienen el número de bytes que se insertarán en la pila, mientras que en el tercero son los siguientes 4 bytes los que contienen el número de bytes que se añadirán a la pila. En estos códigos el proceso de añadir los bytes se realizará en formato endian.

OP_NEGATIVE = 0x4f y OP_TRUE = OP_1: En este caso, el número negativo -1 se empuja a la pila, mientras que en OP_TRUE el número positivo 1 se empuja a la pila.

Códigos de control

OP_NOP = 0x61: este código no ejecuta ninguna operación, pero se utiliza en los casos en los que haya que rellenar algún espacio dentro del programa.

OP_IF = 0x63 y OP_NOTIF = 0x64: ambos códigos se utilizan para ejecutar las declaraciones. En el primer código, se ejecutan si el valor de la pila superior no es FALSE; en el segundo código, se ejecutan si los valores de la pila superior si es FALSE. Así en ambos casos, el valor de la pila superior se elimina.

OP_ELSE = 0x67: se utiliza para afirmar o negar las declaraciones. En caso de haberse ejecutado los dos códigos anteriores (OP_IF y OP_NOTIF) las declaraciones se niegan. En caso de no haberse ejecutado, las declaraciones se afirman.

OP_ENDIF = 0x68: se utiliza para terminar un bloque, ya que sin esto, las transacciones no serían válidas. Un código OP_ENDIF sin un código OP_IF anterior tampoco será válido.

OP_RETURN = 0x6a: se utiliza para marcar una salida de transacción como no válida.

Códigos de aplicaciones y operaciones de pila

OP_TOALTSTACK = 0x6b y OP_FROMALTSTACK = 0x6c: el primer código se emplea para mover la entrada en la parte superior de la pila alternativa y eliminarla de la pila principal. El segundo código ejecuta el proceso contrario; mueve la entrada hacia la parte superior de la pila principal y la elimina de la pila alternativa.

OP_DROP = 0x75 y OP_DUP = 0x76: se utilizan para eliminar un elemento de la pila superior y para duplicar un elemento de la pila superior, respectivamente.

Códigos de operaciones de empalmes

OP_SIZE = 0x82: este código empuja la longitud de la cadena del elemento superior de la pila, sin reventarlo.

Los códigos OP_SUBSTR = 0x7f, OP_LEFT = 0X80 y OP_RIGHT = 0x81 han sido deshabilitados. Se utilizaban para:

  • Devolver una sección en una cadena.
  • Mantener sólo los caracteres restantes de un punto específico en una cadena, y
  • Mantener sólo los caracteres restantes al lado derecho de un punto específico en una cadena, respectivamente.

Códigos para operaciones numéricas

OP_1ADD = 0x8b y OP_1SUB = 0x8c: se utilizan para añadir (sumar) o eliminar (restar) 1 a la entrada respectivamente.

OP_2MUL = 0x8d y OP_1DIV = 0x8e: se utilizaban para multiplicar o dividir por 2 la entrada respectivamente, pero ambos fueron deshabilitados.

OP_ABS = 0x90 y OP_NEGATE = 0x8f: se utilizan para invertir el signo de la entrada, es decir, para hacer positiva o negativa la entrada respectivamente.

OP_MIN = 0xa3 y OP_MAX = 0xa4: estos códigos se utilizan para devolver el menor valor de a y b, o en su caso para devolver el mayor valor de a y b respectivamente.

Códigos para codificación y encriptación

OP_RIPEMD160 = 0xa6: se emplea para codificar la entrada con el algoritmo RIPEMD-160, con la finalidad de obtener hash más cortos pero igualmente seguros para la creación de direcciones.

OP_SHA1 = 0xa7: se emplea para codificar la entrada con el algoritmo SHA-1, el cual se utiliza para calcular y obtener un valor de comprobación única para todas las entradas no mayor a 264 – 1 bit.

OP_SHA256 = 0xa8: se emplea para codificar la entrada con el algoritmo SHA-256.

OP_HASH160 = 0xa9: se utiliza para codificar la entrada 2 veces. La primera codificación a través del algoritmo SHA-256 y la segunda con el algoritmo RIPEMD-160

OP_HASH256 = 0xaa: se utiliza para codificar la entrada 2 veces a través del algoritmo SHA-256.

OP_CHECKMULTISIG = 0xae: se emplea para realizar una comparación entre la primera firma con cada clave pública hasta encontrar una coincidencia ECDSA. Luego repite el proceso con la segunda firma y las claves públicas posteriores y así sucesivamente hasta que todas las firmas hayan sido verificadas.

Códigos para bloqueo de tiempo

OP_CHECKLOCKTIMEVERIFY = 0xb1: este código marca como no válida la entrada si el elemento superior de la pila es mayor que el campo establecido como nLockTime, que representa la condición que se debe cumplir. En la aplicación de este código hay varias implicaciones que también hacen que la entrada sea inválida. Por ejemplo, si la pila está vacía o su elemento superior es negativo, entre otros.

OP_CHECKSEQUENCEVERIFY = 0xb2: también se usa para marcar la entrada como no válida si el tiempo de bloqueo es diferente o mayor al valor del elemento superior de la pila.

Cada uno de estos OP_CODE realiza una función bien definida, y el arreglo conjunto de estos OP_CODE es lo que permite al Bitcoin funciona tal como lo hace. Sin embargo, los OP_CODE no son únicos de Bitcoin. Ethereum por ejemplo, también tiene su propio registro de OP_CODE que le permite introducir instrucciones a su Ethereum Virtual Machine, y de allí realizar todas las operaciones de esta blockchain. Eso va desde las transacciones más simples hasta operaciones complejas de smart contracts de esa plataforma. Lo mismo pasa con el resto de criptomonedas que tienen también sus OP_CODES o herramientas análogas para su funcionamiento.

De allí la importancia de los mismos, no solo conocerlos sino desarrollarlos para ampliar las funcionalidades de las criptomonedas y los ecosistemas que estas contienen.