Substrate: del runtime al consenso propio

Artículo 16 de 20

80%

completado al llegar aquí

Sistemas distribuidosNota de investigación18 min de lectura

XCM: un lenguaje de intenciones entre sistemas de consenso

Qué es XCM en el Polkadot SDK: programas que ejecuta la XCVM, ubicaciones relativas, reserva frente a teletransporte y la confianza que fija el executor.

Ruta Substrate: 0/20

Dos equipos operan parachains distintas sobre la misma relay chain. El primero emite un token de fidelidad; el segundo quiere aceptarlo como pago. Nadie quiere copiar el código del otro ni compartir claves. La pregunta del segundo equipo es concreta: cuando llegue un mensaje que diga "deposita 100 unidades en la cuenta de Bob", ¿por qué habría de creerle? ¿Quién respalda esas 100 unidades?

Este capítulo responde esa pregunta con XCM (Cross-Consensus Messaging), el formato de mensajes del Polkadot SDK. Al terminar deberías poder leer un programa XCM, distinguir una transferencia por reserva de un teletransporte y señalar en la configuración del runtime el lugar exacto donde una cadena decide en quién confía.

Brújula de lectura

Actor, evidencia y estado

Antes de avanzar, ubica quién actúa, qué prueba queda y qué parte del sistema cambia.

Actor

La XCVM de la cadena receptora

El executor del runtime destino interpreta el programa; la cadena origen solo lo envía.

Evidencia

El origen del mensaje y la configuración del executor

No viaja una prueba criptográfica del activo: la cadena receptora decide si confía en el origen.

Estado

Saldos en las dos cadenas y el Holding Register

Los activos pasan por un registro temporal de la XCVM antes de llegar al beneficiario.

Preguntas guía

  • ¿Por qué XCM se define como un lenguaje y no como un protocolo de red?
  • ¿Qué hace la XCVM con cada instrucción y dónde quedan los activos mientras tanto?
  • ¿Qué diferencia de confianza hay entre una transferencia por reserva y un teletransporte?
  • ¿En qué tipos del executor se declara esa confianza?

Conexiones dentro de la serie

  • Antes: Parachains con Cumulus explica cómo una parachain hereda la seguridad de la relay chain. Extrinsics explica cómo entra una orden firmada en un runtime; XCM es la forma de que esa orden cruce a otra cadena.
  • Después: Sassafras vuelve al consenso de producción de bloques, y BEEFY trata la mitad que XCM no resuelve: probar finalidad ante una cadena externa.
  • Riesgo entre cadenas: Puentes y riesgo cross-chain en Ethereum explica de dónde vienen las pérdidas cuando dos sistemas confían mal el uno en el otro.

Un lenguaje, no un transporte

La documentación del SDK define XCM sin rodeos: "XCM, or Cross-Consensus Messaging, is a language to communicate intentions between consensus systems." Tres palabras pesan en esa frase. Lenguaje: hay una sintaxis y una semántica. Intenciones: el mensaje expresa lo que el emisor quiere, no lo que el receptor está obligado a hacer. Sistemas de consenso: el destinatario puede ser una cadena, un pallet o una cuenta, no solo otra parachain.

La guía de Polkadot Docs lo dice desde el ángulo contrario: "XCM is not a protocol but a standardized messaging format". El formato define la estructura y el comportamiento de los mensajes, pero no su entrega. Esa separación es la idea central del capítulo.

Una analogía útil es una orden de pago escrita en un idioma común. El idioma no dice si la carta viaja por correo o por mensajero, ni obliga al banco receptor a pagar. El banco paga si reconoce al remitente y si la orden tiene sentido según sus propias reglas. XCM funciona igual: el programa es la carta, el canal entre cadenas es el correo y la configuración del runtime receptor es la política del banco.

