Interoperabilidad Lisk : mensajes entre cadena cruzada

octubre 09, 2021 VICTOR HUGO LAZARTE 0 Comments

 

En esta edición de la serie en curso que cubre la solución de interoperabilidad Lisk, discutimos la sal y la pimienta de la interoperabilidad: mensajes entre cadenas. En la publicación anterior del blog , Maxime Gagnebin presentó las actualizaciones entre cadenas, las transacciones utilizadas para intercambiar información entre cadenas en el ecosistema Lisk. A continuación se ofrece un breve resumen de esto; sin embargo, se recomienda leer la publicación completa del blog antes de sumergirse en los mensajes entre cadenas. Además, Maxime también discutió mensajes de cadena transversal en Lisk.js .

Si las actualizaciones de cadena cruzada son los sobres que se utilizan para entregar información de una cadena a otra, los mensajes de cadena cruzada son el contenido real dentro del sobre. Los usuarios pueden enviar mensajes de una cadena a otra para mover tokens, enviar información o, en general, implementar cualquier tipo de lógica personalizada entre cadenas.

Visión general

Para comprender por qué necesitamos mensajes entre cadenas, es mejor comenzar desde lo más básico.

Reduciéndolo a lo esencial, una cadena de bloques es una base de datos distribuida. En un momento dado, la base de datos se encuentra en uno de los muchos estados precisos finitos (también llamado máquina de estados finitos ). Por ejemplo, el estado de la cadena de bloques podría corresponder a que Alice tenga 5 LSK y Bob no tenga LSK. La cadena de bloques puede sufrir transiciones de estado y pasar de un estado de base de datos a otro. Los usuarios pueden activar una transición de estado enviando una transacción . Cada transacción contiene un comandoque, una vez ejecutado, cambia el estado de la base de datos. Por ejemplo, Alice puede enviar 2 LSK a Bob emitiendo un comando de transferencia LSK. Los lotes de transacciones se recopilan regularmente en bloques que se envían a través de la red para mantener sincronizada la base de datos distribuida.

Sin embargo, no se permiten todas las transiciones de estado. En general, el conjunto de transiciones de estado válidas depende del estado actual de la cadena de bloques. En el ejemplo anterior, un comando que envía 10 LSK de Alice a Bob no sería válido, ya que Alice no tiene suficientes LSK. Las reglas que definen las transiciones de estado válidas se denominan protocolo blockchain (nuevamente, estamos simplificando un poco las cosas aquí, ya que las reglas de consenso también son parte del protocolo).

Figura 1: En el estado inicial de la cadena de bloques, Alice tiene 5 LSK y Bob no tiene ninguna. Alice envía 2 LSK a Bob con una transacción de transferencia de token. Una vez procesada la transacción, la cadena de bloques pasa a un estado en el que Alice tiene 3 LSK y Bob 2 LSK.

Pero, ¿qué sucede si tenemos dos cadenas de bloques que se ejecutan de forma independiente entre sí? ¿Cómo pueden los usuarios de blockchain A desencadenar una transición de estado en blockchain B? Una forma obvia sería simplemente enviar una transacción a blockchain B directamente. Sin embargo, esta transacción solo se puede validar contra el estado de la cadena de bloques B. Lo que realmente queremos es activar una transición de estado en la cadena de bloques B desde la cadena de bloques A (validando el estado de la cadena de bloques A).

Aquí es donde entran en juego las transacciones entre cadenas . Una transacción entre cadenas es una transacción que, tras su ejecución, crea uno o más mensajes entre cadenas . Los mensajes entre cadenas son una nueva estructura de datos introducida con interoperabilidad. Desempeñan un papel similar a las transacciones, en el sentido de que contienen un comando de cadena cruzada . En analogía con los comandos, los comandos de cadena cruzada inducen una transición de estado en la cadena de recepción. Varios mensajes de cadena cruzada se recopilan juntos y se publican en otra cadena como parte de una actualización de cadena cruzada (nuevamente, se puede encontrar más información en la publicación anterior del blog ).

