Разработка NFT-аренды (ERC-4907)
До появления ERC-4907 «аренда» NFT реализовывалась через костыли: передача токена в escrow-контракт, доверительные off-chain договорённости или кастомные role-маппинги без единого стандарта. Любой протокол, желавший использовать чужой NFT (игра, метавселенная, lending), должен был писать интеграцию под каждый проект отдельно. EIP-4907, принятый в 2022 году, решает это чисто: добавляет второй адрес — user — с временными правами использования, не трогая владельца.
Как работает ERC-4907
Стандарт расширяет ERC-721 двумя функциями и одним событием:
interface IERC4907 {
event UpdateUser(uint256 indexed tokenId, address indexed user, uint64 expires);
function setUser(uint256 tokenId, address user, uint64 expires) external;
function userOf(uint256 tokenId) external view returns (address);
function userExpires(uint256 tokenId) external view returns (uint256);
}
Ключевой момент: user автоматически сбрасывается в address(0) после expires. Никакого cron-job, никакого keeper — просто проверка в userOf():
function userOf(uint256 tokenId) public view virtual returns (address) {
if (uint256(_users[tokenId].expires) >= block.timestamp) {
return _users[tokenId].user;
}
return address(0);
}
owner сохраняет полный контроль: может передавать токен, получать royalty, устанавливать нового user. При трансфере токена user и expires автоматически сбрасываются — это защита от ситуации, когда арендатор остаётся с правами после смены владельца.
Архитектура rental-маркетплейса
Сам ERC-4907 — это только стандарт на уровне токена. Полноценная система аренды требует rental-контракта поверх него.
Escrow-free vs. escrow подходы
Escrow-free (рекомендуемый): владелец одобряет rental-контракт через approve(), арендатор оплачивает, контракт вызывает setUser() от имени владельца. Токен остаётся в кошельке владельца всё время аренды. Никакого custodial риска.
Escrow: токен блокируется в контракте. Нужен только для случаев, когда владелец хочет гарантированно не использовать токен сам во время аренды — редкий use case.
Структура rental-ордера
struct RentalOrder {
address tokenContract;
uint256 tokenId;
address lender;
uint256 pricePerDay; // в wei
uint64 minDuration; // в секундах
uint64 maxDuration;
uint64 deadline; // до когда ордер валиден
bytes signature; // EIP-712 подпись лендера
}
Офчейн книга ордеров (like 0x protocol) + ончейн settlement. Лендер подписывает ордер офчейн — нет газовых затрат на листинг. Арендатор вызывает rent(order, duration) — одна транзакция, оплата + setUser().
Автоматическое продление и досрочное завершение
ERC-4907 не предусматривает досрочного завершения аренды арендодателем — expires неизменяем после setUser(). Для collateral-based аренды (защита от повреждения активов в игре) нужна дополнительная логика: депозит арендатора + possibility для арендодателя вызвать slash с on-chain доказательством нарушения условий.
Интеграция в игры и протоколы
Протоколы должны заменить проверку ownerOf() на userOf():
// Было:
require(IERC721(nft).ownerOf(tokenId) == msg.sender, "Not owner");
// Стало:
address user = IERC4907(nft).userOf(tokenId);
require(user == msg.sender, "Not authorized user");
Для обратной совместимости с контрактами, не поддерживающими ERC-4907: wrapper-контракт, который оборачивает обычный ERC-721 в ERC-4907. Владелец депозирует оригинальный токен, получает wrapped-версию с rental-функциональностью.
Что входит в разработку
- ERC-4907 контракт (если коллекция создаётся с нуля) или wrapper для существующей
- Rental-маркетплейс контракт: офчейн ордера с EIP-712 подписями, ончейн settlement
- Логика pricing: фиксированная цена/день, Dutch auction для снижения цены со временем
- Frontend: листинг, поиск доступных токенов, one-click аренда
- Интеграция с протоколом-потребителем: замена
ownerOfнаuserOf
Ориентиры по срокам
Только ERC-4907 контракт + базовый rental — 2 дня. С офчейн ордербуком, frontend и интеграцией в игровой контракт — 4-5 дней.







