Tutorial: Como decodificar una transaccion Counterparty en Rust
- Counterparty: Es un metaprocolo que usa el OP_RETURN de bitcoin como almacenamiento y registro de transacciones.
- Rust: Lenguaje de Programacion compilado de alto rendimiento.
- OP_RETURN: Es un opcode en el script de Bitcoin que marca una transacción como inválida si se intenta gastar, esencialmente creando una salida que no se puede gastar. A pesar de que la transacción en sí es válida y puede ser incluida en un bloque, las salidas que contienen OP_RETURN no pueden ser utilizadas como entradas en transacciones futuras.
Historia de Counterparty
Sus fundadores Robert Dermody, Adam Krellenstein y Evan Wagner Lanzaron Counterparty en enero del 2014 en un intento de usar la blockchain de bitcoin como capa para ejecutar el metaprotocolo de transacciones en el OPCODE OP_RETURN.
Los OP CODES son un metalenguaje de scripting de bitcoin, que permiten realizar operaciones lógicas sencillas, esto permitió que se pudiesen grabar un registro de transacciones en Bitcoin. Desde el 2014 se han lanzado numerosos activos, de hecho Counterparty ha sido el protocolo pionero en la acuñación de NFTs (Token no fungibles) mucho antes que Ethereum, y es a su vez la blockchain conocida por iniciar un movimiento de memes, trolls y pepes de internet, siendo la base de operaciones de verdaderos coleccionistas de memes y activos de alto valor.
Como se ve una Transacción en Counterparty?
01000000012162ea3e786716e164e1a1d7aeb9483261e0fe011fde940ff9876b76e15bef6b01000
0006a47304402207bdf83995b082bb5f71eb5fe391d47fcdd243f66eb4345dde0b83ed635b3da24
02204c47944f962622b3f70e13978491affa10ce68838528ada8712780555a214da2012103851e3
9acc36f6f8c2e2afb196e349455b0c276a139fb6d5c658be733f633a4f4ffffffff020000000000
000000306a2e3191977b5d15331c37ebd99b9beb3ac704de6b78a7111281af2121706dfda547376
5e68c2ffddc8c1a4e9763cd1c28880400000000001976a914e9170009761869cb7bbd0e8d8c2add
ccd9db514588ac00000000
Tomemos como ejemplo una transacción del primer NFT de la historia de Counterparty. OLGA vamos a diseccionar la transacción poco a poco.
El primer paso es decodificar la transacción a un formato JSON estándar que podamos entender, esto lo podemos hacer con la siguiente función de RUST que podemos encontrar en nuestro repositorio que hace parte de una API para decodificar y consultar transacciones en counterparty.
Enlace: https://github.com/blocklack-team/counterpartydb
1NFTzmvY1RE8xg6jJaK8TewZAvbJwnUC6G
6bef5be1766b87f90f94de1f01fee0613248b9aed7a1e164e11667783eea6221
Esa entrada hace referencia a una transaccion entrante de 298000 satoshis. aunque en el objeto JSON veamos que el value es 0, esto es asi por que la funcion Rust solo decodifica la transaccion y no consulta que cantida de satoshis tiene el UTXO de entrada. Pero la parte que nos permitira identificar si es una transaccion de Counterparty es el vout (UTXO de salida) que contiene un OP_RETURN. este es un script, y esta en dos formatos, en scriptpubkey_asm y scriptpubkey en hexadecimal, vamos a diseccionar el scriptpubkey en hexadecimal.
6a2e3191977b5d15331c37ebd99b9beb3ac704de6b78a7111281af2121706dfda5473765e68c2ffddc8c1a4e9763cd1c
El primer byte 6a nos inidcan que el script es un OP_RETURN el siguiente byte contiene la longitud del script 2e que en numero entero es 46, una vez identificados la longitud del script de 46 bytes, sabemos que el mensaje posiblemente este en los siguientes 46 bytes.
3191977b5d15331c37ebd99b9beb3ac704de6b78a7111281af2121706dfda5473765e68c2ffddc8c1a4e9763cd1c
Una vez que tenemos el mensaje counterparty el siguiente paso es descifrar el mensaje, los mensajes enchance send de counterparty usan el cifrado RC4 que es un algoritmo de cifrado rapido y liviano. el siguiente bloque de código descifra el mensaje usando como clave el txId de la entrada vin(UTXO).
434e54525052545902000000000003ded8000000000000000105a27e34308292591f706e989290629cb9dbd83749
Este es el resultado y asi se ve una transaccion de counterparty.
Decodificando la transacción de counterparty.
Una vez que se obtiene el mensaje de counterparty, debemos diseccionar cada byte para saber que tipo de transaccion es.
Los primeros 8 bytes son 434e545250525459 si transformamos los 8 bytes a un formato ASCII obtenemos CNTRPRTY , el byte en la position numero 9 contiene el identificador de la transaccion, en este caso es 02 , este es el identificador que nos indica que el mensaje es un enchance send.
000000000003ded8000000000000000105a27e34308292591f706e989290629cb9dbd83749
El cuerpo de la transacción se ve así, ahora lo siguiente es identificar el tipo de activo, la dirección de destino y la cantidad. para identificar el tipo de activo contamos desde la posicion de 9 byte y nos movemos 8 bytes a la derecha, 000000000003ded8 este rango de bytes contiene el identificador del activo que esta comprimido. para obtener el nombre del activo aplicamos la siguiente funcion enviando los bytes como u64 o numero entero.
Si el identificador es 0 el activo enviado es BTC, si es 1 es XCP que es el activo principal de Counterparty, pero si el identificador del activo esta en este rango
id >= 95428956661682177 and id < 18446744073709551615
El activo es numerico, si ninguna de las condiciones anteriores se cumplen, los bytes en numero entero se decodifican y se obtiene el nombre del mensaje en este caso es OLGA.
- Para saber la cantidad que se envia en la transaccion sustraemos los bytes desde la posicion 16 hasta la posicion 24, 0000000000000001 estos 8 bytes contienen la cantidad de envio, si convertimos de bytes a entero obtenemos 1.
Ahora ya hemos identificado el activo y la cantidad, ahora el ultimo paso es identificar a que dirección se esta enviando. el byte en la posicion 25 hace referencia a la version de la direccion. 05 si es base58 para direcciones legacy o pay to hash, 80 si es una direccion bech32 que es usada por direcciones segwit. en este caso la version del bytes es 05 lo que indica que es una direccion legacy. la siguiente funcion decodifica la direccion en hexadecimal a una direccion en texto compatible con cualquier billetera Bitcoin.
ahora que ya tenemos la transacción completa decodificada sabemos que
1NFTzmvY1RE8xg6jJaK8TewZAvbJwnUC6G envio la cantidad 1 del NFT OLGA a la dirección 3GWCaREJRyrcB4iccpDw9kcnctJpPDAjKh
Algo curioso del la dirección del remitente es que sus primeras letras son 1 NFT 🙂