Por lo tanto, los comandos de cadena cruzada se validan en la cadena de envío. En la cadena de recepción, se puede asumir la validez de los mensajes de cadena cruzada (hay ciertas verificaciones que se realizan a la actualización de cadena cruzada que garantizan la validez de todos los mensajes de cadena cruzada contenidos en ella). Si el mensaje de cadena cruzada también es válido con respecto al estado de la cadena de recepción, finalmente se puede procesar la transición de estado.

Alice ahora puede enviar 2 LSK que tiene en la cadena de bloques A a Bob en la cadena de bloques B. Para hacer eso, emite un comando de transferencia de LSK de cadena cruzada en la cadena de bloques A. El comando crea un mensaje de cadena cruzada que se incluye en una cadena cruzada comando de actualización incluido en blockchain B. La actualización de cadena cruzada se procesa junto con todos los mensajes de cadena cruzada contenidos en ella, incluida la transferencia LSK de Alice. Bob finalmente obtiene sus 2 LSK directamente en blockchain B.


Figura 2: Alice envía 2 LSK a Bob de la cadena A a la cadena B. La transacción de cadena cruzada T genera un mensaje que se incluye en la CCU de actualización de cadena cruzada La actualización de cadena cruzada se incluye en la cadena B para inducir la transición de estado que acredita a Bob con 2 LSK.

Resumen de terminología

  • Transacción : un objeto de sobre para un comando.
  • Comando : Disparador de una transición de estado en la misma cadena.
  • Transacción entre cadenas : transacción que genera uno o más mensajes entre cadenas.
  • Mensaje de cadena cruzada : un objeto de sobre para un comando de cadena cruzada.
  • Comando de cadena cruzada : disparador de una transición de estado procedente de otra cadena.
  • Actualizaciones entre cadenas : un comando especial que contiene mensajes entre cadenas.

Formato de mensajes entre cadenas

En esta sección, describimos brevemente las propiedades comunes a todos los mensajes entre cadenas (consulte LIP "Introducción de mensajes entre cadenas" para obtener más información).

Envío de ID de cadena y recepción de ID de cadena

Como se explicó anteriormente, los mensajes entre cadenas se generan en una cadena de bloques y se procesan en otra. La cadena de bloques donde se crea el mensaje de cadena cruzada se denomina cadena de envío y se identifica mediante el ID de la cadena de envío. La cadena de bloques donde se procesa el mensaje se denomina cadena de recepción y se identifica mediante el ID de la cadena de recepción. La cadena principal utiliza el ID de la cadena de recepción para enrutar el mensaje a la cadena correcta.

Mientras tanto

Esta propiedad cuenta el número total de mensajes que se enviaron desde la cadena de envío. Cuando se crea un mensaje de cadena cruzada, se le asigna automáticamente el nonce correcto. La cadena principal no actualiza este valor cuando se enruta un mensaje.

ID de módulo e ID de comando de cadena cruzada

Al igual que las transacciones, los mensajes entre cadenas tienen un ID de módulo y un ID de comando entre cadenas. El ID del módulo y el ID del comando de cadena cruzada se utilizan para identificar la lógica que debe procesarse en la cadena de recepción.

Tarifa

Las tarifas de transacción pagan por el procesamiento en la cadena de envío. Del mismo modo, las tarifas de los mensajes pagan por el procesamiento en la cadena de recepción. Las tarifas de los mensajes se pagan en LSK en todo el ecosistema. Al enrutar un mensaje, la cadena principal también transfiere LSK de la cadena de envío a la cadena de recepción para contabilizar las tarifas transferidas.

Estado

La propiedad de estado se utiliza para el manejo de errores. Si no es posible entregar un mensaje de cadena cruzada (por ejemplo, si la cadena de recepción no existe), el estado del mensaje se actualiza y el mensaje se enruta de regreso a la cadena de envío. La cadena de envío puede procesar el mensaje fallido y potencialmente reembolsar a los usuarios.

