Ir para o conteúdo

Transferências Nativas de Tokens Entre Cadeias

Introdução

Como apresentado no artigo sobre Comunicação Nativa Entre Cadeias na seção Learn, redes powered by Tanssi contam com a capacidade nativa de se comunicar e interoperar com qualquer outra rede do ecossistema. Essa comunicação entre cadeias permite transferências de tokens seguras e rápidas usando o formato Cross-Consensus Message (XCM), que facilita a comunicação entre diferentes sistemas de consenso.

O protocolo de comunicação que possibilita as transferências é construído sobre o Substrate e opera em um nível mais baixo que o EVM, o que dificulta o acesso direto para desenvolvedores EVM.

Ainda assim, redes EVM contam com um precompile XCM que preenche a lacuna entre as camadas de execução, expondo uma interface de smart contract que abstrai as complexidades subjacentes e torna a execução de transferências cross-chain tão simples quanto qualquer chamada de contrato.

Este guia mostra como interagir com o precompile XCM Interface para executar transferências de tokens entre cadeias via Ethereum API.

O precompile XCM está localizado no seguinte endereço:

0x0000000000000000000000000000000000000804

Note

O uso de precompiladas pode trazer consequências inesperadas. As precompiladas do Tanssi são derivadas das do Moonbeam; portanto, familiarize-se com as considerações de segurança das precompiladas do Moonbeam.

A Interface Solidity XCM

A interface XCMInterface.sol nas redes EVM da Tanssi é uma interface Solidity que permite aos desenvolvedores interagir com as funções do precompile.

XCMInterface.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.3;

/// @dev The XCM contract's address.
address constant XCM_CONTRACT_ADDRESS = 0x0000000000000000000000000000000000000804;

/// @dev The XCM contract's instance.
XCM constant XCM_CONTRACT = XCM(XCM_CONTRACT_ADDRESS);

/// @author The Moonbeam Team
/// @title XCM precompile Interface
/// @dev The interface that Solidity contracts use to interact with the substrate pallet-xcm.
interface XCM {
    // A location is defined by its number of parents and the encoded junctions (interior)
    struct Location {
        uint8 parents;
        bytes[] interior;
    }

    // Support for Weights V2
    struct Weight {
        uint64 refTime;
        uint64 proofSize;
    }

    // A way to represent fungible assets in XCM using Location format
    struct AssetLocationInfo {
        Location location;
        uint256 amount;
    }

    // A way to represent fungible assets in XCM using address format
    struct AssetAddressInfo {
        address asset;
        uint256 amount;
    }

    /// @dev Function to send assets via XCM using transfer_assets() pallet-xcm extrinsic.
    /// @custom:selector 59df8416
    /// @param dest The destination chain.
    /// @param beneficiary The actual account that will receive the tokens on dest.
    /// @param assets The combination (array) of assets to send.
    /// @param feeAssetItem The index of the asset that will be used to pay for fees.
    /// @param weight The weight to be used for the whole XCM operation.
    /// (uint64::MAX in refTime means Unlimited weight) 
    function transferAssetsLocation(
        Location memory dest,
        Location memory beneficiary,
        AssetLocationInfo[] memory assets,
        uint32 feeAssetItem,
        Weight memory weight
    ) external;

    /// @dev Function to send assets via XCM to a 20 byte-like parachain 
    /// using transfer_assets() pallet-xcm extrinsic.
    /// @custom:selector b489262e
    /// @param paraId The para-id of the destination chain.
    /// @param beneficiary The actual account that will receive the tokens on paraId destination.
    /// @param assets The combination (array) of assets to send.
    /// @param feeAssetItem The index of the asset that will be used to pay for fees.
    /// @param weight The weight to be used for the whole XCM operation.
    /// (uint64::MAX in refTime means Unlimited weight)
    function transferAssetsToPara20(
        uint32 paraId,
        address beneficiary,
        AssetAddressInfo[] memory assets,
        uint32 feeAssetItem,
        Weight memory weight
    ) external;

