logoAcademy

Sending a Message

Learn to send messages with Avalanche Interchain Messaging.

Sending a message is nothing more than a simple contract call to the Interchain Messaging messenger contract.

The dApp on the Source Subnet has to call the sendCrossChainMessage function of the Interchain Messaging contract. The Interchain Messaging contract implements the ITeleporterMessenger interface below. Note that the dApp itself does not have to implement the interface.

/lib/teleporter/contracts/src/Teleporter/ITeleporterMessenger.sol
pragma solidity 0.8.18;
 
struct TeleporterMessageInput {
    bytes32 destinationBlockchainID;
    address destinationAddress;
    TeleporterFeeInfo feeInfo;
    uint256 requiredGasLimit;
    address[] allowedRelayerAddresses;
    bytes message;
}
 
struct TeleporterFeeInfo {
    address feeTokenAddress;
    uint256 amount;
}
 
/**
 * @dev Interface that describes functionalities for a cross chain messenger.
 */
interface ITeleporterMessenger {
    /**
     * @dev Emitted when sending a interchain message cross chain.
     */
 	event SendCrossChainMessage(
        uint256 indexed messageID,
        bytes32 indexed destinationBlockchainID,
        TeleporterMessage message,
        TeleporterFeeInfo feeInfo
    );
 
    /**
     * @dev Called by transactions to initiate the sending of a cross subnet message.
     */
	function sendCrossChainMessage(TeleporterMessageInput calldata messageInput)
        external
        returns (uint256);
 
}

The sendCrossChainMessage function takes TeleporterMessageInput struct as an input. In that multiple values are contained: This data will then be included in the payload of the Warp message:

  • destinationChainID: The chainID where the contract that should receive the message is deployed. This is not the EVM chain ID you may know from adding a network to a wallet, but the blockchain ID on the P-Chain. The P-Chain uses the transaction ID of the transaction that created those blockchain on the P-Chain for the chain ID, e.g.: 0xd7cdc6f08b167595d1577e24838113a88b1005b471a6c430d79c48b4c89cfc53
  • destinationAddress: The address of the contract that should receive the message
  • feeInfo: A struct consisting of a contract address of an ERC20 which the fee is paid in as well as the amount of tokens to be paid as an incentive for the relayer. We will look at this later in more detail.
  • requiredGasLimit: The amount of gas the delivery of the message requires. If the relayer provides the required gas, the message will be considered delivered whether or not its execution succeeds, such that the relayer can claim their fee reward.
  • allowedRelayerAddresses: An array of addresses of allowed relayers. An empty allowed relayers list means anyone is allowed to deliver the message. We will look at this later in more detail.
  • message: The message to be sent as bytes. The message can contain multiple encoded values. DApps using Interchain Messaging are responsible for defining the exact format of this payload in a way that can be decoded on the receiving end. The message can hold multiple values that be encoded in a single bytes object. For example, applications may encode multiple method parameters on the sending side, then decode this data in the contract implementing the receiveTeleporterMessage function and call another contract with the parameters from there.

title: Sending a Message description: Learn to send messages with Avalanche Interchain Messaging. updated: 2024-05-31 authors: [martineckardt] icon: Terminal

Sending a message is nothing more than a simple contract call to the Interchain Messaging messenger contract.

The dApp on the Source Avalanche L1 has to call the sendCrossChainMessage function of the Interchain Messaging contract. The Interchain Messaging contract implements the ITeleporterMessenger interface below. Note that the dApp itself does not have to implement the interface.

/lib/teleporter/contracts/src/Teleporter/ITeleporterMessenger.sol
pragma solidity 0.8.18;
 
struct TeleporterMessageInput {
    bytes32 destinationBlockchainID;
    address destinationAddress;
    TeleporterFeeInfo feeInfo;
    uint256 requiredGasLimit;
    address[] allowedRelayerAddresses;
    bytes message;
}
 
struct TeleporterFeeInfo {
    address feeTokenAddress;
    uint256 amount;
}
 
/**
 * @dev Interface that describes functionalities for a cross chain messenger.
 */
interface ITeleporterMessenger {
    /**
     * @dev Emitted when sending a interchain message cross chain.
     */
 	event SendCrossChainMessage(
        uint256 indexed messageID,
        bytes32 indexed destinationBlockchainID,
        TeleporterMessage message,
        TeleporterFeeInfo feeInfo
    );
 
    /**
     * @dev Called by transactions to initiate the sending of a cross subnet message.
     */
	function sendCrossChainMessage(TeleporterMessageInput calldata messageInput)
        external
        returns (uint256);
 
}

The sendCrossChainMessage function takes TeleporterMessageInput struct as an input. In that multiple values are contained: This data will then be included in the payload of the Warp message:

  • destinationChainID: The chainID where the contract that should receive the message is deployed. This is not the EVM chain ID you may know from adding a network to a wallet, but the blockchain ID on the P-Chain. The P-Chain uses the transaction ID of the transaction that created those blockchain on the P-Chain for the chain ID, e.g.: 0xd7cdc6f08b167595d1577e24838113a88b1005b471a6c430d79c48b4c89cfc53
  • destinationAddress: The address of the contract that should receive the message
  • feeInfo: A struct consisting of a contract address of an ERC20 which the fee is paid in as well as the amount of tokens to be paid as an incentive for the relayer. We will look at this later in more detail.
  • requiredGasLimit: The amount of gas the delivery of the message requires. If the relayer provides the required gas, the message will be considered delivered whether or not its execution succeeds, such that the relayer can claim their fee reward.
  • allowedRelayerAddresses: An array of addresses of allowed relayers. An empty allowed relayers list means anyone is allowed to deliver the message. We will look at this later in more detail.
  • message: The message to be sent as bytes. The message can contain multiple encoded values. DApps using Interchain Messaging are responsible for defining the exact format of this payload in a way that can be decoded on the receiving end. The message can hold multiple values that be encoded in a single bytes object. For example, applications may encode multiple method parameters on the sending side, then decode this data in the contract implementing the receiveTeleporterMessage function and call another contract with the parameters from there.
Updated:

On this page

Edit on Github