LogoLogo
  • Entangle
    • Overview
    • Security Audits
  • Universal Interoperability Protocol
    • Overview
    • Architecture
      • Scalability and Network Stability
        • L2 Utility Blockchains
        • Transmitter Groups
      • Security and Consensus Mechanism
      • Finality
      • Execution Latency
      • Compatibility and Interoperability
    • Developer Guides
      • Getting Started
      • Solidity
        • Simple Abstract Messenger Example
        • Deploying Your Custom EVM Protocol
        • Bridging Tokens with UIP
        • Become an EVM Transmitter
      • Solana
        • Simple Abstract Messenger Example
        • Deploying Your Custom Solana Protocol
        • Become a Solana Transmitter
      • Calculate Cross-Chain Transaction Cost
      • Customizable Message Transmission Options
      • How to Debug Sent Messages
      • SDK Setup
      • Revenue Sharing for Transmitters
      • How to Become a Super Transmitter
    • Endpoints
  • Universal Data Feeds
    • Overview
    • Architecture
      • Data Delivery Methods
        • Pull Model
        • Push Model
      • Oracle Contract & User Interaction
    • Developer Guides
      • Custom Data Feeds
      • Fetch Data via Pull Model (PAYG)
        • EVM Smart Contracts
        • Solana Smart Contracts
      • Fetch Data via Pull Model (Subscriptions)
        • EVM Smart Contracts
        • Solana Smart Contracts
      • Fetch Data via Push Model
        • EVM Smart Contracts
        • Solana Smart Contracts
    • User Guides
      • Accessing Feeds
      • Subscribe to a Data Feed
      • Check Subscription
      • Manage Subscription
      • Renew Subscription
    • Data Endpoints
  • Universal Token Standard
    • Overview
    • Architecture
      • Fee Components
    • Developer Guides
      • Manual Deploy
        • Token Deployment Types
        • Create a Custom Token
        • Factory Blueprint Deployment
        • Examples
          • Initial Setup
          • UTS Connector
            • Mint & Burn Connector Scheme
            • Lock & Unlock Connector Scheme
            • Connector Over Native Currency
          • UTS Token
            • Simple Token
            • Token with Messages
      • Bridge SDK
      • Token Verification
      • Fees Calculation & Gas Estimation Logic
      • Estimations
    • User Guides
      • Launch Universal Token
      • Create a Liquidity Pool
      • Expand Existing Token
      • Transfer Liquidity to Connector
      • Bridging
    • Contract Addresses
  • Entangle Interoperable Blockchain
    • Overview
    • Architecture
    • Developer Guides
      • Set up a Validator Node
      • Delegating to Validators
      • Undelegating from Validators
      • Supported Accounts
  • More
    • Media Kit
    • FAQ
    • Report an Issue
    • Become a Partner
Powered by GitBook
On this page
  • Prerequisites
  • Package Installation
  • Deployment Steps
  • Troubleshooting & Notes

Was this helpful?

Export as PDF
  1. Universal Interoperability Protocol
  2. Developer Guides
  3. Solidity

Deploying Your Custom EVM Protocol

PreviousSimple Abstract Messenger ExampleNextBridging Tokens with UIP

Last updated 2 months ago

Was this helpful?

This guide provides step-by-step instructions on how to deploy your custom EVM protocol. By following these steps, you can successfully deploy your custom EVM protocol across multiple chains. If you encounter issues, refer to the section of this guide and the guide or reach out to us through our .

Prerequisites

Before deployment, ensure you are familiar with payable functions in and have initiated a project.

Package Installation

To streamline development, start by installing the Entangle Labs UIP Contracts package. It includes ready-to-use code and interfaces for deployment.

npm install @entangle-labs/uip-contracts

Deployment Steps

1

Endpoint Contract Address

Obtain the endpoint contract address for the chain where you plan to deploy your protocol. You can find endpoint addresses for each connected chain in the Entangle Labs UIP Contracts NPM package.

For testnet, they are located in the following folder:

@entangle-labs/uip-contracts/addresses/testnet/

For mainnet, they are located in the following folder:

@entangle-labs/uip-contracts/addresses/mainnet/
2

Interfaces and Libraries

Ensure the following imports are included in your contract:

import {IEndpoint, TransmitterParams} from "@entangle-labs/uip-contracts/contracts/interfaces/endpoint/IEndpoint.sol";
import "@entangle-labs/uip-contracts/contracts/lib/SelectorLib.sol";
3

Default Selector Variable

To interact with the Endpoint properly, you need to send message with the correct selector to call its "execute" function. Make sure it's included in your contract like so:

bytes4 public constant DEFAULT_SELECTOR = bytes4(keccak256("execute(bytes calldata)"));
4

Payable Function to Send Proposals

Read section to learn more about the propose function, its parameters and the customizable message transmission options.

Develop a payable function that interacts with the endpoint. For example, sending a message to the endpoint requires calling the propose function using the IEndpoint interface:

IEndpoint(endpoint).propose{value: msg.value}(
    chainID,
    SelectorLib.encodeDefaultSelector(DEFAULT_SELECTOR),
    encodedParams,
    destAddress,
    abi.encode(abi.encode(_msg), abi.encode(_msgSender()))
);
5

Receive and Execute Messages

This step will only apply if your contract is designed to receive messages too.

The receiving contract must implement the MessageReceiver interface, which you can find in @entagle-labs/uip-contracts npm package — installed in the step — specifically the execute function:

function execute(bytes calldata data) external override payable

The execute function processes the received payload. Note that the Endpoint contract should have access control to this function. Make sure that your contract imports MessageReceiver and inherits from it, for example:

import {MessageReceiver} from "@entangle-labs/uip-contracts/contracts/MessageReceiver.sol";
contract ExampleProtocol is MessageReceiver

Below, we provide the MessageReceiver code for convenience. Please refer to the package for the most up-to-date version.

MessageReceiver Code
abstract contract MessageReceiver {
    /**
     * @dev Executes a function call from a specified source chain and address.
     *
     * This external function is intended to be used for executing cross-chain
     * calls with the provided payload. It requires to be overridden by child contracts to execute the command
     * @param data The data payload to be sent along with the function call.
     *
     */
    function execute(bytes calldata data) external payable virtual {}

    function _decode(
        bytes calldata data
    )
        internal
        virtual
        returns (
            uint256 sourceChainId,
            bytes memory senderAddr,
            bytes memory payload
        )
    {
        (sourceChainId, senderAddr, payload) = abi.decode(
            data,
            (uint256, bytes, bytes)
        );
    }
}

Troubleshooting & Notes

This section provides information, tips, and solutions for common issues you may encounter while deploying the protocol.

Deployment Failure
  1. Check the signer account balance: Ensure the account has enough native currency on the target blockchain for deployment.

  2. Verify the credentials: Double-check that you've correctly pasted the mnemonic phrase or private key in the hardhat.config.ts file under the appropriate chain section.

  3. Compile before deploying: Run npx hardhat compile before deployment. If it fails, thoroughly check your contract for compilation errors.

Sending Message Failure
  1. Check the signer account balance: Ensure the account has sufficient native currency for transactions.

  2. Confirm function signature compliance: Ensure your contract correctly follows the propose function signature in the Endpoint contract:

    function propose(
        uint256 destChainID, 
        bytes32 selectorSlot, 
        bytes calldata transmitterParams, 
        bytes calldata destAddress, 
        bytes calldata payload
    ) external payable;
Message Not Reaching Destination Contract
  1. Check destination chain support: Ensure that the destination chain is currently supported.

Message Status Explanations

  • NOT_INITIALIZED: This indicates that the message was not proposed by the Endpoint on the source chain. Verify that the Endpoint address in your contract matches the official Endpoint address for your source chain.

  • UNDERESTIMATED: This status means that the source transaction’s msg.value was too low to cover gas costs on the destination chain. Try resending the message with a higher msg.value.

  • OUT_OF_GAS: This means that the customGasLimit in the source transaction was too low, causing the execution on the destination chain to consume more gas than provided. Try resending the message with a higher customGasLimit.

Transaction Delivery Fee and Currency

All transactions use the native currency of the chain you're working on. Themsg.value sent during the propose call is considered the combined delivery fee.

Package Referencing Issues

Ensure all configurations adhere to the latest documentation and libraries provided in the @entangle-labs/uip-contracts package.

Verify the installed package version: Make sure you have the latest version of the @entangle-labs/uip-contracts npm package installed. To check the latest version, visit the official .

Retrieve message hash: Use the following command to obtain the TEIB transaction hash for your message:

Check message status: Once you have the hash, use:

PROTOCOL_FAILED: This occurs when the destination protocol is incompatible with the destination Endpoint. Ensure that the destination protocol implements the MessageReceiver interface (as described in the section).

npm page
Receiver Contract Requirements
How to Debug Sent Messages
contact form
Solidity
Hardhat
NPM
Troubleshooting
Package Installation
this
npx hardhat getMsgHash
getMsgStatusByHash