Розробка Lazy-Minting NFT
Стандартний мінтинг NFT-колекції: творець розгортає контракт та заздалегідь робить мінтинг всіх токенів, платячи газ за кожен. При 10 000 токенів на Ethereum mainnet при 30 gwei — це 30–50 ETH лише на мінтинг. Для незалежного художника, який випускає 100 робіт, це $3000–5000 авансом, до першої продажі.
Lazy minting перевертає модель: NFT існує лише як підписаний voucher до першої покупки. Покупець платить газ на мінтинг під час покупки. Творець не несе витрат до отримання доходу.
Як працює Lazy Minting на криптографічному рівні
Voucher = підписана структура даних
Творець підписує off-chain дані своїм приватним ключем. Voucher містить усі параметри майбутнього NFT:
struct NFTVoucher {
uint256 tokenId;
uint256 minPrice; // мінімальна ціна у wei
string uri; // IPFS URI метаданих
bytes signature; // підпис творця
}
Підпис створюється через EIP-712 (підписування типізованих структурованих даних), а не через сирий eth_sign. EIP-712 важливий: користувачі бачать читабельні дані в MetaMask при підписуванні, не hex-рядок. Це захищає від фішингу — підроблений домен не може створити дійсну EIP-712 підпис для чужого контракту.
On-chain верифікація підпису
При виклику redeem(voucher, recipient) контракт відновлює адресу підписувача через ecrecover:
function _verify(NFTVoucher calldata voucher) internal view returns (address) {
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
keccak256("NFTVoucher(uint256 tokenId,uint256 minPrice,string uri)"),
voucher.tokenId,
voucher.minPrice,
keccak256(bytes(voucher.uri))
)));
return ECDSA.recover(digest, voucher.signature);
}
Якщо відновлена адреса збігається з MINTER_ROLE, підпис дійсний, мінтинг дозволено. Контракт використовує ECDSA з OpenZeppelin 5.x для безпечного recover.
Критичні вразливості Lazy Minting
Replay атака — без унікального nonce або tokenId одна підпис може використовуватися багаторазово. Захист: перевірка _exists(tokenId) перед мінтингом + tokenId є частиною підписаних даних. Вже заминтований tokenId повернеться revert.
Cross-contract replay — підпис дійсна для конкретного контракту на конкретній мережі. EIP-712 domain включає chainId та адресу verifyingContract. Підпис з Ethereum mainnet не пройде верифікацію на Polygon — вони мають різні chainId. Різні контракти — різні verifyingContract — різні domain separator.
Front-running voucher — технічно будь-хто, хто бачить voucher в mempool, може спробувати заминтити його для своєї адреси. Захист: recipient включена в підписані дані. Voucher дійсна лише для конкретної адреси отримувача.
Зберігання та дистрибуція vouchers
Vouchers зберігаються off-chain — у базі даних платформи або на IPFS. Marketplace API видає voucher при ініціації покупки. Для відкритих продаж (будь-хто може купити) vouchers публічні. Для whitelist продаж — voucher видається лише верифікованим адресам.
Lazy Minting для платформ творців (Rarible, OpenSea модель)
На платформах типу OpenSea lazy minting працює інакше: творець підписує voucher через сервіс платформи. Платформа зберігає vouchers. При першій продажі — платформа викликає mintAndTransfer або lazyMint. Роялті EIP-2981 включено в дані voucher.
Для кастомного marketplace: той же принцип, але контракт та signing сервіс під вашим контролем.
Стек та інструменти
Контракт: Solidity 0.8.x, OpenZeppelin ERC721URIStorage, EIP-712 через EIP712 з OpenZeppelin, AccessControl для MINTER_ROLE.
Бекенд: сервіс генерування vouchers — Node.js з viem для підписування, зберігання у PostgreSQL або Redis.
Фронтенд: wagmi хуки для writeContract, відображення стану транзакції, інтеграція з IPFS через NFT.Storage для завантаження метаданих при створенні.
Тести: Foundry — тест коректної верифікації, тест replay атак (повинен revert), тест cross-contract (повинен revert), fork-тест на mainnet для перевірки сумісності ECDSA.
Процес і графік
Розробка контракту (1–2 дні): ERC-721 з логікою lazy mint, EIP-712 підписування, верифікація, роялті.
Сервіс Voucher (0.5 дня): API для генерування та зберігання vouchers, підписування через приватний ключ творця.
Компонент фронтенду (1 день): сторінка купівлі/мінтингу з підключенням гаманця, відображення стану транзакції.
Тестування (0.5 дня): Foundry unit-тести включаючи replay атаки.
Разом: 3–5 днів. Для платформи з кількома творцями та панеллю управління vouchers — 1–2 тижні. Вартість розраховується індивідуально.







