Реализация Token-Gated контента (доступ по владению токеном) на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация Token-Gated контента (доступ по владению токеном) на сайте
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

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

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация Token-Gated контента (доступ по владению токеном) на сайте

Token Gating — механизм, при котором доступ к контенту или функциям сайта открывается только пользователям, владеющим определёнными NFT или токенами в своём кошельке. Проверка баланса происходит через RPC-вызов к блокчейну.

Логика Token Gating

Пользователь подключает кошелёк
         │
Сайт проверяет баланс токенов через RPC
         │
    [Есть токен?]
    │           │
   Да          Нет
    │           │
[Доступ        [Предложить купить
 открыт]        токен / уведомление]

Проверка ERC-20 баланса

import { createPublicClient, http, parseAbi } from 'viem';
import { mainnet } from 'viem/chains';

const client = createPublicClient({
  chain: mainnet,
  transport: http(process.env.ETHEREUM_RPC_URL)
});

const ERC20_ABI = parseAbi([
  'function balanceOf(address owner) view returns (uint256)',
  'function decimals() view returns (uint8)'
]);

async function checkERC20Balance(
  walletAddress: string,
  tokenContractAddress: `0x${string}`,
  minBalance: bigint
): Promise<boolean> {
  const balance = await client.readContract({
    address: tokenContractAddress,
    abi: ERC20_ABI,
    functionName: 'balanceOf',
    args: [walletAddress as `0x${string}`]
  });

  return balance >= minBalance;
}

// Пример: нужно >= 100 токенов EXAMPLE
const hasAccess = await checkERC20Balance(
  userWalletAddress,
  '0xYourTokenContract',
  100n * 10n ** 18n  // 100 токенов с 18 decimals
);

Проверка NFT (ERC-721)

const ERC721_ABI = parseAbi([
  'function balanceOf(address owner) view returns (uint256)',
  'function ownerOf(uint256 tokenId) view returns (address)'
]);

async function checkNFTOwnership(
  walletAddress: string,
  nftContract: `0x${string}`,
  specificTokenId?: bigint
): Promise<boolean> {
  if (specificTokenId !== undefined) {
    // Проверить владение конкретным токеном
    const owner = await client.readContract({
      address: nftContract,
      abi: ERC721_ABI,
      functionName: 'ownerOf',
      args: [specificTokenId]
    });
    return owner.toLowerCase() === walletAddress.toLowerCase();
  }

  // Проверить наличие хотя бы одного токена
  const balance = await client.readContract({
    address: nftContract,
    abi: ERC721_ABI,
    functionName: 'balanceOf',
    args: [walletAddress as `0x${string}`]
  });
  return balance > 0n;
}

Middleware для защиты роутов

// Серверная проверка при каждом защищённом запросе
async function tokenGateMiddleware(req, res, next) {
  const user = req.user;  // JWT с walletAddress

  if (!user?.walletAddress) {
    return res.status(401).json({ error: 'Wallet not connected' });
  }

  // Кеширование результата проверки (5 минут) — RPC-вызовы платные
  const cacheKey = `token_gate:${user.walletAddress}:${TOKEN_CONTRACT}`;
  const cached = await redis.get(cacheKey);

  if (cached !== null) {
    if (cached === '0') return res.status(403).json({ error: 'Token required' });
    return next();
  }

  const hasToken = await checkNFTOwnership(user.walletAddress, TOKEN_CONTRACT);
  await redis.setex(cacheKey, 300, hasToken ? '1' : '0');

  if (!hasToken) {
    return res.status(403).json({
      error: 'Access denied',
      requiredToken: TOKEN_CONTRACT,
      purchaseUrl: 'https://opensea.io/collection/your-nft'
    });
  }

  next();
}

// Применение к роутам
app.get('/premium/content', authenticate, tokenGateMiddleware, getContent);
app.get('/members-only/*', authenticate, tokenGateMiddleware, handleMemberRoute);

Морально стойкий подход: кеширование с инвалидацией

Баланс токенов может измениться (пользователь продал NFT). Инвалидация кеша через блокчейн-события:

// Слушатель Transfer-событий NFT
const ERC721_TRANSFER_ABI = parseAbi([
  'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)'
]);

client.watchContractEvent({
  address: TOKEN_CONTRACT,
  abi: ERC721_TRANSFER_ABI,
  eventName: 'Transfer',
  onLogs: async (logs) => {
    for (const log of logs) {
      // Инвалидируем кеш для отправителя и получателя
      await redis.del(`token_gate:${log.args.from}:${TOKEN_CONTRACT}`);
      await redis.del(`token_gate:${log.args.to}:${TOKEN_CONTRACT}`);
    }
  }
});

Сроки

Token Gating с ERC-20/ERC-721 проверкой, кешированием и middleware — 3–5 дней.