Actualmente, la interoperabilidad admite 5 códigos de estado. El estado utilizado para el manejo de errores describe el motivo del error del mensaje como se muestra a continuación:

  1. Aceptar : el estado predeterminado de un mensaje entre cadenas.

  2. MODULE_NOT_SUPPORTED : estado asignado en la cadena de recepción si no implementa ningún módulo con ID igual al ID del módulo de mensaje.

  3. CROSS_CHAIN_COMMAND_NOT_SUPPORTED : estado asignado en la cadena de recepción si no implementa ningún comando con ID igual al ID del comando del mensaje.

  4. CHANNEL_UNAVAILABLE : estado asignado en la cadena principal si la cadena receptora no está disponible (no existe, no está activa o ha sido cancelada).

  5. RECUPERADO : estado asignado en la cadena principal a un mensaje de cadena cruzada después de que se haya recuperado de la bandeja de salida de una cadena lateral terminada (se proporcionará más información en una publicación de blog futura).

Los módulos pueden introducir nuevos valores para la propiedad de estado, que se pueden utilizar para el manejo personalizado de errores. Tenga en cuenta que los primeros 64 códigos de error están reservados para el módulo de interoperabilidad.

Por ejemplo, el nuevo módulo Token define el estado TOKEN_NOT_SUPPORTED para indicar que una transferencia de token entre cadenas no es válida porque la cadena de recepción no admite ese token específico.

Parámetros

De manera similar a las transacciones, la propiedad params contiene los parámetros específicos que se utilizan para procesar el mensaje entre cadenas. Esta propiedad está definida por el módulo correspondiente y puede seguir cualquier esquema. Tenga en cuenta que la cadena principal no deserializa ni valida esta propiedad al enrutar un mensaje.

Mensajes de cadena cruzada del módulo de interoperabilidad

Hay 4 mensajes especiales entre cadenas que se utilizan para facilitar la interoperabilidad. A continuación, en esta sección, se incluye una breve descripción de estos mensajes.

Recibo de actualización entre cadenas

El recibo de actualización entre cadenas reconoce la inclusión de una transacción de actualización entre cadenas. La cadena de recepción genera automáticamente este mensaje, que luego se envía de vuelta a la cadena de envío.   

El recibo de actualización entre cadenas contiene las siguientes propiedades:

  • payFee : la tarifa de la actualización entre cadenas. Esta propiedad se puede usar nuevamente en la cadena de envío para reembolsar al retransmisor, por ejemplo (recuerde que el retransmisor es el usuario que preparó y envió la actualización entre cadenas).
  • relayerAddress : la dirección del retransmisor.
  • partnerChainInboxSize : el tamaño de la bandeja de entrada en la cadena de recepción. Esta propiedad informa a la cadena de envío sobre el número de mensajes que se han procesado en la cadena de recepción. En general, el tamaño de la bandeja de salida en la cadena de envío no es igual al tamaño de la bandeja de entrada en la cadena de recepción (ya que, por ejemplo, todavía no se ha publicado una actualización entre cadenas en la cadena de recepción). Esta propiedad permite a los usuarios recuperar mensajes no procesados ​​de una bandeja de salida de cadena lateral terminada.

Mensaje de canal terminado

Cuando se termina una cadena lateral, la cadena principal genera automáticamente un mensaje de canal terminado y lo envía a la cadena lateral terminada. Este mensaje también contiene la propiedad partnerChainInboxSize .

Mensaje de registro

Cuando una cadena lateral se registra en la cadena principal, se genera un mensaje de registro para reconocer el registro exitoso. Este mensaje contiene el ID de red y el nombre de la cadena lateral. El ID de red y el nombre incluidos en la transacción de registro de la cadena principal (ver "Proceso de registro de la cadena principal" en la publicación del blog "El ciclo de vida de una cadena lateral en el ecosistema Lisk" ) deben coincidir con estos valores, lo que garantiza su exactitud.

Mensaje de terminación de cadena lateral

El mensaje de terminación de la cadena lateral se crea en la cadena principal cuando un mensaje debe enrutarse a una cadena terminada o inactiva. Este mensaje se envía a la cadena de envío original, lo que le permite crear una cuenta de cadena lateral terminada que luego se puede usar para los comandos de recuperación. Contiene el ID de la cadena y la última raíz de estado certificada de la cadena lateral terminada.

 Ciclo de vida de un mensaje entre cadenas

