Разработка мультичейн-токена

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Разработка мультичейн-токена
Сложный
~1-2 недели
Часто задаваемые вопросы

Направления блокчейн-разработки

Этапы блокчейн-разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1307
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1219
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    920
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1148
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    611
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    886

Разработка мультичейн-токена

Мультичейн-токен — это не просто деплой одного и того же ERC-20 на несколько сетей. Это архитектурное решение с серьёзными последствиями для supply management, безопасности и UX. Неправильно спроектированный мультичейн-токен создаёт иллюзию единого актива при реально раздробленном supply, открывает поверхность для bridge-атак и усложняет governance. Разберём, как это делается правильно.

Модели мультичейн-токена

Прежде чем писать код, нужно выбрать архитектурную модель. Их три, и они фундаментально различаются.

Lock & Mint (каноническая модель)

Токен существует нативно на одном чейне (home chain, обычно Ethereum). На всех остальных чейнах существуют wrapped версии. Bridge блокирует токены на home chain и минтит wrapped на destination chain. При бриджинге обратно — burning wrapped, unlock оригинала.

Плюсы: единый canonical supply, простая ментальная модель для пользователей.

Минусы: если bridge взломан — злоумышленник может минтить wrapped токены без обеспечения. Так был взломан Wormhole ($320M в 2022) и Ronin Bridge ($625M).

Burn & Mint (omnichain модель)

При трансфере токен сжигается на source chain и минтится на destination chain. Total supply глобально постоянен. Этот подход используют LayerZero OFT (Omnichain Fungible Token) и Axelar ITS.

Плюсы: нет locked liquidity на одном чейне, равноценность токенов на всех сетях.

Минусы: транзакция не атомарна — токен уничтожен на source, но может не доминтиться на destination при сбое. Нужен механизм recovery.

Liquidity Pool модель

Независимые токены на каждом чейне соединены через AMM-пулы в bridge-протоколах (Stargate, Synapse). Bridge нативного свопа, не wrapped tokens.

Плюсы: мгновенность (атомарный своп из пула), нет wrapped токенов.

Минусы: требует bootstrap liquidity на каждом чейне, slippage при несбалансированных пулах.

Реализация через LayerZero OFT

LayerZero стал де-факто стандартом для новых мультичейн-токенов. OFT (Omnichain Fungible Token) — burn & mint модель с messaging через LayerZero Endpoint.

Базовая реализация OFT

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

import { OFT } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFT.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";

contract MyToken is OFT {
    constructor(
        string memory _name,
        string memory _symbol,
        address _lzEndpoint,   // LayerZero Endpoint адрес для текущей сети
        address _delegate
    ) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {}

    // Минтинг только при деплое или через governance
    function mint(address _to, uint256 _amount) external onlyOwner {
        _mint(_to, _amount);
    }
}

На home chain деплоим этот контракт и минтим весь supply. На остальных чейнах деплоим тот же контракт, но без начального минтинга — токены туда приходят через bridge.

Конфигурация OFT после деплоя

После деплоя на всех чейнах нужно связать контракты через setPeer:

// На каждом чейне для каждой другой сети
function configurePeers() external onlyOwner {
    // eid = endpoint ID в системе LayerZero
    // Ethereum mainnet: 30101, Arbitrum: 30110, Base: 30184, BSC: 30102

    // Если мы на Ethereum, регистрируем Arbitrum peer
    oft.setPeer(30110, bytes32(uint256(uint160(ARBITRUM_OFT_ADDRESS))));

    // Регистрируем Base peer
    oft.setPeer(30184, bytes32(uint256(uint160(BASE_OFT_ADDRESS))));
}

Отправка токенов между чейнами

// Подготовка параметров для cross-chain transfer
function bridgeTokens(
    uint32 _dstEid,       // destination endpoint ID
    address _recipient,
    uint256 _amount
) external payable {
    SendParam memory sendParam = SendParam({
        dstEid: _dstEid,
        to: bytes32(uint256(uint160(_recipient))),
        amountLD: _amount,
        minAmountLD: (_amount * 995) / 1000, // 0.5% slippage tolerance
        extraOptions: OptionsBuilder.newOptions()
            .addExecutorLzReceiveOption(200000, 0), // gas на destination
        composeMsg: "",
        oftCmd: ""
    });

    // Получаем quote на native fee для оплаты LayerZero messaging
    MessagingFee memory fee = oft.quoteSend(sendParam, false);

    oft.send{ value: fee.nativeFee }(sendParam, fee, payable(msg.sender));
}