    /// @dev Function to send assets via XCM to a 32 byte-like parachain 
    /// using transfer_assets() pallet-xcm extrinsic.
    /// @custom:selector 4461e6f5
    /// @param paraId The para-id of the destination chain.
    /// @param beneficiary The actual account that will receive the tokens on paraId destination.
    /// @param assets The combination (array) of assets to send.
    /// @param feeAssetItem The index of the asset that will be used to pay for fees.
    /// @param weight The weight to be used for the whole XCM operation.
    /// (uint64::MAX in refTime means Unlimited weight)
    function transferAssetsToPara32(
        uint32 paraId,
        bytes32 beneficiary,
        AssetAddressInfo[] memory assets,
        uint32 feeAssetItem,
        Weight memory weight
    ) external;

    /// @dev Function to send assets via XCM to the relay chain 
    /// using transfer_assets() pallet-xcm extrinsic.
    /// @custom:selector d7c89659
    /// @param beneficiary The actual account that will receive the tokens on the relay chain.
    /// @param assets The combination (array) of assets to send.
    /// @param feeAssetItem The index of the asset that will be used to pay for fees.
    /// @param weight The weight to be used for the whole XCM operation.
    /// (uint64::MAX in refTime means Unlimited weight)
    function transferAssetsToRelay(
        bytes32 beneficiary,
        AssetAddressInfo[] memory assets,
        uint32 feeAssetItem,
        Weight memory weight
    ) external;
}

A interface inclui as estruturas de dados necessárias e as funções a seguir:

transferAssetsToPara20(paraId, beneficiary, assets, feeAssetItem, weight) — envia assets para outra rede compatível com EVM usando a transação transfer_assets() do pallet XCM
  • paraId uint32 - ID da rede de destino
  • beneficiary address - conta do tipo ECDSA na cadeia de destino que receberá os tokens
  • assets AssetAddressInfo[] memory - array de assets a enviar
  • feeAssetItem uint32 - índice do asset que pagará as taxas
  • weight Weight memory - gás máximo de toda a operação. Definir uint64::MAX em refTime equivale na prática a weight ilimitado
  • paraId - 888
  • beneficiary - 0x3f0Aef9Bd799F1291b80376aD57530D353ab0217
  • assets - [["0x0000000000000000000000000000000000000800", 1000000000000000000]]
  • feeAssetItem - 0
  • weight - [9223372036854775807, 9223372036854775807]
transferAssetsToPara32(paraId, beneficiary, assets,feeAssetItem, weight) — envia assets para uma rede Substrate usando a transação transfer_assets() do pallet XCM
  • paraId uint32 - ID da rede de destino
  • beneficiary bytes32 - conta do tipo SR25519 na cadeia de destino que receberá os tokens
  • assets AssetAddressInfo[] memory - array de assets a enviar
  • feeAssetItem uint32 - índice do asset que pagará as taxas
  • weight Weight memory - gás máximo de toda a operação. Definir uint64::MAX em refTime equivale na prática a weight ilimitado
  • paraId - 888
  • beneficiary - 0xf831d83025f527daeed39a644d64d335a4e627b5f4becc78fb67f05976889a06
  • assets - [["0x0000000000000000000000000000000000000800", 1000000000000000000]]
  • feeAssetItem - 0
  • weight - [9223372036854775807, 9223372036854775807]
transferAssetsToRelay(beneficiary, assets, feeAssetItem, weight) — envia assets para a relay chain usando a transação transfer_assets() do pallet XCM
  • beneficiary bytes32 - conta do tipo sr25519 na relay chain que receberá os tokens
  • assets AssetAddressInfo[] memory - array de assets a enviar
  • feeAssetItem uint32 - índice do asset que pagará as taxas
  • weight Weight memory - gás máximo de toda a operação. Definir uint64::MAX em refTime equivale na prática a weight ilimitado
  • beneficiary - 0xf831d83025f527daeed39a644d64d335a4e627b5f4becc78fb67f05976889a06
  • assets - [["0x0000000000000000000000000000000000000800", 1000000000000000000]]
  • feeAssetItem - 0
  • weight - [9223372036854775807, 9223372036854775807]
transferAssetsLocation(dest, beneficiary, assets, feeAssetItem, weight) — envia assets usando a transação transfer_assets() do pallet XCM
  • dest Location memory - cadeia de destino
  • beneficiary Location memory - conta na cadeia de destino que receberá os tokens
  • assets AssetLocationInfo[] memory - array de assets a enviar
  • feeAssetItem uint32 - índice do asset que pagará as taxas
  • weight Weight memory - gás máximo de toda a operação. Definir uint64::MAX em refTime equivale na prática a weight ilimitado
  • dest - ["1",[]]
  • beneficiary - [0, ["0x01f831d83025f527daeed39a644d64d335a4e627b5f4becc78fb67f05976889a0600"]]
  • assets - [[[1, ["0x010000000000000000000000000000000000000800"]], 1000000000000000000]]
  • feeAssetItem - 0
  • weight - [9223372036854775807, 9223372036854775807]

