Розробка системи підписок на контент за токени з автоподовженням

Традиційні підписки забирають комісію та централізують контроль, залишаючи автора без прямого зв'язку з аудиторією. Ми розробляємо систему підписок на контент за токени з автоподовженням під ключ — на смарт-контрактах, з шифруванням та автоматичним продовженням, забезпечуючи надійну роботу та підтримку.
Часті запитання

Ми розробляємо системи токен-гейтингу контенту під ключ. На відміну від традиційних підписок (Patreon, Medium), де управління доступом централізоване і creator платить комісію платформі (до 12%), наше рішення базується на смарт-контрактах. Платежі проходять безпосередньо від підписника до автора, а доступ до контенту верифікується on-chain. Реалізація такої схеми вимагає вирішення кількох технічних викликів: шифрування контенту з доступом лише для підписників, автоматичне продовження підписки та організація tiered access без зайвих газових витрат. Нижче розберемо архітектуру, яку ми використовуємо в продакшені — від вибору стандарту токена до інтеграції децентралізованого шифрування. Наш стек: Solidity 0.8.x, Foundry, Lit Protocol, IPFS, Chainlink Automation. Наводяться конкретні приклади коду та конфігів.

Як обрати оптимальний стандарт токена для підписки?

Кожен стандарт вирішує свою задачу. ERC-1155 став індустріальним стандартом для тимчасових підписок: він використовує batch transfer та динамічну генерацію tokenId на основі періоду, знижуючи газові витрати на 30–50% порівняно з ERC-721 при масових продовженнях. ERC-721 краще підходить для довічних NFT-членств з можливістю перепродажу та роялті за ERC-2981. ERC-20 стейкінг — найпростіший варіант, але він заморожує ліквідність користувача.

Модель Тип підписки Перепродаж Газ під час mint Роялті
ERC-721 Довічна / обмежена Так Високий ERC-2981
ERC-1155 Тимчасова (за періодами) Ні Середній (batch - низький) Ні
ERC-20 стейкінг Безперервна Ні (тільки анстейк) Дуже низький Ні

Приклад структури контракту підписки:

contract ContentSubscription {
    struct SubscriptionTier {
        uint256 pricePerMonth; // в wei або ERC-20 токенах
        address paymentToken; // address(0) = native ETH
        uint256 maxSubscribers; // 0 = unlimited
        string contentCID; // IPFS CID для зашифрованого контенту
        bytes32 encryptionKeyHash; // хеш ключа шифрування для цього тиру
    }

    struct Subscription {
        uint256 tierId;
        uint256 expiresAt;
        uint256 startedAt;
        bool autoRenew;
    }

    mapping(uint256 => SubscriptionTier) public tiers;
    mapping(address => mapping(uint256 => Subscription)) public subscriptions;

    address public creator;
    uint256 public platformFeeBps = 250; // 2.5%

    modifier onlyCreator() {
        require(msg.sender == creator, "Not creator");
        _;
    }

    function subscribe(uint256 tierId, uint256 months, bool autoRenew) external payable {
        SubscriptionTier memory tier = tiers[tierId];
        uint256 totalCost = tier.pricePerMonth * months;

        if (tier.paymentToken == address(0)) {
            require(msg.value >= totalCost, "Insufficient ETH");
        } else {
            IERC20(tier.paymentToken).transferFrom(msg.sender, address(this), totalCost);
        }

        Subscription storage sub = subscriptions[msg.sender][tierId];
        // Продовження існуючої або нова підписка
        uint256 currentExpiry = sub.expiresAt > block.timestamp ? sub.expiresAt : block.timestamp;
        sub.expiresAt = currentExpiry + months * 30 days;
        sub.tierId = tierId;
        sub.autoRenew = autoRenew;
        if (sub.startedAt == 0) sub.startedAt = block.timestamp;

        _distributeRevenue(tier, totalCost);
        emit Subscribed(msg.sender, tierId, sub.expiresAt);
    }

    function isSubscribed(address user, uint256 tierId) external view returns (bool) {
        return subscriptions[user][tierId].expiresAt > block.timestamp;
    }

    function _distributeRevenue(SubscriptionTier memory tier, uint256 amount) internal {
        uint256 platformFee = amount * platformFeeBps / 10000;
        uint256 creatorAmount = amount - platformFee;

        if (tier.paymentToken == address(0)) {
            payable(creator).transfer(creatorAmount);
            payable(platform).transfer(platformFee);
        } else {
            IERC20(tier.paymentToken).transfer(creator, creatorAmount);
            IERC20(tier.paymentToken).transfer(platform, platformFee);
        }
    }
}

Як захистити контент від неавторизованого доступу?

Зберігати контент on-chain неможливо і безглуздо. Стандартна схема: контент шифрується і завантажується в IPFS, ключ шифрування видається лише верифікованим підписникам. Проблема: хто видає ключ? Якщо централізований сервер — немає сенсу в блокчейні. Рішення — Lit Protocol або Threshold Network: децентралізована мережа нод зберігає ключові шарди і видає доступ лише при виконанні on-chain умови. Реалізація на JavaScript:

import { LitNodeClient, checkAndSignAuthMessage } from '@lit-protocol/lit-node-client';

