> For the complete documentation index, see [llms.txt](https://docs.midpointapi.com/midpoint-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.midpointapi.com/midpoint-documentation/get-started/sample-midpoints/data-bridge-pass-arbitrary-messages-between-chains.md).

# Data Bridge: Pass arbitrary messages between chains

## Overview

Frequently, you need to send information from one chain to another.  To do this, you can create a Data Bridge, a Midpoint that can receive messages from one chain and send them on to a contract on another chain.

## Setup

To build a Data Bridge you need to construct three parts

1. The sending contract, which lives on one chain and sends the message.
2. The Midpoint itself, which observes the event and transfers it over to the other contract
3. The receiving contract

#### Creating the Midpoint

It’s almost always easiest to create the Midpoint *first*, because you need its ID to create the contracts, but as the the source and the task need the addresses of the contracts, you won’t be able to set up them up until after the contracts are created.

#### The sending contract

The job of the sending contract, whatever else it does, is to invoke a function on a special contract, called a Startpoint, provided on every chain as a portal to Midpoints. &#x20;

The source for the sending contract should look something like this:

```solidity
pragma solidity>=0.8.0;

interface IMidpoint {
    function callMidpoint(uint64 midpointId, bytes calldata _data) 
                    external returns(uint256 requestId);
}

contract SendingContract {  

    // ... all your code goes here, and at some point invokes sendMessage() below
    
    uint64 constant midpointID = 758;
    address constant startpointAddress = 0x711D64597FD64bCE7460F555fA928d02862a6f55;

    function sendMessage(string memory subject) public {
        
        bytes memory args = abi.encodePacked(subject, bytes1(0x00));
        IMidpoint(startpointAddress).callMidpoint(midpointID, args);
    }
}
```

The actual value for `startpointAddress` depends on the chain you are deploying on.  For the list of values, see here: [Startpoints](/midpoint-documentation/more-reading/startpoints.md)

Note that you must invoke the Startpoint with a specially packed array of bytes.  For more information about how to pack them, see here: [Startpoint Called](/midpoint-documentation/sources/startpoint-called.md)

#### The receiving contract

The receiving contract just have to have a public function that takes the appropriate arguments, something like this:

```solidity
pragma solidity>=0.8.0;

contract ReceivingContract {  
    address constant callbackAddress = 0xC0FFEE4a3A2D488B138d090b8112875B90b5e6D9;
  
   function receiveMessage(uint256 midpointId, 
                          string memory subject) public {
       // Only permit a verified callback address to call your callback function.
       require(tx.origin == callbackAddress, "Invalid callback address");
       require(midpointId == 271, "Invalid midpoint ID");

      // do whatever you need to with the data
   }
}
```

As with the the startpointAddress in the sending contract, the callbackAddress in the receiving contract depends on the chain that the receiving contract is deployed on.  See here for values: [Midpoint EOAs](/midpoint-documentation/more-reading/midpoint-eoas.md)

## Midpoint

`$ npm install -g midpoint-cli`

`$ midpoint init blank my-data-feed`

#### **1 . Startpoint Called**

`$ midpoint add-source startpointCalledSource startpoint-called-source`

We define the [Startpoint Called](/midpoint-documentation/sources/startpoint-called.md) source so that contract can make a midpoint request.&#x20;

```json
{
    "startpointCalledSource": {
        "whitelist": [
            {
                "chainId": "5",
                "contractAddress": "0xa89c2f3A20cED98cd39AFd0Ab5B207C46Fb2Cdf3"
            }
        ],
        "variables": [
            {
                "name": "subject",
                "datatype": "string"
            }
        ]
    }
}
```

#### **2.  Transact To EVM Function**

`$ midpoint add-task transactToEvmFunctionTestnet post-subject-on-blockchain`

We define the [Transact to EVM Function](/midpoint-documentation/tasks/transact-to-evm-function.md) Task to send the summary back to the contract.&#x20;

```json
{
  "transactToEvmFunctionTestnet": {
    "chainId": "420",
    "contractAddress": "0x83986ff4fbcaa2acf6092930fcebbe25583be452",
    "functionName": "heartbeat",
    "arguments": [
        {
            "name": "subject",
            "datatype": "string",
            "value": "{{subject}}"
        }
      }
    ]
  }
}
```

#### **3.  Define Path**

We define our path file.&#x20;

```
startpoint-called-source => post-subject-on-blockchain
```

#### **4.  Publish Midpoint**

`$ midpoint publish`


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.midpointapi.com/midpoint-documentation/get-started/sample-midpoints/data-bridge-pass-arbitrary-messages-between-chains.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
