Cross-chain interaction is the bottleneck of any multi-chain architecture. We encounter daily cases where blockchain isolation hinders a product: tokens locked in one network, users unable to use DeFi on another. History remembers costly mistakes — Wormhole, Ronin, Nomad bridge hacks totaling billions of dollars. Let's explore how to build cross-chain messaging correctly using three top protocols: LayerZero, Wormhole, and Axelar. Cross-chain messaging is not just data transfer; it's an architecture of trust between isolated environments.
Why is cross-chain messaging hard?
The problem isn't sending data — technically that's trivial. The difficulty lies in trust: how to ensure that a message on the destination chain is valid and not forged? Each protocol solves this differently. LayerZero uses configurable DVNs, Wormhole uses a Guardian network of 19 nodes, Axelar uses Cosmos validators. The choice determines not only speed (from 15 seconds to 5 minutes) but also security.
LayerZero: Omnichain messaging
LayerZero v2 is the most popular protocol for EVM-to-EVM and EVM-to-non-EVM, supporting over 50 networks. The architecture separates verification and execution: DVNs (Decentralized Verifier Networks) confirm the message, Executors execute it on the destination chain. This allows configuring a security threshold: e.g., require 2 out of 3 (LayerZero Labs DVN + Google Cloud DVN + Polyhedra DVN).
How the protocol works
A message in LayerZero goes through the following path:
Source Chain: OApp.send() → EndpointV2.send() → emit PacketSent event
↓
DVNs monitor the event
DVNs verify on destination
↓
Destination Chain: EndpointV2 receives verifications → Executor calls lzReceive()
Writing an OApp (Omnichain Application)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { OApp, Origin, MessagingFee } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/OApp.sol";
import { OptionsBuilder } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/libs/OptionsBuilder.sol";
contract CrossChainMessenger is OApp {
using OptionsBuilder for bytes;
event MessageReceived(uint32 srcEid, bytes32 sender, string message);
constructor(address _endpoint, address _owner)
OApp(_endpoint, _owner) {}
function sendMessage(
uint32 dstEid,
string calldata message,
bytes calldata options
) external payable {
bytes memory payload = abi.encode(message);
bytes memory lzOptions = OptionsBuilder.newOptions()
.addExecutorLzReceiveOption(200_000, 0);
MessagingFee memory fee = _quote(dstEid, payload, lzOptions, false);
require(msg.value >= fee.nativeFee, "Insufficient fee");
_lzSend(dstEid, payload, lzOptions, MessagingFee(msg.value, 0), payable(msg.sender));
}
function _lzReceive(
Origin calldata origin,
bytes32 guid,
bytes calldata payload,
address executor,
bytes calldata extraData
) internal override {
string memory message = abi.decode(payload, (string));
emit MessageReceived(origin.srcEid, origin.sender, message);
}
function quoteSend(
uint32 dstEid,
string calldata message
) external view returns (uint256 nativeFee) {
bytes memory payload = abi.encode(message);
bytes memory options = OptionsBuilder.newOptions()
.addExecutorLzReceiveOption(200_000, 0);
MessagingFee memory fee = _quote(dstEid, payload, options, false);
return fee.nativeFee;
}
}
What is OFT and why is it needed?
The OFT standard allows a token to exist on multiple networks without wrapped versions: tokens are burned on the source chain and minted on the destination chain. The total supply remains constant. No liquidity pools, no lock-and-mint. This reduces impermanent loss risks and decreases the number of steps for the user.
import { OFT } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFT.sol";
contract MyOFTToken is OFT {
constructor(
string memory name,
string memory symbol,
address lzEndpoint,
address owner
) OFT(name, symbol, lzEndpoint, owner) {}
}
Wormhole: Universal messaging
Wormhole v2 supports 30+ networks: Ethereum, Solana, Cosmos, Aptos, Sui. Its architecture is a Guardian network of 19 nodes (PoA) that publish VAAs (Verifiable Action Approvals) — signed confirmations of events. Average gas cost for a VAA on Ethereum is $0.5–$2, and latency is 15–60 seconds.
Core VAA mechanics
import {
getSignedVAAWithRetry,
parseSequenceFromLogEth,
CHAIN_ID_ETH,
} from "@certusone/wormhole-sdk";
import { ethers } from "ethers";
const coreBridge = new ethers.Contract(WORMHOLE_ETH_BRIDGE, BRIDGE_ABI, signer);
const tx = await coreBridge.publishMessage(0, payload, 1);
const receipt = await tx.wait();
const sequence = parseSequenceFromLogEth(receipt, WORMHOLE_ETH_BRIDGE);
const { vaaBytes } = await getSignedVAAWithRetry(
["https://wormhole-v2-mainnet-api.certus.one"],
CHAIN_ID_ETH,
emitterAddress,
sequence,
{ retryTimeout: 1000, retryAttempts: 60 }
);
// vaaBytes contains the signed VAA for redemption on the destination chain
Wormhole vs LayerZero
| Criteria | LayerZero v2 | Wormhole v2 |
|---|---|---|
| Supported networks | ~50 (EVM-focused) | 30+ (including non-EVM) |
| Security model | Configurable DVN | Guardian PoA (19 nodes) |
| Token standard | OFT | NTT / xERC20 |
| Solana support | Yes | Yes (native) |
| Developer tooling | Excellent | Good |
| Latency | 2–5 min (EVM→EVM) | 15–60 sec |
If you need EVM-to-EVM — choose LayerZero v2. If your project includes Solana, Aptos, or Cosmos — look at Wormhole.
Axelar: General Message Passing
Axelar is a Cosmos-based blockchain acting as a routing layer. GMP (General Message Passing) allows arbitrary smart contract calls. It is strong for Cosmos↔EVM bridging via IBC.
import { AxelarExecutable } from "@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol";
import { IAxelarGasService } from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol";
contract CrossChainNFTBridge is AxelarExecutable {
IAxelarGasService immutable gasService;
constructor(address gateway, address _gasService)
AxelarExecutable(gateway) {
gasService = IAxelarGasService(_gasService);
}
function bridgeNFT(
string calldata destChain,
string calldata destContract,
uint256 tokenId
) external payable {
bytes memory payload = abi.encode(msg.sender, tokenId);
gasService.payNativeGasForContractCall{value: msg.value}(
address(this), destChain, destContract, payload, msg.sender
);
gateway.callContract(destChain, destContract, payload);
// _burnNFT logic
}
function _execute(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) internal override {
(address recipient, uint256 tokenId) = abi.decode(payload, (address, uint256));
// _mintNFT logic
}
}
Protocol security comparison
| Protocol | Trust model | Risks |
|---|---|---|
| LayerZero | DVN (configurable) | DVN compromise |
| Wormhole | Guardian (19 nodes) | Guardian collusion |
| Axelar | Cosmos validators | 1/3 slashing condition |
What is included in cross-chain solution development
- Analytics: protocol selection, architecture design, gas cost estimation.
- Development: smart contracts (Solidity/Rust), off-chain relay services, frontend integration.
- Testing: unit tests, integration tests on testnet, fuzzing with Echidna.
- Audit: internal code review, external auditors (Zellic, OtterSec).
- Deployment: mainnet setup, monitoring configuration (Tenderly, Etherscan API).
- Documentation: API reference, deploy guide, troubleshooting.
How to ensure cross-chain transfer security?
Rate limiting — cap the amount of funds: if the protocol is compromised, the damage is limited. Pause mechanism with multisig (no timelock for emergencies). Trusted path validation — check that the message came from your contract.
How to choose a protocol for cross-chain messaging?
LayerZero — if you are building an omnichain token (OFT), omnichain NFT, or EVM-to-EVM data messaging with flexible security.
Wormhole — if you need Solana, Aptos, or Sui, or the widest network coverage.
Axelar — if your architecture includes Cosmos chains, or you need high-level GMP with network abstraction.
We have integrated cross-chain components in 15+ projects — from NFT bridges to DeFi aggregators. Get a consultation on cross-chain solution architecture — we will analyze your requirements and suggest the optimal protocol. Order the development of a secure bridge for your project.







