Beyond Blockchain Bridges: An Introduction to Axelar Protocol

Beyond  Blockchain Bridges: An Introduction to Axelar Protocol

Blockchain is an amazing technology. It is a decentralized ledger that allows anyone to access its records, and also write to it. Blockchains are secured by default, relatively fast, and enable a lot of use cases that are not feasible with traditional technology.

Blockchain Drawback

Just as amazing as blockchains are, they have a major drawback - Blockchains fundamentally run in isolated environments. Each blockchain is its entity and runs parallel to one another, thereby making communication between blockchains quite difficult.

This seeming drawback is by design. Every blockchain has its native token. The native token is used to pay gas fees for transactions on the blockchain. To write to a blockchain, you have to pay a fee(gas fee) in the native token that helps to keep the miners happy and the chain as secure as possible. This is why inter-chain communication is difficult because one native token on one blockchain, cannot be used to pay gas fees on another blockchain.

The Interchain Problem

As a developer, to make your dApp(Decentralized Application) available on different blockchains, you must deploy a fresh smart contract on each blockchain, as a separate service. There is no virtually no communication between each instance of your contract. This forces your users to decide on which chain they want to interact with, depending on their available tokens.

For users, this interchain limitation has also staggered the number of innovative app choices in web3, as users are mostly limited to the dApps available on a particular blockchain ecosystem. For example, a borrowing protocol deployed on the Ethereum blockchain can only accept and process transactions from users connected to the Ethereum blockchain. Users on other blockchains will have to switch to the Ethereum network whenever they wish to interact with the contract. Furthermore, the execution of the protocol smart contract is only limited to the Ethereum blockchain. There is no possibility of interaction with say, the deployed instance on the Polygon network.

The Axelar Solution

The above challenge is what Axelar solves for both developers and users. Axelar is a unique interchain network that allows different blockchains to communicate seamlessly with each other. Axelar acts as a linker between blockchains, not just for token transfers, but also to enable interchain communication and execution.

Axelar solves the problem of inter-chain communication by implementing the General Message Passing(GMP) feature. GMP allows two different blockchains, say Ethereum and Polygon, to send messages and execute functions between each other.

The GMP is dependent on two services:

  1. Gateway service - This enables the execution of smart contracts between different chains.

  2. Gas Service - This converts one native token to another to allow the gateway execution.

This architecture has proven to be efficient, secure, and scalable. Axelar also allows the transfer of ERC-20 across supported chains. You can also build your token and register it on Axelar to enable inter-chain transfer!

To see this action, let us build a simple interchain smart contract. I will walk you through from code to deployment and also show you how two smart contracts on different blockchains can send messages to each other:

Smart Contract Interoperability with Axelar

To demonstrate the ease of interchain communication between smart contracts using Axelar, we will deploy a SendMessage smart contract to the Fantom and Celo network. Then we'll send a message from the smart contract on Fantom, and view the message on the Celo network, and vice versa. Let's Go!

I'll be using Remix, so you can follow along easily:

// SPDX-License-Identifier: MIT

pragma solidity ~0.8.9; //locked to ensure this code dosen't break in future

import { AxelarExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol';
import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';
import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol';
import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';

contract SendMessage is AxelarExecutable {}

First, we import the Axelar SDK. You can access the SDK in Remix, from the Axelar Github, or by running npm install @axelar-network/axelar-gmp-sdk-solidity if on a local development environment.

We then extend AxelarExecutable. This automatically gives our smart contract superpowers and enables interchain capabilities!

Let's now add functionalities to our smart contract, and I'll explain further.

//...
contract SendMessage is AxelarExecutable {
    //Stores the interchain message 
    string message;
    //stores the source chain name
    string public sourceChain;
    //stores the source chain address
    string public sourceAddress;

    //holds the gas service address
    IAxelarGasService public immutable gasService;

    //we update the Axelar gateway and Gas receiver on deployment
    constructor(address gateway_, address gasReceiver_) AxelarExecutable(gateway_) {
        gasService = IAxelarGasService(gasReceiver_);
    }

    //returns interchain message
    function getMessage() external view returns (string memory){
        return message;
    }

    //send interchain message. 
    /*
    @params destinationChain - the destination chain we wish to send message to
    @params destinationAddress - the smart contract address on the destination chain
    @params _msg - The message we wish to send. 
    */
    function sendMessage(string calldata destinationChain, string calldata destinationAddress, string calldata _msg) external payable {
        //Require native tokens for interchain communication. 
        //Axelar gas service converts this to the destination native token 
        require(msg.value > 0, "Please send gas fees");

        // the message is encoded into bytes
        bytes memory payload = abi.encode(_msg);

        //here we pay the gas receiver for conversion 
        gasService.payNativeGasForContractCall{ value: msg.value }(
            address(this),
            destinationChain,
            destinationAddress,
            payload,
            msg.sender
        );

        //We then call the gateway service that does the interchain 
        // communicaton with the payload!
        gateway.callContract(destinationChain, destinationAddress, payload);
    }

    //the execute function only runs on the destination chain
    function _execute(string calldata sourceChain_, string calldata sourceAddress_, bytes calldata payload_) internal override {
        //We decode the message from the source chain and 
        // store in our local variable
        (message) = abi.decode(payload_, (string));
        //We update the source chain & address
        sourceChain = sourceChain_;
        sourceAddress = sourceAddress_;
    }
}

The comments are self-explanatory, but I'll also summarize:

Remember we talked about the Gas and Gateway service above? Right. These are smart contracts that perform the Axelar interchain magic. Each Axelar-supported blockchain has a deployed Gas service and Gateway contract. You can find the full list here.

We save the Gateway and Gas service address on our contract deployment using the constructor. This way, our smart contract can call these services whenever we wish to perform an interchain communication.

To send an interchain message, we define a sendMessage() method that takes the destination chain name, address, and message we wish to send. This method calls gasService.payNativeGasForContractCall() to send Gas which is converted to the destination chain token, then, encodes the message and calls the Axelar gateway gateway.callContract() with the parameters.

Once the gas is paid, and Gateway executed, Axelar routes the message to the destination chain smart contract and calls the execute() method. The execution of the execute() method is paid in the destination gas fees converted from the Gas service. It is worth noting that any extra gas is refunded back to the source wallet.

Let's visualize it

We have written our interchain smart contract and now understand the concept. To see it in action, we'll deploy our sendMessage contract, using Remix, to Fantom and Celo networks by replicating these steps:

  1. Deploy SendMessage contract to Fantom network, using the Gas and Gateway service address on the Fantom network:

    • FTM Gateway: 0x97837985Ec0494E7b9C71f5D3f9250188477ae14

    • FTM Gas Service: 0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6

  2. Deploy SendMessage to the Celo network, using the Axelar Gas and Gateway service address on the Celo network:

    • Celo Gateway: 0xe432150cce91c13a887f7D836923d5597adD8E31

    • Celo Gas Service: 0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6

  3. On the Fantom network, call sendMessage() by passing "Celo" as the destination chain, the deployed SendMessage contract address deployed to the Celo network and the message you wish to send. Enter a gas fee of 1 FTM (Excess will be refunded).

  4. Copy the transaction hash and paste it into Axelar Scan to monitor the interchain transaction status.

  5. Once the interchain transaction is successful, you can call getMessage() function on the Celo network, and you should see the message was sent successfully!

  6. Repeat 3 to 5 from Celo to Fantom, and you should also get the sent message.

Congratulations, You just sent your first interchain message powered by Axelar General Message Passing. Welcome to the future of web3!

You can view my interchain transaction on Axelar Scan here

Conclusion

In this article, we discussed how the blockchain works and pointed out a big drawback which is blockchain interoperability. We saw how this has posed a big limitation to innovative dApp development and showed how Axelar solves this problem with finesse by utilizing Axelar's GMP. We deployed two smart contracts on different chains and sent messages between them. This is highly difficult to perform without the Axelar protocol.

Axelar is one technology I am excited about in the web3 ecosystem because it removes a huge barrier to entry by providing seamless integration between smart contracts which unlocks myriads of potential in the web3 ecosystem.

In my next article, I'll show you how I built an interchain verification system using Axelar. Kindly subscribe to get notified.

Thanks for reading! Feel free to drop any questions in the comments for more clarification, or send me a tweet!

Further Reading

Axelar Website - here

Axelar docs - here

Interoperable storage for web3 - here

UniSwap approves Axelar - here