name: El protocolo RGB, de la teoría a la práctica goal: Adquirir los conocimientos necesarios para comprender y utilizar el RGB objectives:


Descubrir el protocolo RGB

Sumérjase en el mundo de RGB, un protocolo diseñado para implementar y hacer cumplir los derechos digitales, en forma de contratos y activos, basado en las reglas de consenso y las operaciones de la blockchain de Bitcoin. Este completo curso de formación le guiará a través de los fundamentos técnicos y prácticos de RGB, desde los conceptos de "Validación del lado del cliente" y "Sellos de un solo uso", hasta la implementación de contratos inteligentes avanzados.

A través de un programa estructurado paso a paso, descubrirá los mecanismos de validación del lado del cliente, los compromisos deterministas en Bitcoin y los patrones de interacción entre usuarios. Aprenda a crear, gestionar y transferir tokens RGB en Bitcoin o la Lightning Network.

Tanto si eres un desarrollador, un entusiasta de Bitcoin, o simplemente tienes curiosidad por aprender más sobre esta tecnología, este curso de formación te proporcionará las herramientas y conocimientos que necesitas para dominar RGB y construir soluciones innovadoras sobre Bitcoin.

El curso se basa en un seminario en directo organizado por Fulgur'Ventures e impartido por tres profesores de renombre y expertos en RGB.

Introducción

Presentación del curso

Hola a todos, y bienvenidos a este curso de formación dedicado a RGB, un sistema de contrato inteligente validado del lado del cliente que se ejecuta en Bitcoin y la Red Lightning. La estructura de este curso está diseñada para permitir la exploración en profundidad de este complejo tema. Así es como está organizado el curso:

**Sección 1: Teoría

La primera sección está dedicada a los conceptos teóricos necesarios para entender los fundamentos de la validación del lado del cliente y RGB. Como descubrirá en este curso, RGB introduce una serie de conceptos técnicos que no suelen verse en Bitcoin. En esta sección también encontrará un glosario con definiciones de todos los términos específicos del protocolo RGB.

**Sección 2: Práctica

La segunda sección se centrará en la aplicación de los conceptos teóricos vistos en la sección 1. Aprenderemos a crear y manipular contratos RGB. También veremos cómo programar con estas herramientas. Estas dos primeras secciones están presentadas por Maxim Orlovsky.

**Sección 3: Aplicaciones

La sección final corre a cargo de otros ponentes que presentan aplicaciones concretas basadas en RGB, para poner de relieve casos de uso de la vida real.


Este curso de formación surgió originalmente de un bootcamp de desarrollo avanzado de dos semanas en Viareggio, Toscana, organizado por Fulgur'Ventures. La primera semana, centrada en Rust y SDKs, se puede encontrar en este otro curso:

https://planb.network/courses/9fbd8b57-f278-4304-8d88-a2d384eaff58

En este curso, nos centraremos en la segunda semana del bootcamp, que se centra en RGB.

Semana 1 - LNP402:

RGB-Bitcoin

Semana 2 - Formación actual CSV402:

RGB-Bitcoin

Muchas gracias a los organizadores de estos cursos en directo y a los 3 profesores que participaron:

La versión escrita de este curso de formación se redactó utilizando 2 recursos principales:

¿Listo para sumergirte en el complejo y fascinante universo de RGB? ¡Vamos allá!

RGB en teoría

Introducción a los conceptos de informática distribuida

RGB es un protocolo diseñado para aplicar y hacer cumplir derechos digitales (en forma de contratos y activos) de forma escalable y confidencial, basado en las reglas de consenso y las operaciones de la blockchain de Bitcoin. El objetivo de este primer capítulo es presentar los conceptos básicos y la terminología en torno al protocolo RGB, destacando en particular sus estrechos vínculos con conceptos básicos de computación distribuida como la Validación del lado del cliente y los Sellos de un solo uso.

En este capítulo, exploramos los fundamentos de los sistemas de consenso distribuido y vemos cómo RGB encaja en esta familia de tecnologías. También introduciremos los principios fundamentales que nos ayudan a entender por qué RGB pretende ser extensible e independiente del propio mecanismo de consenso de Bitcoin, mientras se apoya en él cuando es necesario.

Introducción

La informática distribuida, una rama específica de la informática, estudia los protocolos utilizados para hacer circular y procesar información en una red de nodos. En conjunto, estos nodos y las reglas del protocolo constituyen lo que se conoce como un sistema distribuido. Entre las propiedades esenciales que caracterizan a un sistema de este tipo se encuentran :

En particular, la noción de consenso en un sistema distribuido abarca dos aspectos:

La primera implementación funcional y sin permisos de un mecanismo de consenso distribuido fue introducida por Satoshi Nakamoto con Bitcoin, gracias al uso combinado de una estructura de datos blockchain y un algoritmo Proof-of-Work (PoW). En este sistema, la credibilidad del historial de bloques depende de la potencia de cálculo que le dediquen los nodos (mineros). Bitcoin es, por tanto, un ejemplo importante e histórico de sistema de consenso distribuido abierto a todos (sin permisos).

En el mundo del blockchain y la computación distribuida, podemos distinguir dos paradigmas fundamentales: blockchain en el sentido tradicional, y canales de estado, cuyo mejor ejemplo en producción es la Lightning Network. El blockchain se define como un registro de eventos ordenados cronológicamente, replicados por consenso dentro de una red abierta y libre de permisos. Los canales de estado, por su parte, son canales entre pares que permiten a dos (o más) participantes mantener un estado actualizado fuera de la cadena, utilizando la blockchain sólo al abrir y cerrar estos canales.

En el contexto de Bitcoin, sin duda está familiarizado con los principios de minería, descentralización y finalidad de las transacciones en la blockchain, así como con el funcionamiento de los canales de pago. Con RGB, estamos introduciendo un nuevo paradigma llamado Validación del lado del cliente, que, a diferencia de blockchain o Lightning, consiste en almacenar y validar localmente (del lado del cliente) las transiciones de estado de un contrato inteligente. Esto también difiere de otras técnicas "DeFi" (rollups, plasma, ARK, etc.), en que Client-side Validation se basa en la blockchain para evitar el doble gasto y disponer de un sistema de sellado de tiempo, manteniendo el registro de estados y transiciones fuera de la cadena, sólo con los participantes afectados.

RGB-Bitcoin

Más adelante, también introduciremos un término importante: la noción de "stash", que se refiere al conjunto de datos del lado del cliente necesarios para preservar el estado de un contrato, ya que estos datos no se replican globalmente en toda la red. Por último, veremos los fundamentos de RGB, un protocolo que aprovecha la validación del lado del cliente, y por qué complementa los enfoques existentes (blockchain y canales de estado).

Trilemas de la informática distribuida

Para entender cómo Client-side Validation y RGB abordan problemas no resueltos por blockchain y Lightning, descubramos 3 grandes "trilemas" de la computación distribuida:

1. Escalabilidad, descentralización y confidencialidad

Blockchain está muy descentralizada, pero no es muy escalable. Además, como todo está en un registro público global, la confidencialidad es limitada. Podemos intentar mejorar la confidencialidad con tecnologías de conocimiento cero (transacciones confidenciales, esquemas mimblewimble, etc.), pero la cadena pública no puede ocultar el gráfico de transacciones.

Los canales estatales (como Lightning Network) son más escalables y más privados que blockchain, ya que las transacciones tienen lugar fuera de la cadena. Sin embargo, la obligación de anunciar públicamente ciertos elementos (transacciones de financiación, topología de la red) y la supervisión del tráfico de la red pueden comprometer en parte la confidencialidad. La descentralización también se resiente: el enrutamiento requiere mucho dinero y los principales nodos pueden convertirse en puntos de centralización. Este es precisamente el fenómeno que empezamos a ver en Lightning.

Este nuevo paradigma es aún más escalable y más confidencial, porque no sólo podemos integrar técnicas de prueba de conocimiento de divulgación cero, sino que no existe un grafo global de transacciones, ya que nadie posee todo el registro. Por otro lado, también implica un cierto compromiso sobre la descentralización: el emisor de un contrato inteligente puede tener un papel central (como un "desplegador de contratos" en Ethereum). Sin embargo, a diferencia de blockchain, con Client-side Validation sólo se almacenan y validan los contratos que interesan, lo que mejora la escalabilidad al evitar la necesidad de descargar y verificar todos los estados existentes.

RGB-Bitcoin

2. Teorema CAP (Consistencia, Disponibilidad, Tolerancia a la partición)

El teorema CAP subraya que es imposible que un sistema distribuido satisfaga simultáneamente la consistencia (Consistencia), la disponibilidad (Disponibilidad) y la tolerancia a la partición (Tolerancia a la partición).

La cadena de bloques favorece la coherencia y la disponibilidad, pero no se lleva bien con la partición de la red: si no puedes ver un bloque, no puedes actuar y tener la misma visión que toda la red.

Un sistema de canales de estado tiene disponibilidad y tolerancia a la partición (ya que dos nodos pueden permanecer conectados entre sí aunque la red se fragmente), pero la coherencia global depende de la apertura y cierre de canales en la blockchain.

Un sistema como el RGB ofrece coherencia (cada participante valida sus datos localmente, sin ambigüedades) y tolerancia a la partición (mantiene sus datos de forma autónoma), pero no garantiza la disponibilidad global (todo el mundo tiene que asegurarse de que dispone de las piezas pertinentes del historial, y algunos participantes pueden no publicar nada o dejar de compartir cierta información).

RGB-Bitcoin

3. Trilema CIA (Confidencialidad, Integridad, Disponibilidad)

Este trilema nos recuerda que la confidencialidad, la integridad y la disponibilidad no pueden optimizarse al mismo tiempo. Blockchain, Lightning y Client-side Validation entran de forma diferente en este equilibrio. La idea es que ningún sistema puede ofrecerlo todo por sí solo; es necesario combinar varios enfoques (el sellado de tiempo de blockchain, el enfoque síncrono de Lightning y la validación local con RGB) para obtener un paquete coherente que ofrezca buenas garantías en cada dimensión.

RGB-Bitcoin

El papel de la cadena de bloques y la noción de fragmentación

El blockchain (en este caso, Bitcoin) sirve principalmente como mecanismo de estampado de tiempo y protección contra el doble gasto. En lugar de insertar los datos completos de un contrato inteligente o sistema descentralizado, simplemente incluimos compromisos criptográficos (commitments) a las transacciones (en el sentido de Validación del Lado del Cliente, que llamaremos "transiciones de estado"). Así :

Sharding es un concepto que tiene su origen en las bases de datos distribuidas (por ejemplo, MySQL para redes sociales como Facebook o Twitter). Para resolver el problema del volumen de datos y las latencias de sincronización, la base de datos se segmenta en shards (EE.UU., Europa, Asia, etc.). Cada segmento es consistente localmente y sólo se sincroniza parcialmente con los demás.

Para los contratos inteligentes de tipo RGB, fragmentamos en función de los propios contratos. Cada contrato es un shard independiente. Por ejemplo, si sólo tienes tokens USDT, no tienes que almacenar o validar todo el historial de otro token como USDC. En Bitcoin, el blockchain no hace sharding: tienes un conjunto global de UTXOs. Con la validación del lado del cliente, cada participante conserva sólo los datos del contrato que posee o utiliza.

Por tanto, podemos imaginar el ecosistema de la siguiente manera:

RGB-Bitcoin

Estos tres elementos forman un conjunto triangular, en lugar de una pila lineal de "capa 2", "capa 3" y así sucesivamente. Lightning puede conectarse directamente a Bitcoin, o asociarse a transacciones de Bitcoin que incorporen datos RGB. Del mismo modo, un uso "BiFi" (finanzas en Bitcoin) puede componerse con la blockchain, con Lightning y con RGB según las necesidades de confidencialidad, escalabilidad o lógica contractual.

RGB-Bitcoin

Noción de transiciones de estado

En cualquier sistema distribuido, el objetivo del mecanismo de validación es poder determinar la validez y el orden cronológico de los cambios de estado. Se trata de verificar que se han respetado las reglas del protocolo, y demostrar que estos cambios de estado se suceden en un orden definitivo e inatacable.

Para entender cómo funciona esta validación en el contexto de Bitcoin y, más en general, para comprender la filosofía que hay detrás de la Validación del Lado del Cliente, echemos primero un vistazo a los mecanismos de la blockchain de Bitcoin, antes de ver en qué se diferencia de ellos la Validación del Lado del Cliente y qué optimizaciones posibilita.

RGB-Bitcoin

En el caso de la cadena de bloques de Bitcoin, la validación de las transacciones se basa en una regla sencilla:

RGB-Bitcoin

Sin embargo, este modelo presenta dos grandes inconvenientes:

RGB-Bitcoin

En la práctica, este modelo funciona para Bitcoin como capa base (Capa 1), pero puede resultar insuficiente para usos más complejos que requieran simultáneamente un alto rendimiento de las transacciones y un cierto grado de confidencialidad.

La validación del lado del cliente se basa en la idea contraria: en lugar de exigir a toda la red que valide y almacene todas las transacciones, cada participante (cliente) validará sólo la parte del historial que le concierna:

RGB-Bitcoin

Al mismo tiempo, para que el resto de la red (o más concretamente, la capa subyacente, como Bitcoin) pueda bloquear el estado final sin ver los detalles de estos datos, la Validación del Lado del Cliente se basa en la noción de compromiso.

Un compromiso es un compromiso criptográfico, típicamente un hash (SHA-256 por ejemplo) insertado en una transacción Bitcoin, que prueba que se han incluido datos privados, sin revelar estos datos.

Gracias a estos compromisos, podemos demostrar:

El contenido exacto, sin embargo, no se revela, preservando así su confidencialidad.

En concreto, así es como funciona una transición de estado RGB:

RGB-Bitcoin

La validación en el lado del cliente ofrece dos grandes ventajas:

Los compromisos (commitments) incluidos en la cadena de bloques son pequeños (del orden de unas pocas docenas de bytes). Esto garantiza que no se sature el espacio del bloque, ya que sólo es necesario incluir el hash. También permite que el protocolo fuera de la cadena evolucione, ya que cada usuario sólo tiene que almacenar su fragmento de historia (su stash).

Las transacciones en sí (es decir, su contenido detallado) no se publican en la cadena. Sólo se publican sus huellas dactilares (hash). Así, los importes, las direcciones y la lógica de los contratos siguen siendo privados, y el receptor puede verificar, localmente, la validez de su fragmento inspeccionando todas las transiciones anteriores. No hay ninguna razón para que el receptor haga públicos estos datos, excepto en caso de disputa o cuando se requiera una prueba.

En un sistema como RGB, múltiples transiciones de estado de diferentes contratos (o diferentes activos) pueden agregarse en una única transacción Bitcoin a través de un único commitment. Este mecanismo establece un vínculo determinista y con fecha y hora entre la transacción en la cadena y los datos fuera de la cadena (las transiciones validadas del lado del cliente), y permite registrar simultáneamente múltiples fragmentos en un único punto de anclaje, reduciendo aún más el coste y la huella en la cadena.

En la práctica, cuando esta transacción de Bitcoin se valida, "bloquea" permanentemente el estado de los contratos subyacentes, ya que resulta imposible modificar el hash ya inscrito en la blockchain.

RGB-Bitcoin

El concepto de alijo

Un stash es el conjunto de datos del lado del cliente que un participante debe conservar absolutamente para mantener la integridad y el historial de un contrato inteligente RGB. A diferencia de un canal Lightning, donde ciertos estados pueden reconstruirse localmente a partir de información compartida, el stash de un contrato RGB no se replica en ningún otro lugar: si lo pierdes, nadie podrá devolvértelo, ya que eres responsable de tu parte del historial. Por eso es necesario adoptar un sistema con procedimientos de copia de seguridad fiables en RGB.

RGB-Bitcoin

Sello de un solo uso: origen y funcionamiento

A la hora de aceptar un activo como una divisa, son esenciales dos garantías:

En el caso de los activos físicos, como un billete de banco, la presencia física basta para demostrar que no ha sido duplicado. Sin embargo, en el mundo digital, donde los activos son puramente informativos, esta verificación es más compleja, ya que la información puede multiplicarse y duplicarse fácilmente.

Como hemos visto antes, la revelación por parte del emisor del historial de transiciones de estado nos permite garantizar la autenticidad de un token RGB. Al tener acceso a todas las transacciones desde la transacción de génesis, podemos confirmar la autenticidad del token. Este principio es similar al de Bitcoin, donde la historia de las monedas puede rastrearse hasta la transacción original en Coinbase para verificar su validez. Sin embargo, a diferencia de Bitcoin, este historial de transiciones de estado en RGB es privado y se mantiene en el lado del cliente.

Para evitar el doble uso de las fichas RGB, utilizamos un mecanismo denominado "Sello de un solo uso". Este sistema garantiza que cada ficha, una vez utilizada, no pueda reutilizarse fraudulentamente una segunda vez.

Los sellos de un solo uso son primitivas criptográficas, propuestas en 2016 por Peter Todd, afines al concepto de los sellos físicos: una vez que se ha colocado un sello en un contenedor, resulta imposible abrirlo o modificarlo sin romper irreversiblemente el sello.

RGB-Bitcoin

Este enfoque, trasladado al mundo digital, permite demostrar que una secuencia de acontecimientos ha tenido lugar efectivamente, y que ya no puede alterarse a posteriori. Los sellos de un solo uso van así más allá de la simple lógica de hash + timestamp, añadiendo la noción de un sello que puede cerrarse sólo una vez.

RGB-Bitcoin

Para que los sellos de un solo uso funcionen, se necesita un medio de prueba de publicación capaz de demostrar la existencia o ausencia de una publicación, y difícil (si no imposible) de falsificar una vez que la información se ha difundido. Una blockchain (como Bitcoin) puede desempeñar este papel, al igual que un periódico en papel de tirada pública, por ejemplo. La idea es la siguiente:

Una cadena de bloques se presta idealmente a esta función: en cuanto una transacción se incluye en un bloque, toda la red tiene la misma prueba infalsificable de su existencia y contenido (al menos en parte, ya que el compromiso puede ocultar los detalles al tiempo que prueba la autenticidad del mensaje).

Por tanto, un Sello de un solo uso puede considerarse una promesa formal de publicar un mensaje (aún desconocido en esta fase) una vez y sólo una vez, de forma que pueda ser verificado por todas las partes interesadas.

A diferencia de los simples compromisos (hash) o sellos de tiempo, que dan fe de una fecha de existencia, un Sello de un solo uso ofrece la garantía adicional de que no puede coexistir ningún compromiso alternativo: no se puede cerrar dos veces el mismo sello, ni intentar sustituir el mensaje sellado.

La siguiente comparación ayuda a comprender este principio:

Compromiso simple (digest/hash)TimestampsSellos de un solo uso
La publicación del compromiso no revela el mensaje
Prueba de la fecha del compromiso / existencia del mensaje antes de una fechaImposiblePosiblePosible
Prueba de que no puede existir ningún otro compromiso alternativoImposibleImposiblePosible

Los precintos de un solo uso funcionan en tres etapas principales:

Sello Definición :

RGB-Bitcoin

Sello de cierre :

RGB-Bitcoin

Verificación del sello :

El proceso puede resumirse del siguiente modo:

# Défini par Alice, validé ou accepté par Bob
seal <- Define()
# Fermeture du sceau par Alice avec le message
witness <- Close(seal, message)
# Vérification par Bob
bool <- Verify(seal, witness, message)

Sin embargo, la validación del lado del cliente va un paso más allá: si la definición de un sello en sí queda fuera de la cadena de bloques, es posible (en teoría) que alguien cuestione la existencia o legitimidad del sello en cuestión. Para superar este problema, se utiliza una cadena de sellos de un solo uso entrelazados:

Esto es precisamente lo que hace el sistema RGB:

Resumiendo:

Esta unicidad es importante para la Validación del Lado del Cliente: cuando se valida una transición de estado, se comprueba que corresponde a un UTXO único, no gastado previamente en un compromiso competidor. Esto es lo que garantiza la ausencia de gasto doble en los contratos inteligentes fuera de la cadena.

Múltiples compromisos y raíces

Un contrato inteligente RGB puede necesitar gastar varios Sellos de un solo uso (varios UTXOs) simultáneamente. Es más, una única transacción Bitcoin puede hacer referencia a varios contratos distintos, cada uno sellando su propia transición de estado. Esto requiere un mecanismo de compromiso múltiple para probar, de forma determinista y única, que ninguno de los compromisos existe por duplicado. Aquí es donde la noción de anclaje entra en juego en RGB: una estructura especial que vincula una transacción Bitcoin y uno o más compromisos del lado del cliente (transiciones de estado), cada uno potencialmente perteneciente a un contrato diferente. Veremos este concepto con más detalle en el próximo capítulo.

RGB-Bitcoin

Dos de los principales repositorios GitHub del proyecto (bajo la organización LNPBP) agrupan las implementaciones básicas de estos conceptos estudiados en el primer capítulo:

RGB-Bitcoin

Tenga en cuenta que estos ladrillos de software son agnósticos de Bitcoin; en teoría, podrían aplicarse a cualquier otro medio de prueba de publicación (otro registro, una revista, etc.). En la práctica, RGB confía en Bitcoin por su solidez y amplio consenso.

RGB-Bitcoin

Preguntas del público

Hacia un uso más generalizado de los precintos de un solo uso

Peter Todd también creó el protocolo Open Timestamps, y el concepto de sello de un solo uso es una extensión natural de estas ideas. Más allá del RGB, se pueden prever otros casos de uso, como la construcción de sidechains sin recurrir a la merge mining o propuestas relacionadas con el drivechain como BIP300. Cualquier sistema que requiera un único compromiso puede, en principio, explotar esta primitiva criptográfica. En la actualidad, RGB es la primera gran aplicación a gran escala.

Problemas de disponibilidad de datos

Dado que en la validación del lado del cliente cada usuario almacena su propia parte del historial, la disponibilidad de los datos no está garantizada globalmente. Si un emisor de contratos retiene o revoca cierta información, es posible que desconozca la evolución real de la oferta. En algunos casos (como las stablecoins), se espera que el emisor mantenga datos públicos para demostrar el volumen en circulación, pero no existe ninguna obligación técnica de hacerlo. Por tanto, es posible diseñar contratos deliberadamente opacos con una oferta ilimitada, lo que plantea cuestiones de confianza.

Fragmentación y aislamiento de contratos

Cada contrato representa un "fragmento" aislado: USDT y USDC, por ejemplo, no tienen por qué compartir sus historiales. Los intercambios atómicos siguen siendo posibles, pero no implican la fusión de sus registros. Todo se hace por compromiso criptográfico, sin revelar todo el gráfico del historial a cada participante.

Conclusión

Hemos visto dónde encaja el concepto de Validación del Lado del Cliente con blockchain y canales de estado, cómo responde a los trilemas de la computación distribuida, y cómo aprovecha el blockchain de Bitcoin de forma única para evitar el doble gasto y para el estampado de tiempo. La idea se basa en la noción de Sello de un solo uso, que permite crear compromisos únicos que no se pueden volver a gastar a voluntad. De este modo, cada participante carga sólo el historial estrictamente necesario, aumentando la escalabilidad y confidencialidad de los contratos inteligentes y conservando la seguridad de Bitcoin como telón de fondo.

El siguiente paso será explicar con más detalle cómo se aplica este mecanismo de sello de un solo uso en Bitcoin (a través de UTXOs), cómo se crean y validan los anclajes y, a continuación, cómo se construyen contratos inteligentes completos en RGB. En particular, veremos el tema de los compromisos múltiples, el desafío técnico de probar que una transacción Bitcoin sella simultáneamente múltiples transiciones de estado en diferentes contratos, sin introducir vulnerabilidades o compromisos dobles.