La misma guía enumera cuatro principios: asíncrono, absoluto, asimétrico y agnóstico. El tercero tiene consecuencias de diseño: un mensaje es "fire and forget" y el emisor no recibe respuesta automática. Si necesitas saber cómo terminó, el destino tiene que enviar otro mensaje de vuelta. El segundo, la garantía de entrega ordenada y oportuna, es una afirmación de la documentación sobre el ecosistema Polkadot, no una propiedad del formato; depende del transporte concreto y queda a validar para cada canal.

La XCVM y el Holding Register

"XCM is executed on a virtual machine called the XCVM." Un programa XCM es una lista de instrucciones que la máquina ejecuta una tras otra. La máquina tiene registros; el más importante para activos es el Holding Register, un lugar temporal donde quedan los activos entre una instrucción y la siguiente.

El ejemplo canónico del SDK es una transferencia local en tres pasos. El fragmento viene de docs/sdk/src/polkadot_sdk/xcm.rs, sin cambios salvo el comentario:

rust
// Fragmento de docs/sdk/src/polkadot_sdk/xcm.rs (polkadot-sdk)
let _transfer_program = Xcm::<()>(vec![
    WithdrawAsset((Here, 100u128).into()),
    BuyExecution { fees: (Here, 100u128).into(), weight_limit: Unlimited },
    DepositAsset {
        assets: All.into(),
        beneficiary: AccountId32 { id: [0u8; 32].into(), network: None }.into(),
    },
]);

WithdrawAsset saca activos de la cuenta del origen y los pone en el Holding Register. BuyExecution usa parte de esos activos para pagar el peso de ejecución, el mismo concepto de pesos y comisiones que ya conoces. DepositAsset mueve lo que queda a la cuenta del beneficiario. El orden importa: sin BuyExecution, el destino no tiene por qué gastar cómputo en tu programa.

Las instrucciones no las inventa cada cadena. El tipo Instruction vive en el crate xcm, y en el código actual latest apunta a la versión 5 del formato. Qué versión acepta una cadena concreta en producción es una decisión de su runtime y queda a validar caso por caso.

El SDK reparte la implementación en piezas con nombre propio: xcm define tipos e instrucciones, xcm_executor implementa la máquina virtual, pallet_xcm es el pallet FRAME que permite a los usuarios interactuar con el executor y xcm_builder reúne tipos para configurarlo. Para un ingeniero de runtime, la pieza que más decisiones contiene es la configuración del executor, que veremos más abajo.

Ubicaciones: direcciones relativas

Para decir "la cuenta de Bob en la parachain 2000" hace falta un sistema de direcciones. XCM usa Location, que el código describe como "A relative path between state-bearing consensus systems."

Una ubicación tiene dos partes. Primero, un número de parents: cuántas veces hay que subir al sistema que contiene al actual. Después, una lista de junctions: los pasos para bajar dentro de ese sistema hasta una parte concreta del estado. Desde una parachain, (1, [Parachain(2000)]) significa "sube a la relay chain y baja a la parachain 2000". Desde la relay chain, la misma parachain es (0, [Parachain(2000)]).

La consecuencia práctica es que una ubicación no es un identificador universal. El código lo advierte: no puede usarse en general para referirse a una ubicación de forma universal. Un error frecuente al empezar es copiar una ubicación escrita desde el punto de vista de una cadena y usarla en otra. La transferencia no se pierde: se dirige a otro lugar o falla.

Here, que aparece en el ejemplo anterior, es la ubicación vacía: el propio sistema que interpreta el mensaje. Por eso (Here, 100u128) significa "100 unidades del activo nativo de esta cadena". El mismo activo, visto desde otra parachain, tendría otra ubicación.

Reserva frente a teletransporte

Mover un activo entre cadenas que no comparten estado obliga a elegir un modelo de confianza. XCM ofrece dos, y la diferencia está escrita en las notas de seguridad de dos instrucciones.

