Introduction
This tutorial demonstrates how to use Chainlink's Cross-Chain Interoperability Protocol (CCIP) to transfer tokens and arbitrary data between smart contracts on different blockchains. You'll learn two methods for covering CCIP fees: paying in LINK tokens or using the native gas token of the source blockchain (like ETH on Ethereum or AVAX on Avalanche).
๐ Learn more about CCIP fundamentals
Prerequisites
Before beginning this tutorial, ensure you have:
- Basic smart contract development skills including writing, compiling, and deploying contracts
Testnet tokens:
- AVAX and LINK on Avalanche Fuji
- ETH on Ethereum Sepolia
- CCIP-BnM test tokens (acquired through the CCIP test tokens guide)
- Completed the basic token transfer tutorial
Tutorial Overview
This guide will walk you through:
- Setting up sender and receiver contracts
- Transferring tokens with data while paying fees in LINK
- Transferring tokens with data while paying fees in native gas
Contract Deployment
Deploying the Sender Contract (Avalanche Fuji)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import {IRouterClient} from "@chainlink/contracts-ccip/contracts/interfaces/IRouterClient.sol";
import {OwnerIsCreator} from "@chainlink/contracts/src/v0.8/shared/access/OwnerIsCreator.sol";
import {Client} from "@chainlink/contracts-ccip/contracts/libraries/Client.sol";
import {CCIPReceiver} from "@chainlink/contracts-ccip/contracts/applications/CCIPReceiver.sol";
import {IERC20} from "@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol";
contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator {
using SafeERC20 for IERC20;
// Contract implementation...
}Configuration Steps
Set Router and LINK Addresses:
- Avalanche Fuji Router:
0xF694E193200268f9a4868e4Aa017A0118C9a8177 - LINK Token:
0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846
- Avalanche Fuji Router:
Fund Contracts:
- Transfer 0.002 CCIP-BnM to sender contract
- Approve Ethereum Sepolia as destination chain
Transferring Tokens with Data
Paying Fees in LINK
function sendMessagePayLINK(
uint64 _destinationChainSelector,
address _receiver,
string calldata _text,
address _token,
uint256 _amount
) external returns (bytes32 messageId) {
// Function implementation...
}Parameters:
| Argument | Value | Description |
|---|---|---|
_destinationChainSelector | 16015286601757825753 | Ethereum Sepolia chain identifier |
_receiver | Contract address | Receiver contract on destination chain |
_text | Any string | Message content |
_token | CCIP-BnM address | Token contract address |
_amount | Token amount | Quantity to transfer |
๐ View complete CCIP directory
Paying Fees in Native Gas
function sendMessagePayNative(
uint64 _destinationChainSelector,
address _receiver,
string calldata _text,
address _token,
uint256 _amount
) external returns (bytes32 messageId) {
// Function implementation...
}Key Differences:
- Uses native gas (AVAX) instead of LINK for fees
- Requires sufficient native token balance
Security Implementation
The contract includes several security measures:
- Destination chain allowlisting
- Source chain verification
- Sender authorization
- Router-only message reception
Frequently Asked Questions
What is the gas limit for CCIP transactions?
The example uses 200,000 gas as a reasonable starting point, but this should be adjusted based on your specific contract requirements.
How do I verify a cross-chain transaction?
Use the CCIP explorer with your transaction hash to track the status and details of your cross-chain transfer.
Can I use this for production environments?
This example uses unaudited code and should not be used in production without proper security audits and testing.
What tokens are supported by CCIP?
Refer to the CCIP Directory for the complete list of supported tokens across different networks.
How are fees calculated?
Fees depend on multiple factors including destination chain, data size, and current network conditions. The getFee function provides accurate estimates.
Conclusion
This tutorial demonstrated how to implement cross-chain token transfers with arbitrary data using Chainlink CCIP. The example contract provides flexibility in payment methods (LINK or native gas) while maintaining robust security through multiple verification layers.
For production implementations, consider:
- Dynamic gas limit calculation
- Comprehensive error handling
- Additional security audits