Управление supply между чейнами

Это самый сложный аспект. Нужен мониторинг:

Метрика Как отслеживать
Supply per chain Вызов totalSupply() на каждом деплое
Circulating supply Сумма всех totalSupply() минус locked в bridge контрактах
Bridge flow Ивенты OFTSent / OFTReceived
Pending messages LayerZero Scan API

Для Lock & Mint модели (если используете кастомный bridge) нужен invariant check: sum(wrapped supplies) <= locked_on_home_chain. Мониторинг через Tenderly или собственный скрипт с алертингом в PagerDuty.

Безопасность мультичейн-токена

DVN (Decentralized Verifier Network) конфигурация

LayerZero V2 позволяет настраивать, какие верификаторы должны подтвердить сообщение перед исполнением. Минимальная безопасная конфигурация — 2 из N верификаторов:

// Настройка ULN (Ultra Light Node) конфигурации
UlnConfig memory ulnConfig = UlnConfig({
    confirmations: 15,           // блоков для finality
    requiredDVNCount: 2,         // минимум 2 DVN должны подтвердить
    optionalDVNCount: 0,
    optionalDVNThreshold: 0,
    requiredDVNs: [LAYERZERO_DVN, GOOGLE_CLOUD_DVN],
    optionalDVNs: new address[](0)
});

Для production рекомендуется использовать LayerZero DVN + один независимый DVN (Google Cloud, Nethermind, p2p.org).

Rate limiting

Даже с надёжным bridge — добавьте rate limiting на уровне токен-контракта как последнюю линию защиты:

// Ограничение на максимальный transfer за период
mapping(uint256 => uint256) public dailyBridgeVolume; // day => volume
uint256 public constant MAX_DAILY_BRIDGE = 1_000_000e18; // 1M токенов/день

modifier withRateLimit(uint256 amount) {
    uint256 today = block.timestamp / 1 days;
    require(
        dailyBridgeVolume[today] + amount <= MAX_DAILY_BRIDGE,
        "Daily bridge limit exceeded"
    );
    dailyBridgeVolume[today] += amount;
    _;
}

Если bridge взломан — rate limit даст время на реакцию, ограничив ущерб.

Pause механизм

Контракт должен иметь pause функцию, управляемую мультисигом с коротким timelock (или без него — для экстренных случаев). При обнаружении аномального bridge activity — мгновенная остановка передач.

Деплой и инфраструктура

Последовательность деплоя

  1. Деплой на home chain, минтинг supply
  2. Деплой на все destination chains
  3. Вызов setPeer на каждом чейне для каждой пары
  4. Верификация: тестовый bridge transfer небольшой суммы
  5. Мониторинг: настройка алертов на bridge events

Сети и LayerZero Endpoint IDs (актуальные)

Сеть Endpoint ID Chain ID
Ethereum 30101 1
Arbitrum One 30110 42161
Base 30184 8453
Optimism 30111 10
BSC 30102 56
Polygon 30109 137
Avalanche 30106 43114

Скрипт деплоя через Hardhat

// scripts/deploy-oft.ts
import { ethers } from "hardhat";
import { EndpointId } from "@layerzerolabs/lz-definitions";

async function main() {
    const [deployer] = await ethers.getSigners();

    const lzEndpoint = getEndpointForNetwork(network.name);

    const OFT = await ethers.getContractFactory("MyToken");
    const oft = await OFT.deploy(
        "My Token",
        "MYT",
        lzEndpoint,
        deployer.address
    );
    await oft.waitForDeployment();

    console.log(`OFT deployed to: ${await oft.getAddress()}`);

    // Минтинг только на home chain
    if (network.name === "ethereum") {
        await oft.mint(deployer.address, ethers.parseEther("100000000"));
    }
}

Governance и мультичейн-токен

Если токен используется для governance — возникает проблема: как считать voting power при распределённом supply? Три подхода:

Hub-and-spoke: голосование только на home chain. Пользователи с других чейнов должны bridge токены обратно. Просто, но UX плохой.

Cross-chain voting: off-chain snapshot голосов на всех чейнах, агрегация через LayerZero или Axelar. Использует Snapshot + XCHAIN voting.

Dedicated governance token: отдельный non-transferable governance token на одном чейне, distribution token — мультичейн. Сложнее, но чище архитектурно.

Мультичейн-токен — это не feature, это commitment. Каждый новый чейн добавляет операционную нагрузку, аудит поверхность и риски. Добавляйте сети только там, где реально есть ликвидность и пользователи.