En esta sección, resumimos nuevamente las principales características de la interoperabilidad de Lisk desde el punto de vista de un mensaje entre cadenas. 

Enrutamiento de la cadena principal : el ecosistema Lisk está organizado en una topología en estrella: cada cadena lateral está conectada a la cadena principal Lisk. Los mensajes de cadena cruzada de cadena lateral a cadena lateral siempre se publican primero en la cadena principal. La cadena principal es entonces responsable de entregar el mensaje a la cadena de recepción correcta. Tenga en cuenta que al hacerlo, la cadena principal no procesa el mensaje, sino que simplemente lo mueve de la bandeja de entrada de la cadena de envío a la bandeja de salida de la cadena de recepción.

Manejo de errores de la cadena principal : mientras se entregan mensajes, la cadena principal también proporciona un nivel básico de manejo de errores: si la cadena de recepción no existe, no está activa o se ha terminado, el mensaje se envía de vuelta a la cadena de envío con el estado establecido en CHANNEL_UNAVAILABLE y el ID de la cadena de envío y el ID de la cadena de recepción intercambiados. La cadena lateral de envío original puede procesar esto y, por ejemplo, revertirlo. En general, el manejo de errores de la cadena principal permite que las cadenas laterales envíen mensajes sin monitorear el estado de otras cadenas.

Figura 3: Un ejemplo de manejo de errores de la cadena principal. Una transacción de cadena cruzada T en la cadena lateral A crea un mensaje M de cadena cruzada . El mensaje de cadena cruzada se incluye en una actualización de cadena cruzada CCU 1 que se publica en la cadena principal. Aquí se procesa, sin embargo, por ejemplo, se ha terminado la cadena de recepción. Por lo tanto, se crea un nuevo mensaje de error M err y se envía de vuelta a la cadena lateral A. Se incluye en otra CCU 2 de actualización de cadena cruzada que se publica en la cadena lateral A, donde se puede revertir

Manejo de errores de cadena lateral : por otro lado, a veces un mensaje de cadena cruzada puede tener errores solo una vez que llega a la cadena de recepción. Como se mencionó anteriormente, el módulo de interoperabilidad proporciona los códigos de error predefinidos MODULE_NOT_SUPPORTED y CROSS_CHAIN_COMMAND_NOT_SUPPORTED . Además, los módulos personalizados pueden introducir nuevos códigos de error.


Figura 4: Un ejemplo de manejo de errores de cadena lateral. Una transacción de cadena cruzada T en la cadena lateral A crea un mensaje M de cadena cruzada El mensaje de cadena cruzada se incluye en una actualización de cadena cruzada CCU 1 que se publica en la cadena principal y luego se reenvía a la cadena lateral B. Luego se incluye en una segunda actualización CCU 2 de cadena cruzada que se publica en la cadena lateral B. En la cadena lateral B se procesa pero, por ejemplo, el ID del módulo corresponde a un módulo no admitido. Por lo tanto, se crea un nuevo mensaje de error err y se envía de vuelta a la cadena lateral A. Esto se incluye en otra actualización de cadena cruzada CCU 3que se publica en la cadena principal y luego se enruta hacia la cadena lateral B. Finalmente, se incluye en la actualización final de la cadena cruzada CCU 4 y se publica en la cadena lateral B, donde se puede revertir.

 

Seguimiento de mensajes : todos los mensajes se identifican de forma única en el ecosistema mediante la tupla (sendChainID, nonce) . Los mensajes que se han devuelto desde la cadena principal con el estado CHANNEL_UNAVAILABLE se identifican en cambio por la tupla (ReceiveChainID, nonce) , ya que los ID de la cadena de envío y recepción se han intercambiado. Esta propiedad es muy útil para rastrear mensajes en todo el ecosistema, por ejemplo, usando una herramienta de interfaz de usuario. Además, al igual que para las transacciones, definimos el ID de mensaje de cadena cruzada como el hash del objeto de mensaje serializado.

Es más fácil seguir el camino de un mensaje de cadena cruzada en el ecosistema con dos ejemplos concretos. Observe que en ambos ejemplos, el usuario que inicia el proceso, Alice, solo tiene que preocuparse por enviar el comando de cadena cruzada inicial. Desde su punto de vista, todo lo demás sucede automágicamente.

