Deploying Your Custom EVM Protocol
Prerequisites
Package Installation
npm install @entangle-labs/uip-contractsDeployment Steps
1
2
3
4
Troubleshooting & Notes
Last updated
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 Troubleshooting section of this guide and the How to Debug Sent Messages guide or reach out to us through our contact form.
Before deployment, ensure you are familiar with payable functions in Solidity and have initiated a Hardhat project.
To streamline development, start by installing the Entangle Labs UIP Contracts NPM package. It includes ready-to-use code and interfaces for deployment.
npm install @entangle-labs/uip-contractsObtain 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/Read this 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()))
);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 Package Installation step — specifically the execute function:
function execute(bytes calldata data) external override payableThe 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 MessageReceiverBelow, we provide the MessageReceiver code for convenience. Please refer to the package for the most up-to-date version.
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)
);
}
}This section provides information, tips, and solutions for common issues you may encounter while deploying the protocol.
Check the signer account balance: Ensure the account has enough native currency on the target blockchain for deployment.
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.
Compile before deploying: Run npx hardhat compile before deployment. If it fails, thoroughly check your contract for compilation errors.
Check the signer account balance: Ensure the account has sufficient native currency for transactions.
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 npm page.
Confirm function signature compliance: Ensure your contract correctly follows the propose function signature in the Endpoint contract:
Check destination chain support: Ensure that the destination chain is currently supported.
Retrieve message hash: Use the following command to obtain the TEIB transaction hash for your message: npx hardhat getMsgHash
Check message status: Once you have the hash, use: getMsgStatusByHash
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.
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 Receiver Contract Requirements section).
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.
Last updated
function propose(
uint256 destChainID,
bytes32 selectorSlot,
bytes calldata transmitterParams,
bytes calldata destAddress,
bytes calldata payload
) external payable;