Interaja com a Interface Solidity

Verificando Pré-requisitos

Para acompanhar este tutorial, configure sua carteira para sua rede EVM e tenha uma conta com tokens nativos. Você pode adicionar sua rede EVM à MetaMask com um clique no Tanssi dApp. Ou configurar a MetaMask para a Tanssi com a rede EVM de demonstração.

Note

É necessário ter canais de comunicação estabelecidos com a cadeia de destino antes de usar a funcionalidade deste precompile. Para isso, consulte o guia Gerenciar Canais de Comunicação Entre Cadeias. Além disso, se o token transferido for nativo da sua rede, a cadeia de destino deve ter registrado o asset estrangeiro.

Configuração do Remix

Você pode interagir com o precompile XCM Interface usando o Remix. Para adicioná-lo ao Remix, siga:

  1. Obtenha uma cópia de XCMInterface.sol
  2. Cole o conteúdo em um arquivo do Remix chamado XcmInterface.sol

Compile o Contrato

Em seguida, compile a interface no Remix:

  1. Clique na aba Compile (segunda de cima)
  2. Clique em Compile XCMInterface.sol para compilar

Compiling XcmInterface.sol

Quando a compilação concluir, um check verde aparecerá ao lado da aba Compile.

Acesse o Contrato

Em vez de implantar o precompile, acesse a interface informando o endereço do contrato pré-compilado:

  1. Clique na aba Deploy and Run logo abaixo de Compile no Remix. Os contratos pré-compilados já estão acessíveis em seus endereços, portanto não há etapa de deployment
  2. Certifique-se de que Injected Provider - Metamask está selecionado em ENVIRONMENT. Ao selecionar, a MetaMask pode solicitar conexão com o Remix
  3. Garanta que a conta correta apareça em ACCOUNT
  4. Selecione XCM - XCMInterface.sol em CONTRACT. Como é um contrato pré-compilado, não há deployment; apenas informe o endereço do precompile no campo At Address
  5. Informe o endereço do precompile: 0x0000000000000000000000000000000000000804 e clique em At Address

Access the address

O precompile XCM Interface aparecerá em Deployed Contracts.

Envie tokens para outra rede compatível com EVM

Para enviar tokens a uma conta em outra rede compatível com EVM, siga:

  1. Expanda a função transferAssetsToPara20
  2. Informe o ID da rede (paraId)
  3. Informe a conta de destino (20 bytes, estilo Ethereum)
  4. Especifique os tokens a transferir. Este parâmetro é um array com pelo menos um asset; cada asset é definido por seu endereço e montante

    Note

    Os tokens são especificados pelo endereço ERC-20. Se o token que você deseja transferir for o nativo da rede, a precompilada ERC-20 do token nativo ajuda a referenciá-lo por meio de uma interface ERC-20.

  5. Informe o índice do asset que pagará as taxas (baseado em zero)

  6. Informe o gás máximo da transação, derivado de refTime e proofSize. Na prática, definir refTime como uint64::MAX equivale a weight ilimitado
  7. Clique em transact
  8. A MetaMask aparecerá para revisão; clique em Confirm para enviar

Confirm Approve Transaction

Após a confirmação, aguarde alguns blocos para o saldo aparecer na cadeia de destino.

Envie Tokens para uma Rede Substrate

Para enviar tokens a uma conta em uma rede Substrate, siga:

  1. Expanda a função transferAssetsToPara32
  2. Informe o ID da rede (paraId)
  3. Informe a conta de destino do tipo sr25519
  4. Especifique os tokens a transferir. Este parâmetro é um array com pelo menos um asset; cada asset é definido por seu endereço e montante

    Note

    Os tokens são especificados pelo endereço ERC-20. Se o token que você deseja transferir for o nativo da rede, a precompilada ERC-20 do token nativo ajuda a referenciá-lo por meio de uma interface ERC-20.

  5. Informe o índice do asset que pagará as taxas (baseado em zero)

  6. Informe o gás máximo da transação, derivado de refTime e proofSize. Na prática, definir refTime como uint64::MAX equivale a weight ilimitado
  7. Clique em transact
  8. A MetaMask aparecerá para revisão; clique em Confirm para enviar