Antes de sumergirse en los detalles más técnicos del segundo capítulo, no dude en releer las definiciones clave (Validación del lado del cliente, Sello de un solo uso, anclas, etc.) y tenga en cuenta la lógica general: estamos tratando de conciliar los puntos fuertes de la cadena de bloques de Bitcoin (seguridad, descentralización, sellado de tiempo) con los de las soluciones fuera de la cadena (velocidad, confidencialidad, escalabilidad), y esto es precisamente lo que RGB y la Validación del lado del cliente están tratando de lograr.

El nivel de compromiso

En este capítulo, veremos la implementación de la Validación del Lado del Cliente y los Sellos de un solo uso dentro de la blockchain de Bitcoin. Presentaremos los principios fundamentales de la capa de compromiso (capa 1) de RGB, con especial atención al esquema TxO2, que RGB utiliza para definir y cerrar un sello en una transacción Bitcoin. A continuación, discutiremos dos puntos importantes que aún no han sido tratados en detalle:

Es la combinación de estos conceptos lo que nos permite superponer varios sistemas o contratos sobre un único UTXO y, por tanto, una única blockchain.

Cabe recordar que las operaciones criptográficas descritas pueden aplicarse, en términos absolutos, a otras blockchains o soportes de publicación, pero las características de Bitcoin (en términos de descentralización, resistencia a la censura y apertura a todos) lo convierten en la base ideal para desarrollar una programabilidad avanzada como la que requiere RGB.

Esquemas de compromiso en Bitcoin y su uso por RGB

Como vimos en el primer capítulo del curso, los sellos de un solo uso son un concepto general: hacemos la promesa de incluir un compromiso (commitment) en una ubicación específica de una transacción, y esta ubicación actúa como un sello que cerramos en un mensaje. Sin embargo, en la blockchain de Bitcoin, hay varias opciones para elegir dónde colocar este compromiso.

Para entender la lógica, recordemos el principio básico: para cerrar un sello de un solo uso, gastamos el área sellada insertando el compromiso en un mensaje dado. En Bitcoin, esto puede hacerse de varias maneras:

Podemos decidir que una determinada clave pública o dirección es el sello de uso único. En cuanto esta clave o dirección aparece en la cadena en una transacción, significa que el sello se cierra con un mensaje determinado.

Esto significa que un precinto de un solo uso se define como un punto de salida preciso (un par TXID + número de salida). En cuanto se gasta este outpoint, el precinto se cierra.

Mientras trabajábamos en RGB, identificamos al menos 4 formas diferentes de implementar estos sellos en Bitcoin:

Nombre del esquemaDefinición del selloCierre del selloRequisitos adicionalesAplicación principalEsquemas de compromiso posibles
PkOValor de la clave públicaSalida de transacciónP2(W)PKHNinguna por el momentoKeytweak, taptweak, opret
TxO2Salida de transacciónSalida de transacciónRequiere compromisos deterministas en BitcoinRGBv1 (universal)Keytweak, tapret, opret
PkIValor de la clave públicaEntrada de transacciónSolo Taproot & no compatible con carteras legacyIdentidades basadas en BitcoinSigtweak, witweak
TxO1Salida de transacciónEntrada de transacciónSolo Taproot & no compatible con carteras legacyNinguna por el momentoSigtweak, witweak

No entraremos en detalle en cada una de estas configuraciones, ya que en RGB hemos optado por utilizar un outpoint como definición del sello, y situar el commitment en la salida de la transacción gastando este outpoint. Por lo tanto, podemos introducir los siguientes conceptos para la secuela:

Este esquema se ha seleccionado por su compatibilidad con la arquitectura RGB, pero otras configuraciones podrían ser útiles para diferentes usos.

El "O2" en "TxO2" nos recuerda que tanto la definición como el cierre se basan en el gasto (o creación) de una salida de transacción.

Ejemplo de diagrama TxO2

Como recordatorio, definir un sello de un solo uso no requiere necesariamente publicar una transacción en la cadena. Basta con que Alice, por ejemplo, tenga ya un UTXO sin gastar. Ella puede decidir: "Este punto de salida (ya existente) es ahora mi sello". Lo anota localmente (del lado del cliente), y hasta que este UTXO se gaste, el sello se considera abierto.

RGB-Bitcoin

