logoAcademy

Receiver Contract

Create a contract to receive messages with Teleporter.

Now it's time to deploy our receiver contract to our L1. It will implement the callback for the TeleporterMessenger contract when the message is received, decoding our message and storing the last received string.

Read the Receiver Contract

The following contract is located inside contracts/interchain-messaging/send-receive directory. Read through the contract below and and understand what is happening:

contracts/interchain-messaging/send-receive/receiverOnSubnet.sol
// (c) 2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
 
// SPDX-License-Identifier: Ecosystem
 
pragma solidity ^0.8.18;
 
import "@teleporter/ITeleporterMessenger.sol";
import "@teleporter/ITeleporterReceiver.sol";
 
contract ReceiverOnSubnet is ITeleporterReceiver {
    ITeleporterMessenger public immutable messenger = ITeleporterMessenger(0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf);
 
    string public lastMessage;
 
    function receiveTeleporterMessage(bytes32, address, bytes calldata message) external {
        // Only the Interchain Messaging receiver can deliver a message.
        require(msg.sender == address(messenger), "ReceiverOnSubnet: unauthorized TeleporterMessenger");
 
        // Store the message.
        lastMessage = abi.decode(message, (string));
    }
}

The key things to understand:

  • Importing Interchain Messaging contracts (L8, L9): We are importing the ITeleporterMessenger and ITeleporterReceiver interface we looked at in the previous activity.
  • Inheriting from ITeleporterReceiver (L11): We are inheriting the interface that will require us to implement the receiveTeleporterMessage() function.
  • Defining the lastMessage variable (L14): Setting the lastMessage variable as public, will make that variable readable from the outside without the need of a getValue function.
  • Implementing receiveTeleporterMessage (L16): We implement the function that will be called when the message is received. Please note that we are not checking who calls that function for now. So anyone can pretend to deliver messages for now.
  • Decode message (L21): We decode the message using abi.decode(message, (string)), which takes the bytes array as the first input and a tuple of the types of the encoded data in the message. Since our message only contains a single value, the tuple only has one value.

Deploy Receiver Contract

To deploy a contract using Foundry use the following command:

forge create --rpc-url myblockchain --private-key $PK contracts/interchain-messaging/send-receive/receiverOnSubnet.sol:ReceiverOnSubnet
[⠊] Compiling...
[⠢] Compiling 2 files with Solc 0.8.18
[⠆] Solc 0.8.18 finished in 158.51ms
Compiler run successful!
Deployer: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC
Deployed to: 0x52C84043CD9c865236f11d9Fc9F56aa003c1f922
Transaction hash: 0x48a1ffaa8aa8011f842147a908ff35a1ebfb75a5a07eb37ae96a4cc8d7feafd7

Save Receiver Contract Address

Then save the receiver contract address in an environment variable:

export RECEIVER_ADDRESS=0x52C84043CD9c865236f11d9Fc9F56aa003c1f922

On this page