Розробка NFT-gated контенту

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка NFT-gated контенту
Середній
~3-5 днів
Часті запитання

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

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

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

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

Розробка NFT-gated контенту

Типична помилка при реалізації NFT-gated доступу — перевіряти ownership тільки на фронтенді. Користувач підключає гаманець, JS робить ownerOf(tokenId), отримує адресу, порівнює з account з гаманця — все, доступ відкритий. Проблема: цю перевірку тривіально обійти з DevTools. Весь gating повинен відбуватись на бекенді, фронтенд тільки ініціює flow.

Як правильно верифікувати ownership

Схема з підписом сообщения (Sign-In With Ethereum)

Стандарт EIP-4361 (SIWE) — правильний путь. Користувач підписує стандартизоване сообщение своїм приватним ключем, бекенд верифікує підпис та перевіряє ownership контракту.

Схема:

  1. Фронтенд запитує у бекенду nonce для адреси (захист від replay-атак)
  2. Формує SIWE message — стандартний текст з доменом, адресою, nonce, timestamp, expiry
  3. Користувач підписує через гаманець (personal_sign)
  4. Бекенд верифікує підпис: відновлює адресу з підпису через ecrecover, перевіряє nonce, перевіряє timestamp, перевіряє ownerOf / balanceOf на контракті
// Backend verification (Node.js)
import { SiweMessage } from "siwe"
import { createPublicClient, http } from "viem"

async function verifyNFTAccess(message: string, signature: string, contractAddress: string) {
  const siweMessage = new SiweMessage(message)
  const { success, data } = await siweMessage.verify({ signature })

  if (!success) throw new Error("Invalid signature")
  if (data.nonce !== await getNonce(data.address)) throw new Error("Invalid nonce")
  if (new Date(data.expirationTime!) < new Date()) throw new Error("Expired")

  // Check NFT ownership on-chain
  const client = createPublicClient({ chain: mainnet, transport: http(RPC_URL) })
  const balance = await client.readContract({
    address: contractAddress,
    abi: ERC721_ABI,
    functionName: "balanceOf",
    args: [data.address as `0x${string}`]
  })

  if (balance === 0n) throw new Error("No NFT found")

  // Issue JWT session token
  return issueJWT(data.address)
}

Після успішної верифікації — JWT токен з коротким TTL (наприклад, 24 години). Повторна верифікація ownership при кожному запиті не потрібна — перевіряємо JWT, а ownership перепроверяємо при обновленні токена.

Гранулярний доступ: конкретний токен vs. будь-який з колекції

Два режими:

Collection-level gating: будь-який тримач токена колекції отримує доступ. Перевіряємо balanceOf(address) > 0. Швидко, дешево по RPC вызовам.

Token-specific gating: доступ тільки для тримача конкретного tokenId (наприклад, NFT-тікет на івент). Перевіряємо ownerOf(tokenId) == address. Потрібно зберігати маппинг tokenId → ресурс.

Trait-based gating: доступ тільки для NFT з визначеними атрибутами (рідкісні traits, визначений рівень). Либо on-chain запис атрибутів, либо верифицируемий маппинг з IPFS метаданих. Найскладніший варіант — потрібно заранее проіндексувати metadata колекції.

ERC-1155: multi-token gating

ERC-1155 відкриває більш гнучкі моделі. balanceOf(address, tokenId) повертає кількість токенів конкретного ID. Можна будувати tier-based доступ:

  • tokenId 1 = базовий доступ
  • tokenId 2 = премиум доступ
  • tokenId 3 = VIP доступ

Або: потрібно 10 токенів tokenId 1 для визначеної дії (gamification). Логіка складніша, але верифікується одним balanceOf вызовом.

Інфраструктура для масштабованого gating

Кеширування ownership даних

При активній аудиторії 10k+ користувачів перевіряти ownerOf на кожен запит — це нагрузка на RPC. Рішення: кеш з TTL.

User authenticates → check ownership → cache result (TTL: 5 min) → issue JWT (TTL: 24h)
На кожен API запит: перевіряємо JWT (локально, швидко)
При refresh JWT: перевіряємо кеш, якщо промах — йдемо до RPC

При трансфері NFT кеш застаріває за 5 хвилин — для більшості сценаріїв прийнятно. Якщо потрібна немедленна реакція на transfer — підписуємось на Transfer события через WebSocket та інвалідуємо кеш.

Моніторинг transfer события для відзиву доступу

Продаж NFT повинна немедленно відозвати доступ у продавця — критично для платних спільнот. Підписка на Transfer event через Alchemy/Infura WebSocket:

const filter = {
  address: NFT_CONTRACT,
  topics: [
    ethers.id("Transfer(address,address,uint256)"),
    null,  // from: any
    null   // to: any
  ]
}

provider.on(filter, (log) => {
  const [from, to, tokenId] = parseTransferEvent(log)
  revokeAccess(from)    // invalidate session for previous owner
  grantAccess(to)       // pre-cache for new owner
})

Мультичейн gating

Колекція може бути на Ethereum, а користувачі хочуть платити газ на Polygon — частий кейс для мостованих колекцій. Мультичейн gating: перевіряємо ownership на кількох чейнах, достатньо одного совпадения.

Moralis або Alchemy NFT API спрощують — single API call з указанням кількох чейнів:

const nfts = await alchemy.nft.getNftsForOwner(address, {
  contractAddresses: [CONTRACT_ETH, CONTRACT_POLYGON],
})
const hasAccess = nfts.ownedNfts.length > 0

Контент: що і як захищати

Статичний контент (PDF, відео, зображення): файли в S3/R2 з приватним доступом. Бекенд генерує signed URL з коротким TTL (15-60 хвилин) тільки для верифікованих тримачів. Прямі ссилки на файли не утекають.

Динамичний контент (сторінки, API дані): middleware перевіряє JWT токен перед кожним відповіддю. Без валідного JWT — 401.

Стриміння контент (live відео): аутентифікація через токен в query param або заголовку при підключенні до стриму. Після підключення — періодична ревалідація кожні N хвилин.

Строки розробки

SIWE інтеграція з базовим collection-level gating та JWT сесіями — 2 дні. Додавання Transfer event watcher та автоматичного відзиву доступу — ще 1 день. Trait-based gating з індексацією metadata — 1-2 дні залежно від розміру колекції. Мультичейн підтримка — ще 1-2 дні.

Повна система з моніторингом, кешуванням та мультичейн верифікацією — 4-5 робочих днів.