// Умова доступу: активна підписка на тир 1
const accessControlConditions = [
  {
    contractAddress: SUBSCRIPTION_CONTRACT_ADDRESS,
    standardContractType: '',
    chain: 'ethereum',
    method: 'isSubscribed',
    parameters: [':userAddress', '1'], // tierId = 1
    returnValueTest: {
      comparator: '=',
      value: 'true'
    }
  }
];

// Шифрування контенту (виконується creator'ом при завантаженні)
async function encryptContent(content) {
  const client = new LitNodeClient();
  await client.connect();
  const authSig = await checkAndSignAuthMessage({ chain: 'ethereum' });
  const { encryptedString, symmetricKey } = await LitJsSdk.encryptString(content);
  const encryptedSymmetricKey = await client.saveEncryptionKey({
    accessControlConditions,
    symmetricKey,
    authSig,
    chain: 'ethereum'
  });
  return { encryptedContent: encryptedString, encryptedKey: encryptedSymmetricKey };
}

// Розшифровка (користувач при читанні)
async function decryptContent(encryptedContent, encryptedKey) {
  const client = new LitNodeClient();
  await client.connect();
  const authSig = await checkAndSignAuthMessage({ chain: 'ethereum' });
  const symmetricKey = await client.getEncryptionKey({
    accessControlConditions,
    toDecrypt: encryptedKey,
    chain: 'ethereum',
    authSig
  });
  return await LitJsSdk.decryptString(encryptedContent, symmetricKey);
}

Чому Chainlink Automation — стандарт для автоподовження?

Автоподовження підписки вимагає зовнішнього тригера — смарт-контракт не може сам себе викликати за розкладом. Chainlink Automation (колишній Keepers) перевіряє умову checkUpkeep() і викликає performUpkeep() при необхідності:

contract AutoRenewSubscription is AutomationCompatibleInterface {
    function checkUpkeep(bytes calldata) external view override returns (bool upkeepNeeded, bytes memory performData) {
        // Знайти підписки, що закінчуються, з autoRenew=true
        address[] memory toRenew = _findExpiringSubscriptions();
        upkeepNeeded = toRenew.length > 0;
        performData = abi.encode(toRenew);
    }

    function performUpkeep(bytes calldata performData) external override {
        address[] memory toRenew = abi.decode(performData, (address[]));
        for (uint256 i = 0; i < toRenew.length; i++) {
            _attemptRenewal(toRenew[i]);
        }
    }

    function _attemptRenewal(address subscriber) internal {
        // Спроба списати кошти, якщо баланс достатній
        // При невдачі — подія, сповіщення користувача
    }
}

Chainlink Automation дешевший і надійніший за ручний виклик — він автоматизує продовження, знижуючи навантаження на користувача. Альтернативи (Gelato) теж працюють, але Chainlink дає більш щільну інтеграцію з екосистемою Ethereum.

Моделі монетизації для creator'а: порівняння

Модель Дохід Складність реалізації Приклад використання
Flat (фіксована) Передбачуваний Низька Новинні розсилки
Tiered access Максимальний при сегментації Середня Освітні платформи
Pay-per-content Низький поріг входу Висока Преміум-статті
NFT membership Роялті при перепродажі Середня Закриті спільноти

Вибір моделі залежить від аудиторії. Наприклад, для закритої спільноти з високою лояльністю підходить NFT membership, а для масового контенту — tiered access.

Що входить в нашу роботу

  • Аналіз моделі монетизації та вибір оптимального стандарту токенів.
  • Розробка та аудит смарт-контрактів (Solidity, Foundry) з покриттям тестами, включаючи fuzzing через Echidna.
  • Інтеграція децентралізованого шифрування (Lit Protocol / Threshold).
  • Налаштування IPFS-шлюзу та системи роздачі ключів.
  • Створення користувацького інтерфейсу (React + wagmi/viem, RainbowKit).
  • Підключення автоподовження через Chainlink Automation.
  • Розгортання в обраній мережі (Ethereum, Polygon, Arbitrum, Base).
  • Технічна документація та навчання команди.
  • Підтримка після запуску.
Досвід та гарантії

Ми реалізували 15+ проектів у сфері DeFi, NFT та токенізації контенту. Використовуємо власні бібліотеки перевірених смарт-контрактів, що скорочує ризики та час розробки. Гарантуємо стабільність роботи завдяки fuzzing-тестуванню (Echidna) та моніторингу on-chain. За статистикою, наші клієнти економлять до 30% на газі за рахунок оптимізації batch-операцій — при обсязі в $10 000 щомісячних транзакцій це $3 000 економії.

Терміни розробки

Базова система підписок з одним тиром, інтеграцією Lit Protocol та простим фронтендом — від 4 до 6 тижнів. Повноцінна платформа з tiered access, NFT membership, auto-renewal та аналітикою для creator'а — від 10 до 14 тижнів. Точні терміни залежать від складності інтеграцій та обсягу функціоналу.

Зв'яжіться з нами для отримання консультації та оцінки вашого проекту. Ми допоможемо спроектувати та впровадити систему підписок під ваш кейс. Замовте аналіз вашої моделі монетизації — це займе не більше години. Докладніше про стандарти можна прочитати у Wikipedia про ERC-1155.

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

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

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139