Confirm Approve Transaction

Após a confirmação, aguarde alguns blocos para o saldo aparecer na cadeia de destino.

Envie Tokens para a Relay Chain

Para enviar tokens a uma conta na relay chain, siga:

  1. Expanda a função transferAssetsToRelay
  2. Informe a conta de destino do tipo sr25519
  3. Especifique os tokens a transferir. Este parâmetro é um array com pelo menos um asset; cada asset é definido por seu endereço e montante

    Note

    Os tokens são especificados pelo endereço ERC-20. Se o token que você deseja transferir for o nativo da rede, a precompilada ERC-20 do token nativo ajuda a referenciá-lo por meio de uma interface ERC-20.

  4. Informe o índice do asset que pagará as taxas (baseado em zero)

  5. Informe o gás máximo da transação, derivado de refTime e proofSize. Na prática, definir refTime como uint64::MAX equivale a weight ilimitado
  6. Clique em transact
  7. A MetaMask aparecerá para revisão; clique em Confirm para enviar

Confirm Approve Transaction

Após a confirmação, aguarde alguns blocos para o saldo aparecer na cadeia de destino.

Envie Tokens para Locais Específicos

Esta função é mais genérica e permite especificar cadeia de destino, conta e assets usando XCM Multilocations. Para enviar tokens para locais específicos:

  1. Expanda a função transferAssetsLocation
  2. Informe a multilocation que especifica a cadeia de destino. Qualquer cadeia pode ser informada, independentemente de tipo ou configuração
  3. Informe a multilocation que especifica a conta de destino. Qualquer conta pode ser informada, independentemente do tipo (ECDSA, sr25519 ou outro)
  4. Especifique os tokens a transferir. Este parâmetro é um array com pelo menos um asset; cada asset é definido por sua multilocation e montante

    Note

    Os tokens são especificados pelo endereço ERC-20. Se o token que você deseja transferir for o nativo da rede, a precompilada ERC-20 do token nativo ajuda a referenciá-lo por meio de uma interface ERC-20.

  5. Informe o índice do asset que pagará as taxas (baseado em zero)

  6. Informe o gás máximo da transação, derivado de refTime e proofSize. Na prática, definir refTime como uint64::MAX equivale a weight ilimitado
  7. Clique em transact
  8. A MetaMask aparecerá para revisão; clique em Confirm para enviar

Confirm Approve Transaction

Após a confirmação, aguarde alguns blocos para o saldo aparecer na cadeia de destino.

As informações apresentadas aqui foram fornecidas por terceiros e estão disponíveis apenas para fins informativos gerais. A Tanssi não endossa nenhum projeto listado e descrito no Site de Documentação da Tanssi (https://docs.tanssi.network/). A Tanssi Foundation não garante a precisão, integridade ou utilidade dessas informações. Qualquer confiança depositada nelas é de sua exclusiva responsabilidade. A Tanssi Foundation se exime de toda responsabilidade decorrente de qualquer confiança que você ou qualquer outra pessoa possa ter em qualquer parte deste conteúdo. Todas as declarações e/ou opiniões expressas nesses materiais são de responsabilidade exclusiva da pessoa ou entidade que as fornece e não representam necessariamente a opinião da Tanssi Foundation. As informações aqui não devem ser interpretadas como aconselhamento profissional ou financeiro de qualquer tipo. Sempre busque orientação de um profissional devidamente qualificado em relação a qualquer assunto ou circunstância em particular. As informações aqui podem conter links ou integração com outros sites operados ou conteúdo fornecido por terceiros, e tais sites podem apontar para este site. A Tanssi Foundation não tem controle sobre esses sites ou seu conteúdo e não terá responsabilidade decorrente ou relacionada a eles. A existência de qualquer link não constitui endosso desses sites, de seu conteúdo ou de seus operadores. Esses links são fornecidos apenas para sua conveniência, e você isenta e exonera a Tanssi Foundation de qualquer responsabilidade decorrente do uso dessas informações ou das informações fornecidas por qualquer site ou serviço de terceiros.
Última atualização: 23 de dezembro de 2025
| Criada: 27 de novembro de 2025