Skip to main content

Moonbeam was built on Polkadot and shares its interoperability vision, but cross-chain communication doesn’t stop with parachains. The Axelar Network protocol has extended the number of networks to be within Moonbeam’s reach by allowing tokens to be bridged between select Cosmos and EVM networks. In addition to token bridging, Axelar’s general message passing (GMP) allows smart contracts to communicate with each other across chains. This allows developers to build cross-chain connected applications on Moonbeam that can tap into functionality from Polkadot, Ethereum, Avalanche, Cosmos, and beyond.

Multichain dApps are currently unified interfaces for protocols duplicated across multiple EVMs. Protocols will be able to connect their contracts cross-chain using Axelar’s general message passing to become multichain aware, allowing for advanced interoperability and functionality between what would otherwise be isolated ecosystems.

Axelar connected contracts

To demonstrate the power of connected contracts, we will walk through a demo that sends and stores a string from one testnet EVM to another. If you don’t have MetaMask set up for it yet, you can add the Moonbase Alpha network on the docs site.

Intro to Axelar Contracts

Axelar is a delegated proof of stake chain that provides secure cross-chain communication. Every validator in Axelar’s network runs light nodes on chains that Axelar supports. These validators work together to confirm that messages are being sent from one chain to another by monitoring each chain’s Axelar Gateway contract, which is one of the two Axelar contracts we will be interacting with later in the demo.

Axelar connected contracts

Image from Axelar Network

The other contract we will be working with is the Axelar Gas Receiver microservice. Whenever you use the Axelar Gateway to send a cross-chain transaction, IAxelarGasReceiver lets you pay for the subsequent transaction on the destination chain. While not necessary, it allows the end user to only send one transaction to automatically update the destination chain.

Connected SimpleGeneralMessage Contract

Now let’s try it out in the most basic way possible. To understand what we’re doing, let’s take a look at the contract that we’ll deploy, which has been made available in a Github gist.

If you take a look at the contract’s parent, you’ll find that it inherits from an abstract contract IAxelarExecutable. This pa rent contract contains some code that Axelar’s contracts require to interact with for general message passing.

There are two functions in the parent contract. The first is sendMessage. It sends an encoded string message across chains via Axelar with the option to pay for its gas on the destination chain.

Axelar connected contracts

The second function is _execute, which overrides a function inherited by IAxelarExecutable. This function is internal, and can only be called by Axelar’s gateway contract when it receives a message from another chain that is directed at this contract. This is where we parse the string from the message’s payload.

Axelar connected contracts

Doing is the best way to learn, so try to follow along with the deployment and message passing yourself on Moonbase Alpha.

Deploying with Remix on Moonbase Alpha

The easiest way to deploy the single demo contract is through Remix. You’ll need DEV to deploy on Moonbase Alpha, which you can get from our faucet if you don’t have any already.

To deploy the script, first copy and paste the contract into Remix. Then compile in the compile tab. Ensure that your MetaMask is connected to the Moonbase Alpha network. Then, in the deploy tab of Remix, set the environment to the Injected Web3, this will use MetaMask as the Web3 provider.

This contract and many connected contracts that use Axelar, will need to know the addresses of two contracts: the Axelar Gateway and the Axelar Gas Receiver. You will have to provide their instances on Moonbase Alpha when constructing SimpleGeneralMessage.sol.

Contract Address
IAxelarGateway 0x5769D84DD62a6fD969856c75c7D321b84d455929
IAxelarGasService 0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6

Once your contract has been deployed on Moonbase Alpha, I highly recommend you repeat the process with any of the other EVM testnets that are connected to Axelar. Here are a few of them with a link to a faucet. I’ve also included the SimpleGeneralMessage contracts that were previously deployed if you’re in a major time crunch.

Network SimpleGeneralMessage Address
Ropsten Testnet 0xb96f012b2879117F9D4a2393Bd630202D6D4ba38
Polygon Mumbai 0x06071356e3A09EA6365f63744aC5a4e0B2EE1f68
Avalanche Fuji 0x06071356e3A09EA6365f63744aC5a4e0B2EE1f68
Fantom Testnet 0x06071356e3A09EA6365f63744aC5a4e0B2EE1f68
Moonbase Alpha 0xaeA7F9E44eda220fa10206690de9aB7852047B51

