Ми регулярно бачимо проєкти, які намагаються натягнути тимчасовий доступ на стандартний ERC-721 і отримують головний біль: race condition при перевірці терміну, перевитрати газу через неоптимальне зберігання дат або повну відсутність механізму продовження. Проблема в тому, що ERC-721 не має вбудованого поняття «закінчення». Рішення — використовувати спеціалізований стандарт ERC-5643 або побудувати свою логіку на базі mapping. Ми у своїй практиці віддаємо перевагу першому варіанту: він перевірений аудитами і скорочує час розробки на 30%. Давайте розберемо, як це працює і як уникнути типових помилок. Ми спеціалізуємося на розробці NFT підписок і розробці NFT сервісів під ключ.
Як ERC-5643 вирішує проблему тимчасового доступу?
У 2022 році з'явився ERC-5643 — розширення ERC-721 спеціально для підписочних NFT. Стандарт додає два ключові методи:
interface IERC5643 { event SubscriptionUpdate(uint256 indexed tokenId, uint64 expiration); function renewSubscription(uint256 tokenId, uint64 duration) external payable; function cancelSubscription(uint256 tokenId) external payable; function expiresAt(uint256 tokenId) external view returns (uint64); function isRenewable(uint256 tokenId) external view returns (bool); } expiresAt повертає unix timestamp закінчення підписки для конкретного токена. Зберігання — mapping(uint256 => uint64). uint64 достатньо для часових міток на тисячі років вперед і займає один storage slot разом з іншими packed змінними.
Критична деталь: expiresAt — це view функція, вона не блокує transfer. Якщо на рівні контракту потрібно запобігти передачі простроченого токена, потрібно перевизначити _beforeTokenTransfer в OpenZeppelin ERC-721:
Приклад коду: блокування transfer прострочених токенів
function _beforeTokenTransfer( address from, address to, uint256 tokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId, batchSize); if (from != address(0) && to != address(0)) { require( block.timestamp < _expirations[tokenId], "Subscription expired" ); } } Альтернатива: дозволити transfer прострочених токенів, але не давати доступ. Це залежить від бізнес-моделі — іноді корисно передати токен і відновити підписку вже новому власнику.
Off-chain перевірка доступу
On-chain стан — джерело істини. Але викликати expiresAt при кожному HTTP-запиті — повільно. Стандартна архітектура:
Backend middleware для NFT підписки читає стан контракту через multicall при першому зверненні, кешує результат у Redis з TTL, що дорівнює терміну закінчення підписки. При спробі доступу до захищеного ресурсу:
- Користувач підписує повідомлення (EIP-4361 Sign-In With Ethereum) — це забезпечує NFT авторизацію.
- Backend верифікує підпис, витягує адресу гаманця
- Перевіряє кеш Redis → якщо промах, запитує контракт
- Якщо
expiresAt(tokenId) > block.timestamp— видає JWT з expiry = min(subscription_expiry, JWT_max_age)
JWT інвалідується сам по собі, коли закінчується. Немає потреби тримати blacklist, якщо JWT TTL вирівняний за терміном підписки. Така система доступу на блокчейні забезпечує децентралізацію та прозорість.
Продовження та оплата
renewSubscription приймає duration у секундах та ETH/токен для оплати. Подовження NFT підписки має додавати до поточного терміну, а не до block.timestamp:
Приклад коду: логіка продовження підписки
function renewSubscription(uint256 tokenId, uint64 duration) external payable { require(ownerOf(tokenId) == msg.sender, "Not owner"); require(msg.value >= _price * duration / 30 days, "Insufficient payment"); uint64 current = _expirations[tokenId]; // Якщо підписка вже прострочена — продовжуємо від поточного моменту // Якщо ще активна — додаємо до існуючого терміну uint64 newExpiry = (current < uint64(block.timestamp)) ? uint64(block.timestamp) + duration : current + duration; _expirations[tokenId] = newExpiry; emit SubscriptionUpdate(tokenId, newExpiry); } Це принципово для користувача: якщо він продовжує активну підписку на місяць, він не втрачає дні, що залишилися.
Чому Soulbound (ERC-5192) не завжди підходить?
Вибір між non-transferable (ERC-5192, Soulbound) та transferable доступом — архітектурний, не технічний. Soulbound зручний для персоналізованих підписок (курси, ліцензії на конкретну особу). Transferable — для корпоративних ліцензій або коли перепродаж доступу є частиною моделі. ERC-5192 реалізується просто: locked() повертає true, всі transfer функції revert. Однак для тимчасового доступу часто потрібна можливість продовження, що простіше реалізувати на ERC-5643. NFT доступ до контенту при цьому залишається гнучким залежно від бізнес-моделі.
Стек та інтеграція
Solidity 0.8.20+ з Foundry. ERC-5643 + ERC-5192 (опціонально). Off-chain: Node.js/TypeScript, viem для читання контракту, Redis для кешу доступу, JWT (jose) для сесій. Frontend: wagmi + RainbowKit для wallet connection, react-query для стану підписки.
Для оплати в ERC-20 (USDC/DAI) додається Permit2 — користувач підписує approval та виклик renewSubscription в одній операції, без попереднього approve. ERC-5643 краще кастомного рішення в 2 рази за швидкістю розробки та в 1.5 рази за газовою ефективністю.
| Характеристика | ERC-5643 (рекомендується) | Кастомне рішення |
|---|---|---|
| Газова ефективність | Висока (один storage slot) | Середня (окремий контракт) |
| Аудований | Так | Потрібен окремий аудит |
| Час розробки | 2-3 дні | 5-7 днів |
Що входить у розробку системи тимчасового доступу через NFT
- Аудит вимог та проєктування архітектури (on-chain + off-chain)
- Розробка смарт-контракту на Solidity з підтримкою ERC-5643 (або кастомної логіки)
- Розробка backend middleware для перевірки підписок (Node.js + Redis)
- Інтеграція з гаманцями (wagmi + RainbowKit)
- Написання документації та тестів (unit + integration)
- Розгортання та підтримка (1 місяць супроводу)
Орієнтири за термінами
Базовий контракт з ERC-5643 + backend middleware перевірки доступу + frontend компонент управління підпискою — 3-4 дні. З Permit2 оплатою, мультирівневим доступом (декілька тарифів) та аналітикою продовжень — 5-7 днів.
Як ми працюємо
Наша команда має 8+ років досвіду в блокчейн-розробці, випустила 50+ смарт-контрактів у mainnet, сумарно проаудована на $5M+ TVL. Ми підходимо до кожного проєкту з урахуванням ваших бізнес-завдань і пропонуємо рішення під ключ із гарантією якості та сертифікованими аудитами.
Зв'яжіться з нами для обговорення вашого завдання — ми запропонуємо оптимальне рішення під ваш бюджет і терміни. Пишіть у Telegram або на пошту, отримайте безкоштовну оцінку проєкту.