Transferencia LSK de cadena principal a cadena lateral

Podría decirse que el mensaje de cadena cruzada más importante, y uno que muchos usuarios realmente usarán, es la transferencia LSK de cadena cruzada .

LSK son los tokens nativos de la cadena principal de Lisk. Esto significa que originalmente todas las LSK se almacenan en la cadena principal. Los tokens LSK se utilizan para impulsar la interoperabilidad: todas las tarifas de mensajes entre cadenas se pagan en LSK, y las actualizaciones entre cadenas publicadas en la cadena principal pagan una tarifa en LSK (como cualquier otra transacción de la cadena principal). Por lo tanto, los usuarios deben mover su LSK a una cadena lateral para comenzar a enviar comandos entre cadenas desde allí. El primer paso es enviar un comando de transferencia LSK entre cadenas en la cadena principal, apuntando a la cadena lateral.

 

Alice tiene 10 LSK en la cadena principal de Lisk y quiere enviar 5 LSK a su cuenta en la cadena lateral A. El proceso completo de transferencia de LSK de la cadena principal a una cadena lateral se ve así:

1. Alice envía un comando de transferencia LSK entre cadenas con los siguientes parámetros:

{

  tokenID = {"chainID": 1, "localID": 0} : el ID del token LSK

  cantidad = 5 : la cantidad de LSK a transferir

  ivingChainID = 16 : el ID de la cadena lateral A

  destinatarioAddress = 0x0a11ce : dirección de Alice

  data = "": Alice podría agregar un mensaje personalizado en este campo

  messageFee = 0.01 : la tarifa asociada al mensaje

}

2. A Alice se le cargan las 5 LSK en la cadena principal.

3. El comando genera un mensaje entre cadenas con los siguientes parámetros:

{

  nonce = 21 : en este ejemplo, el nonce de la cadena principal actual

  moduleID = MODULE_ID_TOKEN : ID del módulo token

  crossChainCommandID = 0 : ID del comando de cadena cruzada de transferencia de token

  sendChainID = 1 : ID de la cadena principal Lisk

  ReceiveChainID = 16 : ID de la cadena lateral A

  tarifa = 0.01 : tarifa de mensaje especificada en el comando

  status = OK : estado predeterminado de un mensaje entre cadenas

  params = {

              tokenID = {"chainID": 1, "localID": 0} =

              cantidad = 5

              senderAddress = 0x0a11ce

              destinatarioDirección = 0x0a11ce

              datos = ""

           }: estos parámetros corresponden a los parámetros del comando

}

4. El mensaje de cadena cruzada se agrega a la bandeja de salida de la cadena lateral A.

5. El mensaje de cadena cruzada se incluye en una actualización de cadena cruzada publicada en la cadena lateral A.

6. La actualización de la cadena cruzada se procesa en la cadena lateral A. El mensaje de la cadena cruzada se agrega a la bandeja de entrada de la cadena principal y tiene su efecto. A Alice se le atribuyen 5 LSK en la cadena lateral A. 🎉

Mensaje personalizado de cadena lateral a cadena lateral

Los mensajes de cadena lateral a cadena lateral son el humus en el que puede florecer un ecosistema de interoperabilidad rico. La interoperabilidad de Lisk proporciona el protocolo general para el intercambio de mensajes, pero la verdadera diversión ocurre con los comandos y mensajes personalizados de cadena cruzada que los desarrolladores crean para las aplicaciones de cadena de bloques. Como se mencionó anteriormente, la cadena principal no procesa mensajes personalizados entre cadenas, sino que solo los enruta sin siquiera mirarlos.

Alice decide enviar un mensaje de cadena cruzada desde la cadena lateral A a la cadena lateral B. El efecto de este mensaje en la cadena lateral B es parte de su protocolo, y aquí no nos importa la funcionalidad específica, solo el procedimiento general.

1. Alice envía una transacción personalizada entre cadenas con algunos parámetros personalizados.

2. El comando se procesa en la cadena lateral A.

