Getting Started
This quick start guide outlines how to connect your contract with Analog Gateway contracts to enable cross-chain messaging. On the origin chain, the source contract sends encoded data via the submitMessage function. The payload is then routed to the destination chain, where the destination contract receives and processes it using the onGmpReceived function.
Prerequisites
- Basic knowledge of Solidity.
- Network IDs for source and destination chains. See Gateway Addresses & Network IDs for more details.
- An EVM wallet set up and funded with enough tokens for the chains you’ll be working with. For testnet tokens, use the following faucet links:
Ethereum Sepolia
Procedure
Follow these steps to send a GMP request from chain A to chain B.
Step 1: Implement Receiver Contract
All destination contracts must implement IGmpReceiver:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IGmpReceiver} from "./IGmpReceiver.sol";
contract CrossChainReceiver is IGmpReceiver {
// Store the Gateway address for security checks
address public immutable gateway;
// Events to track received messages
event MessageReceived(bytes32 id, uint128 sourceNetwork, bytes32 source, bytes payload);
constructor(address _gateway) {
gateway = _gateway;
}
function onGmpReceived(
bytes32 id,
uint128 sourceNetwork,
bytes32 source,
uint64 nonce,
bytes calldata payload
) external payable override returns (bytes32) {
// Security check: only the Gateway can call this function
require(msg.sender == gateway, "Unauthorized sender");
// Process the received message
emit MessageReceived(id, sourceNetwork, source, payload);
// Implement your cross-chain logic here
// ...
// Return a result (can be used for verification or additional logic)
return keccak256(abi.encodePacked(id, block.timestamp));
}
}
Step 2: Send Cross-Chain Messages
Use the Gateway to send messages between chains:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IGateway} from "./IGateway.sol";
contract CrossChainSender {
// Gateway contract reference
IGateway public immutable gateway;
// Events to track sent messages
event MessageSent(bytes32 messageId, address destination, uint16 destinationNetwork);
constructor(address _gateway) {
gateway = IGateway(_gateway);
}
function sendCrossChainMessage(
address destinationContract,
uint16 destinationNetwork,
bytes calldata payload
) external payable returns (bytes32) {
// Estimate the cost of sending the message
uint256 gasCost = gateway.estimateMessageCost(
destinationNetwork,
payload.length,
100000 // Gas limit for execution on destination chain
);
// Ensure enough funds are provided
require(msg.value >= gasCost, "Insufficient funds for cross-chain message");
// Send the message
bytes32 messageId = gateway.submitMessage{value: msg.value}(
destinationContract,
destinationNetwork,
100000, // Gas limit
payload
);
emit MessageSent(messageId, destinationContract, destinationNetwork);
return messageId;
}
}Gas Management:
- When sending messages, always ensure you provide enough gas for execution on the destination chain. Use estimateMessageCost to estimate costs:
gateway.estimateMessageCost(networkId, messageSize, gasLimit)- Use
destinationNetworkfrom Gateway'snetworkId()
Step 3: Make a GMP request
- Deploy your source and destination chain contracts using the gateway addresses for the specified networks. You can find these addresses on the Gateway Addresses & Network ID page.
- Estimate the gas cost by calling
estimateMessageCoston the gateway by passing in the appropriatenetworkid,messageSize, andgasLimit. - Make the GMP call using the
submitMessagemethod. Here's an example:
gateway.submitMessage{value: msg.value}(dest_address, dest_network, GMP_GAS_LIMIT, payload);When making the GMP call using the submitMessage method, ensure that the gas fee is included as a value in the request. If the value provided is less than the estimated message cost, the transaction will fail with the error: "execution reverted: insufficient tx value."
- Upon finalizing the transaction on the source chain, a
Task IDwill be created on the Timechain. You can track the status of your task on the Timechain Explorer . For more details, see Track GMP Messages. - Once your task is completed, your destination chain contract state will be updated.
Congratulations! You just sent your first GMP request using Analog GMP. Next, try tracking the status of the GMP call after you send it.
Next Steps
Try tracking the status of the GMP call after you send it.
Build your first cross-chain DApp using Analog GMP.
See how Foundry can help you set up your cross-chain project.