El día que quiere cerrar el sello (para señalar un evento, o para anclar un mensaje en particular), gasta este UTXO en una nueva transacción (esta transacción suele llamarse "transacción de testigo_" (no tiene relación con segwit, es sólo el término que le damos). Esta nueva transacción contendrá el compromiso con el mensaje.

RGB-Bitcoin

Tenga en cuenta que en este ejemplo :

Para ilustrar este esquema TxO2, podemos utilizar un sello de un solo uso como mecanismo para revocar una clave PGP. En lugar de publicar un certificado de revocación en los servidores, Alice puede decir: "Esta salida de Bitcoin, si se gasta, significa que mi clave PGP está revocada".

Por lo tanto, Alice tiene un UTXO específico, al que se asocia localmente (en el lado del cliente) un determinado estado o dato (que sólo ella conoce).

Alice informa a Bob de que si se gasta este UTXO, se considerará que se ha producido un evento concreto. Desde fuera, todo lo que vemos es una transacción de Bitcoin; pero Bob sabe que este gasto tiene un significado oculto.

RGB-Bitcoin

A medida que Alice gasta este UTXO, cierra el sello de un mensaje indicando su nueva clave, o simplemente la revocación de la antigua. De esta forma, cualquiera que monitorice en la cadena verá que el UTXO se ha gastado, pero sólo los que tengan la prueba completa sabrán que se trata precisamente de la revocación de la clave PGP.

RGB-Bitcoin

Para que Bob o cualquier otra persona implicada pueda comprobar el mensaje oculto, Alice debe proporcionarle información fuera de la cadena.

RGB-Bitcoin

Por lo tanto, Alice debe proporcionar a Bob :

RGB-Bitcoin

Los terceros no disponen de esta información. Sólo ven que se ha gastado un UTXO. Por tanto, la confidencialidad está garantizada.

Para aclarar la estructura, resumamos el proceso en dos transacciones:

RGB-Bitcoin RGB-Bitcoin

Por lo tanto, llamamos a la segunda transacción "transacción de testigos".

Para ilustrarlo desde otro ángulo, podemos representar dos capas:

RGB-Bitcoin

Pero al cerrar el sello, se plantea la cuestión de dónde debe insertarse el compromiso

En la sección anterior, mencionamos brevemente cómo el modelo de Validación del Lado del Cliente puede aplicarse a RGB y otros sistemas. Aquí, abordamos la parte sobre compromisos deterministas de Bitcoin y cómo integrarlos en una transacción. La idea es entender por qué estamos intentando insertar un único compromiso en la transacción testigo, y sobre todo cómo asegurar que no puede haber otros compromisos competidores no revelados.

Lugares de compromiso en una transacción

Cuando le das a alguien la prueba de que un determinado mensaje está incrustado en una transacción, necesitas poder garantizar que no hay otra forma de compromiso (un segundo mensaje oculto) en la misma transacción que no te haya sido revelado. Para que la validación del lado del cliente siga siendo robusta, necesitas un mecanismo determinista para colocar un único compromiso en la transacción que cierre el sello de uso único.

La transacción testigo gasta el famoso UTXO (o definición del sello) y este gasto corresponde al cierre del sello. Técnicamente hablando, sabemos que cada punto de salida sólo puede gastarse una vez. Esto es precisamente lo que sustenta la resistencia de Bitcoin al doble gasto. Pero la transacción de gasto puede tener varias entradas, varias salidas, o estar compuesta de forma compleja (coinjoins, canales Lightning, etc.). Por lo tanto, necesitamos definir claramente dónde insertar el compromiso en esta estructura, de forma inequívoca y uniforme.

Sea cual sea el método (PkO, TxO2, etc.), el compromiso puede insertarse :

RGB-Bitcoin

He aquí los detalles de cada método:

RGB-Bitcoin

Ajustes de seguridad (firma por contrato) :

Un esquema anterior consistía en explotar la parte aleatoria de una firma (ECDSA o Schnorr) para incrustar el compromiso: esta es la técnica conocida como "Firma-a-contrato". Se sustituye el nonce generado aleatoriamente por un hash que contiene los datos. De este modo, la firma revela implícitamente tu compromiso, sin espacio adicional en la transacción. Este enfoque tiene una serie de ventajas:

Sin embargo, han surgido 2 grandes inconvenientes:

En la práctica, sig tweak tampoco es muy compatible con el hardware (monederos hardware) y los formatos existentes (Lightning, etc.). Así que esta gran idea es difícil de poner en práctica.

*Reto clave (pago por contrato) :

El "ajuste de claves" retoma el concepto histórico de "pago por contrato". Tomamos la clave pública X y la modificamos añadiendo el valor H(mensaje). En concreto, si X = x * G y h = H(mensaje), la nueva clave será X' = X + h * G. Esta clave modificada oculta el compromiso con el "mensaje". El poseedor de la clave privada original puede, añadiendo h a su clave privada x, demostrar que tiene la clave para gastar la salida. En teoría, esto es elegante, porque :

En la práctica, sin embargo, nos encontramos con las siguientes dificultades:

En el contexto del RGB, esta vía estaba prevista hasta 2021, pero resultó demasiado complicada para hacerla funcionar con las normas y la infraestructura actuales.


Otra idea, que algunos protocolos como inscriptions Ordinals han puesto en práctica, consiste en colocar los datos directamente en la sección testigo de la transacción (de ahí la expresión "witness tweak"). Sin embargo, este método :

Además, el testigo está diseñado para ser podable en determinados contextos, lo que puede complicar la obtención de pruebas sólidas.

Apertura-retorno (opret) :

Muy simple en su funcionamiento, un OP_RETURN permite almacenar un hash o mensaje en un campo especial de la transacción. Pero es inmediatamente detectable: todo el mundo ve que hay un commitment en la transacción, y puede ser censurado o descartado, además de añadir salida extra. Dado que esto aumenta la transparencia y el tamaño, se considera menos satisfactorio desde el punto de vista de una solución de validación del lado del cliente.

34-byte_Opret_Commitment =
OP_RETURN   OP_PUSHBYTE_32   <mpc::Commitment>
|_________| |______________| |_________________|
1-byte       1-byte         32 bytes

Tapret

La última opción es el uso de Taproot (introducido con BIP341) con el esquema Tapret. Tapret es una forma más compleja de compromiso determinista, que aporta mejoras en términos de huella en la blockchain y confidencialidad para las operaciones contractuales. La idea principal es ocultar el compromiso en la parte Script Path Spend de una transacción taproot.

RGB-Bitcoin

Antes de describir cómo se inserta el compromiso en una transacción taproot, veamos la forma exacta del compromiso, que debe imperativamente corresponder a una cadena de 64 bytes construida como sigue:

64-byte_Tapret_Commitment =
OP_RESERVED ...  ... .. OP_RESERVED   OP_RETURN   OP_PUSHBYTE_33  <mpc::Commitment>  <Nonce>
|___________________________________| |_________| |______________| |_______________|  |______|
OP_RESERVED x 29 times = 29 bytes      1 byte         1 byte          32 bytes        1 byte
|________________________________________________________________| |_________________________|
TAPRET_SCRIPT_COMMITMENT_PREFIX = 31 bytes                    MPC commitment + NONCE = 33 bytes

Así que el método Tapret de 64 bytes parece un Opret al que hemos prefijado 29 bytes de OP_RESERVED y añadido un byte extra como Nonce.

Para mantener la flexibilidad en términos de implementación, confidencialidad y escalado, el esquema Tapret tiene en cuenta varios casos de uso, en función de los requisitos:

Veamos más de cerca cada uno de estos dos escenarios.

Incorporación de Tapret sin Script Path existente

En este primer caso, partimos de una clave de salida taproot (Taproot Output Key) Q que contiene únicamente la clave pública interna P (Internal Key), sin ruta de script asociada (Script Path) :

RGB-Bitcoin

Para incluir un compromiso de Tapret, añada un Gasto de Ruta de Script con un script único, como sigue:

RGB-Bitcoin

La prueba de inclusión y unicidad en el árbol raíz se reduce aquí a la única clave pública interna P.

Integración de Tapret en una Script Path preexistente

El segundo escenario se refiere a una salida Q taproot** más compleja, que ya contiene varios scripts. Por ejemplo, tenemos un árbol de 3 scripts:

RGB-Bitcoin

Para añadir el compromiso de Tapret, necesitamos insertar un script no gastable en el primer nivel del árbol, desplazando los scripts existentes un nivel hacia abajo. Visualmente, el árbol se convierte en :

RGB-Bitcoin

Según las reglas de taproot, cada rama/hoja debe combinarse según un orden hash lexicográfico. Hay dos casos posibles:

Ejemplo visual para el primer caso (tHABC < tHT):

RGB-Bitcoin

Ejemplo para el segundo caso (tHABC > tHT):

RGB-Bitcoin

Optimización con el nonce

Para mejorar la confidencialidad, podemos "minar" (un término más preciso sería "bruteforcing") el valor del <Nonce> (el último byte del Tapret de 64 bytes) en un intento de obtener un hash tHT tal que tHABC < tHT. En este caso, el compromiso se coloca a la derecha, ahorrando al usuario tener que divulgar todo el contenido de los scripts existentes para probar la unicidad del Tapret.

En resumen, el Tapret ofrece una forma discreta y determinista de incorporar un compromiso a una transacción taproot, respetando al mismo tiempo el requisito de unicidad e inequívoco esencial para la validación del lado del cliente y la lógica de sello de un solo uso de RGB.

Salidas válidas

Para las transacciones de compromiso RGB, el requisito principal para un esquema de compromiso Bitcoin válido es el siguiente: La transacción (transacción testigo) debe contener de forma demostrable un único compromiso. Este requisito hace imposible construir un historial alternativo para los datos validados del lado del cliente dentro de la misma transacción. Esto significa que el mensaje alrededor del cual se cierra el sello de uso único es único.

Para satisfacer este principio, e independientemente del número de salidas en una transacción, exigimos que una y sólo una salida pueda contener un compromiso (commitment). Para cada uno de los esquemas utilizados (Opret o Tapret), las únicas salidas válidas que pueden contener un compromiso RGB son :

Tenga en cuenta que es muy posible que una transacción contenga un único compromiso Opret y un único compromiso Tapret en dos salidas separadas. Gracias a la naturaleza determinista de Seal Definition, estos dos compromisos corresponden entonces a dos piezas distintas de datos validados en el lado del cliente.

Análisis y opciones prácticas en RGB

Cuando iniciamos RGB, revisamos todos estos métodos para determinar dónde y cómo colocar un commitment en una transacción de forma determinista. Definimos algunos criterios:

MétodoRastro y tamaño on-chainTamaño en clienteIntegración de monederosCompatibilidad de hardwareCompatibilidad LightningCompatibilidad Taproot
Keytweak (P2C determinista)🟢🟡🔴🟠🔴 BOLT, 🔴 Bifrost🟠 Taproot, 🟢 MuSig
Sigtweak (S2C determinista)🟢🟢🟠🔴🔴 BOLT, 🔴 Bifrost🟠 Taproot, 🔴 MuSig
Opret (OP_RETURN)🔴🟢🟢🟠🔴 BOLT, 🟠 Bifrost-
Algoritmo Tapret: nodo superior izquierdo🟠🔴🟠🟢🔴 BOLT, 🟢 Bifrost🟢 Taproot, 🟢 MuSig
Algoritmo Tapret #4: cualquier nodo + prueba🟢🟠🟠🟢🔴 BOLT, 🟢 Bifrost🟢 Taproot, 🟢 MuSig
Esquema de compromiso deterministaEstándarCosto en la cadenaTamaño de la prueba en el cliente
Keytweak (P2C determinista)LNPBP-1, 20 bytes33 bytes (clave no modificada)
Sigtweak (S2C determinista)WIP (LNPBP-39)0 bytes0 bytes
Opret (OP_RETURN)-36 (v)bytes (TxOut adicional)0 bytes
Algoritmo Tapret: nodo superior izquierdoLNPBP-632 bytes en el testigo (8 vbytes) en cualquier multisig n-of-m y gasto a través de la ruta de script0 bytes en scriptless scripts taproot ~270 bytes en un caso de script único, ~128 bytes si hay múltiples scripts
Algoritmo Tapret #4: cualquier nodo + prueba de unicidadLNPBP-632 bytes en el testigo (8 vbytes) para casos de script único, 0 bytes en el testigo en la mayoría de los otros casos0 bytes en scriptless scripts taproot, 65 bytes hasta que el Taptree tenga una docena de scripts
CapaCosto on-chain (bytes/vbytes)Costo on-chain (bytes/vbytes)Costo on-chain (bytes/vbytes)Costo on-chain (bytes/vbytes)Costo on-chain (bytes/vbytes)Costo lado cliente (bytes)Costo lado cliente (bytes)Costo lado cliente (bytes)Costo lado cliente (bytes)Costo lado cliente (bytes)
TipoTapretTapret #4KeytweakSigtweakOpretTapretTapret #4KeytweakSigtweakOpret
Single-sig00003200320?0
MuSig (n-of-n)0000320032? > 00
Multi-sig 2-de-332/832/8 o 00n/a32~2706532n/a0
Multi-sig 3-de-532/832/8 o 00n/a32~3406532n/a0
Multi-sig 2-de-3 con timeouts32/800n/a32646532n/a0
CapaCosto on-chain (vbytes)Costo on-chain (vbytes)Costo on-chain (vbytes)Costo lado cliente (bytes)Costo lado cliente (bytes)
TipoBaseTapret #2Tapret #4Tapret #2Tapret #4
MuSig (n-of-n)16.50000
FROST (n-of-m)?0000
Multi_a (n-of-m)1+16n+8m8833 * m65
Rama MuSig / Multi_a (n-of-m)1+16n+8n+8xlog(n)806465
Con timeouts (n-of-m)1+16n+8n+8xlog(n)806465
MétodoPrivacidad y escalabilidadInteroperabilidadCompatibilidadPortabilidadComplejidad
Keytweak (P2C determinista)🟢🔴🔴🟡🟡
Sigtweak (S2C determinista)🟢🔴🔴🟢🔴
Opret (OP_RETURN)🔴🟠🔴🟢🟢
Algo Tapret: Nodo superior izquierdo🟠🟢🟢🔴🟠
Algo Tapret #4: Cualquier nodo + prueba🟢🟢🟢🟠🔴

En el transcurso del estudio, quedó claro que ninguno de los esquemas de compromiso era totalmente compatible con el actual estándar Lightning (que no emplea Taproot, muSig2 ni soporte adicional de commitment). Se está intentando modificar la construcción de canales de Lightning (BiFrost) para permitir la inserción de compromisos RGB. Esta es otra área en la que necesitamos revisar la estructura de la transacción, las claves y la forma en que se firman las actualizaciones del canal.

El análisis demostró que, de hecho, otros métodos (key tweak, sig tweak, witness tweak, etc.) presentaban otras formas de complicación:

Para RGB, destacan dos métodos en particular: Opret y Tapret, ambos clasificados como "Transaction Output", y compatibles con el modo TxO2 utilizado por el protocolo.

Compromisos multiprotocolo - MPC

En esta sección, veremos cómo RGB gestiona la agregación de múltiples contratos (o, más concretamente, sus paquetes de transición) dentro de un único compromiso (commitment) registrado en una transacción Bitcoin mediante un esquema determinista (según Opret o Tapret). Para conseguirlo, el orden de Merkelización de los distintos contratos tiene lugar en una estructura denominada Árbol MPC (Árbol de Compromisos Multiprotocolo). En esta sección, veremos la construcción de este Árbol MPC, cómo obtener su raíz, y cómo múltiples contratos pueden compartir la misma transacción de forma confidencial y sin ambigüedades.

El Compromiso Multiprotocolo (MPC) está diseñado para satisfacer dos necesidades:

En concreto, cada paquete de transición pertenece a un contrato concreto. Toda esta información se inserta en un Árbol MPC, cuya raíz (mpc::Root) se somete de nuevo a hash para obtener el mpc::Commitment. Es este último hash el que se coloca en la transacción Bitcoin (transacción testigo), según el método determinista elegido.

RGB-Bitcoin

Hash raíz MPC

El valor realmente escrito en la cadena (en Opret o Tapret) se denomina mpc::Commitment. Se calcula en forma de BIP-341, según la fórmula :

mpc::Commitment = SHA-256(SHA-256(mpc_tag) || SHA-256(mpc_tag) || depth || cofactor || mpc::Root )

donde :

RGB-Bitcoin

MPC Construcción de árboles

Para construir este árbol MPC, tenemos que asegurarnos de que cada contrato corresponde a una única posición de hoja. Supongamos que tenemos :

A continuación, construimos un árbol de anchura w y profundidad d tal que 2^d = w, con w > C, de modo que cada contrato pueda colocarse en una hoja independiente. La posición pos(c_i) de cada contrato en el árbol viene determinada por :

pos(c_i) = c_i mod (w - cofactor)

donde cofactor es un número entero que aumenta la probabilidad de obtener posiciones distintas para cada contrato. En la práctica, la construcción sigue un proceso iterativo:

El objetivo es evitar los árboles demasiado altos, reduciendo al mínimo el riesgo de colisión. Nótese que el fenómeno de la colisión sigue una lógica de distribución aleatoria, vinculada a la Paradoja del Aniversario.

Hojas habitadas

Una vez obtenidas C posiciones distintas pos(c_i) para los contratos i = {0,1,..,C-1}, se rellena cada hoja con una función hash (tagged hash):

tH_MPC_LEAF(c_i) = SHA-256(SHA-256(merkle_tag) || SHA-256(merkle_tag) || 0x10 || c_i || BundleId(c_i))

donde :

Hojas deshabitadas

Las hojas restantes, no asignadas a un contrato (es decir, las hojas w - C), se rellenan con un valor "ficticio" (hoja de entropía) :

tH_MPC_LEAF(j) = SHA-256(SHA-256(merkle_tag) || SHA-256(merkle_tag) || 0x11 || entropy || j )

donde :

Nodos MPC

Tras generar las hojas w (habitadas o no), procedemos a la merkelización. Todos los nodos internos se merkelizan de la siguiente manera:

tH_MPC_BRANCH(tH1 || tH2) = SHA-256(SHA-256(merkle_tag) || SHA-256(merkle_tag) || b || d || w || tH1 || tH2)

donde :

Avanzando de este modo, obtenemos la raíz mpc::Root. A continuación, podemos calcular mpc::Commitment (como se ha explicado anteriormente) e insertarlo en la cadena.

Para ilustrarlo, imaginemos un ejemplo en el que C=3 (tres contratos). Se supone que sus posiciones son pos(c_0)=7, pos(c_1)=4, pos(c_2)=2. Las otras hojas (posiciones 0, 1, 3, 5, 6) son hojas de entropía. El siguiente diagrama muestra la secuencia de hashes hasta la raíz con :

El resultado final es el mpc::Root, y después el mpc::Commitment.

RGB-Bitcoin

Comprobación del eje MPC

Cuando un verificador desea asegurarse de que un contrato c_i (y su BundleId) está incluido en el mpc::Commitment final, simplemente recibe una prueba Merkle. Esta prueba indica los nodos necesarios para rastrear las hojas (en este caso, la hoja de contrato de c_i) hasta la raíz. No es necesario revelar todo el Árbol del MPC: así se protege la confidencialidad de otros contratos.

En el ejemplo, un verificador c_2 sólo necesita un hash intermedio (tH_MPC_LEAF(D)), dos tH_MPC_BRANCH(...), la prueba de posición pos(c_2) y el valor cofactor. Entonces puede reconstruir localmente la raíz, recalcular el mpc::Commitment y compararlo con el escrito en la transacción Bitcoin (dentro de Opret o Tapret).

RGB-Bitcoin

Este mecanismo garantiza que :

Resumen de la estructura de los PSM

El Compromiso Multiprotocolo* (MPC) es el principio que permite a RGB agregar múltiples contratos en una única transacción Bitcoin, manteniendo la unicidad de los compromisos y la confidencialidad frente a otros participantes. Gracias a la construcción determinista del árbol, a cada contrato se le asigna una posición única, y la presencia de hojas "ficticias" (Hojas de Entropía) enmascara parcialmente el número total de contratos que participan en la transacción.

El árbol de Merkle completo nunca se almacena en el cliente. Nos limitamos a generar una Ruta Merkle para cada contrato en cuestión, que se transmitirá al destinatario (quien podrá validar el compromiso). En algunos casos, puede tener varios activos que hayan pasado por el mismo UTXO. En ese caso, puede fusionar varios Merkle paths en un denominado bloque de compromiso multiprotocolo, para evitar duplicar demasiados datos.

Cada prueba de Merkle es por tanto ligera, sobre todo porque la profundidad del árbol no superará los 32 en RGB. También existe la noción de "bloque de Merkle", que conserva más información (sección transversal, entropía, etc.), útil para combinar o separar varias ramas.

Por eso tardamos tanto en finalizar RGB. Teníamos la visión general desde 2019: poner todo en el lado del cliente, hacer circular los tokens fuera de la cadena. Pero detalles como la fragmentación para múltiples contratos, la estructura del árbol de Merkle, cómo gestionar las colisiones y las pruebas de fusión... todo esto requirió iteraciones.

Anclajes: una asamblea global

Siguiendo con la construcción de nuestros compromisos (Opret o Tapret) y nuestro MPC (Multi Protocol Commitment), necesitamos abordar la noción de Ancla en el protocolo RGB. Un Ancla es una estructura validada por el cliente que reúne los elementos necesarios para verificar que un compromiso Bitcoin contiene realmente información contractual específica. En otras palabras, un Ancla resume todos los datos necesarios para validar los compromisos descritos anteriormente.

Un Ancla consta de tres campos ordenados:

Cada uno de estos campos desempeña un papel en el proceso de validación, ya se trate de reconstruir la transacción Bitcoin subyacente o de demostrar la existencia de un compromiso oculto (especialmente en el caso de Tapret).

TxId

El campo Txid corresponde al identificador de 32 bytes de la transacción Bitcoin que contiene el compromiso Opret o Tapret.

En teoría, sería posible encontrar este Txid rastreando la cadena de transiciones de estado que a su vez apuntan a cada transacción testigo, siguiendo la lógica de los Sellos de un solo uso. Sin embargo, para facilitar y acelerar la verificación, este Txid simplemente se incluye en el Ancla, ahorrando así al validador tener que retroceder por todo el historial fuera de la cadena.

Prueba MPC

El segundo campo, MPC Proof, se refiere a la prueba de que este contrato concreto (por ejemplo, c_i) está incluido en el Compromiso Multiprotocolo. Es una combinación de :

Este mecanismo se describió en la sección anterior sobre la construcción del Árbol del CMN, donde cada contrato obtiene una hoja única gracias a la función :

pos(c_i) = c_i mod (w - cofactor)

A continuación, se utiliza un esquema de merkelización determinista para agregar todas las hojas (contratos + entropía). Al final, el MPC Proof permite reconstruir localmente la raíz y compararla con el mpc::Commitment incluido en la cadena.

Prueba de Transacción Extra - ETP

El tercer campo, el ETP, depende del tipo de compromiso utilizado. Si el compromiso es del tipo Opret, no se requiere ninguna prueba adicional. El validador inspecciona la primera salida OP_RETURN de la transacción y encuentra el mpc::Commitment directamente allí.

Si el compromiso es del tipo Tapret, se debe proporcionar una prueba adicional denominada Prueba de Transacción Extra - ETP. Contiene :

Esta prueba adicional es esencial porque, a diferencia de Opret, el compromiso Tapret está integrado en la estructura de un script taproot, lo que requiere revelar parte del árbol taproot para validar correctamente la ubicación del compromiso.

RGB-Bitcoin

Los Anchors encapsulan por tanto toda la información necesaria para validar un compromiso Bitcoin en el contexto de RGB. Indican tanto la transacción relevante (Txid) como la prueba de posicionamiento del contrato (MPC Proof), al tiempo que gestionan la prueba adicional (ETP) en el caso de Tapret. De este modo, un Ancla protege la integridad y la unicidad del estado fuera de la cadena garantizando que la misma transacción no pueda ser reinterpretada para otros datos contractuales.

Conclusión

En este capítulo tratamos :

En la práctica, la implementación técnica se reparte entre varios crates dedicados a Rust (en client_side_validation, commit-verify, bp_core, etc.). Las nociones fundamentales están ahí:

RGB-Bitcoin

En el próximo capítulo, veremos el componente puramente fuera de la cadena de RGB, es decir, la lógica del contrato. Veremos cómo los contratos de RGB, organizados como máquinas de estado finito parcialmente replicadas, logran una expresividad mucho mayor que los scripts de Bitcoin, al tiempo que preservan la confidencialidad de sus datos.

Introducción a los contratos inteligentes y sus estados

En este capítulo y en el siguiente, estudiaremos la noción de contrato inteligente dentro del entorno RGB y exploraremos las diferentes formas en que estos contratos pueden definir y evolucionar su estado. Veremos por qué la arquitectura RGB, utilizando la secuencia ordenada de Sellos de un solo uso, hace posible ejecutar varios tipos de Operaciones contractuales de forma escalable y sin pasar por un registro centralizado. También veremos el papel fundamental de la Lógica Empresarial a la hora de enmarcar la evolución del estado del contrato.

Contratos inteligentes y derechos digitales al portador

El objetivo de RGB es proporcionar una infraestructura para implementar contratos inteligentes en Bitcoin. Por "contrato inteligente" entendemos un acuerdo entre varias partes que se aplica de forma automática y computacional, sin intervención humana para hacer cumplir las cláusulas. En otras palabras, la ley del contrato es aplicada por el software, no por un tercero de confianza.

Esta automatización plantea la cuestión de la descentralización: ¿cómo liberarse de un registro centralizado (por ejemplo, una plataforma o base de datos central) para gestionar la propiedad y la ejecución de los contratos? La idea original, retomada por RGB, es volver a un modo de propiedad conocido como "instrumentos al portador". Históricamente, ciertos títulos (bonos, acciones, etc.) se emitían al portador, lo que permitía a cualquiera que poseyera físicamente el documento hacer valer sus derechos.

RGB-Bitcoin

RGB aplica este concepto al mundo digital: los derechos (y obligaciones) se encapsulan en datos que se manipulan fuera de la cadena, y el estado de estos datos es validado por los propios participantes. Esto permite, a priori, un grado de confidencialidad e independencia mucho mayor que el que ofrecen otros enfoques basados en registros públicos.

Introducción al contrato inteligente Estado RGB

Un contrato inteligente en RGB puede verse como una máquina de estados, definida por :

RGB-Bitcoin

Es importante entender que estos contratos no se limitan a la simple transferencia de tokens. Pueden incorporar una amplia variedad de aplicaciones: desde activos tradicionales (tokens, acciones, bonos) hasta mecanismos más complejos (derechos de uso, condiciones comerciales, etc.). A diferencia de otras blockchains, en las que el código del contrato es accesible y ejecutable por todos, el enfoque de RGB compartimenta el acceso y el conocimiento del contrato a los participantes ("participantes en el contrato"). Existen varios roles:

Esta separación de roles contribuye a la resistencia a la censura, al garantizar que sólo las personas autorizadas puedan interactuar con el estado contractual. También confiere a RGB la capacidad de escalar horizontalmente: la mayoría de las validaciones tienen lugar fuera de la blockchain, y solo los anclajes criptográficos (los compromisos) se inscriben en Bitcoin.

Estado y lógica empresarial en RGB

Desde un punto de vista práctico, la Lógica Empresarial del contrato adopta la forma de reglas y guiones, definidos en lo que RGB denomina un Esquema. El esquema codifica :

Al mismo tiempo, el Estado contratante suele dividirse en dos componentes:

Como veremos en los siguientes capítulos, cualquier actualización de estado (Operación de contrato) debe acoplarse a un compromiso de Bitcoin (mediante Opret o Tapret) y cumplir con los guiones de Lógica de negocio para considerarse válida.

Operaciones contractuales: creación y evolución del Estado

En el universo RGB, una Operación de contrato es cualquier evento que cambia el contrato de un estado antiguo a un estado nuevo. Estas operaciones siguen la siguiente lógica:

RGB-Bitcoin

El resultado final es un contrato actualizado, ahora con un estado diferente. Esta transición no requiere que toda la red Bitcoin se preocupe de los detalles, ya que sólo una pequeña huella criptográfica (el compromiso) se registra en la blockchain. La secuencia de Sellos de un solo uso impide cualquier doble gasto o doble uso del Estado.

Cadena de operaciones: del Génesis al Estado Terminal

Para ponerlo en perspectiva, un contrato inteligente RGB comienza con un Génesis, el primer estado. A partir de ahí, se suceden varias operaciones contractuales, formando un DAG (Gráfico acíclico dirigido) de operaciones:

RGB-Bitcoin

Esta topología DAG (en lugar de una simple cadena lineal) refleja la posibilidad de que distintas partes del contrato evolucionen en paralelo, siempre que no se contradigan entre sí. RGB se encarga entonces de evitar cualquier incoherencia mediante la verificación del lado del cliente de cada participante implicado.

Resumen

Los contratos inteligentes en RGB introducen un modelo de instrumentos digitales al portador, descentralizados pero anclados en Bitcoin para sellar el tiempo y garantizar el orden de las transacciones. La ejecución automatizada de estos contratos se basa en :

En el próximo capítulo, entraremos en más detalle sobre la representación concreta de estos estados y transiciones de estado a nivel fuera de la cadena, y cómo se relacionan con los UTXOs y los Sellos de un solo uso incrustados en Bitcoin. Esta será una oportunidad para ver cómo la mecánica interna de RGB, basada en la validación del lado del cliente, consigue mantener la consistencia de los contratos inteligentes a la vez que preserva la confidencialidad de los datos.

Operaciones contractuales RGB

En este capítulo, veremos cómo funcionan las operaciones en los contratos inteligentes y las transiciones de estado, de nuevo dentro del protocolo RGB. También se tratará de entender cómo cooperan varios participantes para transferir la propiedad de un activo.

Transiciones de estado y su mecánica

El principio general sigue siendo el de la validación del lado del cliente, donde los datos de estado los tiene el propietario y los valida el destinatario. Sin embargo, la especificidad aquí con RGB radica en el hecho de que Bob, como destinatario, pide a Alice que incorpore cierta información a los datos del contrato para tener un control real sobre el bien recibido, a través de una referencia oculta a uno de sus UTXOs.

Para ilustrar el proceso de una Transición de Estado (que es una de las Operaciones de Contrato fundamentales en RGB), tomemos un ejemplo paso a paso de una transferencia de activos entre Alice y Bob:

Situación inicial:

Alice tiene un stash RGB de datos validados localmente (client-side). Este alijo se refiere a uno de sus UTXOs en Bitcoin. Esto significa que una definición de sello en estos datos apunta a un UTXO perteneciente a Alice. La idea es permitirle a ella transferir ciertos derechos digitales vinculados a un activo (por ejemplo, tokens RGB) a Bob.

RGB-Bitcoin

Bob también tiene UTXOs :

Bob, por otro lado, tiene al menos un UTXO propio, sin vínculo directo con el de Alice. En el caso de que Bob no tenga UTXO, todavía es posible hacer la transferencia a él utilizando la propia transacción testigo: la salida de esta transacción incluirá entonces el compromiso (commitment) y asociará implícitamente la propiedad del nuevo contrato con Bob.

RGB-Bitcoin

Construcción de la nueva propiedad (Nuevo Estado) :

Bob envía a Alice información codificada en forma de factura (entraremos en más detalle sobre la construcción de facturas en capítulos posteriores), pidiéndole que cree un nuevo estado que se ajuste a las reglas del contrato. Este estado incluirá una nueva definición de sello apuntando a uno de los UTXOs de Bob. De este modo, Bob recibe la propiedad de los activos definidos en este nuevo estado, por ejemplo una cierta cantidad de tokens RGB.

RGB-Bitcoin

Preparación de la transacción de muestra:

Alice crea entonces una transacción Bitcoin gastando el UTXO referenciado en el sello anterior (el que la legitimó como titular). En la salida de esta transacción, se inserta un compromiso (mediante Opret o Tapret) para anclar el nuevo estado RGB. Los compromisos Opret o Tapret se derivan de un árbol MPC (como se ha visto en capítulos anteriores), que puede agregar varias transiciones de diferentes contratos.

Transmisión de Consignación a Bob:

Antes de emitir la transacción, Alice envía a Bob una Consignación que contiene todos los datos del lado del cliente necesarios (su stash) y la nueva información de estado a favor de Bob. En este punto, Bob aplica las reglas de consenso RGB:

Terminación de la transición:

Si Bob está satisfecho, puede dar su aprobación (por ejemplo, firmando la consignación). Alice puede entonces emitir la transacción de muestra preparada. Una vez confirmada, esto cierra el sello que anteriormente tenía Alice y formaliza la propiedad por parte de Bob. La seguridad contra el doble gasto se basa entonces en el mismo mecanismo que en Bitcoin: el UTXO se gasta, lo que demuestra que Alice ya no puede reutilizarlo.

RGB-Bitcoin

El nuevo estado ahora hace referencia al UTXO de Bob, dándole a Bob la propiedad que antes tenía Alice. La salida de Bitcoin donde se anclan los datos RGB se convierte en la prueba irrevocable de la transferencia de propiedad.

Un ejemplo de un DAG mínimo (Gráfico acíclico dirigido) que comprende dos operaciones contractuales (una Génesis y luego una Transición de estado) puede ilustrar cómo el estado RGB (capa del lado del cliente, en rojo) se conecta a la blockchain de Bitcoin (capa Compromiso, en naranja).

RGB-Bitcoin

Muestra que un Genesis define un sello (seal definition), luego un State Transition cierra este sello para crear uno nuevo en otro UTXO.

En este contexto, he aquí algunos recordatorios terminológicos:

Las Transiciones de Estado**, descritas en el capítulo anterior, son la principal forma de operación contractual. Hacen referencia a uno o más estados anteriores (de Génesis o de otra Transición de Estado) y los actualizan a un nuevo estado.

RGB-Bitcoin

Este diagrama muestra cómo, en un Bundle de Transiciones de Estado, pueden cerrarse varios sellos en una única transacción de muestra, al tiempo que se abren nuevos sellos. De hecho, una característica interesante del protocolo RGB es su capacidad para escalar: varias transiciones pueden agregarse en un Paquete de Transiciones, estando cada agregación asociada a una hoja distinta del árbol MPC (un identificador único de paquete). Gracias al mecanismo Deterministic Bitcoin Commitment (DBC), el mensaje completo se inserta en una salida Tapret u Opret, al tiempo que se cierran los sellos anteriores y posiblemente se definen otros nuevos. El `Anchor* sirve de enlace directo entre el compromiso almacenado en la blockchain y la estructura de validación del lado del cliente (client-side).

En los siguientes capítulos, veremos todos los componentes y procesos implicados en la construcción y validación de una Transición de Estado. La mayoría de estos elementos forman parte del consenso RGB, implementado en la RGB Core Library.

Paquete de transición

En RGB, es posible agrupar diferentes transiciones de estado que pertenezcan al mismo contrato (es decir, que compartan el mismo ContractId, derivado del OpId de Génesis). En el caso más sencillo, como entre Alice y Bob en el ejemplo anterior, un Conjunto de Transiciones contiene una sola transición. Pero la compatibilidad con operaciones multipago (como coinjoins, aperturas de canales Lightning, etc.) significa que varios usuarios pueden combinar sus transiciones de estado en un único paquete.

Una vez recogidas, estas transiciones se anclan (mediante el mecanismo MPC + DBC) en una única transacción Bitcoin:

Técnicamente hablando, el BundleId insertado en la hoja MPC se obtiene a partir de un hash etiquetado aplicado a la serialización estricta del campo InputMap del bundle:

BundleId = SHA256( SHA256(bundle_tag) || SHA256(bundle_tag) || InputMap )

En el que bundle_tag = urn:lnp-bp:rgb:bundle#2024-02-03 por ejemplo.

El InputMap es una estructura de datos que lista, para cada entrada i de la transacción de muestra, la referencia al OpId de la correspondiente Transición de Estado. Por ejemplo:

InputMap =
N               input_0    OpId(input_0)    input_1    OpId(input_1)   ...    input_N-1  OpId(input_N-1)
|____________________| |_________||______________| |_________||______________|       |__________||_______________|
16-bit Little Endian   32-bit LE   32-byte hash
|_________________________| |_________________________|  ...  |___________________________|
MapElement1                MapElement2                       MapElementN

Al hacer referencia a cada entrada una sola vez y de forma ordenada, evitamos que el mismo sello se gaste dos veces en dos transiciones de estado simultáneas.

Generación de estados y estado activo

Por tanto, las transiciones de estado pueden utilizarse para transferir la propiedad de un bien de una persona a otra. Sin embargo, no son las únicas operaciones posibles en el protocolo RGB. El protocolo define tres operaciones de contrato :

Entre ellas, Génesis y Extensión de estados se denominan a veces "operaciones de generación de estados", porque crean nuevos estados sin cerrar ninguno inmediatamente. Este es un punto muy importante: Génesis y Extensión de Estado no implican el cierre de un sello. Más bien, definen un nuevo sello, que luego debe ser gastado por una Transición de Estado posterior para ser realmente validado en el historial del blockchain.

RGB-Bitcoin

El Estado Activo de un contrato suele definirse como el conjunto de los últimos estados resultantes del historial (el DAG) de transacciones, empezando por la Génesis y siguiendo por todas las anclas en la blockchain de Bitcoin. Cualquier estado antiguo que ya esté obsoleto (es decir, unido a UTXOs gastados) ya no se considera activo, pero sigue siendo esencial para comprobar la consistencia del historial.

Génesis

La Génesis es el punto de partida de todo contrato RGB. Es creada por el emisor del contrato y define los parámetros iniciales, de acuerdo con el Esquema. En el caso de un token RGB, el Génesis puede especificar, por ejemplo :

Al ser la primera transacción del contrato, el Génesis no hace referencia a ningún estado anterior, ni cierra ningún sello. Sin embargo, para aparecer en el historial y ser validada, la Génesis debe ser consumida (cerrada) por una primera Transición de Estado (a menudo una transacción de escaneo/autogiro al propio emisor, o la distribución inicial a los usuarios).

Extensión estatal

Las Extensiones de Estado** ofrecen una característica original para los contratos inteligentes. Permiten rescatar ciertos derechos digitales (Valencias) previstos en la definición del contrato, sin cerrar inmediatamente el sello. En la mayoría de los casos, se trata de :

Desde un punto de vista técnico, una Extensión de Estado hace referencia a un Redeem (un tipo particular de entrada RGB) que corresponde a una Valencia definida previamente (por ejemplo, en Génesis o en otra Transición de Estado). Define un nuevo sello, disponible para la persona o condición que se beneficia de él. Para que este sello se haga efectivo, debe ser gastado por una Transición de Estado posterior.

RGB-Bitcoin

Por ejemplo: el Génesis crea un derecho de emisión (Valencia). Esto puede ser ejercido por un actor autorizado, que luego construye una Extensión del Estado :

Componentes de una operación contractual

Me gustaría ahora examinar en detalle cada uno de los elementos constitutivos de una Operación de Contrato en RGB. Una Operación Contractual es la acción que modifica el estado de un contrato, y que es validada en el lado cliente, de forma determinista, por el destinatario legítimo. En concreto, veremos cómo la Operación de Contrato tiene en cuenta, por un lado, el estado antiguo (Old State) del contrato, y por otro, la definición de un nuevo estado (New State).

+---------------------------------------------------------------------------------------------------------------------+
|  Contract Operation                                                                                                 |
|                                                                                                                     |
|  +-----+     +-----------------------+      +--------------------------------+      +---------+     +------------+  |
|  | Ffv |     | ContractId | SchemaId |      | TransitionType | ExtensionType |      | Testnet |     | AltLayers1 |  |
|  +-----+     +-----------------------+      +--------------------------------+      +---------+     +------------+  |
|                                                                                                                     |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |
|  | Metadata                                      |  | Global State                                               |  |
|  |                                               |  | +----------------------------------+                       |  |
|  | +-------------------------------------+       |  | | +-------------------+ +--------+ |                       |  |
|  | |          Structured Data            |       |  | | |  GlobalStateType  | |  Data  | |     ...     ...       |  |
|  | +-------------------------------------+       |  | | +-------------------+ +--------+ |                       |  |
|  |                                               |  | +----------------------------------+                       |  |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |         +------+
|                                                                                                                     +---------> OpId |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |         +------+
|  | Inputs                                        |  | Assignments                                                |  |
|  |                                               |  |                                                            |  |
|  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
|  | | Input #1                                  | |  | | Assignment #1                                          | |  |
+------+       |  | | +----------+ +----------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
| OpId +--------------> PrevOpId | | AssignmentType | | Index | | |  | | | AssignmentType | | Owned State | | Seal Definition +--------------> Bitcoin UTXO |
+------+       |  | | +----------+ + ---------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
|  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
|  |                                               |  |                                                            |  |
|  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
|  | | Input #2                                  | |  | | Assignment #2                                          | |  |
+------+       |  | | +----------+ +----------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
| OpId +--------------> PrevOpId | | AssignmentType | | Index | | |  | | | AssignmentType | | Owned State | | Seal Definition +--------------> Bitcoin UTXO |
+------+       |  | | +----------+ +----------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
|  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
|  |                                               |  |                                                            |  |
|  |       ...           ...          ...          |  |     ...          ...             ...                       |  |
|  |                                               |  |                                                            |  |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |
|                                                                                                                     |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |
|  | Redeems                                       |  | Valencies                                                  |  |
|  |                                               |  |                                                            |  |
|  | +------------------------------+              |  |                                                            |  |
+------+       |  | | +----------+ +-------------+ |              |  |  +-------------+  +-------------+                          |  |
| OpId +--------------> PrevOpId | | ValencyType | |  ...   ...   |  |  | ValencyType |  | ValencyType |         ...              |  |
+------+       |  | | +----------+ +-------------+ |              |  |  +-------------+  +-------------+                          |  |
|  | +------------------------------+              |  |                                                            |  |
|  |                                               |  |                                                            |  |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |
|                                                                                                                     |
+---------------------------------------------------------------------------------------------------------------------+

Si observamos el diagrama anterior, podemos ver que una Operación Contractual incluye elementos referidos al Estado Nuevo y otros referidos al Estado Antiguo actualizado.

Los elementos del Nuevo Estado son :

El Estado Antiguo está referenciado mediante :

Además, una Operación Contractual incluye campos más generales específicos de la operación:

Por último, todos estos campos se condensan mediante un proceso de hash personalizado, para producir una huella digital única, el OpId. Este OpId se integra en el paquete de transición, lo que permite autenticarlo y validarlo dentro del protocolo.

Por tanto, cada Operación de contrato se identifica mediante un hash de 32 bytes denominado OpId. Este hash se calcula mediante un hash SHA256 de todos los elementos que componen la operación. En otras palabras, cada Operación de Contrato tiene su propio compromiso criptográfico, que incluye todos los datos necesarios para verificar la autenticidad y consistencia de la operación.

Un contrato RGB se identifica entonces mediante un ContractId, derivado del OpId de Génesis (ya que no existe ninguna operación previa a Génesis). En concreto, tomamos el OpId de Génesis, invertimos el orden de los bytes y aplicamos una codificación Base58. Esta codificación hace que el ContractId sea más fácil de manejar y reconocer.

Métodos y reglas de actualización de estado

El Estado del contrato representa el conjunto de informaciones que el protocolo RGB debe seguir para un contrato dado. Se compone de :

RGB-Bitcoin

El Estado Global se incluye directamente en la Operación de Contrato como un único bloque. Los Owned States se definen en cada Assignment, junto a la Seal Definition.

Una característica importante de RGB es la forma en que se modifican el Estado Global y los Estados Propios. En general, existen dos tipos de comportamiento:

Si, en el contrato, un elemento de estado no se define como mutable o acumulativo, este elemento permanecerá vacío para las operaciones posteriores (en otras palabras, no hay nuevas versiones para este campo). Es el Esquema del contrato (es decir, la lógica de negocio codificada) el que determina si un estado (Global o Propio) es mutable, acumulativo o fijo. Una vez definida la Génesis, estas propiedades sólo pueden modificarse si el propio contrato lo permite, por ejemplo a través de una Extensión de Estado específica.

La tabla siguiente ilustra cómo cada tipo de Operación de contrato puede manipular (o no) el Estado global y el Estado propio:

GénesisExtensión de EstadoTransición de Estado
Adición de Global State+-+
Mutación de Global Staten/a-+
Adición de Owned State+-+
Mutación de Owned Staten/aNo+
Adición de Valencies+++

+ : acción posible si el Esquema del contrato lo permite.

-: la operación debe ser confirmada por una Transición de Estado posterior (la Extensión de Estado por sí sola no cierra el Sello de un solo uso).

Además, el ámbito temporal y los derechos de actualización de cada tipo de datos pueden distinguirse en la siguiente tabla:

MetadatosEstado GlobalEstado Propietario
AlcanceDefinido para una única operación de contratoDefinido globalmente para el contratoDefinido para cada sello (Assignment)
¿Quién puede actualizarlo?No actualizable (datos efímeros)Operación emitida por los actores (emisor, etc.)Depende del poseedor legítimo que tiene el sello (quien puede gastarlo en una transacción posterior)
Alcance temporalSolo para la operación actualEl estado se establece al final de la operaciónEl estado se define antes de la operación (por la Seal Definition de la operación anterior)

Estado mundial

El Estado Global se describe a menudo como "nadie posee, todo el mundo conoce". Contiene información general sobre el contrato, que es públicamente visible. Por ejemplo, en un contrato de emisión de tokens, puede contener :

Este Estado Global puede colocarse en recursos públicos (sitios web, IPFS, Nostr, Torrent, etc.) y distribuirse a la comunidad. Además, el incentivo económico (la necesidad de mantener y transferir estos tokens, etc.) impulsa de forma natural a los usuarios contratantes a mantener y propagar estos datos por sí mismos.

Asignaciones

La Asignación es la estructura básica para definir :

Una Asignación puede verse como el análogo de una salida de transacción de Bitcoin, pero con más flexibilidad. Aquí reside la lógica de la transferencia de propiedad: la Asignación asocia un tipo particular de activo o derecho (Tipo de Asignación) con un sello. Quien posea la clave privada del UTXO vinculado a este sello (o quien pueda gastar este UTXO) se considera propietario de este Estado de propiedad.

Uno de los grandes puntos fuertes de RGB reside en la capacidad de revelar (revelar) u ocultar (ocultar) los campos Seal Definition y Owned State a voluntad. Esto ofrece una potente combinación de confidencialidad y selectividad. Por ejemplo, puedes demostrar que una transición es válida sin revelar todos los datos, proporcionando la versión revelada a la persona que tiene que validarla, mientras que terceros sólo ven la versión oculta (un hash). En la práctica, el OpId de una transición siempre se calcula a partir de los datos ocultos.

RGB-Bitcoin

Definición de foca

La Seal Definition, en su forma revelada, tiene cuatro campos básicos: txptr, vout, blinding y method :

La forma oculta de la Definición del Sello es un hash SHA256 (etiquetado) de la concatenación de estos 4 campos, con una etiqueta específica para RGB.

RGB-Bitcoin

Estados propios

El segundo componente de Asignación es el Estado Propio. A diferencia del Estado Global, puede existir en forma pública o privada:

RGB define cuatro posibles tipos de estado (StateTypes) para un Estado Propio:

SHA-256(SHA-256(tag_data) || SHA-256(tag_data) || blob)

Con, por ejemplo :

tag_data = urn:lnp-bp:rgb:state-data#2024-02-12
SHA-256(SHA-256(tag_attachment) || SHA-256(tag_attachment) || file_hash || media_type || salt)

Con, por ejemplo :

tag_attachment = urn:rgb:state-attach#2024-02-12

En resumen, estos son los 4 tipos de estado posibles en la forma pública y oculta:

State                      Concealed form                              Revealed form
+---------------------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------+
|                                                                                |
Declarative        |                              < void >                                          |
|                                                                                |
+--------------------------------------------------------------------------------+
+---------------------------------------------------------------------------------------------------------
+--------------------------+             +---------------------------------------+
| +----------------------+ |             |         +--------+ +----------+       |
Fungible           | | Pedersen Commitement | | <========== |         | Amount | | Blinding |       |
| +----------------------+ |             |         +--------+ +----------+       |
+--------------------------+             +---------------------------------------+
+---------------------------------------------------------------------------------------------------------
+--------------------------+             +---------------------------------------+
| +----------------------+ |             |         +--------------------+        |
Structured         | |     Tagged Hash      | | <========== |         |     Data Blob      |        |
| +----------------------+ |             |         +--------------------+        |
+--------------------------+             +---------------------------------------+
+---------------------------------------------------------------------------------------------------------
+--------------------------+             +---------------------------------------+
| +----------------------+ |             | +-----------+ +------------+ +------+ |
Attachments        | |     Tagged Hash      | | <========== | | File Hash | | Media Type | | Salt | |
| +----------------------+ |             | +-----------+ +------------+ +------+ |
+--------------------------+             +---------------------------------------+
ElementoDeclarativoFungibleEstructuradoAdjuntos
DatosNingunoEntero de 64 bits firmado o sin firmarCualquier tipo de datos estrictosCualquier archivo
Tipo de infoNingunoFirmado o sin firmarTipos estrictosTipo MIME
PrivacidadNo requeridaPedersen commitmentHash con blindingIdentificador de archivo hasheado
Límites de tamañoN/A256 bytesHasta 64 KBHasta ~500 GB

Entradas

Las Entradas de una Operación de Contratación se refieren a las Asignaciones que se están gastando en esta nueva operación. Una Entrada indica :

Las Entradas nunca aparecen en Génesis, ya que no hay Asignaciones previas. Tampoco aparecen en las Ampliaciones de Estado (porque las Ampliaciones de Estado no cierran sellos, sino que redefinen nuevos sellos basados en Valencias).

Cuando tenemos Estados Propios de tipo Fungible, la lógica de validación (a través del script AluVM proporcionado en el Esquema) comprueba la consistencia de las sumas: la suma de tokens entrantes (Entradas) debe ser igual a la suma de tokens salientes (en las nuevas Asignaciones).

Metadatos

El campo Metadatos puede tener un máximo de 64 KiB y se utiliza para incluir datos temporales útiles para la validación, pero no integrados en el estado permanente del contrato. Por ejemplo, aquí pueden almacenarse variables de cálculo intermedias para scripts complejos. Este espacio no está destinado a ser almacenado en el historial global, por lo que queda fuera del ámbito de los Estados propios o del Estado global.

Valencias

Las valencias** son un mecanismo original del protocolo RGB. Pueden encontrarse en Génesis, Transiciones de Estado o Extensiones de Estado. Representan derechos numéricos que pueden ser activados por una Extensión de Estado (a través de Redeems), y luego finalizados por una Transición posterior. Cada Valencia se identifica mediante un ValencyType (16 bits). Su semántica (derecho de reemisión, intercambio de fichas, derecho de quema, etc.) se define en el Esquema.

Concretamente, podríamos imaginar un Génesis que defina una valencia "derecho de reemisión". Una Extensión de Estado la consumirá (Reemitir) si se cumplen ciertas condiciones, con el fin de introducir una nueva cantidad de fichas. A continuación, una Transición de Estado emanada del poseedor del sello así creado podrá transferir estas nuevas fichas.

Redime

Las Redenciones son el equivalente en Valencia de las Entradas para Asignaciones. Sólo aparecen en las Extensiones de Estado, ya que es aquí donde se activa una Valencia previamente definida. Un Canje consta de dos campos:

Ejemplo: un Canje puede corresponder a una ejecución de CoinSwap, dependiendo de lo que se haya codificado en la Valencia.

Características de estado RGB

Ahora vamos a echar un vistazo a varias características de estado fundamentales en RGB. En particular, veremos :

Como siempre, ten en cuenta que todo lo relacionado con el estado del contrato se valida en el lado del cliente según las reglas de consenso establecidas en el protocolo, y cuya referencia criptográfica última está anclada en las transacciones de Bitcoin.

Sistema de tipos estricto

RGB utiliza un Sistema de Tipos Estricto y un modo de serialización determinista (Codificación Estricta). Esta organización está concebida para garantizar una perfecta reproducibilidad y precisión en la definición, tratamiento y validación de los datos contractuales.

En muchos entornos de programación (JSON, YAML...), la estructura de datos puede ser flexible, incluso demasiado permisiva. En RGB, en cambio, la estructura y los tipos de cada campo se definen con restricciones explícitas. Por ejemplo :

Gracias a este estricto protocolo de codificación :

En la práctica, se compilan la estructura (Esquema) y el código resultante (Interfaz y lógica asociada). Se utiliza un lenguaje descriptivo para definir el contrato (tipos, campos, reglas) y generar un formato binario estricto. Una vez compilado, el resultado es :

El estricto sistema de tipos también permite un seguimiento preciso de los cambios: cualquier modificación de la estructura (incluso un cambio de nombre de campo) es detectable y puede provocar un cambio en la huella global.

Por último, cada compilación produce una huella digital, un identificador criptográfico que da fe de la versión exacta del código (datos, reglas, validación). Por ejemplo, un identificador de la forma :

BEiLYE-am9WhTW1-oK8cpvw4-FEMtzMrf-mKocuGZn-qWK6YF#ginger-parking-nirvana

Esto permite gestionar las actualizaciones de consenso o de aplicación, garantizando al mismo tiempo una trazabilidad detallada de las versiones utilizadas en la red.

Para evitar que el estado de un contrato RGB resulte demasiado engorroso de validar del lado del cliente, una regla de consenso impone un tamaño máximo de 2^16 bytes (64 Kio) para cualquier dato que intervenga en los cálculos de validación. Esto se aplica a cada variable o estructura: no más de 65536 bytes, o el equivalente en números (32768 enteros de 16 bits, etc.). Esto también se aplica a las colecciones (listas, conjuntos, mapas), que no pueden superar los 2^16 elementos.

Este límite garantiza :

El paradigma Validación != Apropiación

Una de las principales innovaciones de RGB es la estricta separación entre dos conceptos:

La validación** tiene lugar a nivel de la pila de software de RGB (bibliotecas, protocolo de compromisos, etc.). Su función es garantizar que se respetan las normas internas del contrato (importes, permisos, etc.). Los observadores u otros participantes también pueden validar el historial de datos.

La propiedad**, por otro lado, depende totalmente de la seguridad de Bitcoin. Poseer la clave privada de un UTXO significa controlar la capacidad de lanzar una nueva transición (cerrar el sello de un solo uso). Por lo tanto, aunque alguien pueda ver o validar los datos, no podrá cambiar el estado si no posee el UTXO en cuestión.

RGB-Bitcoin

Este enfoque limita las vulnerabilidades clásicas encontradas en blockchains más complejas (donde todo el código de un contrato inteligente es público y modificable por cualquiera, lo que a veces ha llevado a hackeos). En RGB, un atacante no puede simplemente interactuar con el estado de la cadena, ya que el derecho a actuar sobre el estado (propiedad) está protegido por la capa Bitcoin.

Además, este desacoplamiento permite a RGB integrarse de forma natural con la red Lightning. Los canales Lightning se pueden utilizar para comprometer y mover activos RGB sin comprometer compromisos en la cadena cada vez. Veremos más de cerca esta integración de RGB en Lightning en capítulos posteriores del curso.

Evolución del consenso en RGB

Además del versionado semántico del código, RGB incluye un sistema de evolución o actualización de las reglas de consenso de un contrato a lo largo del tiempo. Existen dos formas principales de evolución:

Un avance rápido se produce cuando una norma que antes no era válida pasa a serlo. Por ejemplo, si el contrato evoluciona para permitir un nuevo tipo de AssignmentType o un nuevo campo :

Un "push-back" significa que una norma anteriormente válida pasa a ser inválida. Se trata, por tanto, de un "endurecimiento" de las normas, pero no propiamente de un softfork:

En este capítulo sobre las operaciones contractuales RGB, hemos explorado los principios fundamentales que subyacen a este protocolo. Como te habrás dado cuenta, la complejidad inherente al protocolo RGB requiere el uso de muchos términos técnicos. Por ello, en el próximo capítulo, le proporcionaré un glosario que resumirá todos los conceptos tratados en esta primera parte teórica, con definiciones de todos los términos técnicos relacionados con RGB. A continuación, en la siguiente sección, abordaremos de forma práctica la definición y aplicación de los contratos RGB.

Glosario RGB

Si necesitas volver a este breve glosario de términos técnicos importantes utilizados en el mundo RGB (enumerados por orden alfabético), te resultará útil. Este capítulo no es esencial si ya has entendido todo lo que hemos tratado en la primera sección.

AluVM

La abreviatura AluVM significa "Algorithmic logic unit Virtual Machine", una máquina virtual basada en registros diseñada para la validación de contratos inteligentes y la computación distribuida. Se utiliza (pero no se reserva exclusivamente) para la validación de contratos RGB. Los scripts u operaciones incluidos en un contrato RGB pueden así ejecutarse en el entorno AluVM.

Para más información: Sitio web oficial de AluVM

Ancla

Un Ancla representa un conjunto de datos del lado del cliente utilizados para demostrar la inclusión de un único compromiso en una transacción. En el protocolo RGB, un anclaje consta de los siguientes elementos:

Por lo tanto, un Ancla sirve para establecer un vínculo verificable entre una transacción Bitcoin específica y los datos privados validados por el protocolo RGB. Garantiza que estos datos están efectivamente incluidos en la blockchain, sin que su contenido exacto quede expuesto públicamente.

Asignación

En la lógica de RGB, una Asignación es el equivalente de una salida de transacción que modifica, actualiza o crea ciertas propiedades dentro del estado de un contrato. Una asignación consta de dos elementos:

Por lo tanto, una Asignación indica que una parte del estado (por ejemplo, un activo) está ahora asignada a un titular concreto, identificado mediante un Sello de un solo uso vinculado a un UTXO.

Lógica empresarial

La lógica empresarial agrupa todas las reglas y operaciones internas de un contrato, descritas por su esquema (es decir, la estructura del propio contrato). Dicta cómo puede evolucionar el estado del contrato y en qué condiciones.

Validación en el lado del cliente

La validación del lado del cliente se refiere al proceso mediante el cual cada parte (cliente) verifica un conjunto de datos intercambiados de forma privada, de acuerdo con las reglas de un protocolo. En el caso de RGB, estos datos intercambiados se agrupan en lo que se conoce como consignaciones. A diferencia del protocolo Bitcoin, que exige que todas las transacciones se publiquen en la cadena, RGB sólo permite que las consignaciones (ancladas en Bitcoin) se almacenen en público, mientras que la información esencial del contrato (transiciones, atestaciones, pruebas) permanece fuera de la cadena, compartida únicamente entre los usuarios implicados.

Compromiso

Un Compromiso (en el sentido criptográfico) es un objeto matemático, denotado C, derivado determinísticamente de una operación sobre datos estructurados m (el mensaje) y un valor aleatorio r. Escribimos :

C = \text{commit}(m, r)

Este mecanismo comprende dos operaciones principales:

Un compromiso debe respetar dos propiedades:

m' : \, | \, : m' \neq m \quad \text{and} \quad r' : \, | \, : r' \neq r \quad

Tales como :

\text{verify}(m, r, C) = \text{verify}(m', r', C) \rightarrow \text{True}

En el protocolo RGB, se incluye un compromiso en una transacción Bitcoin para demostrar la existencia de cierta información en un momento dado, sin revelar la información en sí.

Consignación

Una Consignación agrupa los datos intercambiados entre las partes, sujetos a Validación por el Cliente en RGB. Existen dos categorías principales de consignación:

Estos envíos no se registran públicamente en la cadena de bloques, sino que se intercambian directamente entre las partes interesadas a través del canal de comunicación que elijan.

Contrato

Un Contrato es un conjunto de derechos ejecutados digitalmente entre varios actores a través del protocolo RGB. Tiene un estado activo y una lógica de negocio, definida por un Esquema, que especifica qué operaciones están autorizadas (transferencias, ampliaciones, etc.). El estado de un contrato, así como sus reglas de validez, se expresan en el Esquema. En un momento dado, el contrato evoluciona únicamente de acuerdo con lo permitido por este Esquema y por los scripts de validación (ejecutados, por ejemplo, en AluVM).

Operación contractual

Una operación de contrato es una actualización del estado de un contrato realizada de acuerdo con las reglas del esquema. En RGB existen las siguientes operaciones:

Cada operación modifica el estado añadiendo o sustituyendo determinados datos (Estado Global, Estado Propio...).

Participante en el contrato

Un Participante en el Contrato es un actor que interviene en las operaciones relativas al contrato. En RGB se distingue entre :

Derechos contractuales

Los derechos contractuales se refieren a los diversos derechos que pueden ejercer los implicados en un contrato RGB. Se dividen en varias categorías:

Estado del contrato

El Estado del Contrato corresponde al estado actual de un contrato en un momento dado. Puede estar compuesto tanto por datos públicos como privados, reflejando el estado del contrato. RGB distingue entre :

Compromiso bitcoin determinista - DBC

Deterministic Bitcoin Commitment (DBC) es el conjunto de reglas utilizadas para registrar de forma demostrable y única un compromiso en una transacción Bitcoin. En el protocolo RGB, hay dos formas principales de DBC:

Estos mecanismos definen con precisión cómo se codifica el compromiso en la salida o estructura de una transacción Bitcoin, para asegurar que este compromiso es determinísticamente rastreable y verificable.

Gráfico acíclico dirigido - DAG

Un DAG (o Gráfico Guiado Acíclico) es un grafo sin ciclos, que permite la programación topológica. Las Blockchains, como los shards de los contratos RGB, pueden representarse mediante DAGs.

Para más información: Grafo acíclico dirigido

Grabado

El grabado es una cadena de datos opcional que los sucesivos propietarios de un contrato pueden introducir en el historial del contrato. Esta función existe, por ejemplo, en la interfaz RGB21 y permite añadir información conmemorativa o descriptiva al historial del contrato.

Prueba de Transacción Extra - ETP

El ETP (Extra Transaction Proof) es la parte del Anchor que contiene los datos adicionales necesarios para validar un Tapret commitment (en el contexto de taproot). Incluye, entre otras cosas, la clave pública interna del taproot script (internal PubKey) e información específica del Script Path Spend.

Génesis

Génesis se refiere al conjunto de datos, gobernado por un Esquema, que forma el estado inicial de cualquier contrato en RGB. Puede compararse con el concepto de Bloque Génesis de Bitcoin, o con el concepto de transacción de Coinbase, pero aquí a nivel de lado del cliente y de token RGB.

Estado mundial

El Estado Global es el conjunto de propiedades públicas contenidas en el Estado del Contrato. Se define en Génesis y, dependiendo de las reglas del contrato, puede ser actualizado por transiciones autorizadas. A diferencia de los Estados Propios, el Estado Global no pertenece a una entidad en particular; está más cerca de un registro público dentro del contrato.

Interfaz

La Interfaz es el conjunto de instrucciones utilizadas para descodificar los datos binarios compilados en un Esquema o en operaciones de contrato y sus estados, con el fin de hacerlos legibles para el usuario o su monedero. Actúa como una capa de interpretación.

Aplicación de la interfaz

La implementación de la interfaz es el conjunto de declaraciones que vinculan una Interfaz a un Esquema. Permite la traducción semántica realizada por la propia Interfaz, de forma que los datos brutos de un contrato puedan ser entendidos por el usuario o el software implicado (los monederos).

Factura

Una factura adopta la forma de una URL codificada en base58, que incorpora los datos necesarios para la construcción de una transición de estado (por parte del pagador). En otras palabras, es una factura que permite a la contraparte (pagador) crear la transición correspondiente para transferir el activo o actualizar el estado del contrato.

Red del Rayo

La Lightning Network es una red descentralizada de canales de pago (o canales de estado) en Bitcoin, formada por monederos 2/2 multi-firma. Permite transacciones rápidas y de bajo coste fuera de la cadena, al tiempo que confía en la Capa 1 de Bitcoin para el arbitraje (o cierre) cuando es necesario.

Para más información sobre cómo funciona Lightning, te recomiendo que sigas este otro curso:

https://planb.network/courses/34bd43ef-6683-4a5c-b239-7cb1e40a4aeb

Compromiso multiprotocolo - MPC

Multi Protocol Commitment (MPC) se refiere a la estructura de árbol de Merkle utilizada en RGB para incluir, dentro de una única transacción Bitcoin, varios Transition Bundles de diferentes contratos. La idea es agrupar varios compromisos (potencialmente correspondientes a diferentes contratos o diferentes activos) en un único punto de anclaje para optimizar la ocupación del espacio de bloque.

Estado de propiedad

Un Estado de titularidad es la parte de un Estado de contrato que está incluida en una Asignación y asociada a un titular concreto (mediante un Sello de un solo uso que apunta a un UTXO). Representa, por ejemplo, un activo digital o un derecho contractual específico asignado a esa persona.

Propiedad

La propiedad se refiere a la capacidad de controlar y gastar un UTXO referenciado por una Definición de Sello. Cuando un Estado Propio está vinculado a un UTXO, el propietario de este UTXO tiene derecho, potencialmente, a transferir o evolucionar el estado asociado, según las reglas del contrato.

Transacción Bitcoin Parcialmente Firmada - PSBT

Una PSBT (Transacción Bitcoin Parcialmente Firmada) es una transacción Bitcoin que aún no está totalmente firmada. Puede ser compartida entre varias entidades, cada una de las cuales puede añadir o verificar ciertos elementos (firmas, scripts...), hasta que la transacción se considere lista para su distribución en la cadena.

Para más información: BIP-0174

Compromiso de Pedersen

Un compromiso de Pedersen es un tipo de compromiso criptográfico con la propiedad de ser homomórfico con respecto a la operación de suma. Esto significa que es posible validar la suma de dos compromisos sin revelar los valores individuales.

Formalmente, si :

C1=\text{commit}(m1,r1) \quad C2=\text{commit}(m2,r2)

entonces :

C3=C1⋅C2=\text{commit}(m1+m2, r1+r2)

Esta propiedad es útil, por ejemplo, para ocultar las cantidades de fichas intercambiadas, sin dejar de poder verificar los totales.

Para más información: Pedersen commitment

Canjear

En una Extensión de Estado, un Canje se refiere a la acción de reclamar (o explotar) una Valencia previamente declarada. Como una Valencia es un derecho público, el Rescate permite a un participante autorizado reclamar una extensión de estado de contrato específica.

Esquema

Un esquema en RGB es un fragmento de código declarativo que describe el conjunto de variables, reglas y lógica de negocio (Lógica de negocio) que rigen el funcionamiento de un contrato. El esquema define la estructura de estados, los tipos de transiciones permitidas y las condiciones de validación.

Definición de foca

La Definición del Sello es la parte de una Cesión que asocia el compromiso con un UTXO propiedad del nuevo titular. En otras palabras, indica dónde se encuentra la condición (en qué UTXO), y establece la propiedad de un activo o derecho.

Fragmento

Un fragmento representa una rama en el DAG del historial de transiciones de estado de un contrato RGB. En otras palabras, es un subconjunto coherente del historial global del contrato, que corresponde, por ejemplo, a la secuencia de transiciones necesarias para demostrar la validez de un determinado activo desde la Génesis.

Sello de un solo uso

Un sello de un solo uso es una promesa criptográfica de compromiso con un mensaje aún desconocido, que sólo se revelará una vez en el futuro y que debe ser conocido por todos los miembros de un público específico. El objetivo es evitar la creación de múltiples compromisos competidores para el mismo sello.

Alijo

El Stash es el conjunto de datos del lado del cliente que un usuario almacena para uno o varios contratos RGB, con fines de validación (Validación del lado del cliente). Esto incluye el historial de transiciones, envíos, pruebas de validez, etc. Cada titular conserva sólo las partes del historial que necesita (shards).

Extensión estatal

Una Extensión de Estado es una operación de contrato que se utiliza para volver a activar actualizaciones de estado mediante el canje de Valencias declaradas previamente. Para ser efectiva, una Extensión de Estado debe cerrarse mediante una Transición de Estado (que actualiza el estado final del contrato).

Transición de estados

La Transición de Estado es la operación que cambia el estado de un contrato RGB a un nuevo estado. Puede modificar datos del Estado Global y/o del Estado Propio. En la práctica, cada transición se verifica mediante reglas de Esquema y se ancla en la blockchain de Bitcoin mediante un commitment.

Taproot

Se refiere al formato de transacción Segwit v1 de Bitcoin, introducido por BIP341 y BIP342. Taproot mejora la confidencialidad y la flexibilidad de los scripts, en particular haciendo que las transacciones sean más compactas y más difíciles de distinguir unas de otras.

Terminal Consignación - Terminal Consignación

La Consignación Terminal (o Punto Final de la Consignación) es una consignación de transferencia que contiene el estado final del contrato, incluida la Transición de Estado creada a partir de la Factura del destinatario (beneficiario). Es, por tanto, el punto final de una transferencia, con los datos necesarios para demostrar que se ha transferido la propiedad o el estado.

Paquete de transición

Un paquete de transiciones es un conjunto de transiciones de estado RGB (pertenecientes al mismo contrato) que participan en la misma transacción de testigo Bitcoin. Esto permite agrupar varias actualizaciones o transferencias en un único anclaje en cadena.

UTXO

Un Bitcoin UTXO (Unspent Transaction Output) se define por el hash de una transacción y el índice de salida (vout). También se denomina a veces outpoint. En el protocolo RGB, la referencia a un UTXO (a través de una Seal Definition) permite la localización del Owned State, es decir, la propiedad mantenida en el blockchain.

Valencia

Una Valencia es un derecho público que no requiere almacenamiento estatal como tal, pero que puede ser canjeado a través de una Ampliación Estatal. Se trata, por tanto, de una forma de posibilidad abierta a todos (o a determinados jugadores), declarada en la lógica del contrato, para llevar a cabo una determinada extensión en una fecha posterior.

Transacción con testigos

La Transacción Testigo es la transacción Bitcoin que cierra el Sello de un solo uso en torno a un mensaje que contiene un Compromiso Multiprotocolo (MPC). Esta transacción gasta un UTXO o crea uno, para sellar el compromiso vinculado al protocolo RGB. Actúa como una prueba en la cadena de que el estado se ha establecido en un punto específico en el tiempo.

Programación en RGB

Implantación de contratos RGB

En este capítulo veremos más de cerca cómo se define e implementa un contrato RGB. Veremos cuáles son los componentes de un contrato RGB, cuáles son sus funciones y cómo se construyen.

Los componentes de un contrato RGB

Hasta ahora, ya hemos hablado de la Génesis, que representa el punto de partida de un contrato, y hemos visto cómo encaja con la lógica de una Operación de contrato y el estado del protocolo. Sin embargo, la definición completa de un contrato RGB no se limita únicamente a la Génesis: implica tres componentes complementarios que, juntos, forman el corazón de la implementación.

El primer componente se denomina Esquema. Se trata de un archivo que describe la estructura fundamental y la lógica empresarial (lógica empresarial) del contrato. Especifica los tipos de datos utilizados, las reglas de validación, las operaciones permitidas (por ejemplo, emisión inicial de tokens, transferencias, condiciones especiales, etc.); en resumen, el marco general que dicta cómo funciona el contrato.

El segundo componente es la Interfaz. Se centra en cómo los usuarios (y, por extensión, el software de la cartera) interactuarán con este contrato. Describe la semántica, es decir, la representación legible de los distintos campos y acciones. Así, mientras que el Esquema define cómo funciona técnicamente el contrato, la Interfaz define cómo presentar y exponer estas funcionalidades: nombres de métodos, visualización de datos, etc.

El tercer componente es la implementación de la interfaz, que complementa a los dos anteriores actuando como una especie de puente entre el esquema y la interfaz. En otras palabras, asocia la semántica expresada por la Interfaz con las reglas subyacentes definidas en el Esquema. Es esta implementación la que gestionará, por ejemplo, la conversión entre un parámetro introducido en el monedero y la estructura binaria impuesta por el protocolo, o la compilación de las reglas de validación en lenguaje máquina.

Esta modularidad es una característica interesante de RGB, ya que permite que diferentes grupos de desarrolladores trabajen por separado en estos aspectos (Esquema, Interfaz, Implementación), siempre que sigan las reglas de consenso del protocolo.

En resumen, cada contrato consta de :

RGB-Bitcoin

Es importante tener en cuenta que para que un monedero pueda gestionar un activo RGB (ya sea un token fungible o un derecho de cualquier tipo), debe tener compilados todos estos elementos: Schema, Interface, Interface Implementation y Genesis. Esto se transmite a través de una envío de contrato, es decir, un paquete de datos que contiene todo lo necesario para validar el contrato del lado del cliente.

Para ayudar a aclarar estas nociones, he aquí una tabla resumen que compara los componentes de un contrato RGB con conceptos ya conocidos en la programación orientada a objetos (POO) o en el ecosistema Ethereum:

Componente del contrato RGBSignificadoEquivalente OOPEquivalente en Ethereum
GenesisEstado inicial del contratoConstructor de claseConstructor del contrato
SchemaLógica de negocio del contratoClaseContrato
InterfaceSemántica del contratoInterfaz (Java) / trait (Rust) / protocolo (Swift)Estándar ERC
Interface ImplementationMapeo de la semántica y la lógicaImpl (Rust) / Implements (Java)Application Binary Interface (ABI)

La columna de la izquierda muestra los elementos específicos del protocolo RGB. La columna central muestra la función concreta de cada componente. A continuación, en la columna "Equivalente OOP", encontramos el término equivalente en programación orientada a objetos:

En el contexto de Ethereum, el Génesis está más cerca del constructor del contrato, el Esquema de la definición del contrato, la Interfaz de un estándar como ERC-20 o ERC-721, y la Interfaz de Implementación de la ABI (Application Binary Interface), que especifica el formato de las interacciones con el contrato.

La ventaja de la modularidad de RGB reside también en el hecho de que las distintas partes interesadas pueden escribir, por ejemplo, su propia implementación de interfaz, siempre que respeten la lógica del Esquema y la semántica de la Interfaz. Así, un emisor podría desarrollar un nuevo front-end (Interfaz) más fácil de usar, sin modificar la lógica del contrato, o a la inversa, se podría ampliar el Esquema para añadir funcionalidad, y proporcionar una nueva versión de la Implementación de Interfaz adaptada, mientras que las antiguas implementaciones seguirían siendo válidas para la funcionalidad básica.

Cuando compilamos un nuevo contrato, generamos un Genesis (el primer paso para emitir o distribuir el activo), así como sus componentes (Schema, Interface, Interface Implementation). Después de esto, el contrato es totalmente operativo y puede propagarse a los monederos y a los usuarios. Este método, en el que Génesis se combina con estos tres componentes, garantiza un alto grado de personalización (cada contrato puede tener su propia lógica), descentralización (todo el mundo puede contribuir a un componente determinado) y seguridad (la validación sigue estando estrictamente definida por el protocolo, sin depender de código arbitrario en la cadena, como suele ocurrir en otras blockchains).

Ahora me gustaría examinar más de cerca cada uno de estos componentes: el Esquema, la Interfaz y la Implementación de la Interfaz.

Esquema

En la sección anterior vimos que, en el ecosistema RGB, un contrato se compone de varios elementos: el Génesis, que establece el estado inicial, y varios otros componentes complementarios. El objetivo del Esquema es describir de forma declarativa toda la lógica de negocio del contrato, es decir, la estructura de datos, los tipos utilizados, las operaciones permitidas y sus condiciones. Es, por tanto, un elemento muy importante para hacer operativo un contrato en el lado del cliente, ya que cada participante (un monedero, por ejemplo) debe comprobar que las transiciones de estado que recibe se ajustan a la lógica definida en el Esquema.

Un esquema puede asimilarse a una "clase" en programación orientada a objetos (POO). En términos generales, sirve como modelo que define los componentes de un contrato, como :

RGB-Bitcoin

Cuando el emisor de un activo en RGB publica un contrato, proporciona el Génesis y el Esquema asociado al mismo. Los usuarios o monederos que deseen interactuar con el activo recuperan este Esquema para comprender la lógica que subyace al contrato, y poder verificar posteriormente que las transiciones en las que van a participar son legítimas.

El primer paso, para cualquiera que reciba información sobre un activo RGB (por ejemplo, una transferencia de fichas), es validar esta información con el esquema. Esto implica utilizar la compilación del esquema para :

En la práctica, Schema no es código ejecutable, como puede verse en blockchains que almacenan código en la cadena (EVM en Ethereum). Por el contrario, RGB separa la lógica de negocio (declarativa) del código ejecutable en la blockchain (que se limita a los anclajes criptográficos). Así, el Esquema determina las reglas, pero la aplicación de estas reglas tiene lugar fuera de la blockchain, en el sitio de cada participante, según el principio de Validación del Lado del Cliente.

Un esquema debe compilarse antes de que pueda ser utilizado por las aplicaciones RGB. Esta compilación produce un archivo binario (por ejemplo .rgb) o un archivo binario encriptado (.rgba). Cuando el monedero importa este archivo, sabe que :

Como se ha explicado en capítulos anteriores, el sistema de tipos estricto nos proporciona un formato de codificación estable y determinista: todas las variables, ya sean estados propios, estados globales o valencias, se describen con precisión (tamaño, límites inferior y superior si es necesario, tipo con o sin signo, etc.). También es posible definir estructuras anidadas, por ejemplo para dar soporte a casos de uso complejos.

Opcionalmente, el esquema puede hacer referencia a un SchemaId raíz, lo que facilita la reutilización de una estructura básica existente (una plantilla). De este modo, se puede hacer evolucionar un contrato o crear variaciones (por ejemplo, un nuevo tipo de ficha) a partir de una plantilla ya probada. Esta modularidad evita la necesidad de recrear contratos enteros y fomenta la estandarización de las mejores prácticas.

Otro punto importante es que la lógica de evolución del estado (transferencias, actualizaciones, etc.) se describe en el Esquema en forma de scripts, reglas y condiciones. Así, si el diseñador del contrato desea autorizar una reemisión o imponer un mecanismo de quema (destrucción de tokens), puede especificar los scripts correspondientes para AluVM en la parte de validación del Esquema.

Diferencia con las cadenas de bloques en cadena programables

A diferencia de sistemas como Ethereum, donde el código del contrato inteligente (ejecutable) se escribe en la propia blockchain, RGB almacena el contrato (su lógica) fuera de la cadena, en forma de documento declarativo compilado. Esto implica que :

Utilización por el emisor y por los usuarios

Cuando un emisor crea un activo (por ejemplo, una ficha fungible no inflacionista), prepara :

A continuación, pone a disposición de los usuarios el Esquema compilado (un archivo .rgb), para que cualquiera que reciba una transferencia de este token pueda comprobar localmente la coherencia de la operación. Sin este esquema, un usuario no podría interpretar los datos de estado ni comprobar si cumplen las normas del contrato.

De este modo, cuando un nuevo monedero quiere admitir un activo, sólo tiene que integrar el Schema correspondiente. Este mecanismo hace posible añadir compatibilidad a nuevos tipos de activos RGB, sin cambiar invasivamente la base de software del monedero: todo lo que se requiere es importar el binario Schema y entender su estructura.

El Esquema define la lógica de negocio en RGB. Enumera las reglas de evolución de un contrato, la estructura de sus datos (Estados Propios, Estado Global, Valencias) y los scripts de validación asociados (ejecutables por AluVM). Gracias a este documento declarativo, la definición de un contrato (archivo compilado) está claramente separada de la ejecución real de las reglas (del lado del cliente). Este desacoplamiento proporciona a RGB una gran flexibilidad, permitiendo una amplia gama de casos de uso (tokens fungibles, NFT, contratos más sofisticados) al tiempo que evita la complejidad y los defectos típicos de las cadenas de bloques programables.

Ejemplo de esquema

Veamos un ejemplo concreto de esquema para un contrato RGB. Se trata de un extracto en Rust del archivo nia.rs (iniciales de "Non-Inflatable Assets"), que define un modelo para tokens fungibles que no pueden ser reemitidos más allá de su suministro inicial (un activo no inflacionario). Este tipo de token puede considerarse el equivalente, en el universo RGB, del ERC20 en Ethereum, es decir, tokens fungibles que respetan ciertas reglas básicas (por ejemplo, sobre transferencias, inicialización del suministro, etc.).

Antes de entrar en el código, conviene recordar la estructura general de un esquema RGB. Hay una serie de declaraciones que enmarcan :

RGB-Bitcoin

El código siguiente muestra la definición completa del esquema Rust. Lo comentaremos parte por parte, siguiendo las anotaciones (1) a (9) a continuación:

// ===== PART 1: Function Header and SubSchema =====
fn nia_schema() -> SubSchema {
// definitions of libraries and variables
// ===== PART 2: General Properties (ffv, subset_of, type_system) =====
Schema {
ffv: zero!(),
subset_of: None,
type_system: types.type_system(),
// ===== PART 3: Global States =====
global_types: tiny_bmap! {
GS_NOMINAL => GlobalStateSchema::once(types.get("RGBContract.DivisibleAssetSpec")),
GS_DATA => GlobalStateSchema::once(types.get("RGBContract.ContractData")),
GS_TIMESTAMP => GlobalStateSchema::once(types.get("RGBContract.Timestamp")),
GS_ISSUED_SUPPLY => GlobalStateSchema::once(types.get("RGBContract.Amount")),
},
// ===== PART 4: Owned Types =====
owned_types: tiny_bmap! {
OS_ASSET => StateSchema::Fungible(FungibleType::Unsigned64Bit),
},
// ===== PART 5: Valencies =====
valency_types: none!(),
// ===== PART 6: Genesis: Initial Operations =====
genesis: GenesisSchema {
metadata: Ty::<SemId>::UNIT.id(None),
globals: tiny_bmap! {
GS_NOMINAL => Occurrences::Once,
GS_DATA => Occurrences::Once,
GS_TIMESTAMP => Occurrences::Once,
GS_ISSUED_SUPPLY => Occurrences::Once,
},
assignments: tiny_bmap! {
OS_ASSET => Occurrences::OnceOrMore,
},
valencies: none!(),
},
// ===== PART 7: Extensions =====
extensions: none!(),
// ===== PART 8: Transitions: TS_TRANSFER =====
transitions: tiny_bmap! {
TS_TRANSFER => TransitionSchema {
metadata: Ty::<SemId>::UNIT.id(None),
globals: none!(),
inputs: tiny_bmap! {
OS_ASSET => Occurrences::OnceOrMore,
},
assignments: tiny_bmap! {
OS_ASSET => Occurrences::OnceOrMore,
},
valencies: none!(),
}
},
// ===== PART 9: Script AluVM and Entry Points =====
script: Script::AluVM(AluScript {
libs: confined_bmap! { alu_id => alu_lib },
entry_points: confined_bmap! {
EntryPoint::ValidateGenesis => LibSite::with(FN_GENESIS_OFFSET, alu_id),
EntryPoint::ValidateTransition(TS_TRANSFER) => LibSite::with(FN_TRANSFER_OFFSET, alu_id),
},
}),
}
}

La función nia_schema() devuelve un SubSchema, lo que indica que este esquema puede heredar parcialmente de un esquema más genérico. En el ecosistema RGB, esta flexibilidad permite reutilizar ciertos elementos estándar de un esquema maestro, y luego definir reglas específicas para el contrato en cuestión. En este caso, optamos por no permitir la herencia, ya que subset_of será None.

La propiedad ffv corresponde a la versión fast-forward del contrato. Un valor de ¡cero!() aquí indica que estamos en la versión 0 o la versión inicial de este esquema. Si más adelante desea añadir nuevas funcionalidades (nuevo tipo de operación, etc.), puede incrementar esta versión para indicar un cambio de consenso.

La propiedad subset_of: None confirma la ausencia de herencia. El campo type_system hace referencia al sistema de tipos estricto ya definido en la biblioteca types. Esta línea indica que todos los datos utilizados por el contrato utilizan la implementación de serialización estricta proporcionada por la biblioteca en cuestión.

En el bloque global_types declaramos cuatro elementos. Utilizamos la clave, como GS_NOMINAL o GS_ISSUED_SUPPLY, para referenciarlos posteriormente:

La palabra clave once(...) significa que cada uno de estos campos sólo puede aparecer una vez.

En owned_types, declaramos OS_ASSET, que describe un estado fungible. Utilizamos StateSchema::Fungible(FungibleType::Unsigned64Bit), indicando que la cantidad de activos (tokens) se almacena como un entero de 64 bits sin signo. Así, cualquier transacción enviará una cierta cantidad de unidades de este token, que se validará según esta estructura numérica estrictamente tipada.

Indicamos valency_types: none!(), lo que significa que no hay valencias en este esquema, es decir, ningún derecho especial o extra (como reemisión, quemado condicional, etc.). Si un esquema incluyera alguna, se declararía en esta sección.

Aquí entramos en la parte que declara las Operaciones Contractuales. El Génesis es descrito por :

Así limitamos la definición de la emisión inicial de tokens: debemos declarar el suministro emitido (GS_ISSUED_SUPPLY), más al menos un poseedor (un Owned State de tipo OS_ASSET).

El campo extensions: none!() indica que en este contrato no está prevista ninguna Extensión de Estado. Esto significa que no hay ninguna operación para redimir un derecho digital (Valency) o para realizar una extensión de estado antes de una Transición. Todo se realiza a través de Génesis o Transiciones de Estado.

En transitions, definimos el tipo de operación TS_TRANSFER. Explicamos que :

Esto modela el comportamiento de una transferencia básica, que consume tokens en un UTXO, luego crea nuevos Estados Propios a favor de los receptores, y así preserva la igualdad de la cantidad total entre entradas y salidas.

Por último, declaramos un script AluVM (Script::AluVM(AluScript { ... })). Este script contiene :

Este código de validación es responsable de aplicar la lógica de negocio. Por ejemplo, comprobará :

Si no se respetan estas normas, la transición se considerará inválida.

Este ejemplo de esquema de "Activo fungible no inflable" nos permite comprender mejor la estructura de un contrato de token fungible RGB sencillo. Podemos ver claramente la separación entre la descripción de datos (Estados Globales y Propios), la declaración de operaciones (Génesis, Transiciones, Extensiones) y la implementación de la validación (scripts AluVM). Gracias a este modelo, un token se comporta como un token fungible clásico, pero permanece validado en el lado del cliente y no depende de la infraestructura on-chain para ejecutar su código. Sólo los compromisos criptográficos están anclados en la blockchain de Bitcoin.

Interfaz

La interfaz es la capa destinada a hacer legible y manipulable un contrato, tanto por los usuarios (lectura humana) como por las carteras (lectura informática). Por tanto, la interfaz desempeña un papel comparable al de una interfaz en un lenguaje de programación orientado a objetos (Java, Rust trait, etc.), en el sentido de que expone y aclara la estructura funcional de un contrato, sin revelar necesariamente los detalles internos de la lógica empresarial.

A diferencia de Schema, que es puramente declarativo y se compila en un archivo binario difícil de utilizar tal cual, Interface proporciona las claves de lectura necesarias para :

RGB-Bitcoin

Gracias a la Interfaz, se puede, por ejemplo, escribir código en un monedero que, en lugar de manipular campos, manipule directamente etiquetas como "número de tokens", "nombre del activo", etc. De esta forma, la gestión de un contrato se vuelve más intuitiva. De este modo, la gestión de un contrato se vuelve más intuitiva.

Funcionamiento general

Este método tiene muchas ventajas:

El mismo tipo de contrato puede ser soportado por una Interfaz estándar, compartida entre varias implementaciones de monederos. Esto facilita la compatibilidad y la reutilización del código.

En el diseño RGB, el esquema (lógica de negocio) y la interfaz (presentación y manipulación) son dos entidades independientes. Los desarrolladores que escriben la lógica del contrato pueden concentrarse en el Esquema, sin preocuparse por la ergonomía o la representación de los datos, mientras que otro equipo (o el mismo equipo, pero con un calendario diferente) puede desarrollar la Interfaz.

La Interfaz puede modificarse o añadirse después de que el activo haya sido emitido, sin tener que cambiar el propio contrato. Esta es una diferencia importante con respecto a algunos sistemas de contratos inteligentes en cadena, en los que la Interfaz (a menudo mezclada con el código de ejecución) se congela en la blockchain.

El mismo contrato podría exponerse a través de diferentes Interfaces adaptadas a distintas necesidades: una Interfaz sencilla para el usuario final, otra más avanzada para el emisor que necesite gestionar operaciones de configuración complejas. El monedero puede entonces elegir qué Interfaz importar, en función de su uso.

RGB-Bitcoin

En la práctica, cuando el monedero recupera un contrato RGB (a través de un archivo .rgb o .rgba), también importa la Interfaz asociada, que también se compila. En tiempo de ejecución, el monedero puede, por ejemplo :

Diferencia con Ethereum y otros sistemas

En Ethereum, la interfaz (descrita a través de la ABI, Application Binary Interface) se deriva generalmente del código almacenado en la cadena (el contrato inteligente). Puede resultar costoso o complicado modificar una parte específica de la interfaz sin tocar el propio contrato. Sin embargo, RGB se basa en una lógica totalmente fuera de la cadena, con datos anclados en compromisos en Bitcoin. Este diseño hace posible modificar la Interfaz (o su implementación) sin impactar en la seguridad fundamental del contrato, ya que la validación de las reglas de negocio permanece en el Esquema y en el código AluVM referenciado.

Compilación de interfaces

Al igual que con Schema, la Interfaz se define en código fuente (a menudo en Rust) y se compila en un archivo .rgb o .rgba. Este archivo binario contiene toda la información que necesita el monedero para :

Una vez importada la Interfaz, el monedero puede mostrar correctamente el contrato y proponer interacciones al usuario.

Interfaces normalizadas por la asociación LNP/BP

En el ecosistema RGB, se utiliza una Interfaz para dar un significado legible y manipulable a los datos y operaciones de un contrato. La Interfaz complementa así al Esquema, que describe internamente la lógica de negocio (tipos estrictos, scripts de validación, etc.). En esta sección, examinaremos las interfaces estándar desarrolladas por la asociación LNP/BP para los tipos de contrato más comunes (fichas fungibles, NFT, etc.).

Como recordatorio, la idea es que cada Interfaz describa cómo mostrar y manipular un contrato en el lado del monedero, nombrando claramente los campos (como spec, ticker, issuedSupply...) y definiendo las posibles operaciones (como Transfer, Burn, Rename...). Varias interfaces ya están operativas, pero habrá más y más en el futuro.

Algunas interfaces listas para usar

RGB20 es la interfaz para activos fungibles, que puede compararse con el estándar ERC20 de Ethereum. Sin embargo, va un paso más allá, ofreciendo una funcionalidad más amplia:

Por ejemplo, la Interfaz RGB20 puede vincularse al esquema Activo no hinchable (NIA), que impone un suministro inicial no hinchable, o a otros esquemas más avanzados según las necesidades.

RGB21 se refiere a los contratos de tipo NFT, o más ampliamente, a cualquier contenido digital único, como la representación de medios digitales (imágenes, música, etc.). Además de describir la emisión y transferencia de un activo único, incluye características como :

RGB25 es un estándar híbrido que combina aspectos fungibles y no fungibles. Está diseñado para activos parcialmente fungibles, como la tokenización inmobiliaria, en la que se desea dividir una propiedad conservando un vínculo a un único activo raíz (en otras palabras, se tienen piezas fungibles de una casa, vinculadas a una casa no fungible). Técnicamente, esta interfaz puede vincularse al esquema *Collectible Fungible Asset (CFA)**, que tiene en cuenta la noción de división al tiempo que rastrea el activo original.

Interfaces en desarrollo

Están previstas otras interfaces para usos más especializados, pero aún no están disponibles:

Por supuesto, dependiendo de la fecha en la que consulte este curso, es posible que estas interfaces ya estén operativas y accesibles.

Ejemplo de interfaz

Este fragmento de código Rust muestra una interfaz RGB20 (activo fungible). Este código está tomado del archivo rgb20.rs de la biblioteca estándar RGB. Echémosle un vistazo para entender la estructura de una Interfaz y cómo proporciona un puente entre, por un lado, la lógica de negocio (definida en el Esquema) y, por otro, las funcionalidades expuestas a los monederos y usuarios.

// ...
fn rgb20() -> Iface {
let types = StandardTypes::with(rgb20_stl());
Iface {
version: VerNo::V1,
name: tn!("RGB20"),
global_state: tiny_bmap! {
fname!("spec") => GlobalIface::required(types.get("RGBContract.DivisibleAssetSpec")),
fname!("data") => GlobalIface::required(types.get("RGBContract.ContractData")),
fname!("created") => GlobalIface::required(types.get("RGBContract.Timestamp")),
fname!("issuedSupply") => GlobalIface::one_or_many(types.get("RGBContract.Amount")),
fname!("burnedSupply") => GlobalIface::none_or_many(types.get("RGBContract.Amount")),
fname!("replacedSupply") => GlobalIface::none_or_many(types.get("RGBContract.Amount")),
},
assignments: tiny_bmap! {
fname!("inflationAllowance") => AssignIface::public(OwnedIface::Amount, Req::NoneOrMore),
fname!("updateRight") => AssignIface::public(OwnedIface::Rights, Req::Optional),
fname!("burnEpoch") => AssignIface::public(OwnedIface::Rights, Req::Optional),
fname!("burnRight") => AssignIface::public(OwnedIface::Rights, Req::NoneOrMore),
fname!("assetOwner") => AssignIface::private(OwnedIface::Amount, Req::NoneOrMore),
},
valencies: none!(),
genesis: GenesisIface {
metadata: Some(types.get("RGBContract.IssueMeta")),
global: tiny_bmap! {
fname!("spec") => ArgSpec::required(),
fname!("data") => ArgSpec::required(),
fname!("created") => ArgSpec::required(),
fname!("issuedSupply") => ArgSpec::required(),
},
assignments: tiny_bmap! {
fname!("assetOwner") => ArgSpec::many(),
fname!("inflationAllowance") => ArgSpec::many(),
fname!("updateRight") => ArgSpec::optional(),
fname!("burnEpoch") => ArgSpec::optional(),
},
valencies: none!(),
errors: tiny_bset! {
SUPPLY_MISMATCH,
INVALID_PROOF,
INSUFFICIENT_RESERVES
},
},
transitions: tiny_bmap! {
tn!("Transfer") => TransitionIface {
optional: false,
metadata: None,
globals: none!(),
inputs: tiny_bmap! {
fname!("previous") => ArgSpec::from_non_empty("assetOwner"),
},
assignments: tiny_bmap! {
fname!("beneficiary") => ArgSpec::from_non_empty("assetOwner"),
},
valencies: none!(),
errors: tiny_bset! {
NON_EQUAL_AMOUNTS
},
default_assignment: Some(fname!("beneficiary")),
},
tn!("Issue") => TransitionIface {
optional: true,
metadata: Some(types.get("RGBContract.IssueMeta")),
globals: tiny_bmap! {
fname!("issuedSupply") => ArgSpec::required(),
},
inputs: tiny_bmap! {
fname!("used") => ArgSpec::from_non_empty("inflationAllowance"),
},
assignments: tiny_bmap! {
fname!("beneficiary") => ArgSpec::from_many("assetOwner"),
fname!("future") => ArgSpec::from_many("inflationAllowance"),
},
valencies: none!(),
errors: tiny_bset! {
SUPPLY_MISMATCH,
INVALID_PROOF,
ISSUE_EXCEEDS_ALLOWANCE,
INSUFFICIENT_RESERVES
},
default_assignment: Some(fname!("beneficiary")),
},
tn!("OpenEpoch") => TransitionIface {
optional: true,
metadata: None,
globals: none!(),
inputs: tiny_bmap! {
fname!("used") => ArgSpec::from_required("burnEpoch"),
},
assignments: tiny_bmap! {
fname!("next") => ArgSpec::from_optional("burnEpoch"),
fname!("burnRight") => ArgSpec::required()
},
valencies: none!(),
errors: none!(),
default_assignment: Some(fname!("burnRight")),
},
tn!("Burn") => TransitionIface {
optional: true,
metadata: Some(types.get("RGBContract.BurnMeta")),
globals: tiny_bmap! {
fname!("burnedSupply") => ArgSpec::required(),
},
inputs: tiny_bmap! {
fname!("used") => ArgSpec::from_required("burnRight"),
},
assignments: tiny_bmap! {
fname!("future") => ArgSpec::from_optional("burnRight"),
},
valencies: none!(),
errors: tiny_bset! {
SUPPLY_MISMATCH,
INVALID_PROOF,
INSUFFICIENT_COVERAGE
},
default_assignment: None,
},
tn!("Replace") => TransitionIface {
optional: true,
metadata: Some(types.get("RGBContract.BurnMeta")),
globals: tiny_bmap! {
fname!("replacedSupply") => ArgSpec::required(),
},
inputs: tiny_bmap! {
fname!("used") => ArgSpec::from_required("burnRight"),
},
assignments: tiny_bmap! {
fname!("beneficiary") => ArgSpec::from_many("assetOwner"),
fname!("future") => ArgSpec::from_optional("burnRight"),
},
valencies: none!(),
errors: tiny_bset! {
NON_EQUAL_AMOUNTS,
SUPPLY_MISMATCH,
INVALID_PROOF,
INSUFFICIENT_COVERAGE
},
default_assignment: Some(fname!("beneficiary")),
},
tn!("Rename") => TransitionIface {
optional: true,
metadata: None,
globals: tiny_bmap! {
fname!("new") => ArgSpec::from_required("spec"),
},
inputs: tiny_bmap! {
fname!("used") => ArgSpec::from_required("updateRight"),
},
assignments: tiny_bmap! {
fname!("future") => ArgSpec::from_optional("updateRight"),
},
valencies: none!(),
errors: none!(),
default_assignment: Some(fname!("future")),
},
},
extensions: none!(),
error_type: types.get("RGB20.Error"),
default_operation: Some(tn!("Transfer")),
type_system: types.type_system(),
}
}

En esta interfaz, notamos similitudes con la estructura del Esquema: encontramos una declaración de Estado Global, Estados Propios, Operaciones de Contrato (Génesis y Transiciones), así como manejo de errores. Pero la Interfaz se centra en la presentación y manipulación de estos elementos para un monedero o cualquier otra aplicación.

La diferencia con Schema radica en la naturaleza de los tipos. Schema utiliza tipos estrictos (como FungibleType::Unsigned64Bit) e identificadores más técnicos. La interfaz utiliza nombres de campo, macros (fname!(), tn!()) y referencias a clases de argumentos (ArgSpec, OwnedIface::Rights...). El objetivo es facilitar la comprensión funcional y la organización de los elementos para la cartera.

Además, la Interfaz puede introducir funcionalidades adicionales al Esquema básico (por ejemplo, la gestión de un derecho burnEpoch), siempre que esto siga siendo coherente con la lógica final validada del lado del cliente. La sección "script" de AluVM en el Esquema garantizará la validez criptográfica, mientras que la Interfaz describe cómo el usuario (o el monedero) interactúa con estos estados y transiciones.

Estado global y asignaciones

En la sección global_state, encontramos campos como spec (descripción del activo), data, created, issuedSupply, burnedSupply, replacedSupply. Son campos que el monedero puede leer y presentar. Por ejemplo:

En la sección asignaciones, definimos varios roles o derechos. Por ejemplo:

La palabra clave public o private (por ejemplo, AssignIface::public(...)) indica si estos estados son visibles (public) o confidenciales (private). En cuanto a Req::NoneOrMore, Req::Optional, indican la ocurrencia esperada.

Génesis y transiciones

La parte "génesis" describe cómo se inicializa el activo:

A continuación, para cada Transición (Transferir, Emitir, Quemar...), la Interfaz define qué campos espera la operación como entrada, qué campos producirá la operación como salida y cualquier error que pueda producirse. Por ejemplo:

Transición :

Transición Issue :

Transición de quemado :

Por tanto, cada operación se describe de forma legible para un monedero. Esto permite mostrar una interfaz gráfica en la que el usuario puede ver claramente: "Tiene derecho a quemar. ¿Desea quemar una determinada cantidad? El código sabe que debe rellenar un campo burnedSupply y comprobar que el burnRight es válido.

En resumen, es importante tener en cuenta que una Interfaz, por completa que sea, no define por sí misma la lógica interna del contrato. El núcleo del trabajo lo realiza el Esquema, que incluye los tipos estrictos, la estructura de Génesis, las transiciones, etcétera. La Interfaz simplemente expone estos elementos de una forma más intuitiva y nombrada, para su uso en una aplicación.

Gracias a la modularidad de RGB, la interfaz puede actualizarse (por ejemplo, añadiendo una transición Rename, corrigiendo la visualización de un campo, etc.) sin tener que reescribir todo el contrato. Los usuarios de esta interfaz pueden beneficiarse inmediatamente de estas mejoras, tan pronto como actualicen el archivo .rgb o .rgba.

Pero una vez declarada una interfaz, hay que vincularla al esquema correspondiente. Esto se hace a través de la Interface Implementation, que especifica cómo asignar cada campo con nombre (como fname!("assetOwner")) al ID estricto (como OS_ASSET) definido en el Esquema. Esto asegura, por ejemplo, que cuando un monedero manipula un campo burnRight, este es el estado que, en el Esquema, describe la capacidad de quemar tokens.

Aplicación de la interfaz

En la arquitectura RGB, hemos visto que cada componente (esquema, interfaz, etc.) puede desarrollarse y compilarse de forma independiente. Sin embargo, todavía hay un elemento indispensable que une estos diferentes bloques de construcción: la Implementación de la Interfaz. Esto es lo que mapea explícitamente los identificadores o campos definidos en el Esquema (en el lado de la lógica de negocio) a los nombres declarados en la Interfaz (en el lado de la presentación y la interacción con el usuario). Así, cuando un monedero carga un contrato, puede entender exactamente qué campo corresponde a qué, y cómo una operación nombrada en la Interfaz se relaciona con la lógica del Esquema.

Un punto importante es que la implementación de la interfaz no pretende necesariamente exponer todas las funcionalidades del esquema, ni todos los campos de la interfaz: puede limitarse a un subconjunto. En la práctica, esto permite restringir o filtrar determinados aspectos del esquema. Por ejemplo, se puede tener un esquema con cuatro tipos de operación, pero una interfaz de implementación que sólo asigne dos de ellos en un contexto determinado. A la inversa, si una Interfaz propone puntos finales adicionales, podemos optar por no implementarlos aquí.

He aquí un ejemplo clásico de implementación de interfaces, en el que asociamos un esquema Non-Inflatable Asset (NIA) con la interfaz RGB20:

fn nia_rgb20() -> IfaceImpl {
let schema = nia_schema();
let iface = Rgb20::iface();
IfaceImpl {
version: VerNo::V1,
schema_id: schema.schema_id(),
iface_id: iface.iface_id(),
script: none!(),
global_state: tiny_bset! {
NamedField::with(GS_NOMINAL, fname!("spec")),
NamedField::with(GS_DATA, fname!("data")),
NamedField::with(GS_TIMESTAMP, fname!("created")),
NamedField::with(GS_ISSUED_SUPPLY, fname!("issuedSupply")),
},
assignments: tiny_bset! {
NamedField::with(OS_ASSET, fname!("assetOwner")),
},
valencies: none!(),
transitions: tiny_bset! {
NamedType::with(TS_TRANSFER, tn!("Transfer")),
},
extensions: none!(),
}
}

En esta interfaz de aplicación :

El resultado tras la compilación es un archivo .rgb o .rgba independiente, que se importará en el monedero además del Esquema y la Interfaz. Así, el software sabe cómo conectar concretamente este contrato NIA (cuya lógica está descrita por su Esquema) con la Interfaz "RGB20" (que proporciona nombres humanos y un modo de interacción para tokens fungibles), aplicando esta Implementación de Interfaz como pasarela entre ambos.

¿Por qué separar la implementación de interfaces?

La separación aumenta la flexibilidad. Un único esquema puede tener varias implementaciones de interfaz distintas, cada una de ellas con un conjunto diferente de funcionalidades. Además, la propia implementación de la interfaz puede evolucionar o reescribirse sin necesidad de modificar ni el esquema ni la interfaz. De este modo se mantiene el principio de modularidad de RGB: cada componente (esquema, interfaz, implementación de interfaz) puede versionarse y actualizarse independientemente, siempre que se respeten las normas de compatibilidad impuestas por el protocolo (mismos identificadores, coherencia de tipos, etc.).

En el uso concreto, cuando el monedero carga un contrato, debe :

Esta arquitectura modular hace posibles escenarios de uso como :

En el próximo capítulo veremos cómo funciona una transferencia de contrato y cómo se generan las facturas RGB.

Transferencias contractuales

En este capítulo, vamos a analizar el proceso de transferencia de un contrato en el ecosistema RGB. Para ilustrarlo, veremos a Alice y Bob, nuestros protagonistas habituales, que desean intercambiar un activo RGB. También mostraremos algunos extractos de comandos de la herramienta de línea de comandos rgb, para ver cómo funciona en la práctica.

Comprender la transferencia de contratos RGB

Veamos un ejemplo de transferencia entre Alice y Bob. En este ejemplo, asumimos que Bob está empezando a usar RGB, mientras que Alice ya tiene activos RGB en su cartera. Veremos cómo Bob configura su entorno, importa el contrato relevante, después solicita una transferencia a Alice, y finalmente cómo Alice lleva a cabo la transacción real en la blockchain de Bitcoin.

1) Instalación de la cartera RGB

En primer lugar, Bob necesita instalar un monedero RGB, es decir, un software compatible con el protocolo. Al principio, éste no contiene ningún contrato. Bob también necesitará :

Como recordatorio, los Estados Propios en RGB se refieren a UTXOs de Bitcoin. Por tanto, siempre debemos poder gestionar y gastar UTXOs en una transacción Bitcoin que incorpore compromisos criptográficos (Tapret u Opret) que apunten a datos RGB.

2) Adquisición de información contractual

Bob necesita entonces recuperar los datos del contrato que le interesan. Estos datos pueden circular por cualquier canal: página web, correo electrónico, aplicación de mensajería... En la práctica, se agrupan en una consigna, es decir, un pequeño paquete de datos que contiene :

RGB-Bitcoin

El tamaño total suele ser del orden de unos pocos kilobytes, ya que cada componente suele pesar menos de 200 bytes. También puede ser posible difundir esta remesa en Base58, a través de canales resistentes a la censura (como Nostr o a través de Lightning Network, por ejemplo), o en forma de código QR.

3) Importación y validación de contratos

Una vez que Bob ha recibido el envío, lo importa a su cartera RGB. Esto hará que :

Ahora Bob puede ver el activo en su cartera (aunque aún no sea de su propiedad) y comprender qué campos están disponibles, qué operaciones son posibles... A continuación, debe ponerse en contacto con la persona que posee el activo que desea transferir. En nuestro ejemplo, se trata de Alice.

El proceso de descubrir quién posee un determinado activo RGB es similar al de encontrar un pagador Bitcoin. Los detalles de esta conexión dependen del uso (mercados, canales de chat privados, facturación, venta de bienes y servicios, salario...).

4) Emitir una factura

Para iniciar la transferencia de un activo RGB, Bob debe emitir primero una factura. Esta factura se utiliza para :

Bob utiliza la herramienta rgb en la línea de comandos. Supongamos que quiere 100 unidades de un token cuyo ContractId es conocido, quiere confiar en Tapret, y especifica su UTXO (456e3..dfe1:0) :

bob$ rgb invoice RGB20 100 <ContractId> tapret1st:456e3..dfe1:0

Al final de este capítulo veremos con más detalle la estructura de las facturas RGB.

5) Transmisión de facturas

La factura generada (por ejemplo, como URL: rgb:2WBcas9.../RGB20/100+utxob:...) contiene toda la información que Alice necesita para preparar la transferencia. Al igual que el envío, puede codificarse de forma compacta (Base58 u otro formato) y enviarse a través de una aplicación de mensajería, correo electrónico, Nostr...

RGB-Bitcoin

6) Preparación de la transacción por parte de Alice

Alice recibe la factura de Bob. En su monedero RGB, tiene un alijo que contiene el activo a transferir. Para gastar el UTXO que contiene el activo, primero debe generar una PSBT (Transacción Bitcoin Parcialmente Firmada), es decir, una transacción Bitcoin incompleta, utilizando el UTXO que tiene:

alice$ wallet construct tx.psbt

Esta transacción básica (sin firmar por el momento) se utilizará para anclar el compromiso criptográfico vinculado a la transferencia a Bob. El UTXO de Alice será así gastado, y en la salida, colocaremos el compromiso Tapret u Opret para Bob.

7) Generación de la remesa de transferencia

A continuación, Alice construye la consigna terminal (a veces llamada "consigna de transferencia") mediante el comando :

alice$ rgb transfer tx.psbt <invoice> consignment.rgb

Este nuevo archivo consignment.rgb contiene :

En esta fase, la transacción aún no se difunde en la red Bitcoin. La consignación es mayor que una consignación básica, ya que incluye todo el historial (cadena de prueba) para demostrar la legitimidad del activo.

8) Bob comprueba y acepta el envío

Alice transmite este envío terminal a Bob. Bob entonces :

bob$ rgb accept consignment.rgb
sig:DbwzvSu4BZU81jEpE9FVZ3xjcyuTKWWy2gmdnaxtACrS
RGB-Bitcoin

9) Opción: Bob envía la confirmación a Alice (factura de pago)

Si Bob lo desea, puede enviar esta firma a Alice. Esto indica:

Esto no es obligatorio, pero puede ofrecer a Alice la seguridad de que no habrá disputas posteriores sobre la transferencia.

10) Alice firma y publica la transacción

Alice puede entonces :

alice$ rgb check <sig>
alice$ wallet sign —publish tx.psbt
RGB-Bitcoin

Una vez confirmada, esta transacción marca la conclusión de la transferencia. Bob se convierte en el nuevo propietario del activo: ahora tiene un Estado de Propiedad que apunta al UTXO que controla, demostrado por la presencia del compromiso en la transacción.

A modo de resumen, he aquí el proceso completo de transferencia:

RGB-Bitcoin

Ventajas de las transferencias RGB

Sólo Alice y Bob tienen acceso a todos los datos de Transición de Estado. Intercambian esta información fuera de la blockchain, mediante consignaciones. Los compromisos criptográficos en la transacción Bitcoin no revelan el tipo de activo ni la cantidad, lo que garantiza una confidencialidad mucho mayor que otros sistemas de tokens en cadena.

Bob puede comprobar la consistencia de la transferencia comparando la consignación con los anclajes en la blockchain de Bitcoin. No necesita la validación de terceros. Alice no tiene que publicar el historial completo en la blockchain, lo que reduce la carga del protocolo base y mejora la confidencialidad.

Los intercambios complejos (swaps atómicos entre BTC y un activo RGB, por ejemplo) pueden realizarse en una sola transacción, evitando la necesidad de scripts HTLC o PTLC. Si el acuerdo no se emite, todo el mundo puede reutilizar sus UTXO de otras formas.

Diagrama resumido de transferencia

Antes de examinar las facturas con más detalle, he aquí un diagrama resumido del flujo global de una transferencia RGB:

RGB-Bitcoin

La transferencia ilustra toda la potencia y flexibilidad del protocolo RGB: un intercambio privado, validado en el lado del cliente, anclado de forma mínima y discreta en la blockchain de Bitcoin, y conservando lo mejor de la seguridad del protocolo (sin riesgo de doble gasto). Esto convierte a RGB en un ecosistema prometedor para transferencias de valor más confidenciales y escalables que las blockchains programables en cadena.

Facturas RGB

En esta sección, explicaremos en detalle cómo funcionan las facturas en el ecosistema RGB y cómo permiten realizar operaciones (en particular transferencias) con un contrato. En primer lugar, veremos los identificadores utilizados, luego cómo se codifican y, por último, la estructura de una factura expresada como URL (un formato bastante práctico para su uso en monederos).

Identificadores y codificación

Se define un identificador único para cada uno de los siguientes elementos:

Esta unicidad es muy importante, ya que cada componente del sistema debe ser distinguible. Por ejemplo, un contrato X no debe confundirse con otro contrato Y, y dos interfaces diferentes (RGB20 frente a RGB21, por ejemplo) deben tener identificadores distintos.

Para que estos identificadores sean a la vez eficientes (tamaño reducido) y legibles, utilizamos :

Por ejemplo, un ContractId podría representarse con algo como :

rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX

El prefijo rgb: confirma que se trata de un identificador RGB, y no de un enlace HTTP u otro protocolo. Gracias a este prefijo, los monederos pueden interpretar la cadena correctamente.

Segmentación de identificadores

Los identificadores RGB suelen ser bastante largos, ya que la seguridad (criptográfica) subyacente puede requerir campos de 256 bits o más. Para facilitar la lectura y verificación por parte de los humanos, cortamos estas cadenas en varios bloques separados por un guión (-). Así, en lugar de tener una cadena de caracteres larga e ininterrumpida, la dividimos en bloques más cortos. Esta práctica es habitual en el caso de las tarjetas de crédito o los números de teléfono, y también se aplica aquí para facilitar la verificación. Así, por ejemplo, se puede decir a un usuario o socio: "Por favor, compruebe que el tercer bloque es 9GEgnyMj7", en lugar de tener que compararlo todo de una vez. El último bloque suele utilizarse como checksum, para disponer de un sistema de detección de errores o erratas.

Como ejemplo, un ContractId en base58 codificado y segmentado podría ser :

2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX

Cada uno de los guiones divide la cadena en secciones. Esto no afecta a la semántica del código, sólo a su presentación.

Utilización de URL para las facturas

Una factura RGB se presenta como una URL. Esto significa que puede pulsarse o escanearse (como un código QR), y un monedero puede interpretarla directamente para realizar una transacción. Esta sencillez de interacción difiere de otros sistemas en los que hay que copiar y pegar varios datos en distintos campos del software.

Una factura de una ficha fungible (por ejemplo, una ficha RGB20) podría tener este aspecto:

rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/RGB20/100+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb

Analicemos esta URL:

El hecho de que todo quepa en una única URL facilita la vida al usuario: un simple clic o escaneado en el monedero, y la operación está lista para ejecutarse.

Se podrían imaginar sistemas en los que se utilizara un simple ticker (por ejemplo, USDT) en lugar del ContractId. Sin embargo, esto plantearía importantes problemas de confianza y seguridad: un ticker no es una referencia única (varios contratos podrían reclamar llamarse USDT). Con RGB, queremos un identificador criptográfico único e inequívoco. De ahí la adopción de la cadena de 256 bits, codificada en base58 y segmentada. El usuario sabe que está manipulando precisamente el contrato cuyo ID es 2WBcas9-yjz... y no cualquier otro.

Parámetros URL adicionales

También puede añadir parámetros adicionales a la URL, del mismo modo que con HTTP, como :

rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/RGB20/100+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb?sig=6kzbKKffP6xftkxn9UP8gWqiC41W16wYKE5CYaVhmEve

Tomemos el caso de un NFT a través de la interfaz RGB21. Por ejemplo, podríamos tener :

rgb:7BKsac8-beMNMWA8r-3GEprtFh7-bjzEvGufY-aNLuU4nSN-MRsLOIK/RGB21/DbwzvSu-4BZU81jEp-E9FVZ3xj-cyuTKWWy-2gmdnaxt-ACrS+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb

Aquí vemos :

La idea es la misma: transmitir un enlace único que el monedero pueda interpretar, identificando claramente el activo único que se va a transferir.

Otras operaciones vía URL

Las URL RGB no sólo se utilizan para solicitar una transferencia. También pueden codificar operaciones más avanzadas, como la emisión de nuevos tokens (issuance). Por ejemplo:

rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/RGB20/issue/100000+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb

Aquí encontramos :

Por ejemplo, la cartera podría decir: "Me han pedido que realice una operación de emisión desde la interfaz RGB20, en tal y tal contrato, por 100.000 unidades, en beneficio de tal y tal Sello de un solo uso*"

Ahora que ya hemos visto los principales elementos de la programación RGB, en el siguiente capítulo te explicaré cómo redactar un contrato RGB.

Redacción de contratos inteligentes

En este capítulo, tomaremos un enfoque paso a paso para escribir un contrato, utilizando la herramienta de línea de comandos rgb. El objetivo es mostrar cómo instalar y manipular la CLI, compilar un Esquema, importar la Interfaz y la Implementación de la Interfaz, y luego emitir (emitir) un activo. También veremos la lógica subyacente, incluyendo la compilación y la validación del estado. Al final de este capítulo, deberías ser capaz de reproducir el proceso y crear tus propios contratos RGB.

Como recordatorio, la lógica interna de RGB se basa en bibliotecas de Rust que ustedes, como desarrolladores, pueden importar a sus proyectos para gestionar la parte de validación del lado del cliente. Además, el equipo de la Asociación LNP/BP está trabajando en bindings para otros lenguajes, pero aún no se ha finalizado. Además, otras entidades como Bitfinex están desarrollando sus propias pilas de integración (hablaremos de ellas en los 2 últimos capítulos del curso). Por el momento, por lo tanto, la CLI rgb es la referencia oficial, incluso si sigue estando relativamente sin pulir.

Instalación y presentación de la herramienta rgb

El comando principal se llama simplemente rgb. Está diseñado para recordar a git, con un conjunto de subcomandos para manipular contratos, invocarlos, emitir activos, etc. Bitcoin Wallet no está integrado actualmente, pero lo estará en una versión inminente (0.11). Esta próxima versión permitirá a los usuarios crear y gestionar sus monederos (a través de descriptores) directamente desde rgb, incluyendo la generación de PSBT, compatibilidad con hardware externo (por ejemplo, un monedero hardware) para firmar, e interoperabilidad con software como Sparrow. Esto simplificará todo el escenario de emisión y transferencia de activos.

Instalación a través de Cargo

Instalamos la herramienta en Rust con :

cargo install rgb-contracts --all-features

(Nota: el crate se llama rgb-contracts, y el comando instalado se llamará rgb. Si ya existía un crate llamado rgb, podría haber habido una colisión, de ahí el nombre)

La instalación compila un gran número de dependencias (por ejemplo, análisis sintáctico de comandos, integración de Electrum, gestión de pruebas de conocimiento-cero, etc.).

Una vez finalizada la instalación, el archivo :

rgb

Al ejecutar rgb (sin argumentos) aparece una lista de subcomandos disponibles, como interfaces, schema, import, export, issue, invoice, transfer, etc. Puede cambiar el directorio de almacenamiento local (un alijo que contiene todos los registros, esquemas e implementaciones), elegir la red (testnet, mainnet) o configurar su servidor Electrum.

RGB-Bitcoin

Primera visión general de los controles

Cuando ejecutes el siguiente comando, verás que ya viene integrada por defecto una interfaz RGB20:

rgb interfaces

Si esta interfaz no está integrada, clone el archivo :

git clone https://github.com/RGB-WG/rgb-interfaces

Compílalo:

cargo run

A continuación, importe la interfaz que desee:

rgb import interfaces/RGB20.rgb
RGB-Bitcoin

Por otro lado, se nos dice que aún no se ha importado ningún esquema al programa. Tampoco hay ningún contrato en el almacén. Para verlo, ejecute el comando :

rgb schemata

A continuación, puede clonar el repositorio para recuperar determinados esquemas:

git clone https://github.com/RGB-WG/rgb-schemata
RGB-Bitcoin

Este repositorio contiene, en su directorio src/, varios archivos Rust (por ejemplo nia.rs) que definen esquemas (NIA para "Activo No Inflable", UDA para "Activo Digital Único", etc.). Para compilar, puede ejecutar :

cd rgb-schemata
cargo run

Esto genera varios archivos .rgb y .rgba correspondientes a los esquemas compilados. Por ejemplo, encontrarás NonInflatableAsset.rgb.

Importación de esquemas e interfaces

Ahora puede importar el esquema en rgb :

rgb import schemata/NonInflatableAssets.rgb
RGB-Bitcoin

Esto lo añade al almacén local. Si ejecutamos el siguiente comando, veremos que ahora aparece el esquema:

rgb schemata

Creación de contratos (emisión)

Existen dos enfoques para crear un nuevo activo:

Puedes encontrar ejemplos en Rust en la carpeta examples, que ilustran cómo se construye un ContractBuilder, se rellena el global state (nombre del activo, ticker, suministro, fecha, etc.), se define el Owned State (a qué UTXO está asignado), y luego se compila todo esto en una contratación de consignación que puedes exportar, validar e importar a un alijo.

La otra forma es editar manualmente un archivo YAML para personalizar el ticker, el name, el supply, etc. Supongamos que el archivo se llama RGB20-demo.yaml. Puede especificar :

He aquí un ejemplo de archivo YAML a crear:

interface: RGB20Fixed
globals:
spec:
ticker: PBN
name: Plan B Network
details: "Pay attention: the asset has no value"
precision: 2
terms:
text: >
SUBJECT TO, AND WITHOUT IN ANY WAY LIMITING, THE REPRESENTATIONS AND WARRANTIES OF ANY SELLER. PROPERTY IS BEING SOLD “AS IS”...
media: ~
issuedSupply: 100000000
assignments:
assetOwner:
seal: tapret1st:b449f7eaa3f98c145b27ad0eeb7b5679ceb567faef7a52479bc995792b65f804:1
amount: 100000000 # this is 1 million (we have two digits for cents)
RGB-Bitcoin

A continuación, basta con ejecutar el comando :

rgb issue '<SchemaID>' ssi:<Issuer> rgb20-demo.yaml
RGB-Bitcoin

En mi caso, el identificador único del esquema (que debe ir entre comillas simples) es RDYhMTR!9gv8Y2GLv9UNBEK1hcrCmdLDFk9Qd5fnO8k y no he puesto ningún emisor. Así que mi orden es :

rgb issue 'RDYhMTR!9gv8Y2GLv9UNBEK1hcrCmdLDFk9Qd5fnO8k' ssi:anonymous rgb20-demo.yaml

Si no conoce el ID del esquema, ejecute el comando :

rgb schemata

La CLI responde que se ha emitido un nuevo contrato y se ha añadido al alijo. Si tecleamos el siguiente comando, veremos que ahora hay un contrato adicional, correspondiente al que se acaba de emitir:

rgb contracts
RGB-Bitcoin

A continuación, el siguiente comando muestra los estados globales (nombre, ticker, suministro...) y la lista de estados propios, es decir, asignaciones (por ejemplo, 1 millón de fichas PBN definidas en UTXO b449f7eaa3f98c145b27ad0eeb7b5679ceb567faef7a52479bc995792b65f804:1).

rgb state '<ContractId>'
RGB-Bitcoin

Exportación, importación y validación

Para compartir este contrato con otros usuarios, puede exportarse desde el alijo a un archivo :

rgb export '<ContractId>' myContractPBN.rgb
RGB-Bitcoin

El archivo myContractPBN.rgb puede pasarse a otro usuario, que puede añadirlo a su alijo con el comando :

rgb import myContractPBN.rgb

En la importación, si se trata de un simple envío de contrato, obtendremos un mensaje "Importing consignment rgb". Si se trata de un envío de transición de estado más grande, el comando será diferente (rgb accept).

Para garantizar la validez, también puede utilizar la función de validación local. Por ejemplo, puede ejecutar :

rgb validate myContract.rgb

Uso, verificación y visualización del alijo

Como recordatorio, el alijo es un inventario local de esquemas, interfaces, implementaciones y contratos (Génesis + transiciones). Cada vez que ejecutas "importar", añades un elemento al alijo. Este alijo puede verse en detalle con el comando :

rgb dump
RGB-Bitcoin

Esto generará una carpeta con los detalles de todo el alijo.

Transferencia y PSBT

Para realizar una transferencia, necesitará manipular un monedero Bitcoin local para gestionar los compromisos Tapret u Opret.

Generar una factura

En la mayoría de los casos, la interacción entre los participantes en un contrato (por ejemplo, Alice y Bob) tiene lugar a través de la generación de una factura. Si Alice quiere que Bob ejecute algo (una transferencia de tokens, una reemisión, una acción en un DAO, etc.), Alice crea una factura detallando sus instrucciones a Bob. Así tenemos :

A diferencia de otros ecosistemas, una factura RGB no se limita a la noción de pago. Puede incluir cualquier solicitud vinculada al contrato: revocar una clave, votar, crear un grabado (grabado) en una NFT, etc. La operación correspondiente puede describirse en la interfaz del contrato. La operación correspondiente puede describirse en la interfaz del contrato.

El siguiente comando genera una factura RGB:

$ rgb invoice $CONTRACT -i $INTERFACE $ACTION $STATE $SEAL

Con :

Por ejemplo, con los siguientes comandos

alice$ CONTRACT='iZgIN9EL-2H21UgQ-x!A3uJc-WwXhCSm-$9Lwcc1-v!mUkKY'
alice$ MY_UTXO=4960acc21c175c551af84114541eace09c14d3a1bb184809f7b80916f57f9ef8:1
alice$ rgb invoice $CONTRACT -i RGB20 --amount 100 $MY_UTXO

La CLI generará una factura como :

rgb:iZgIN9EL-2H21UgQ-x!A3uJc-WwXhCSm-$9Lwcc1-v!mUkKY/RGB20/100+utxob:zlVS28Rb-...

Puede transmitirse a Bob a través de cualquier canal (texto, código QR, etc.).

Realizar una transferencia

Para transferir desde esta factura :

bob$ rgb transfer tx.psbt $INVOICE consignment.rgb
alice$ rgb accept consignment.rgb
bob$ rgb check <sig> && wallet sign --publish tx.psbt

En el próximo capítulo, veremos más de cerca la integración de RGB en la Red Lightning.

RGB en la Red Lightning

En este capítulo, propongo examinar cómo se puede utilizar RGB dentro de la Lightning Network, para integrar y mover activos RGB (tokens, NFTs, etc.) a través de canales de pago fuera de la cadena.

La idea básica es que la transición de estado RGB (Transición de estado) puede confirmarse en una transacción Bitcoin que, a su vez, puede permanecer fuera de la cadena hasta que se cierre el canal Lightning. Así, cada vez que se actualiza el canal, se puede incorporar una nueva transición de estado RGB a la nueva transacción de confirmación, que invalida la transición anterior. De este modo, los canales Lightning pueden utilizarse para transferir activos RGB, y pueden enrutarse del mismo modo que los pagos Lightning convencionales.

Creación de canales y financiación

Para crear un canal Rayo que lleve activos RGB, necesitamos dos elementos:

En términos de Bitcoin, la transacción de financiación debe existir para definir el UTXO de referencia, incluso si sólo contiene una pequeña cantidad de sats (es sólo cuestión de que cada salida en futuras transacciones de compromiso se mantenga por encima del límite de polvo igualmente). Por ejemplo, Alice puede decidir proporcionar 10k sats y 500 USDT (emitidos como un activo RGB). En la transacción de financiación, añadimos un compromiso (Opret o Tapret) que ancla la transición de estado RGB.

RGB-Bitcoin

Una vez preparada la transacción de financiación (pero aún no emitida), se crean transacciones de compromiso para que cualquiera de las partes pueda cerrar el canal unilateralmente en cualquier momento. Estas transacciones se parecen a las transacciones de compromiso clásicas de Lightning, salvo que añadimos una salida adicional que contiene el ancla RGB (OP_RETURN o Taproot) vinculada a la nueva transición de estado.

La transición de estado RGB traslada entonces los activos del multisig 2/2 de la financiación a las salidas de la transacción de compromiso. La ventaja de este proceso es que la seguridad del estado RGB coincide exactamente con la mecánica punitiva de Lightning: si Bob transmite un estado de canal antiguo, Alice puede castigarle y gastar la salida, con el fin de recuperar tanto los sats como las fichas RGB. Por tanto, el incentivo es aún mayor que en un canal Lightning sin activos RGB, ya que un atacante puede perder no sólo los sats, sino también los activos RGB del canal.

Por lo tanto, una transacción de compromiso firmada por Alice y enviada a Bob tendría el siguiente aspecto:

RGB-Bitcoin

Y la transacción de compromiso adjunta, firmada por Bob y enviada a Alice, tendrá este aspecto:

RGB-Bitcoin

Actualización del canal

Cuando se produce un pago entre dos participantes del canal (o desean cambiar la asignación de activos), crean un nuevo par de transacciones de compromiso. La cantidad en sats en cada salida puede o no permanecer inalterada, dependiendo de la implementación, ya que su papel principal es permitir la construcción de UTXOs válidos. Por otro lado, la salida OP_RETURN (o Taproot) debe modificarse para contener el nuevo ancla RGB, que representa la nueva distribución de activos en el canal.

Por ejemplo, si Alice transfiere 30 USDT a Bob en el canal, la nueva transición de estado reflejará un saldo de 400 USDT para Alice y 100 USDT para Bob. La transacción de confirmación se añade a (o es modificada por) el ancla OP_RETURN/Taproot para incluir esta transición. Tenga en cuenta que, desde el punto de vista de RGB, la entrada a la transición sigue siendo el multisig inicial (donde los activos en la cadena se asignan realmente hasta que el canal se cierra). Sólo cambian las salidas de RGB (asignaciones), dependiendo de la redistribución decidida.

La transacción de compromiso firmada por Alice, lista para ser distribuida por Bob :

RGB-Bitcoin

La transacción de compromiso firmada por Bob, lista para ser distribuida por Alice :

RGB-Bitcoin

Gestión de HTLC

En realidad, la Lightning Network permite enrutar los pagos a través de múltiples canales, utilizando HTLCs (Hashed Time-Locked Contracts). Ocurre lo mismo con RGB: por cada pago en tránsito por el canal, se añade una salida HTLC a la transacción que se compromete, y una asignación RGB vinculada a este HTLC. Así, quien gasta la salida HTLC (gracias al secreto o tras la expiración del timelock) recupera tanto la saturación como los activos RGB asociados. Por otro lado, es obvio que se necesita tener suficiente dinero en el camino, tanto en términos de sats como de activos RGB.

RGB-Bitcoin

Por tanto, el funcionamiento de RGB en Lightning debe considerarse en paralelo al de la propia Red Lightning. Si quieres profundizar en este tema, te recomiendo encarecidamente que eches un vistazo a este otro completo curso de formación:

https://planb.network/courses/34bd43ef-6683-4a5c-b239-7cb1e40a4aeb

Mapa de códigos RGB

Por último, antes de pasar a la siguiente sección, me gustaría darte una visión general del código utilizado en RGB. El protocolo se basa en un conjunto de bibliotecas Rust y especificaciones de código abierto. Aquí tienes una visión general de los principales repositorios y crates:

RGB-Bitcoin

Validación en el lado del cliente

Gestión de la validación fuera de la cadena y lógica de los sellos de un solo uso.

Compromisos deterministas de Bitcoin (DBC)

Gestión del anclaje determinista en las transacciones Bitcoin (Tapret, OP_RETURN, etc.).

Compromiso multiprotocolo (MPC)

Múltiples combinaciones de compromiso e integración con distintos protocolos.

Tipos estrictos y codificación estricta

El sistema de tipado estricto y la serialización determinista utilizados para la validación del lado del cliente.

Núcleo RGB

El núcleo del protocolo, que engloba la lógica principal de la validación RGB.

Biblioteca y cartera estándar RGB

Implementaciones estándar, gestión de alijos y carteras.

RGB CLI

La cartera rgb CLI y crate, para la manipulación de contratos desde la línea de comandos.

Esquema RGB

Contiene ejemplos de esquemas (NIA, UDA, etc.) y sus implementaciones.

ALuVM

Máquina virtual basada en el registro utilizada para ejecutar scripts de validación.

Protocolo Bitcoin - BP

Complementos para soportar el protocolo Bitcoin (transacciones, desvíos, etc.).

Computación ubicua determinista - UBIDECO

Ecosistema vinculado a desarrollos deterministas de código abierto.

Basándose en RGB

DIBA y el proyecto Bitmask

Esta sección final del curso se basa en las presentaciones realizadas por varios ponentes en el RGB bootcamp. Incluye testimonios y reflexiones sobre RGB y su ecosistema, así como presentaciones de herramientas y proyectos basados en el protocolo. Este primer capítulo está moderado por Hunter Beast, y los dos siguientes por Frederico Tenga.

De JavaScript a Rust, y al ecosistema Bitcoin

Al principio, Hunter Beast trabajaba principalmente en JavaScript. Entonces descubrió Rust, cuya sintaxis le pareció poco atractiva y frustrante al principio. Sin embargo, llegó a apreciar la potencia del lenguaje, el control sobre la memoria (heap y stack), y la seguridad y el rendimiento que conlleva. Destaca que Rust es un excelente campo de entrenamiento para comprender en profundidad cómo funciona un ordenador.

Hunter Beast cuenta su experiencia en varios proyectos del ecosistema altcoin, como Ethereum (con Solidity, TypeScript, etc.), y más tarde Filecoin. Explica que al principio le impresionaron algunos de los protocolos, pero que acabó sintiéndose desilusionado por la mayoría de ellos, sobre todo por su tokenómica. Denuncia los dudosos incentivos financieros, la creación inflacionaria de tokens que diluye a los inversores y el aspecto potencialmente explotador de estos proyectos. Así que acabó adoptando una postura máximalista de Bitcoin, entre otras cosas porque algunas personas le abrieron los ojos a los mecanismos económicos más sólidos de Bitcoin, y a la solidez de este sistema.

El atractivo del RGB y la construcción por capas

Lo que le convenció definitivamente de la relevancia de Bitcoin, según sus palabras, fue el descubrimiento de RGB y el concepto de capas. Cree que las funcionalidades existentes en otras blockchains podrían reproducirse en capas superiores, por encima de Bitcoin, sin alterar el protocolo básico.

En febrero de 2022, se unió a DIBA para trabajar específicamente en RGB, y en particular en el monedero Bitmask. En aquel momento, Bitmask aún estaba en la versión 0.01 y ejecutaba RGB en la versión 0.4, sólo para la gestión de tokens individuales. Señala que esto estaba menos orientado a la autocustodia que hoy en día, ya que la lógica se basaba en parte en el servidor. Desde entonces, la arquitectura ha evolucionado hacia este modelo, muy apreciado por los bitcoiners.

Las bases del protocolo RGB

El protocolo RGB es la plasmación más reciente y avanzada del concepto colored coins, ya explorado en torno a 2012-2013. Por aquel entonces, varios equipos buscaban asociar distintos valores de bitcoin en UTXOs, lo que dio lugar a múltiples implementaciones dispersas. Esta falta de estandarización y la escasa demanda de entonces impidieron que estas soluciones se afianzaran de forma duradera.

En la actualidad, RGB destaca por su solidez conceptual y sus especificaciones unificadas a través de la asociación LNP/BP. El principio se basa en la validación del lado del cliente. La blockchain de Bitcoin sólo almacena los compromisos criptográficos (commitments, vía Taproot u OP_RETURN), mientras que la mayoría de los datos (definiciones de contratos, historiales de transferencias, etc.) son almacenados por los usuarios interesados. De este modo, se distribuye la carga de almacenamiento y se refuerza la confidencialidad de los intercambios, sin sobrecargar la blockchain. Este enfoque permite la creación de activos fungibles (norma RGB20) o únicos (norma RGB21), dentro de un marco modular y escalable.

La función testigo (RGB20) y los activos únicos (RGB21)

Con RGB20, definimos un token fungible en Bitcoin. El emisor elige una oferta, una precisión, y crea un contrato en el que luego puede realizar transferencias. Cada transferencia está referenciada a un Bitcoin UTXO, que actúa como un Sello de un solo uso. Esta lógica garantiza que el usuario no podrá gastar el mismo activo dos veces, ya que sólo la persona capaz de gastar el UTXO posee la clave para actualizar el estado del contrato del lado del cliente.

RGB21 se dirige a activos únicos (o "NFT"). El activo tiene un suministro de 1, y puede asociarse a metadatos (archivo de imagen, audio, etc.) descritos a través de un campo específico. A diferencia de los NFT en blockchains públicos, los datos y sus identificadores MIME pueden permanecer privados, distribuidos peer-to-peer a discreción del propietario.

La solución Bitmask: un monedero para RGB

Para explotar las capacidades de RGB en la práctica, el proyecto DIBA ha diseñado un monedero llamado Bitmask. La idea es proporcionar una herramienta no custodial, basada en Taproot, accesible como aplicación web o extensión del navegador. Bitmask gestiona activos RGB20 y RGB21, e integra varios mecanismos de seguridad:

Gracias a esta arquitectura, todas las transacciones de activos tienen lugar en el lado del cliente. Desde el exterior, la transacción de Bitcoin no es más que una clásica transacción de gasto en Taproot, de la que nadie sospecharía que también conlleva una transferencia de tokens fungibles o NFT. La ausencia de sobrecarga en la cadena (no hay metadatos almacenados públicamente) garantiza un cierto grado de discreción y hace más fácil resistir posibles intentos de censura.

Seguridad y arquitectura distribuida

En la medida en que el protocolo RGB exige que cada participante conserve su historial de transacciones (para probar la validez de las transferencias que recibe), se plantea la cuestión del almacenamiento. Bitmask propone serializar este alijo localmente, y luego enviarlo a varios servidores o nubes (opcional). Los datos permanecen encriptados por el usuario a través de Carbonado, por lo que un servidor no puede leerlos. En caso de corrupción parcial, la capa de corrección de errores puede reconstituir el contenido.

El uso de CRDT (Conflict-free replicated data type) permite fusionar distintas versiones del alijo, en caso de que diverjan. Todo el mundo es libre de alojar estos datos donde desee, ya que ningún nodo completo contiene toda la información vinculada al activo. Esto refleja exactamente la filosofía Client-side Validation, en la que cada propietario es responsable de almacenar pruebas de la validez de su activo RGB.

Hacia un ecosistema más amplio: mercado, interoperabilidad y nuevas funciones

La empresa que está detrás de Bitmask no se limita al simple desarrollo de un monedero. DIBA pretende desarrollar :

Al mismo tiempo, estamos trabajando en WebBTC o WebLN (estándares que permiten a los sitios web pedir al monedero que firme transacciones Bitcoin o Lightning), así como en la capacidad de "telequemar" entradas Ordinales (si queremos repatriar Ordinales a un formato RGB más discreto y flexible).

Conclusión

Todo el proceso muestra cómo el ecosistema RGB puede desplegarse y hacerse accesible a los usuarios finales mediante soluciones técnicas sólidas. La transición de una perspectiva altcoin a una visión más centrada en Bitcoin, unida al descubrimiento de Client-side Validation, ilustra un camino bastante lógico: entendemos que es posible implementar diversas funcionalidades (tokens fungibles, NFT, contratos inteligentes...) sin bifurcar la blockchain, simplemente aprovechando los compromisos criptográficos en transacciones Taproot u OP_RETURNs.

El monedero Bitmask forma parte de este enfoque: en el lado de la blockchain, todo lo que se ve es una transacción ordinaria de Bitcoin; en el lado del usuario, se manipula una interfaz web en la que se crean, intercambian y almacenan todo tipo de activos fuera de la cadena. Este modelo disocia claramente la infraestructura monetaria (Bitcoin) de la lógica de emisión y transferencia (RGB), al tiempo que garantiza un alto nivel de confidencialidad y una mejor escalabilidad.

El trabajo de Bitfinex en RGB

En este capítulo, basado en una presentación de Frederico Tenga, examinamos un conjunto de herramientas y proyectos creados por el equipo de Bitfinex dedicados al RGB, con el objetivo de fomentar la aparición de un ecosistema rico y diverso en torno a este protocolo. El objetivo inicial del equipo no es lanzar un producto comercial específico, sino proporcionar bloques de construcción de software, contribuir al propio protocolo RGB y proponer referencias de implementación concretas, como un monedero móvil (Iris Wallet) o un nodo Lightning compatible con RGB.

Antecedentes y objetivos

Desde alrededor de 2022, el equipo RGB de Bitfinex se ha concentrado en desarrollar la pila tecnológica que permite explotar y probar RGB de manera eficiente. Se han realizado varias contribuciones:

Este enfoque pretende cubrir toda la cadena de necesidades: desde la biblioteca de bajo nivel (RGBlib), que permite la implementación de un monedero, hasta el aspecto de producción (un nodo Lightning, un monedero para Android, etc.).

La biblioteca RGBlib: simplificación del desarrollo de aplicaciones RGB

Un punto importante para democratizar la creación de monederos y aplicaciones RGB es poner a disposición una abstracción lo suficientemente simple como para que los desarrolladores no tengan que aprender todo sobre la lógica interna del protocolo. Este es precisamente el objetivo de RGBlib, escrito en Rust.

RGBlib actúa como puente entre los requisitos altamente flexibles (pero a veces complejos) de RGB que hemos podido estudiar en capítulos anteriores, y las necesidades concretas de un desarrollador de aplicaciones. En otras palabras, un monedero (o servicio) que desee gestionar transferencias de tokens, emisión de activos, verificación, etc., puede confiar en RGBlib sin conocer cada detalle criptográfico o cada parámetro personalizable de RGB.

La librería ofrece :

RGBlib se apoya por tanto en nociones complejas propias de RGB (Client-side Validation, anclajes Tapret/Opret), pero las encapsula para que la aplicación final no tenga que reprogramarlo todo o tomar decisiones arriesgadas. Además, RGBlib ya está enlazado en varios lenguajes (Kotlin y Python), lo que abre la puerta a usos más allá de un simple universo Rust.

Iris Wallet: un ejemplo de monedero RGB en Android

Para demostrar la eficacia de RGBlib, el equipo de Bitfinex ha desarrollado Iris Wallet, exclusivamente en Android en esta fase. Se trata de un monedero móvil que ilustra una experiencia de usuario similar a la de un monedero Bitcoin ordinario: se puede emitir un activo, enviarlo, recibirlo y ver su historial, mientras se mantiene un modelo de autocustodia.

Iris tiene una serie de características interesantes:

Utilizando un servidor Electrum:

Como cualquier monedero, Iris necesita conocer las confirmaciones de transacciones en la blockchain. En lugar de integrar un nodo completo, Iris utiliza por defecto un servidor Electrum mantenido por el equipo de Bitfinex. Sin embargo, los usuarios pueden configurar su propio servidor u otro servicio de terceros. De esta forma, las transacciones de Bitcoin pueden ser validadas y la información recuperada (indexación) de forma modular.

El servidor proxy RGB:

A diferencia de Bitcoin, RGB requiere el intercambio de metadatos fuera de la cadena (consignaciones) entre emisor y receptor. Para simplificar este proceso, Iris ofrece una solución en la que la comunicación tiene lugar a través de un servidor proxy. El monedero receptor genera una factura que menciona dónde debe enviar el remitente los datos del lado del cliente. Por defecto, la URL apunta a un proxy alojado por el equipo de Bitfinex, pero puedes cambiar este proxy (o alojar el tuyo propio). La idea es volver a una experiencia de usuario familiar en la que el destinatario muestra un código QR, y el remitente escanea este código para la transacción, sin manipulaciones adicionales complejas.

Copia de seguridad continua:

En un contexto estrictamente Bitcoin, hacer una copia de seguridad de la semilla suele ser suficiente (aunque actualmente recomendamos hacer una copia de seguridad de la semilla y los descriptores). Con RGB, esto no es suficiente: también necesitas guardar el historial local (las consignaciones) que prueban que realmente posees un activo RGB. Cada vez que recibes un recibo, el dispositivo almacena nuevos datos, que son esenciales para los gastos posteriores. Iris gestiona automáticamente una copia de seguridad cifrada en Google Drive del usuario. Esto no requiere ninguna confianza especial en Google, ya que la copia de seguridad está cifrada, y en el futuro se prevén opciones más sólidas (como un servidor personal) para evitar cualquier riesgo de censura o eliminación por parte de un operador tercero.

Otras características:

En definitiva, Iris ofrece una experiencia de usuario cercana a la de un monedero Bitcoin clásico, enmascarando la complejidad adicional (gestión del alijo, historial de consignaciones, etc.) gracias a RGBlib y al uso de un servidor proxy.

Servidor proxy y experiencia del usuario

El servidor proxy introducido anteriormente merece ser detallado, ya que es la clave para una experiencia de usuario fluida. En lugar de que el remitente tenga que transmitir manualmente las consignas al destinatario, la transacción RGB tiene lugar en segundo plano a través de un servidor proxy :

De este modo, el monedero se comporta casi como un monedero normal. El usuario desconoce todos los pasos intermedios. Es cierto que el proxy actual no está cifrado ni autenticado (lo que plantea problemas de confidencialidad e integridad), pero estas mejoras son posibles en versiones posteriores. El concepto de proxy sigue siendo extremadamente útil para recrear la experiencia de "yo envío un código QR, tú lo escaneas para pagar".

Integración RGB en la Red Lightning

Otro punto clave del trabajo del equipo de Bitfinex es hacer que la red Lightning sea compatible con los activos RGB. El objetivo es habilitar canales Lightning en USDT (o cualquier otro token), y beneficiarse de las mismas ventajas que bitcoin en Lightning (transacciones casi instantáneas, enrutamiento, etc.). En concreto, se trata de crear un nodo Lightning modificado para :

Esta solución, denominada "RGB Lightning Node", utiliza LDK (Lightning Dev Kit) como base, y añade los mecanismos necesarios para inyectar tokens RGB en los canales. Los compromisos Lightning conservan la estructura clásica (salidas puntuables, timelock...), y además anclan una transición de estado RGB (vía Opret o Tapret). Para el usuario, esto abre el camino a los canales Lightning en stablecoins o en cualquier otro activo emitido vía RGB.

Potencial de DEX e impacto en Bitcoin

Una vez que varios activos se gestionan a través de Lightning, se hace posible imaginar un intercambio atómico en una única ruta de enrutamiento Lightning, utilizando la misma lógica de secretos y timelocks. Por ejemplo, el usuario A tiene bitcoin en un canal Lightning y el usuario B tiene USDT RGB en otro canal Lightning. Pueden construir una ruta que conecte sus dos canales e intercambiar simultáneamente BTC por USDT, sin necesidad de confianza. Esto no es más que un intercambio atómico que tiene lugar en varios saltos, haciendo que los participantes externos sean casi ajenos al hecho de que están realizando una operación, no sólo un enrutamiento. Este enfoque ofrece :

Podemos imaginar entonces un ecosistema en el que los nodos Lightning ofrezcan precios de intercambio (proporcionando liquidez). Cada nodo, si lo desea, puede desempeñar el papel de market maker, comprando y vendiendo diversos activos en Lightning. Esta perspectiva de una DEX de capa-2 refuerza la idea de que no es necesario bifurcar o utilizar blockchains de terceros para obtener intercambios de activos descentralizados.

El impacto sobre Bitcoin podría ser positivo: La infraestructura de Lightning (nodos, canales y servicios) se utilizaría más plenamente gracias a los volúmenes generados por estas stablecoins, derivados y otros tokens. Los comerciantes interesados en los pagos de USDT en Lightning descubrirían mecánicamente los pagos de BTC en Lightning (gestionados por la misma pila). El mantenimiento y la financiación de la infraestructura de la red Lightning también podrían beneficiarse de la multiplicación de estos flujos no BTC, lo que beneficiaría indirectamente a los usuarios de Bitcoin.

Conclusión y recursos

El equipo de Bitfinex dedicado a RGB ilustra con su trabajo la diversidad de lo que se puede hacer sobre el protocolo. Por un lado, está RGBlib, una biblioteca que facilita el diseño de monederos y aplicaciones. Por otro, tenemos Iris Wallet, una demostración práctica en Android de una cuidada interfaz de usuario final. Por último, la integración de RGB con Lightning demuestra que los canales stablecoin son posibles, y abre el camino a una potencial DEX descentralizada en Lightning.

Este enfoque sigue siendo en gran medida experimental y continúa evolucionando: la biblioteca RGBlib se perfecciona a medida que avanzamos, Iris Wallet recibe mejoras periódicas y el nodo Lightning dedicado aún no es un cliente Lightning convencional.

Quienes deseen saber más o contribuir, tienen a su disposición varios recursos, entre ellos :

En el próximo capítulo, veremos más detenidamente cómo lanzar un nodo RGB Lightning.

RLN - Nodo de rayos RGB

En este capítulo final, Frederico Tenga te lleva paso a paso a través de la configuración de un nodo Lightning RGB en un entorno Regtest, y te muestra cómo crear tokens RGB en él. Al lanzar dos nodos separados, también descubrirás cómo abrir un canal Lightning entre ellos e intercambiar activos RGB.

Este vídeo sirve de tutorial, similar al que cubrimos en un capítulo anterior, pero esta vez centrado específicamente en Lightning

El principal recurso para este vídeo es el repositorio de Github RGB Lightning Node, que facilita el lanzamiento de esta configuración en Regtest.

Despliegue de un nodo Lightning compatible con RGB

El proceso retoma y pone en práctica todos los conceptos tratados en los capítulos anteriores:

Presentación del nodo rgb-lightning

El proyecto rgb-lightning-node es un demonio Rust basado en un fork de rgb-lightning (LDK) modificado para tener en cuenta la existencia de activos RGB en un canal. Cuando se abre un canal, se puede especificar la presencia de activos, y cada vez que se actualiza el estado del canal, se crea una transición RGB que refleja la distribución del activo en las salidas de Lightning. Esto permite :

El código aún está en fase alfa: recomendamos utilizarlo únicamente en regtest o en la testnet.

Instalación de nodos

Para compilar e instalar el binario rgb-lightning-node, comenzamos clonando el repositorio y sus submódulos, luego ejecutamos el archivo :

git clone https://github.com/RGB-Tools/rgb-lightning-node --recurse-submodules --shallow-submodules
RGB-Bitcoin

Desde la raíz del proyecto, ejecute el siguiente comando para compilar e instalar el binario :

cargo install --locked --debug --path .
RGB-Bitcoin

Al final de este comando, un ejecutable rgb-lightning-node estará disponible en su $CARGO_HOME/bin/. Asegúrese de que esta ruta está en su $PATH para que pueda invocar el comando desde cualquier directorio.

Requisitos de rendimiento

Para funcionar, el demonio rgb-lightning-node requiere la presencia y configuración de :

Cada instancia de RLN deberá comunicarse con bitcoind para difundir y supervisar sus transacciones en la cadena. Será necesario proporcionar al demonio la autenticación (nombre de usuario/contraseña) y la URL (host/puerto).

El demonio debe ser capaz de listar y explorar transacciones en la cadena, en particular para encontrar el UTXO en el que se ha anclado un activo. Deberá especificar la URL de su servidor Electrum o Esplora.

Como se ha visto en capítulos anteriores, el servidor proxy es un componente (opcional, pero muy recomendable) para simplificar el intercambio de consignas entre pares Lightning. Una vez más, hay que especificar una URL.

Los ID y las URL se introducen cuando el demonio se desbloquea a través de la API. Más sobre esto más adelante.

Lanzamiento de Regtest

Para un uso sencillo, hay un script regtest.sh que inicia automáticamente, a través de Docker, un conjunto de servicios: bitcoind, electrs (indexador), rgb-proxy-server.

RGB-Bitcoin

Permite lanzar un entorno local, aislado y preconfigurado. Crea y destruye contenedores y directorios de datos en cada reinicio. Comenzaremos iniciando el :

./regtest.sh start

Este script :

RGB-Bitcoin

A continuación, lanzaremos varios nodos RLN. En shells separados, ejecute, por ejemplo (para lanzar 3 nodos RLN) :

# 1st shell
rgb-lightning-node dataldk0/ --daemon-listening-port 3001 \
--ldk-peer-listening-port 9735 --network regtest
# 2nd shell
rgb-lightning-node dataldk1/ --daemon-listening-port 3002 \
--ldk-peer-listening-port 9736 --network regtest
# 3rd shell
rgb-lightning-node dataldk2/ --daemon-listening-port 3003 \
--ldk-peer-listening-port 9737 --network regtest
RGB-Bitcoin

También puede ejecutar comandos en sus nodos RLN desde su navegador:

https://rgb-tools.github.io/rgb-lightning-node/

Para que un nodo abra un canal, primero debe tener bitcoins en una dirección generada con el siguiente comando (para el nodo n°1, por ejemplo):

curl -X POST http://localhost:3001/address

La respuesta le proporcionará una dirección.

RGB-Bitcoin

En el Regtest bitcoind, vamos a minar algunos bitcoins. Ejecutar :

./regtest.sh mine 101
RGB-Bitcoin

Envíe los fondos a la dirección del nodo generada anteriormente:

./regtest.sh sendtoaddress <address> <amount>
RGB-Bitcoin

Luego minar un bloque para confirmar la transacción:

./regtest.sh mine 1
RGB-Bitcoin

Lanzamiento de Testnet (sin Docker)

Si desea probar un escenario más realista, puede lanzar 3 nodos RLN en la Testnet en lugar de en Regtest, apuntando a servicios públicos :

rgb-lightning-node dataldk0/ --daemon-listening-port 3001 \
--ldk-peer-listening-port 9735 --network testnet
rgb-lightning-node dataldk1/ --daemon-listening-port 3002 \
--ldk-peer-listening-port 9736 --network testnet
rgb-lightning-node dataldk2/ --daemon-listening-port 3003 \
--ldk-peer-listening-port 9737 --network testnet

Por defecto, si no se encuentra ninguna configuración, el demonio intentará utilizar el archivo :

Con inicio de sesión :

También puedes personalizar estos elementos a través de la API init/unlock.

Emisión de una ficha RGB

Para emitir un token, empezaremos creando UTXOs "coloreables":

curl -X POST -H "Content-Type: application/json" \
-d '{
"up_to": false,
"num": 4,
"size": 2000000,
"fee_rate": 4.2,
"skip_sync": false
}' \
http://localhost:3001/createutxos
RGB-Bitcoin

Por supuesto, puede adaptar el pedido. Para confirmar la transacción, minamos un :

./regtest.sh mine 1

Ahora podemos crear un activo RGB. El comando dependerá del tipo de activo que desee crear y sus parámetros. Aquí estoy creando un token NIA (Non Inflatable Asset) llamado "PBN" con un suministro de 1000 unidades. La precisión le permite definir la divisibilidad de las unidades.

curl -X POST -H "Content-Type: application/json" \
-d '{
"amounts": [
1000
],
"ticker": "PBN",
"name": "Plan B Network",
"precision": 0
}' \
http://localhost:3001/issueassetnia
RGB-Bitcoin

La respuesta incluye el identificador del activo recién creado. No olvide anotar este identificador. En mi caso, es :

rgb:fc7fMj5S-8yz!vIl-260BEhU-Hj1skvM-ZHcjfyz-RTcWc10
RGB-Bitcoin

A continuación, puedes transferirlo a la cadena o asignarlo a un canal Lightning. Eso es exactamente lo que vamos a hacer en la siguiente sección.

Abrir un canal y transferir un activo RGB

Primero debe conectar su nodo a un peer de la red Lightning mediante el comando /connectpeer. En mi ejemplo, controlo ambos nodos. Así que recuperaré la clave pública de mi segundo nodo Lightning con este comando:

curl -X 'GET' \
'http://localhost:3002/nodeinfo' \
-H 'accept: application/json'

El comando devuelve la clave pública de mi nodo n°2 :

031e81e4c5c6b6a50cbf5d85b15dad720fec92c62e84bafb34088f0488e00a8e94
RGB-Bitcoin

A continuación, abriremos el canal especificando el activo correspondiente (PBN). El comando /openchannel permite definir el tamaño del canal en satoshis y optar por incluir el activo RGB. Depende de lo que quieras crear, pero en mi caso, el comando es :

curl -X POST -H "Content-Type: application/json" \
-d '{
"peer_pubkey_and_opt_addr": "031e81e4c5c6b6a50cbf5d85b15dad720fec92c62e84bafb34088f0488e00a8e94@localhost:9736",
"capacity_sat": 1000000,
"push_msat": 10000000,
"asset_amount": 500,
"asset_id": "rgb:fc7fMj5S-8yz!vIl-260BEhU-Hj1skvM-ZHcjfyz-RTcWc10",
"public": true,
"with_anchors": true,
"fee_base_msat": 1000,
"fee_proportional_millionths": 0,
"temporary_channel_id": "a8b60c8ce3067b5fc881d4831323e24751daec3b64353c8df3205ec5d838f1c5"
}' \
http://localhost:3001/openchannel

Más información aquí:

RGB-Bitcoin

Para confirmar la transacción, se minan 6 bloques:

./regtest.sh mine 6
RGB-Bitcoin

El canal Lightning ya está abierto y también contiene 500 tokens PBN por parte del nodo n°1. Si el nodo n°2 desea recibir tokens PBN, debe generar una factura. He aquí cómo hacerlo:

curl -X POST -H "Content-Type: application/json" \
-d '{
"amt_msat": 3000000,
"expiry_sec": 420,
"asset_id": "rgb:fc7fMj5S-8yz!vIl-260BEhU-Hj1skvM-ZHcjfyz-RTcWc10",
"asset_amount": 100
}' \
http://localhost:3002/lninvoice

Con :

En respuesta, obtendrá una factura RGB (como se ha descrito en capítulos anteriores):

lnbcrt30u1pncgd4rdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4qv0grex9c6m22r9ltkzmzhddwg87eykx96zt47e5pz8sfz8qp28fgpp5jksvqtleryhvwr299qdz96qxzm24augy5agkdhltudk463lt9dassp5d6n0sqgl0c4gx52fdmutrdtqamt0y4xuz2rcgel4hpjwne08gmls9qyysgqcqpcxqzdylz5wfnkywnxvvmkvnt2x4fj6wre0gshvjtv95ervvzzg4592t2gdgchx6mkf5k45jrrdfn8j73d2f2xx4mrxycq7qzry4v4jan6uxhhacyqa4gn6plggwpq9j74tu74f2zsamtz6ymt600p8su4c4ap9g9d8ku2x3wdh6fuc8fd8pff2yzpjrf24ys3cltca9fgqut6gzj
RGB-Bitcoin

Ahora pagaremos esta factura desde el primer nodo, que tiene el efectivo necesario con el token PBN:

curl -X POST -H "Content-Type: application/json" \
-d '{
"invoice": "lnbcrt30u1pncgd4rdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4qv0grex9c6m22r9ltkzmzhddwg87eykx96zt47e5pz8sfz8qp28fgpp5jksvqtleryhvwr299qdz96qxzm24augy5agkdhltudk463lt9dassp5d6n0sqgl0c4gx52fdmutrdtqamt0y4xuz2rcgel4hpjwne08gmls9qyysgqcqpcxqzdylz5wfnkywnxvvmkvnt2x4fj6wre0gshvjtv95ervvzzg4592t2gdgchx6mkf5k45jrrdfn8j73d2f2xx4mrxycq7qzry4v4jan6uxhhacyqa4gn6plggwpq9j74tu74f2zsamtz6ymt600p8su4c4ap9g9d8ku2x3wdh6fuc8fd8pff2yzpjrf24ys3cltca9fgqut6gzj"
}' \
http://localhost:3001/sendpayment
RGB-Bitcoin

Se ha efectuado el pago. Esto puede verificarse ejecutando el comando :

curl -X 'GET' \
'http://localhost:3001/listpayments' \
-H 'accept: application/json'
RGB-Bitcoin

He aquí cómo desplegar un nodo Lightning modificado para transportar activos RGB. Esta demostración se basa en :

Gracias a este proceso :

El proyecto sigue en fase alfa. Por tanto, se recomienda encarecidamente limitarse a los entornos de prueba (regtest, testnet).

Las oportunidades que abre esta compatibilidad LN-RGB son considerables: stablecoins en Lightning, DEX layer-2, transferencia de tokens fungibles o NFT a muy bajo coste... Los capítulos anteriores han esbozado la arquitectura conceptual y la lógica de validación. Ahora tienes una visión práctica de cómo poner en marcha un nodo de este tipo, para tus futuros desarrollos o pruebas.

Sección final

Opiniones y valoraciones

true

Conclusión

true