ismp-evm

This section provides a complete guide for enabling ISMP support for solidity contracts deployed on substrate chains.

Runtime Modifications

The following guide assumes you have pallet-ismp and pallet-evm configured for the runtime.
The first step in orchestrating ISMP support for solidity contracts deployed on substrate based EVM chains is to set up the ISMP module for the EVM. The EvmIsmpModule acts as a proxy, it receives all messages on behalf of all contracts then executes the required callback on the target contract.
Adding this proxy module to your ISMP router is very trivial, a guide is given below:
rust
use ismp_evm::module::EvmIsmpModule; pub struct YourModuleRouter; impl IsmpRouter for YourModuleRouter { fn module_for_id(bytes: Vec<u8>) -> Result<Box<dyn IsmpModule>, ismp::Error> { let module_id = ModuleId::from_bytes(&bytes)?; let handler = match module_id { // This ensures all messages to evm contracts are routed to the proxy module ModuleId::EVM(_) => Ok(Box::new(EvmIsmpModule::<Runtime>::default())) _ => Err(ismp::Error::ModuleNotFound(bytes))?, }; Ok(handler) } }
The diagram presents a visual representation of how the module interacts with both pallets
Image without caption

Precompiles

For contracts to be able to dispatch requests and responses, they need to interact with pallet-ismp , solidity contracts can only interact with the substrate runtime through precompiles.
We have implemented three separate precompiles for dispatching requests and post responses.
The recommended address at which these precompiles should be deployed are prescribed below, this is to ensure uniformity for contract deployments across all chains.
Post request dispatch precompile address
0x222A98a2832ae77E72a768bF5be1F82D8959f4Ec
Get request dispatch precompile address
0xf2D8DC5239DdC053BA5151302483fc48D7E24e60
Post response dispatch precompile address
0xEB928e2de75Cb5ab60aBE75f539C5312aeb46f38

Dispatching requests and responses

When dispatching requests and responses to the runtime, the contract needs to abi encode the DispatchPost, DispatchGet or PostResponse that is expected by the precompile, to ensure correct encoding and avoid decoding errors in the precompile execution, a library has been provided in ismp-solidity that exports functions that handle all interactions with the precompiles. This library assumes the precompiles are deployed at the addresses prescribed in the previous section.
You can import SubstrateHost.sol library from ismp-solidity and call the dispatch function to interact with the precompiles.
Below is an example of an interaction with the precompiles in solidity code:
solidity
function transfer( address to, bytes memory dest, uint64 amount, uint64 timeout, uint64 gasLimit ) public { _burn(msg.sender, amount); Payload memory payload = Payload({ from: msg.sender, to: to, amount: amount }); DispatchPost memory dispatchPost = DispatchPost({ body: abi.encode(payload.from, payload.to, payload.amount), dest: dest, timeoutTimestamp: timeout, to: abi.encodePacked(address(12)), gaslimit: gasLimit }); // Interact with precompile by calling the dispatch function on // the SubstrateHost library SubstrateHost.dispatch(dispatchPost); emit BalanceBurnt(); } function dispatchGet( bytes memory dest, bytes[] memory keys, uint64 height, uint64 timeout, uint64 gasLimit ) public { DispatchGet memory get = DispatchGet({ keys: keys, dest: dest, height: height, timeoutTimestamp: timeout, gaslimit: gasLimit }); // Interact with precompile by calling the dispatch function on // the SubstrateHost library SubstrateHost.dispatch(get); emit GetDispatched(); }

Module interface

Solidity contracts using ISMP need to implement the ismp module interface so they can receive messages from the runtime. The ismp module interface for solidity defined as IIsmpModule is available in ismp-solidity . One important security recommendation is that the functions provided by this interface must only be callable by the ismp-evm host address. This ensures that only the ismp-evm module is authorised to call any of the module callbacks.
The ismp-evm host address is defined as:
0x843b131bd76419934dae248f6e5a195c0a3c324d
Below is an example implementation of the module interface:
solidity
address constant HOST = 0x843b131BD76419934dae248F6e5a195c0A3C324D; contract IsmpDemo is IIsmpModule { using SubstrateHost for *; // restricts call to `Host` modifier onlyIsmpHost() { if (msg.sender != HOST) { revert NotIsmpHost(); } _; } function onAccept(PostRequest memory request) public onlyIsmpHost { } function onPostResponse(PostResponse memory response) public onlyIsmpHost { } function onGetResponse(GetResponse memory response) public onlyIsmpHost { } function onGetTimeout(GetRequest memory request) public onlyIsmpHost { } function onPostTimeout(PostRequest memory request) public onlyIsmpHost { } }

Powered by Notaku