Разработка omnichain-NFT (ONFT)

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка omnichain-NFT (ONFT)
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1058
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Разработка omnichain-NFT (ONFT)

NFT, привязанный к одному чейну — это актив с ограниченной ликвидностью. Коллекция на Ethereum имеет доступ к OpenSea и Blur, но отрезана от экосистемы Polygon, Arbitrum, Solana. Владелец, который хочет использовать NFT в игре на Immutable X или как collateral в DeFi-протоколе на Arbitrum — просто не может.

ONFT (Omnichain Non-Fungible Token) — стандарт LayerZero для NFT с нативным кросс-чейн трансфером. Не бридж с lock-and-mint рисками, а единый контракт, развёрнутый на нескольких чейнах, который атомарно перемещает NFT между ними без потери metadata и ownership истории.

Как ONFT работает на уровне протокола

LayerZero: endpoints и Ultra Light Node

LayerZero не является отдельным блокчейном. Это messaging protocol с Endpoint контрактами на каждом поддерживаемом чейне (~50+: Ethereum, Polygon, Arbitrum, Optimism, BSC, Solana, Aptos и другие).

Когда NFT отправляется из Ethereum в Arbitrum:

  1. sendFrom() на Ethereum вызывает Endpoint.send() с encoded payload (tokenId, recipient)
  2. LayerZero Oracle (Chainlink, Sequencer или Google Cloud) фиксирует block header на Arbitrum
  3. LayerZero Relayer передаёт proof транзакции
  4. Endpoint на Arbitrum верифицирует proof через Ultra Light Node (ULN) — не полная верификация блока, только нужный storage proof
  5. lzReceive() на ONFT контракте Arbitrum вызывается с payload, минтит NFT получателю

На исходном чейне NFT сжигается (или лочится в зависимости от реализации). На целевом — минтится. Общий supply не изменяется.

ONFT721 vs. собственная реализация

LayerZero предоставляет ONFT721 base contract в @layerzerolabs/solidity-examples. Это ERC-721 с добавленными функциями sendFrom и lzReceive. Простейшая ONFT реализация — наследование от ONFT721 с добавлением кастомной логики.

Ключевые параметры при деплое:

constructor(
    string memory name,
    string memory symbol,
    uint256 _minGasToTransfer, // минимальный газ для lzReceive на destination
    address _lzEndpoint        // LayerZero Endpoint адрес для данного чейна
) ONFT721(name, symbol, _minGasToTransfer, _lzEndpoint) {}

_minGasToTransfer критичен: если указать слишком мало — lzReceive на destination ревертится из-за out-of-gas, NFT «застревает» между чейнами. Рекомендация LayerZero: 200 000 gas для базового ONFT721, больше если lzReceive содержит дополнительную логику.

Проблемы, которые нужно решить при разработке

Синхронизация metadata при кросс-чейн трансфере

Metadata NFT хранится на IPFS или Arweave — это не проблема, URI одинаков на всех чейнах. Проблема с динамической metadata: если NFT имеет on-chain attributes (уровень персонажа в игре, накопленные очки), эти данные хранятся в storage контракта. При переносе на другой чейн on-chain state не переносится автоматически.

Решение: включить state в LayerZero payload. Кастомная _debitFrom на source упаковывает state, кастомная _creditTo на destination восстанавливает. Это увеличивает gas стоимость трансфера, но сохраняет полное состояние.

function _debitFrom(address _from, uint16, bytes memory, uint _tokenId)
    internal override returns(bytes memory) {
    // Собираем state токена
    TokenState memory state = tokenStates[_tokenId];
    _burn(_tokenId); // или lock
    return abi.encode(_tokenId, state); // включаем в payload
}

function _creditTo(uint16, address _toAddress, bytes memory _payload)
    internal override returns(uint) {
    (uint tokenId, TokenState memory state) = abi.decode(_payload, (uint, TokenState));
    _mint(_toAddress, tokenId);
    tokenStates[tokenId] = state; // восстанавливаем state
    return tokenId;
}

Оценка и оплата LayerZero fee

Трансфер через LayerZero не бесплатен: пользователь платит нативной валютой source чейна за:

  • Gas на source чейне (Endpoint.send)
  • Оракул и relayer fee (уходит в LayerZero)
  • Оценка газа на destination чейне (prepaid)

Клиентская часть обязана вызвать estimateSendFee() перед трансфером и передать результат как msg.value. Если msg.value меньше оценки — транзакция ревертится.

function estimateSendFee(
    uint16 _dstChainId,
    bytes calldata _toAddress,
    uint _tokenId,
    bool _useZro,
    bytes calldata _adapterParams
) public view returns (uint nativeFee, uint zroFee);

Типичная стоимость трансфера ETH → Arbitrum: $0.50–2.00 в ETH в зависимости от congestion.

Trusted Remote конфигурация

Каждый ONFT контракт на каждом чейне должен знать адреса своих «собратьев» на других чейнах. Это trustedRemote — авторизованный список. Без этого любой контракт мог бы минтить ONFT через LayerZero message.

// Выполняется после деплоя на каждом чейне
function setTrustedRemoteAddress(
    uint16 _remoteChainId,   // LayerZero chain ID
    bytes calldata _remoteAddress
) external onlyOwner;

Ошибка: забыть установить trusted remote bidirectionally. Трансфер Ethereum→Polygon работает, Polygon→Ethereum нет — потому что Polygon контракт не добавил Ethereum в trusted remote.

nonce и ordering гарантии

LayerZero v1 гарантирует ordered delivery: сообщения между двумя чейнами доставляются в порядке отправки. Если транзакция с nonce N застряла (релейер не доставил) — все последующие с nonce N+1, N+2 ждут. Это может заблокировать все трансферы из конкретного чейна.

LayerZero v2 (2024) переходит на unordered delivery с application-level ordering — более гибкая модель, не блокирует очередь.

Стек для полноценного ONFT проекта

Контракты: Solidity 0.8.x, @layerzerolabs/lz-evm-oapp-v2 (для LZ v2) или @layerzerolabs/solidity-examples (LZ v1), OpenZeppelin ERC721.

Тестирование: Foundry с LZEndpointMock — mock LayerZero endpoint для локального тестирования кросс-чейн вызовов без реального оракула. Тест: отправить с chain A, проверить mint на chain B.

Frontend: wagmi/viem для мультичейн поддержки, переключение сети при трансфере, отображение estimated fee через estimateSendFee.

Деплой: Foundry scripts для параллельного деплоя на несколько чейнов + скрипт установки trustedRemote для всех пар.

Процесс и сроки

Проектирование (1 день): список целевых чейнов, наличие on-chain state для синхронизации, кастомная логика в _debitFrom/_creditTo.

Разработка контрактов (2–3 дня): ONFT721 с кастомной логикой, тесты через LZEndpointMock.

Frontend компонент (1 день): бридж-интерфейс с выбором destination chain, fee estimation, статус трансфера.

Деплой и конфигурация (0.5 дня): деплой на все чейны, установка trustedRemote.

Итого: 3–5 дней для базового ONFT без on-chain state. С синхронизацией сложного state — 1–2 недели. Стоимость рассчитывается индивидуально.