3. El comando genera un mensaje entre cadenas con los siguientes parámetros:

{

  nonce = 22 : en este ejemplo, la cadena lateral actual A nonce

  moduleID = 1034 : ID del módulo personalizado

  crossChainCommandID = 2 : ID del comando de cadena cruzada personalizado

  sendChainID = 16 : ID de la cadena lateral A

  ReceiveChainID = 42 : ID de la cadena lateral B

  fee = messageFee : tarifa de mensaje especificada en el comando

  status = OK : estado predeterminado de un mensaje entre cadenas

  params : parámetros personalizados del mensaje entre cadenas

}

4. El mensaje entre cadenas se agrega a la bandeja de salida de la cadena principal.

5. El mensaje de cadena cruzada se incluye en una actualización de cadena cruzada publicada en la cadena principal.

6. La actualización entre cadenas se procesa en la cadena principal. El mensaje de cadena cruzada se agrega a la bandeja de entrada de la cadena lateral A e inmediatamente se agrega a la bandeja de salida de la cadena lateral B.

7. El mensaje de cadena cruzada se incluye en una actualización de cadena cruzada publicada en la cadena lateral B.

8. La actualización de la cadena cruzada se procesa en la cadena lateral B. El mensaje de la cadena cruzada se agrega a la bandeja de entrada de la cadena principal y tiene su efecto en la cadena lateral B.

9. ¡Algo salió mal! Se produjo un error durante el procesamiento del mensaje, por ejemplo, la cadena lateral B no admite el ID de comando de cadena cruzada. Luego se crea un nuevo mensaje:

{

  nonce = 31 : en este ejemplo, la cadena lateral actual B nonce

  moduleID = 34 : ID del módulo personalizado

  crossChainCommandID = 2 : ID del comando de cadena cruzada personalizado

  sendChainID = 42 : ID de la cadena lateral B

  ReceiveChainID = 16 : ID de la cadena lateral A

  fee = 0 : la tarifa del mensaje se establece en 0, nadie paga por el error

  status = CROSS_CHAIN_COMMAND_NOT_SUPPORTED : estado de error para comando de cadena cruzada no válido

  params : parámetros personalizados del mensaje entre cadenas

}

10. El mensaje de error se agrega a la bandeja de salida de mainchain.

11. El mensaje de cadena cruzada se incluye en una actualización de cadena cruzada publicada en la cadena principal.

12. La actualización entre cadenas se procesa en la cadena principal. El mensaje de cadena cruzada se agrega a la bandeja de entrada de la cadena lateral B e inmediatamente se agrega a la bandeja de salida de la cadena lateral A.

13. El mensaje de cadena cruzada se incluye en una actualización de cadena cruzada publicada en la cadena lateral A.

14. La actualización de la cadena cruzada se procesa en la cadena lateral A. El mensaje de la cadena cruzada se agrega a la bandeja de entrada de la cadena principal y tiene su efecto en la cadena lateral A. En particular, el código de error se utiliza para activar la lógica de procesamiento correcta (por ejemplo, el mensaje podría simplemente revertirse).

Conclusión y próximo tema

Esta publicación de blog ha presentado los mensajes entre cadenas en detalle. Discutimos el procedimiento general para enviar un mensaje de cadena cruzada entre dos cadenas interoperables y describimos el formato de un mensaje de cadena cruzada. El módulo de interoperabilidad contendrá 4 mensajes estándar por defecto, mientras que el módulo Token permite la transferencia de tokens estándar entre cadenas con el comando de transferencia de token entre cadenas. Los módulos personalizados pueden implementar nuevos comandos de cadena cruzada de manera similar a los comandos personalizados normales. Los detalles del módulo Token se presentarán en la próxima publicación del blog.

Si desea profundizar más en las especificaciones técnicas, puede ver nuestro foro de investigación, en particular en el LIP "Introducir mensajes entre cadenas" . Esperamos sus comentarios sobre la solución de interoperabilidad Lisk en el foro Lisk Research.


Fuente: blog de Lisk

    

  En esta edición de la serie en curso que cubre la solución de interoperabilidad Lisk, discutimos la sal y la pimienta de la interoperabili...