En una transferencia por reserva, una cadena R guarda el activo real y las demás tienen derivados respaldados por él. Cuando llega ReserveAssetDeposited, el código exige: "origin must be trusted to have received and be storing assets such that they may later be withdrawn should this system send a corresponding message." Es decir, la cadena destino acuña un derivado porque confía en que la reserva custodia el original.

En un teletransporte, el origen destruye el activo y el destino lo crea de nuevo. La instrucción ReceiveTeleportedAsset exige que "origin must be trusted to have irrevocably destroyed the corresponding assets prior as a consequence of sending this message." Si el origen miente, el destino emite activos sin respaldo. Por eso el teletransporte solo tiene sentido entre cadenas que confían plenamente la una en la otra.

Figura 1

Formato, transporte y confianza en XCM

Fuentes:

[1][3][6]
Formato, transporte y confianza en XCM
Cómo leer esta figura

Fila superior: tres cajas conectadas por flechas, Formato (programa XCM con instrucciones en orden), Transporte (canal entre cadenas, por ejemplo HRMP) y Confianza (configuración del executor con IsReserve, IsTeleporter y Barrier). Abajo a la izquierda, tres instrucciones apiladas: WithdrawAsset lleva del origen al Holding, BuyExecution paga el peso con el Holding y DepositAsset lleva del Holding al beneficiario. Abajo a la derecha, dos carriles. En el de reserva, la cadena A pide a la reserva R, que guarda el activo real, y R avisa a la cadena B, que acuña un derivado; B confía en que R guarda y respalda el activo. En el de teletransporte, la cadena A quema el activo y avisa directamente a la cadena B, que crea el mismo activo; B confía en que A lo destruyó.

Visual original de TrautsLab. XCM define el formato; el canal lo transporta; la configuración del executor decide en quién confiar. Abajo, el programa de transferencia del SDK y los dos modelos para mover un activo entre cadenas.

pallet-xcm expone ambos caminos a los usuarios: limited_reserve_transfer_assets y limited_teleport_assets, entre otras llamadas. Ambas llevan la misma advertencia: si la ejecución remota necesita más peso que weight_limit, "the operation will fail and the sent assets may be at risk." No es un detalle de interfaz: un límite mal calculado puede dejar activos atrapados en el destino.

Lectura crítica

Qué modelo de transferencia usar

Recomendado

Reserva

Una cadena custodia el activo real; las demás tienen derivados.

Ideal para
Activos cuyo emisor no confía plenamente en las cadenas destino.
Ojo con
Si la reserva falla o es comprometida, todos los derivados quedan sin respaldo.
Precaución

Teletransporte

El origen quema y el destino acuña el mismo activo.

Ideal para
Cadenas con el mismo gobierno o con confianza total entre ellas.
Ojo con
Un origen deshonesto o con un bug puede crear activos de la nada en el destino.

No aceptar el activo

El executor no declara ni reserva ni teletransportador para ese activo.

Ideal para
Activos de origen desconocido o sin necesidad de negocio.
Ojo con
Los usuarios verán mensajes rechazados; documenta la política.
La elección no es de rendimiento sino de confianza: quién tiene que decir la verdad para que el activo exista una sola vez.

Dónde se declara la confianza: el executor

La confianza no se negocia en cada mensaje. Se fija en la configuración del executor, el tipo que el runtime entrega a XcmExecutor. Tres entradas de xcm-executor/src/config.rs concentran las decisiones de seguridad:

  • IsReserve: "Combinations of (Asset, Location) pairs which we trust as reserves."
  • IsTeleporter: "Combinations of (Asset, Location) pairs which we trust as teleporters."
  • Barrier: "Whether we should execute the given XCM at all."

Leídas juntas, responden la pregunta del escenario inicial. La parachain del segundo equipo acepta el token de fidelidad solo si su IsReserve incluye el par (token, parachain emisora). Si no lo incluye, ReserveAssetDeposited falla aunque el mensaje esté bien formado. Y antes de eso, la barrera decide si el programa se ejecuta siquiera; un patrón habitual es exigir que el programa pague su ejecución, como hace la barrera AllowTopLevelPaidExecutionFrom de xcm_builder.

