Integrate Inter-Chain Messaging Facility (ICMF)
This documentation is for dapp developers looking to integrate the Interchain Messaging Facility (ICMF) into their decentralized applications. ICMF facilitates cross-chain communication, enabling interaction between blockchains within a dapp cluster. This guide will walk you through sending and receiving ICMF messages in your dapps.
ICMF operates as an event-based service. When blockchain_#1
emits events through transactions that contain event data
written to block headers, blockchain_#2
subscribes to specific topics to read this data. Other blockchains
(blockchain_n
) can also subscribe to events from blockchain_#1
. As soon as blockchain_#2
reads an event, it
triggers the corresponding function. This enables multiple communication channels between blockchains in a dapp cluster.
From a development standpoint, ICMF supports both omnidirectional and multidirectional communication. In omnidirectional
scenarios, blockchain_#1
emits events that blockchain_#2
and blockchain_#n
can read. In multidirectional channels,
all blockchains subscribe to topics and listen to each other, emitting events that trigger function calls.
Implementation
For simplification purposes, we will refer to the blockchain that sends event messages as sender_chain
, while the
blockchain that reads those events will be referred to as receiver_chain
. In this context, dapps are responsible for
processing the business logic that either sends a transaction with the event data or handles the received data. The dapp
that sends the message is termed sender_dapp
, and the dapp that handles the message is called receiver_dapp
.
Refer to the infographics below to see how ICMF operates:
- The
sender_dapp
submits a transaction with the event data by calling thesend_message
function from the ICMF Rell library. - The network validates the transaction on the
sender_chain
, and the message gets written to the block header. - The
receiver_chain
checks for messages on subscribed topics in the block headers of thesender_chain
. - When the system detects a message, the dapp automatically invokes the
__icmf_message
operation. This function includes the necessary logic to handle the message. - The ICMF Rell library calls the function
handle_icmf_message
, executing any logic defined by the dapp.
Send messages
Integration steps
To enable your blockchain to send ICMF messages, you need to add the ICMF Sender GTX module to your blockchain configuration.
-
Open your blockchain's configuration file.
-
Under the
config
section, insert thegtx
module:config:
gtx:
modules:
- "net.postchain.d1.icmf.IcmfSenderGTXModule" -
If your chain sends large messages, adjust the message query limit to avoid an overload of large queries:
config:
icmf:
sender:
message_query_limit: 100 # Default is 100, adjust to manage processing of large message queries -
Save and apply the configuration changes.
Send ICMF messages
After you integrate the ICMF Sender GTX module, you can use the ICMF module to send messages. Use the function
send_message(topic: text, body: gtv)
for this purpose. The topic
parameter represents the message topic, while the
body
parameter contains the content of the message. To install the ICMF rell code library, see the instructions
here.
Remember that the body
parameter is of type gtv
, which allows you to send messages with various data structures.
Ensure that the receivers can parse the data you send. If you want to learn more about how to serialize and deserialize
data when sending and receiving messages, refer to the
GTV protocol description.
Receive messages
Integration steps
To enable your blockchain to receive ICMF messages, follow these steps to add the ICMF Receiver GTX module and the ICMF Receiver Synchronization Infrastructure Extension to your blockchain configuration.
-
Open your blockchain's configuration file.
-
Locate the
gtx
section underconfig
and insert the following lines:gtx:
modules:
- "net.postchain.d1.icmf.IcmfReceiverGTXModule"
sync_ext:
- "net.postchain.d1.icmf.IcmfReceiverSynchronizationInfrastructureExtension" -
Save and apply the configuration changes.
Implement message reception
To process the received ICMF messages, you need to implement the message receive operation in Rell. Here's an example implementation:
operation __icmf_message(sender: byte_array, topic: text, body: gtv) {
// Parse and handle the message here
}
Argument | Description |
---|---|
sender | Represents the blockchain-rid of the sender chain. |
topic | Specifies the message topic. |
body | This argument carries the message content. |
If you want to utilize the ICMF Rell library for receiving messages, extend the function like this:
@extend(receive_icmf_message) function handle_icmf_message(sender: byte_array, topic: text, body: gtv) {
}
Configure topics and sender chains
ICMF messages organize around topics that serve as communication channels, directing messages to their intended recipients. When you work with ICMF topics, follow these guidelines:
- Prefix all ICMF topics with
L_
. This prefix indicates that the message is sent within your local blockchain network. - Only system chains can send messages on a global level.
To specify which topics and sender chains your blockchain listens to, configure the ICMF receiver settings in your blockchain's configuration file:
icmf:
receiver:
local:
- bc-rid: x"0000000000000000000000000000000000000000000000000000000000000001"
topic: "L_topic1"
- bc-rid: x"0000000000000000000000000000000000000000000000000000000000000002"
topic: "L_topic2"
skip-to-height: 10 # Skip messages from this topic until block height 10
- etc.
In the icmf
section, under receiver
, list the chains and topics your blockchain should monitor. The bc-rid
parameter refers to the blockchain-rid of the sender chain, and the topic
parameter specifies the topic of interest.
The skip-to-height
parameter ensures that messages on the specified topic will be skipped until the mentioned block
height.
Combining ICMF with other extensions
ICMF usually tries to accommodate as many messages as possible into a block. However, when used alongside other extensions, you might need to adjust the space ICMF allocates for them. Use the following configuration to ensure better coordination with other extensions:
config:
icmf:
receiver:
special-tx-margin-bytes: 102400 # Default is 100 KiB; adjust if other extensions require more space
This configuration allows for improved coordination with other extensions by ensuring that ICMF does not consume excessive space in the block.
Staking updates
The ICMF allows your blockchain to configure the global staking topic G_staking_state_update
which will allow any
chain to listen to the staking messages. The messages include the following information:
- The unique account identifier.
- Total staked amount including any active withdrawals.
- A list of active withdrawal requests.
Each message will provide an update for a specific account. Any changes related to staking, such as new staking or withdrawals, will trigger the publication of a new message on the relevant topic for that account. This message will include the most current value of the amount staked.
For demonstration purposes, refer to the code example below which highlights the configuration of the staking topic:
module;
import lib.icmf.constants.*;
/** Topic for staking state updates related to account balance and withdrawals */
val economy_chain_staking_state_update = ICMF_TOPIC_GLOBAL_PREFIX + "staking_state_update";
struct economy_chain_staking_state_withdrawal {
/** Requested amount to withdraw in minor units */
amount: integer;
/** Approximate time when this withdraw is scheduled */
finish_at: integer;
}
/**
* Keeps the staking balance and active withdrawals for a specific FT4 account id.
*/
struct economy_chain_staking_state_update_message {
/** Staking FT4 account id */
staking_account_id: pubkey;
/** Total staked amount in minor units including any active withdrawal */
balance: integer;
/** List of active withdrawal requests */
withdrawals: list<economy_chain_staking_state_withdrawal>;
}
For an in-depth course on using ICMF in a real dapp, visit the Build an event-driven multi-blockchain dapp course.