Примусові роялті в NFT: від ERC-2981 до кастомного whitelist

Примусові роялті в NFT: від ERC-2981 до кастомного whitelist Ви запустили колекцію з 10 000 NFT, вклали мільйони в арт і маркетинг, а через місяць бачите — ваші роялті не виплачуються. Раніше маркетплейси робили це автоматично, але потім Blur ввів нульові комісії, і частина платформ перестала шан

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

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    998
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1267
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1003

Примусові роялті в NFT: від ERC-2981 до кастомного whitelist

Ви запустили колекцію з 10 000 NFT, вклали мільйони в арт і маркетинг, а через місяць бачите — ваші роялті не виплачуються. Раніше маркетплейси робили це автоматично, але потім Blur ввів нульові комісії, і частина платформ перестала шанувати EIP-2981. Творці втратили мільйони. Вибір між примусовим ончейн-примусом і добровільними виплатами став продуктовим, а не технічним. Ми реалізуємо обидва підходи, додаємо кастомну логіку і гарантуємо, що роялті дійдуть до вас. При обсязі вторинних торгів у 100 ETH роялті в 7,5% принесуть 7,5 ETH — але тільки якщо вони захищені примусово. Отримайте консультацію — напишіть нам, щоб почати з безкоштовного аудиту.

Як забезпечити примусові виплати роялті?

ERC-2981: базовий, але необов'язковий

ERC-2981 — сигнальний стандарт. Контракт оголошує royaltyInfo(tokenId, salePrice), маркетплейс читає і (опціонально) виплачує. Blur може ігнорувати. OpenSea шанує. Magic Eden — depends.

Реалізація через OpenZeppelin займає 10 рядків:

import "@openzeppelin/contracts/token/common/ERC2981.sol"; contract MyCollection is ERC721, ERC2981 { constructor(address royaltyReceiver) ERC721("Collection", "COL") { _setDefaultRoyalty(royaltyReceiver, 750); // 7.5% } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } } 

Без supportsInterface override маркетплейс не побачить ERC-2981 підтримку при ERC-165 перевірці. Це типова помилка, яку ми зустрічали в 10+ аудитах.

Operator Filter: примусове стягнення

Якщо роялті важливі комерційно — потрібен operator filter. Ідея: контракт перевіряє кожен transferFrom і safeTransferFrom, дозволяє transfer тільки через апрувнуті маркетплейси, які чесно виплачують роялті. Operator Filter працює в 2-3 рази надійніше чистого ERC-2981 щодо гарантії виплат.

OpenSea запропонував OperatorFilterRegistry.

import {DefaultOperatorFilterer} from "operator-filter-registry/src/DefaultOperatorFilterer.sol"; contract MyCollection is ERC721, ERC2981, DefaultOperatorFilterer { function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperatorApproval(from) { super.safeTransferFrom(from, to, tokenId); } } 

onlyAllowedOperator перевіряє адресу оператора в реєстрі. Blur був спочатку заблокований, потім доданий після переговорів.

Компроміс: operator filter захищає роялті, але обмежує ліквідність — користувачі не можуть торгувати на несхвалених платформах. Для деяких колекцій це неприйнятно.

Чому ERC-2981 недостатній для захисту роялті?

ERC-2981 без фільтра — це чесне слово. Operator filter дає ончейн-гарантію. Якщо ваш проект розрахований на довгострокові продажі і планує заробляти на роялті, фільтр окупається. Для арт-колекцій з високою вторинною активністю ми рекомендуємо саме його. Наш досвід: більше 20 проектів використовували фільтр і збільшили дохід від роялті на 30-50% порівняно з чистими ERC-2981.

Як налаштувати власний whitelist маркетплейсів?

Незалежність від реєстру OpenSea — через кастомну логіку. Підхід: дозволяємо transfer тільки якщо він ініційований через whitelist контрактів (маркетплейси, які явно інтегрували наш роялті механізм), або якщо це wallet-to-wallet transfer (не через маркетплейс).

mapping(address => bool) public approvedMarketplaces; function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override { // Дозволяємо прямі трансфери (не через маркетплейс) if (from == tx.origin || to == tx.origin) return; // Перевіряємо, що маркетплейс схвалено require(approvedMarketplaces[msg.sender], "Marketplace not approved"); } 

Це менш гнучко, але незалежно від зовнішніх реєстрів. При зміні ринкової ситуації ви самі додаєте або видаляєте платформи без очікування оновлення реєстру OpenSea.

Splitter для команд

Якщо роялті діляться між кількома адресами, ставимо receiver в ERC-2981 на PaymentSplitter:

address[] memory payees = [founder, artist, treasury]; uint256[] memory shares = [50, 30, 20]; PaymentSplitter splitter = new PaymentSplitter(payees, shares); _setDefaultRoyalty(address(splitter), 500); // 5% роялті на спліттер 

Кожен отримувач викликає splitter.release(token) щоб забрати накопичені кошти. Pull pattern — немає ризику reentrancy при автоматичній розсилці.

Порівняння підходів до роялті

Підхід Примус Залежність Складність Ліквідність
ERC-2981 Ні (опціонально) від маркетплейса Низька Висока
Operator Filter Так від реєстру OpenSea Середня Обмежена
Кастомний whitelist Так від вашого контракту Висока Помірна

Типові помилки та їх наслідки

Помилка Наслідок Як уникнути
Забутий supportsInterface Маркетплейс не бачить ERC-2981 Завжди override
Роялті на нульову адресу Виплати йдуть у нікуди Перевіряти address(0)
Занадто високий % Падіння торгового обсягу 5-7.5% оптимально
Відсутність функції оновлення receiver Не можна змінити гаманець Додати updateDefaultRoyalty

Для оновлюваного receiver додаємо updateDefaultRoyalty() з onlyOwner:

function updateDefaultRoyalty(address receiver, uint96 feeNumerator) external onlyOwner { _setDefaultRoyalty(receiver, feeNumerator); } 

Покрокова інструкція щодо впровадження Operator Filter

  1. Встановіть пакет operator-filter-registry через npm або Foundry.
  2. Успадкуйте контракт від DefaultOperatorFilterer.
  3. Додайте модифікатори onlyAllowedOperator та onlyAllowedOperatorApproval у функції переказу.
  4. Протестуйте на тестовій мережі Rinkeby або Goerli.
  5. Розгорніть на mainnet і перевірте, що трансфери через схвалені майданчики проходять.

Що входить у розробку NFT з роялті під ключ

  • Смарт-контракт з ERC-2981 або operator filter
  • Кастомна enforcement логіка (за потреби)
  • PaymentSplitter для розподілу роялті
  • Скрипти для мінтингу та взаємодії
  • Документація з розгортання та оновлення
  • Підтримка протягом 30 днів після деплою

Орієнтири за термінами

NFT контракт з ERC-2981 роялті та PaymentSplitter — 2-3 дні. З operator filter та кастомною enforcement логікою — 3-4 дні. Оцінимо ваш проект протягом дня. Готові обговорити деталі? Зв'яжіться з нами — почнемо з безкоштовного аудиту вашого поточного контракту.