Neutron enables IBC and ICQ for CosmWasm smart contract.
IBC (Inter-Blockchain Communication protocol) is an interoperability protocol built to enable communication between pairs of cosmos chains. However, we can’t use IBC communication with unsupported chains like Ethereum or EVM chains.
IBC communication has been actively used to bridge coins between different cosmos chains, such as bridging ATOM from Cosmos Hub to Osmosis. You can monitor IBC transfers in real-time on the Map of zones dashboard.
Although IBC is actively used to bridge coins between chains, there has yet to be any developed use case for IBC communication between CosmWasm smart contracts. The only example seen on Google is developing a CosmWasm smart contract to transfer coins between pairs of cosmos chains. Unlike the EVM ecosystems, which contain many innovative smart contract interchain communication use cases such as an NFT bridging system.
Now, Neutron is the first pioneer to develop IBC communication for smart contracts and encourage developers to develop cross-chain dApps in cosmos ecosystems. Neutron enables CosmWasm smart contract to execute arbitrary message on any other chains and perform some interchain query,
Interchain transaction
Neutron has developed many unique native messages for sending interchain transactions via CosmWasm smart contract, including registering an interchain communication account (ICA) and submitting arbitrary transactions on the destination chain.
This blog highlights an example use case in the quark testnet quest: registering an interchain communication account (ICA), delegating to a validator, and undelegated from a validator on the destination chain. First, you must register an interchain communication account (ICA).
Registering an interchain communication account (ICA)
To register an interchain communication account (ICA), you must return NeutronMsg::register_interchain_account. Registering an ICA requires passing IBC connection ID and interchain account ID as parameters. After that, we use the interchain account ID to get IBC port ID and save it into the storage for further use. The interchain account ID is an arbitrary name of your choice. For example, the quark testnet case uses “version1” as the interchain account ID.
If you want to query an interchain account address, you can use InterchainQueries::InterchainAccountAddress to query for it by passing the interchain account ID and IBC connection ID.
Executing interchain delegation
To execute an interchain delegation transaction, you must define an execution that puts a typical MsgDelegate message into a local variable. After that, we wrap it into ProtobufAny with the type “/cosmos.staking.v1beta1.MsgDelegate,” which is then put into the final NeutronMsg::submit_tx message. The submit_tx message requires passing IBC connection ID, interchain account ID, message protobuf, timeout, and IBC fee.
Executing interchain undelegation
Executing interchain undelegation is similar to interchain delegation except that we need to use MsgUndelegate instead of MsgDelegate message.
Interchain Query (ICQ)
Neutron has developed another exciting feature: the interchain query (ICQ). Interchain query (ICQ) is a protocol to enable CosmWasm smart contract to perform any query on any other chain that is connected by both IBC and ICQ relayer.
The interchain query requires an additional ICQ relayer for each IBC connection. ICQ relayer is responsible for relaying answers for each query registered. You can find a walkthrough on how to set up ICQ relayer on an official repository.
Each registered query will act like a Chainlink oracle but more decentralized. ICQ relayer will query required data from the destination chain and update the state in the source contract every update period.
This blog highlights an example use case in the quark testnet quest: querying balance, transfer history, and removing query.
Register balance query
To register an interchain balance query, you must use the new_register_balance_query_msg helper function from the quark library supplying IBC connection ID, target address to query (recipient), update period, and min-height (optional). This function will generate a message that you must return to register the balance query. Query ID will be returned in the event log.
After waiting for at least 30 seconds plus the update period, you can query your balance by passing the query ID to the query_balance function in the quark library.
Register transfers query
An interchain transfer query is a query to query a collection of coin transfers to the recipient address. It is useful in developing an interchain coin deposit system. The process is similar to registering a balance query except that we must use the register_transfers_query helper function instead of the new_register_balance_query_msg.
After waiting for at least 30 seconds plus the update period, you can query your transfers by passing the query ID to the query_recipient_txs function in the quark library.
Removing interchain query
After an interchain query has been registered, it will update data every update period, which costs you neutron tokens from time to time. After you have finished your job, you should remove the interchain query to stop the ICQ relayer from updating your data and prevent unnecessary draining of your neutron token.
To remove an interchain query, you must define an execution that returns a NeutronMsg::remove_interchain_query message supplying query ID.