Sending a Cross Chain Message from Moonbase with Axelar

To send a cross-chain message with an automatic destination chain transaction, you first need to know how much gas to spend on the destination chain. In this example, Moonbase Alpha’s native currency DEV is being used to pay for the gas. The testnet treats each testnet’s price as equal to its mainnet’s price (GLMR is the mainnet equivalent of DEV). At the time of writing, ETH is much more expensive than AVAX, so the gas price & conversion from DEV to rETH (Ropsten ETH) will be much higher than DEV to Fuji AVAX.

To calculate the conversion of origin chain (Moonbase Alpha) currency to destination chain gas, you can use this script, which uses the Axelar javascript SDK. But to be fast, the equivalent of 100000 gas in DEV Wei for each chain is listed below (at the time of writing). 100000 should be more than enough for most short strings, but paragraphs and essays could cause an issue.

  • Ropsten Testnet: 356806741787800000
  • Polygon Mumbai: 3390032863000000
  • Avalanche Fuji: 97036323830100000
  • Fantom Testnet: 55389864900000

Now that you have the gas fee converted to wei, you can start to use the Remix interface. This example is going to send a cross-chain message to the Fantom testnet, but you can substitute the gas value and chain name for whichever EVM you desire. Check the following things:

  • The environment is “Injected Provider – Web3” on network 1287 (Moonbase Alpha)
  • You have substantial funds in your wallet from the faucet to cover both the transaction cost and the DEV calculated above
  • You have the gas fee calculated in the previous step placed in the value input
  • Put a short message of your choice in the message input of the sendMessage call (in this case “ghost of the moon”)
  • Put the destination chain’s SimpleGeneralMessage contract address in the destinationAddress input of the sendMessage call. This should be either an address that you deployed (recommended) or one of the listed pre-deployed
  • Put “Fantom” (or the canonical name of the mainnet for whichever testnet EVM you want to use) in the destinationChain input of the sendMessage call

Once this is all done, transact the execution and confirm it in MetaMask.

Axelar connected contracts

Tracking Cross Chain Messages

After sending your transaction, you should be able to go into the Moonbase block explorer to take a look at the transaction using its transaction hash. If everything went well, it should be confirmed, and you’ll be able to see traces of the input of your transaction at the very bottom when viewing it as UTF-8.

axelar connected contracts

In a typical transaction, you would be able to see the status and data of the transaction on a single page on a single explorer. But, since this is cross-chain messaging, there are really two EVM transactions happening on two chains.

To truly see if your transaction has been successful, go to the Axelarscan testnet explorer and find your transaction. You can search for a transaction by using the same transaction hash as the one outputted by Remix (on the origin chain). You should see something like this:

Axelar connected contracts

If everything goes smoothly, your transaction will be approved and you will be able to see the lastMessage updated in the origin chain from your successful cross-chain transaction! If it doesn’t automatically update, don’t worry. On average, it takes a few minutes for confirmations to go through on the testnet. The Axelar team is always working to improve the speed of its network, but keep in mind that in the past it has taken longer, so don’t worry if your transaction doesn’t finish immediately.

If you want to see the message stored in the contract, you can do so through Remix. First, connect to the destination network through Metamask. Make sure that you are on the “Injected Provider” environment and that the contract is still “SimpleGeneralMessage”. Then take the address of the destination contract, and paste it into the “At Address” input. Press it, and you should be able to use the outcome contract to view the last message.

Axelar connected contracts

Learn More About Connected Contracts

Moonbeam’s vision for an interoperable hub of networks doesn’t stop here. Learn more about Axelar on their website, general message passing in Axelar’s docs, and read about how Moonbeam is shaping up to be the leader in blockchain interoperability on our connected-contracts page.

If you are interested in Moonbeam and want to learn more, subscribe to our newsletter and follow us on social (links in the page header).

Jeremy Boetticher, PureStake

Author Jeremy Boetticher, PureStake

More posts by Jeremy Boetticher, PureStake