SimpleMessageTest.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title IXTalkBeacon Interface
* @dev Interface for the XTalkBeacon contract.
* It defines the functions that this contract will interact with.
*/
// =================================================================================================
// ================================= XTalk Infrastructure Interface ================================
// =================================================================================================
interface IXTalkBeacon {
/**
* @dev Registers a message to be sent to a destination chain.
* @param _destinationChainId The chain ID of the destination chain.
* @param _destinationAddress The address of the contract on the destination chain.
* @param _messageData The data to be sent.
* @param _messageType The type of the message.
* @param _messageNonce The nonce for this message from the sender.
*/
function registerMessage(uint32 _destinationChainId, bytes32 _destinationAddress, bytes memory _messageData, uint32 _messageType, uint256 _messageNonce) external;
/**
* @dev Gets the next nonce for a sender.
* @param _sender The address of the sender.
* @return The next nonce.
*/
function getSenderRegistrationNextNonce(address _sender) external view returns (uint256);
/**
* @dev Generates a unique message ID.
* This can be used to track the message.
*/
function generateMessageId(uint32 _destinationChainId, bytes32 _destinationAddress, bytes memory _messageData, uint32 _messageType, uint256 _messageNonce) external view returns (bytes32);
}
/**
* @title SimpleMessageTest Contract
* @dev This contract is a simple example of how to use the XTalkBeacon to send and receive cross-chain messages.
* It allows invoking a message to a destination chain and handles received messages.
*/
contract SimpleMessageTest {
// =================================================================================================
// ================================= XTalk Infrastructure Setup ====================================
// =================================================================================================
address public immutable xtalkBeaconAddress;
// =================================================================================================
// ===================================== User-Defined Logic ========================================
// =================================================================================================
// Struct to store details of a received message.
struct Message {
bytes32 messageId;
address sourceInvokerAddress;
uint32 sourceChainId;
uint32 messageType;
bytes messageData;
}
// Mapping from messageId to the received Message struct.
mapping(bytes32 => Message) public receivedMessages;
/**
* @dev Emitted when a message is received from another chain.
*/
event MessageReceived(bytes32 indexed messageId, address sourceInvokerAddress, uint32 sourceChainId, uint32 messageType, bytes messageData);
// =================================================================================================
// ================================= XTalk Infrastructure Setup ====================================
// =================================================================================================
/**
* @dev Constructor to set the address of the XTalkBeacon contract.
* @param _beaconAddress The address of the XTalkBeacon contract.
*/
constructor(address _beaconAddress) {
require(_beaconAddress != address(0), "Invalid beacon address");
xtalkBeaconAddress = _beaconAddress;
}
// =================================================================================================
// ===================================== User-Defined Logic ========================================
// =================================================================================================
/**
* @dev Invokes a message to be sent to a destination chain via the XTalkBeacon.
* @param _destinationChainId The chain ID of the destination chain.
* @param _destinationAddress The address of the contract on the destination chain.
* @param _message The string message to be sent.
*/
function invokeMessage(uint32 _destinationChainId, bytes32 _destinationAddress, string memory _message) public {
// ----------------- User-Defined part -----------------
uint32 messageType = 1; // Example message type
bytes memory messageData = abi.encode(_message);
// -----------------------------------------------------
// ----------------- XTalk Infrastructure part -----------------
uint256 nonce = IXTalkBeacon(xtalkBeaconAddress).getSenderRegistrationNextNonce(address(this));
IXTalkBeacon(xtalkBeaconAddress).registerMessage(_destinationChainId, _destinationAddress, messageData, messageType, nonce);
// ---------------------------------------------------------
}
// =================================================================================================
// ================================= XTalk Infrastructure Callback =================================
// =================================================================================================
/**
* @dev This function is called by the XTalkBeacon when a cross-chain message is received for this contract.
* The function name and signature must be `_xtalkMessageReceived(bytes32,address,uint32,uint32,bytes)`.
* @param _messageId The unique ID of the message.
* @param _sourceInvokerAddress The address of the invoker on the source chain.
* @param _sourceChainId The chain ID of the source chain.
* @param _messageType The type of the message.
* @param _messageData The actual message data.
*/
function _xtalkMessageReceived(bytes32 _messageId, address _sourceInvokerAddress, uint32 _sourceChainId, uint32 _messageType, bytes memory _messageData) public {
// ----------------- XTalk Infrastructure part -----------------
require(msg.sender == xtalkBeaconAddress, "Caller is not the XTalkBeacon");
// ---------------------------------------------------------
// ----------------- User-Defined part -----------------
receivedMessages[_messageId] = Message({
messageId: _messageId,
sourceInvokerAddress: _sourceInvokerAddress,
sourceChainId: _sourceChainId,
messageType: _messageType,
messageData: _messageData
});
emit MessageReceived(_messageId, _sourceInvokerAddress, _sourceChainId, _messageType, _messageData);
// -----------------------------------------------------
}
}
Last updated