Ми розробляємо системи токен-гейтингу контенту під ключ. На відміну від традиційних підписок (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.







