Transfer Tokens with Data Using Chainlink CCIP

ยท

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:

  1. Basic smart contract development skills including writing, compiling, and deploying contracts
  2. Testnet tokens:

    • AVAX and LINK on Avalanche Fuji
    • ETH on Ethereum Sepolia
  3. CCIP-BnM test tokens (acquired through the CCIP test tokens guide)
  4. Completed the basic token transfer tutorial

Tutorial Overview

This guide will walk you through:

  1. Setting up sender and receiver contracts
  2. Transferring tokens with data while paying fees in LINK
  3. 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

  1. Set Router and LINK Addresses:

    • Avalanche Fuji Router: 0xF694E193200268f9a4868e4Aa017A0118C9a8177
    • LINK Token: 0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846
  2. 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:

ArgumentValueDescription
_destinationChainSelector16015286601757825753Ethereum Sepolia chain identifier
_receiverContract addressReceiver contract on destination chain
_textAny stringMessage content
_tokenCCIP-BnM addressToken contract address
_amountToken amountQuantity 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:

Security Implementation

The contract includes several security measures:

  1. Destination chain allowlisting
  2. Source chain verification
  3. Sender authorization
  4. 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: