Build your first XCDP - EVM Contract

Step by Step guide and Repository link provided in Templates Section. In this guide we will use Sepolia and bscTestnet to deploy the client chain contracts and L1X TestNet to deploy X-Talk Contract.

Building Blocks for XCDP

  1. Smart Contracts on Client Chains (example ethereum, binance chain) that will be the endpoints for sending and receiving messages. This is runtime agnostic.

  2. L1X X-Talk Contract that includes Client Chain Contract Registration Initialisation and X-Talk XCDP Contract Deployment and Initialisation to facilitate programmability while sending and receiving messages.

In this guide, we use Sepolia as Source and bscTestnet as Destination network.

Implementing Solidity Contract (Comments for Explanation)

Replace the DESTINATION_X-TALK_GATEWAY_CONTRACT_ADDRESS with respective contract address listed in this table.

//XCDPCore.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/* XCDP Core to implement the interface.*/
contract XCDPCore {
    address public gatewayContractAddress = DESTINATION_X-TALK_GATEWAY_CONTRACT_ADDRESS; //Provided in endpoint
    mapping(bytes32 => XCDPReceiveMessage) public XCDPData;

/* Sending message instruction. You can make this
compatible with Destination or if you want to transform
the message on X-Talk you can send raw instructions and
prepare the payload on X-Talk Contract*/
    struct XCDPSendMessage {
        string message;
    }

/* Same with Receiving the message where you will be
able to provide any struct based on how you want to
receive it based on the transformed payload */
    struct XCDPReceiveMessage {
        string message;
    }

/* This is the encoded format of the paylaod to be 
sent. This will be sent to X-Talk Contract. Provide 
destination details here or add it into X-Talk if you
want to run logic and decide where to send the paylaod */
    event XTalkMessageBroadcasted(
        bytes message,
        string destinationNetwork,
        string destinationSmartContractAddress
    );



/* This is the function to be called when you want to 
send the message. The message is encoded into bytes 
before emitting */
    function _l1xSend(
        string memory message,
        string memory destinationSmartContractAddress, 
        string memory destinationNetwork
    ) external {



    XCDPSendMessage memory myMessage = XCDPSendMessage({
        message: message
    });



    // Convert the struct to bytes
    bytes memory messageBytes = abi.encode(myMessage.message);
        emit XTalkMessageBroadcasted(messageBytes, destinationNetwork, destinationSmartContractAddress);
    }

    /* decoding the message to retrieve the stringified message, 
    and storing it along with the global transaction id ( the message identifier ) */
    function _l1xReceive(bytes32 globalTxId, bytes memory message) external {
        require(msg.sender == gatewayContractAddress, "Caller is not xtalk node");
        XCDPReceiveMessage memory XCDPReceiveMessageData;
        (XCDPReceiveMessageData.message) = abi.decode(message, (string));
        XCDPData[globalTxId] = XCDPReceiveMessageData;
    }
}

Deploying the Solidity Contract (scripts/deploy.js)

Hardhat Configuration JS

At this point, you will have the deployed contract addresses for sepolia and bscTestnet.

Implementing L1X X-Talk Flow Contract

Flow Contracts are at the core of decentralised multi-chain and cross-chain application development. They enable logic programmability, reducing integration and maintenance overhead and enable scalability.

Create a new L1X project that provides the necessary files to get started

Use the provided code below to implement the cross-chain xcdp logic. The X-Talk Flow Contract consists of fundamental building blocks which are re-usable across all development standards with X-Talk.

  1. Payload Definition that is being received. This could be deterministic or a generic vector of bytes. You can be deterministic or make this logic programmable.

  2. Saving the event data that will store the event that is received.

  3. Payload Logic that will allow you to implement logic based on what the destination payload required.

  4. Payload Transformation that will be based on the destination runtime.

  5. Emitting the Event to be sent to the Destination.

The Fundamental Building Blocks of X-Talk require the below building blocks in X-Talk Contract.

  • Data Structures: Define messages and events used within the contract.

  • Event Handling: Parse, log, and handle blockchain events.

  • State Management: Load and save the contract's state to maintain event records.

  • Message Parsing: Convert blockchain event logs into usable data formats.

  • Event Emission and Logging: Emit structured logs for cross-chain messaging.

  • Security: Ensure that only valid and expected data is processed.

Ensure you have all the necessary packages, libraries and dependencies in your cargo.toml file as below.

To deploy the X-Talk flow contract, you can use this command on your project level. After successfully building, you will find the "project_name.o" file in target/l1x/release folder. This is the object file which will be deployed.

To deploy your contract, use an existing L1X Account with L1X for Mainnet and L1X TestNet for TestNet.

Create Wallet

Create your own wallet to generate a new keypair.

Import Wallet

Import you existing wallet using the l1x-cli-beta tool, by providing a private key. If you don't have one, Create Wallet.

Default Wallet

After Importing your wallet set it to be the default interaction account.

-- Check Endpoints in Interface Essentials for TestNet Faucet

Deploy your X-Talk Contract with l1x-cli-beta

Response expected:

To initiate your smart contract, use this command:

Response expected:

The instance address is your contract address which you can use to call your functions and interact.

Register Client Chain and X-Talk Contracts with X-Talk Node

X-Talk Nodes allow for data listening and send to the X-Talk Flow contract.

To register your addresses to the source registry, you need to call this:

Request Example:

To validate that your data has been registered to the registry:

Response Example:

You have successfully deployed your first Bridgeless Cross-Chain Application.

Send the Event

Check the Seoplia Testnet Transaction Log.

X-TALK GATEWAY CONTRACT ADDRESS

Below table contains a list of contract address that serve as an authenticated entry to interact with X-Talk from respective client chain network.

Network
Contract Address

sepolia

0xf650162aF059734523E4Be23Ec5bAB9a5b878f57

bscTestnet

0x77d046D7d733672D44eA2Df53a1663b6CF453432

Last updated