Разработка кросс-чейн мессенджинга (LayerZero, Wormhole, Axelar)
Interoperability — одна из нерешённых проблем блокчейн-индустрии. Ethereum не знает, что происходит на Solana. Arbitrum изолирован от Cosmos. Каждый кросс-чейн мост — это отдельная точка доверия, и история показывает, что это дорого обходится: Wormhole ($325M hack, 2022), Ronin ($625M, 2022), Nomad ($190M, 2022). Несмотря на это, cross-chain messaging — фундаментальная инфраструктура для любого multi-chain продукта. Разберём три основных протокола и как правильно с ними работать.
LayerZero: Omnichain messaging
LayerZero v2 — наиболее популярный протокол для EVM-to-EVM и EVM-to-non-EVM messaging. Архитектура основана на разделении ответственности: DVN (Decentralized Verifier Networks) верифицируют сообщения, Executors исполняют их на destination chain.
Как устроен протокол
Сообщение в LayerZero проходит путь:
Source Chain: OApp.send() → EndpointV2.send() → emit PacketSent event
↓
DVNs мониторят событие
DVNs верифицируют на destination
↓
Destination Chain: EndpointV2 получает верификации → Executor вызывает lzReceive()
DVN — это верификаторы, которые читают source chain и атестуют корректность пакета на destination chain. Можно настроить Required DVN + Optional DVN + threshold. Например: требуется 2 из 3 (LayerZero Labs DVN + Google Cloud DVN + Polyhedra DVN).
Написание 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, // destination endpoint ID (например, 30101 = Ethereum)
string calldata message,
bytes calldata options // gas limit для destination execution
) external payable {
bytes memory payload = abi.encode(message);
// Опции: сколько gas выделить на destination chain
bytes memory lzOptions = OptionsBuilder.newOptions()
.addExecutorLzReceiveOption(200_000, 0); // 200k gas, 0 msg.value
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)
);
}
// Получение сообщения на destination chain
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;
}
}
OFT: Omnichain Fungible Token
Наиболее популярный use case LayerZero — кросс-чейн токен. OFT стандарт позволяет токену нативно существовать на нескольких сетях без wrapped versions:
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) {}
}
На source chain токены burnятся, на destination chain mintятся. Общий supply остаётся константным. Никаких wrapped токенов, никаких liquidity pool'ов для bridging.
Wormhole: универсальный мессенджинг
Wormhole v2 поддерживает 30+ сетей включая Ethereum, Solana, Cosmos chains, Aptos, Sui — более широкое покрытие чем LayerZero. Архитектура: Guardian network из 19 нод (PoA) публикует VAA (Verifiable Action Approval) — подписанное подтверждение события на source chain.
Core механика VAA
import {
getSignedVAAWithRetry,
parseSequenceFromLogEth,
CHAIN_ID_ETH,
CHAIN_ID_SOLANA,
} from "@certusone/wormhole-sdk";
import { ethers } from "ethers";
// 1. Публикуем сообщение на ETH side
const coreBridge = new ethers.Contract(WORMHOLE_ETH_BRIDGE, BRIDGE_ABI, signer);
const tx = await coreBridge.publishMessage(
0, // nonce
payload, // bytes данные
1 // consistency level (finality требование)
);
// 2. Получаем sequence из receipt
const receipt = await tx.wait();
const sequence = parseSequenceFromLogEth(receipt, WORMHOLE_ETH_BRIDGE);
// 3. Ждём VAA от Guardians (обычно 15-60 секунд)
const { vaaBytes } = await getSignedVAAWithRetry(
["https://wormhole-v2-mainnet-api.certus.one"],
CHAIN_ID_ETH,
emitterAddress,
sequence,
{ retryTimeout: 1000, retryAttempts: 60 }
);
// 4. Редимаем на destination chain (например, Solana)
// vaaBytes содержит подписанный VAA, его нужно передать
// в программу на Solana для верификации и исполнения
Wormhole vs LayerZero: выбор
| Критерий | LayerZero v2 | Wormhole v2 |
|---|---|---|
| Поддерживаемые сети | ~50 (EVM-focused) | 30+ (включая non-EVM) |
| Модель безопасности | Configurable DVN | Guardian PoA (19 нод) |
| Токен стандарт | OFT (без liquidity) | NTT / xERC20 |
| Solana поддержка | Да | Да (нативно) |
| Developer tooling | Excellent | Good |
| Latency | ~2–5 мин (EVM→EVM) | ~15–60 сек |
Если нужно EVM-to-EVM — LayerZero v2. Если в проекте есть Solana, Aptos или Cosmos — смотрим на Wormhole.
Axelar: General Message Passing
Axelar — Cosmos-based blockchain, который выступает как routing layer между сетями. GMP (General Message Passing) — протокол для arbitrary вызовов смарт-контрактов на destination chain.
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";
contract CrossChainNFTBridge is AxelarExecutable {
IAxelarGasService immutable gasService;
constructor(address gateway, address _gasService)
AxelarExecutable(gateway) {
gasService = IAxelarGasService(_gasService);
}
function bridgeNFT(
string calldata destChain, // "Polygon", "Avalanche", etc.
string calldata destContract, // адрес контракта на destination
uint256 tokenId
) external payable {
bytes memory payload = abi.encode(msg.sender, tokenId);
// Оплата gas для execution на destination chain
gasService.payNativeGasForContractCall{value: msg.value}(
address(this), destChain, destContract, payload, msg.sender
);
gateway.callContract(destChain, destContract, payload);
_burnNFT(msg.sender, tokenId);
}
// Вызывается Axelar relayer на destination chain
function _execute(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) internal override {
(address recipient, uint256 tokenId) = abi.decode(payload, (address, uint256));
_mintNFT(recipient, tokenId);
}
}
Axelar особенно силён для Cosmos↔EVM bridging — нативная поддержка IBC позволяет маршрутизировать через всю Cosmos экосистему.
Безопасность кросс-чейн протоколов
Кросс-чейн мессенджинг — высокорисковая область. Несколько обязательных практик:
Rate limiting — ограничивайте объём средств, которые можно перевести за период. Если протокол скомпрометирован, это ограничивает потенциальный ущерб.
mapping(uint256 => uint256) public dailyVolume; // день → объём
function _checkRateLimit(uint256 amount) internal {
uint256 today = block.timestamp / 1 days;
dailyVolume[today] += amount;
require(dailyVolume[today] <= DAILY_LIMIT, "Daily limit exceeded");
}
Pause механизм — emergency pause на обе стороны bridge. Контролируется multisig с коротким timelock (или без него — для emergency).
Trusted path validation — на destination chain проверяйте, что сообщение пришло именно с вашего контракта на source chain, а не от произвольного вызывающего.
Избегайте хранить большие суммы в bridge контрактах — liquidity pool модель (lock-and-mint) создаёт огромный honeypot. Mint-and-burn (как в OFT) безопаснее.
Когда какой протокол выбрать
LayerZero — если строите omnichain токен (OFT), omnichain NFT, или EVM-to-EVM data messaging с требованием гибкой конфигурации безопасности.
Wormhole — если нужен Solana, Aptos, Sui, или максимально широкое покрытие сетей.
Axelar — если в архитектуре есть Cosmos chains, или нужен high-level GMP с абстракцией от конкретных сетей.
Для продакшн систем с реальными средствами: аудит cross-chain логики обязателен, и это должна быть команда с опытом именно в bridge security (Zellic, OtterSec, Trail of Bits).







