# Send Arbitrary Data and Receive Transfer Confirmation: A -> B -> A
Source: https://docs.chain.link/ccip/evm/tutorials/application-developers/send-arbitrary-data-receipt-acknowledgment
Last Updated: 2026-05-26

> For the complete documentation index, see [llms.txt](/llms.txt).

In this tutorial, we will use CCIP to send arbitrary data from one chain to another and then have the receiver contract send back an acknowledgment message back to the sender:

- A MessageTracker contract on chain A sends a text message to an Acknowledger contract on chain B.
- After processing the message, the Acknowledger sends an acknowledgment message back to the MessageTracker.
- The MessageTracker updates onchain state to reflect the successful execution of the back and forth pattern.

By tracking acknowledgment onchain, your contracts can safely trigger follow-up actions only after the destination contract has confirmed the receipt.

> **NOTE: CCIP 2.0 supports Faster-Than-Finality (FTF)**

## Before you begin

- This tutorial assumes you have completed the [Send Arbitrary Data](/ccip/evm/tutorials/application-developers/send-arbitrary-data) tutorial.
- You will use *Ethereum Sepolia* (A) and *Arbitrum Sepolia* (B).
- Your wallet should have:
  - Sepolia ETH (for deploying and sending from Ethereum Sepolia)
  - Arbitrum Sepolia ETH (for deploying on Arbitrum Sepolia and funding the Acknowledger)
  - Optional: Sepolia LINK (if you want to pay the CCIP fee in LINK)
- Learn how to [Acquire testnet LINK](/resources/acquire-link).

## Examine the code

The contracts and scripts used in this tutorial live in the Chainlink CCIP 2.0 starter kit repository (`docs-ccip`).

> **CAUTION: Best Practices**
>
> This example is simplified for educational purposes. For production code, follow these best practices:
>
> - **Keep extraArgs mutable**: In production, build extraArgs off-chain and pass them into your contract calls, or store them in a storage variable that can be updated. Never hardcode them. This keeps your contract compatible with future extraArgs versions and lets one deployment serve both pre-2.0 and CCIP 2.0 lanes without redeploying. See [Best Practices: Using extraArgs](/ccip/evm/concepts/best-practices#using-extraargs).
>
> - **Validate the destination chain**: Always ensure the destination chain is valid and supported before sending messages. See [Verify destination chain](/ccip/evm/concepts/best-practices#verify-destination-chain).
>
> - **Use ExtraArgsV3 on CCIP 2.0 lanes**: New integrations should encode [ExtraArgsV3](/ccip/evm/api-reference/v2.0.0/extra-args-codec), which carries the gas limit, requested finality, Cross-Chain Verifiers (CCVs), and executor settings (*More on `ExtraArgsV3` below*)
>
> - Legacy [GenericExtraArgsV2](/ccip/evm/api-reference/v2.0.0/client#genericextraargsv2) arguments are still accepted, but only the gasLimit field is honored. allowOutOfOrderExecution is deprecated in v2.0.
>
> - **Understand CCIP Service Limits**: Review the [CCIP Service Limits](/ccip/evm/service-limits) for constraints on message data size, execution gas, and the number of tokens per transaction. If your requirements exceed these limits, you may need to [contact the Chainlink Labs Team](https://chain.link/ccip-contact).

## Tutorial

Let's get started. Choose your preferred development environment below.

### Foundry

Best for Solidity-native workflows that prefer a modular, powerful scripting framework.

> **NOTE: Want to set up a dev environment from scratch?&#x20;**
>
> Check out the [Getting started page](/ccip/evm/getting-started#foundry) for detailed instructions on setting up a
> Foundry dev environment from scratch.

### Hardhat

Best for devs looking for a mature, TypeScript-based smart contract development framework.

> **NOTE: Want to set up a dev environment from scratch?&#x20;**
>
> Check out the [Getting started page](/ccip/evm/getting-started#hardhat-3) for detailed instructions on setting up a
> Hardhat dev environment from scratch.

## Final note

This tutorial uses a simple acknowledgment message to confirm delivery end-to-end. You can adapt the same pattern to:

- programmable token transfers
- multi-step workflows that depend on destination-side execution
- onchain receipts that unlock follow-up actions on the source chain

> **CAUTION: Educational Example Disclaimer**
>
> This page includes an educational example to use a Chainlink system, product, or service and is provided to
> demonstrate how to interact with Chainlink's systems, products, and services to integrate them into your own. This
> template is provided "AS IS" and "AS AVAILABLE" without warranties of any kind, it has not been audited, and it may be
> missing key checks or error handling to make the usage of the system, product or service more clear. Do not use the
> code in this example in a production environment without completing your own audits and application of best practices.
> Neither Chainlink Labs, the Chainlink Foundation, nor Chainlink node operators are responsible for unintended outputs
> that are generated due to errors in code.