El Trader completa el cuadro: define cómo se compra peso con activos, es decir, qué precio cobra tu cadena por ejecutar mensajes ajenos. Un Trader que acepta cualquier activo como pago abre la puerta a programas que consumen cómputo pagando con algo sin valor.

Para quien diseña el runtime, la revisión de seguridad de XCM es la revisión de estos tipos. El formato y el canal son comunes a todo el ecosistema; la política es tuya.

Lista de verificación

Revisión de un executor antes de abrir un canal

0 de 5 revisados

El canal: lo que XCM no define

Si XCM es el idioma, alguien tiene que llevar la carta. Entre parachains, Polkadot Docs describe el protocolo HRMP (Horizontal Relay-routed Message Passing): una parachain solicita un canal, la otra lo acepta, y el resultado es "a unidirectional HRMP channel, where messages can flow in only one direction between the two parachains." Para comunicarse en los dos sentidos hacen falta dos canales.

Hay un detalle recursivo que ayuda a entender la separación de capas: la propia solicitud del canal se envía como un mensaje XCM a la relay chain, con Transact para invocar hrmpInitOpenChannel. El formato es el mismo; lo que cambia es quién lo recibe y qué llamada autoriza.

Otros transportes (mensajes hacia arriba y hacia abajo entre parachain y relay chain, o el futuro XCMP) no se investigaron en fuentes primarias para este capítulo; sus detalles quedan a validar. Lo que sí es estable es la regla de diseño: cambiar el canal no cambia el significado del programa ni la política del executor.

Para mensajes hacia fuera del ecosistema, Polkadot Docs señala que XCM opera dentro de Polkadot y que los puentes extienden esa función a cadenas externas como Ethereum. Un puente necesita algo que XCM no aporta: una prueba verificable de que el bloque de origen es final. Ese es el tema de BEEFY.

Qué cambia respecto de Ethereum

Quien viene de la ruta de Ethereum conoce dos patrones: llamadas entre contratos dentro de la misma cadena, que son síncronas y atómicas, y puentes entre cadenas, que son asíncronos y dependen de quién verifica qué. XCM se parece al segundo patrón, no al primero.

Comparación

Mensajes entre sistemas: Ethereum frente a XCM

La comparación es de modelo mental; los detalles de cada puente concreto varían.

Llamada entre contratos en Ethereum

Misma cadena, mismo estado, una sola transacción.

  • Síncrona: el llamador recibe el resultado.
  • Atómica: si algo falla, todo revierte.
  • Confianza: la del propio consenso de Ethereum.

Puente desde Ethereum

Dos consensos distintos, un contrato verifica mensajes.

  • Asíncrono.
  • La seguridad depende de quién atestigua el mensaje.
  • Formato propio de cada puente.

XCM entre parachains

Consensos separados que comparten relay chain y formato.

  • Asíncrono y sin respuesta automática.
  • La confianza se declara en el executor del receptor.
  • Formato común a todas las cadenas que implementan la XCVM.

La consecuencia más importante para quien llega desde Ethereum es la falta de atomicidad. Un programa XCM que retira en la cadena A y deposita en la cadena B no revierte la primera parte si la segunda falla. Diseñar flujos entre cadenas exige pensar en estados intermedios, reintentos y activos atrapados, igual que en un puente.

Laboratorio propuesto

Estado: propuesta. Este laboratorio todavía no está publicado en lab.trautslab.dev; describe lo que se construirá, en local, sin red pública ni fondos reales.

Objetivo. Ver una transferencia por reserva entre dos parachains locales y reconocer, en un fallo provocado, qué parte del executor lo causó.

Pasos propuestos.

  1. Extender la red de zombienet del laboratorio de Parachains con Cumulus con una segunda parachain y abrir un canal HRMP en cada sentido.
  2. Enviar una transferencia de reserva con pallet-xcm y seguir los eventos en las dos cadenas y en la relay chain.
  3. Quitar a propósito la entrada de la reserva en IsReserve del runtime receptor, repetir el envío y leer el error que emite el executor.

Evidencia esperada. En el paso 2, un evento de envío en la cadena origen y uno de ejecución completa en la destino, con el saldo del beneficiario aumentado en el importe menos la comisión. En el paso 3, un evento de ejecución fallida en la cadena destino y ningún saldo nuevo para el beneficiario. Los nombres exactos de eventos y errores dependen de la versión del SDK y de XCM, y quedan a validar al construir el laboratorio.

Referencias

Bibliografía académica

Formato IEEENumerado para ingeniería, sistemas y protocolos.
  1. [1]

    Parity Technologies, "polkadot_sdk_docs: XCM," polkadot-sdk, docs/sdk/src/polkadot_sdk/xcm.rs, commit 544e829, 2026.

    Definición de XCM, la XCVM, componentes (xcm, xcm-executor, pallet-xcm, xcm-builder) y un programa de transferencia.

  2. [2]

    Polkadot Developers, "Get Started with XCM," polkadot-docs, docs/parachains/interoperability/get-started.md, 2026.

    docsID: DOCS-XCM-GET-STARTEDAbrir fuente (abre en otra pestaña)

    XCM como formato y no protocolo, los cuatro principios y el ejemplo WithdrawAsset, BuyExecution, DepositAsset.

  3. [3]

    Parity Technologies, "xcm: Version 5 of the Cross-Consensus Message format," polkadot-sdk, polkadot/xcm/src/v5/mod.rs, commit 544e829, 2026.

    Definición de instrucciones (WithdrawAsset, ReserveAssetDeposited, ReceiveTeleportedAsset, BuyExecution, DepositAsset) y sus notas de seguridad.

  4. [4]

    Parity Technologies, "xcm v5: Location," polkadot-sdk, polkadot/xcm/src/v5/location.rs, commit 544e829, 2026.

    source codeID: SDK-XCM-LOCATIONAbrir fuente (abre en otra pestaña)

    Location como ruta relativa: número de padres más junctions; ejemplos de ubicaciones.

  5. [5]

    Parity Technologies, "pallet-xcm," polkadot-sdk, polkadot/xcm/pallet-xcm/src/lib.rs, commit 544e829, 2026.

    source codeID: SDK-PALLET-XCMAbrir fuente (abre en otra pestaña)

    Llamadas send, execute, limited_reserve_transfer_assets y limited_teleport_assets; advertencia sobre weight_limit.

  6. [6]

    Parity Technologies, "xcm-executor: Config," polkadot-sdk, polkadot/xcm/xcm-executor/src/config.rs, commit 544e829, 2026.

    source codeID: SDK-XCM-EXECUTOR-CONFIGAbrir fuente (abre en otra pestaña)

    Tipos asociados del executor: IsReserve, IsTeleporter, Barrier, Trader y otros.

  7. [7]

    Polkadot Developers, "Opening HRMP Channels Between Parachains," polkadot-docs, docs/parachains/interoperability/channels-between-parachains.md, 2026.

    Apertura de canales HRMP: solicitud, aceptación, canales unidireccionales.

  8. [8]

    Polkadot Developers, "Interoperability," polkadot-docs, docs/reference/parachains/interoperability.md, 2026.

    XCM como marco estándar de interacción y puentes hacia redes externas.

Fuentes primarias, papers seminales y especificaciones técnicas citadas en esta investigación.

Rutas vecinas

Si este tema te abrió hambre, sigue por aquí.

Series y labs que comparten área o dependen de esta ruta. Pocas opciones, para no convertir la curiosidad en menú infinito.

Sigue leyendo

Ideas conectadas con este artículo

Una ruta corta para continuar sin abrir veinte pestañas y perder el hilo.

Los comentarios se cargan al final de la lectura para no meter peso antes de tiempo.