Создание системы крафтинга NFT на смарт-контрактах

Вы создали коллекцию NFT, игроки активно майнят и трейдуют — но что дальше? Без механики, которая потребляет существующие токены и мотивирует на взаимодействие, экономика быстро застаивается. Мы столкнулись с этим в проекте P2E с тысячами невостребованных предметов: игроки просто копили их без цели.

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

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1003

Вы создали коллекцию NFT, игроки активно майнят и трейдуют — но что дальше? Без механики, которая потребляет существующие токены и мотивирует на взаимодействие, экономика быстро застаивается. Мы столкнулись с этим в проекте P2E с тысячами невостребованных предметов: игроки просто копили их без цели. Решением стала система крафтинга — возможность объединять несколько NFT или ресурсов для создания нового ценного предмета. Это создаёт экономический цикл: sink-механизм выводит ликвидность, а награда удерживает игроков. В одном проекте мы добились снижения оборота низкоуровневых NFT на 70% за счёт продуманного крафтинга, а средняя стоимость транзакции на Polygon составила всего $0.02 — это примерно в 175 раз дешевле, чем на Ethereum mainnet ($3.50). Экономия газа при грамотной реализации может достигать 40%.

Как работает система крафтинга NFT?

Крафтинг — это не просто вызов safeTransferFrom. Под капотом лежат чёткие паттерны сжигания, чеканки и валидации рецептов. Рассмотрим основные типы:

Тип Описание Пример Случайность Примечания
Fusion (слияние) N токенов одного типа → 1 токен более высокого тира 3 Common меча → 1 Rare меч Нет Упрощает инвентарь, создаёт спрос на низкоуровневые NFT
Recipe (рецепт) Конкретные комбинации материалов → конкретный результат 1 Iron Ore + 2 Coal + 1 Fire Essence → Steel Ingot Нет Детерминированный, подходит для крафта ограниченных предметов
Random Материалы + VRF → результат из диапазона Расходники → случайный предмет из пула (common до legendary) Да (Chainlink VRF) Риск / награда; увеличивает спрос на материалы
Upgrade (прокачка) Существующий NFT + материалы → тот же NFT с улучшенными атрибутами Меч 1 лвл + 10 Essence → Меч 2 лвл Частично (успех/неудача) Korean-MMO стиль: можно потерять предмет

Сравнение эффективности сетей для крафтинга

Сеть Средняя стоимость газа за крафт (USD) Время блока L2 rollup Рекомендация
Ethereum mainnet $3.50 12 с Нет Только для high-value предметов
Polygon (zkEVM) $0.02 2 с Да Лучший баланс цены и скорости
Arbitrum One $0.15 0.25 с Да Для быстрых upgrad-циклов
BNB Chain $0.05 3 с Нет Экономия при частых крафтах

Пример реализации на Solidity

Для случайных крафтов мы используем Chainlink VRF — каждая операция подтверждается честным random. Ниже фрагмент контракта, поддерживающего как детерминированные рецепты, так и случайный крафтинг. Полный код доступен в нашем репозитории.

// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/AccessControl.sol"; contract NFTCraftingSystem is AccessControl, VRFConsumerBaseV2Plus { bytes32 public constant RECIPE_MANAGER = keccak256("RECIPE_MANAGER"); struct CraftingRecipe { uint256 recipeId; string name; // Входящие материалы address[] inputContracts; // адреса NFT контрактов материалов uint256[] inputTokenIds; // tokenId (0 = любой из коллекции) uint256[] inputAmounts; // количество (для ERC-1155) // Входящие ERC-20 токены address[] tokenInputs; uint256[] tokenAmounts; // Выход address outputContract; uint256 outputTokenId; // 0 = random из диапазона uint256 minOutputId; // для random: минимальный tokenId uint256 maxOutputId; // для random: максимальный tokenId bool burnInputs; // сжигать или только потреблять bool requiresVRF; // нужен ли random bool isActive; uint256 cooldown; // секунды между крафтингами одним адресом } mapping(uint256 => CraftingRecipe) public recipes; mapping(address => mapping(uint256 => uint256)) public lastCraftTime; // player → recipeId → timestamp mapping(uint256 => PendingCraft) public pendingCrafts; // vrfRequestId → craft struct PendingCraft { address crafter; uint256 recipeId; bool fulfilled; } function craft(uint256 recipeId, uint256[][] calldata inputTokenIds) external returns (uint256 requestId) { CraftingRecipe storage recipe = recipes[recipeId]; require(recipe.isActive, "Recipe not active"); // Cooldown check require( block.timestamp >= lastCraftTime[msg.sender][recipeId] + recipe.cooldown, "Crafting cooldown active" ); lastCraftTime[msg.sender][recipeId] = block.timestamp; // Валидируем и забираем материалы _consumeInputMaterials(recipe, inputTokenIds); _consumeInputTokens(recipe); if (recipe.requiresVRF) { // Для рандомного крафтинга — запрашиваем VRF requestId = _requestRandomWords(1); pendingCrafts[requestId] = PendingCraft({ crafter: msg.sender, recipeId: recipeId, fulfilled: false, }); emit CraftingInitiated(msg.sender, recipeId, requestId); } else { // Детерминированный крафтинг — минтим сразу _mintCraftingResult(msg.sender, recipe, 0); } } function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override { PendingCraft storage pending = pendingCrafts[requestId]; require(!pending.fulfilled, "Already fulfilled"); pending.fulfilled = true; CraftingRecipe storage recipe = recipes[pending.recipeId]; _mintCraftingResult(pending.crafter, recipe, randomWords[0]); } function _mintCraftingResult( address crafter, CraftingRecipe storage recipe, uint256 random ) internal { uint256 outputTokenId; if (recipe.outputTokenId != 0) { // Детерминированный output outputTokenId = recipe.outputTokenId; } else { // Random output в диапазоне [minOutputId, maxOutputId] outputTokenId = recipe.minOutputId + (random % (recipe.maxOutputId - recipe.minOutputId + 1)); } // Минтим результат IGameItems(recipe.outputContract).mintCraftingResult(crafter, outputTokenId, 1); emit CraftingCompleted(crafter, recipe.recipeId, outputTokenId); } function _consumeInputMaterials( CraftingRecipe storage recipe, uint256[][] calldata inputTokenIds ) internal { for (uint i = 0; i < recipe.inputContracts.length; i++) { IERC1155 nft = IERC1155(recipe.inputContracts[i]); if (recipe.burnInputs) { // Burn материалы IERC1155Burnable(recipe.inputContracts[i]).burn( msg.sender, inputTokenIds[i][0], recipe.inputAmounts[i] ); } else { // Перевести в контракт (без сжигания) nft.safeTransferFrom( msg.sender, address(this), inputTokenIds[i][0], recipe.inputAmounts[i], "" ); } } } } 

Upgrade система (прокачка атрибутов)

Для игр, где предметы нужно улучшать, мы реализуем отдельный контракт с поддержкой уровней, материалов и шанса успеха. Также возможна механика "уничтожение при неудаче" (Korean-MMO стиль) — она драматически увеличивает ценность высокоуровневых предметов.

contract NFTUpgradeSystem { struct UpgradePath { uint256 itemTypeId; uint256 currentLevel; uint256 maxLevel; uint256[] materialCosts; // материалы для каждого уровня uint256[] tokenCosts; uint256 successRate; // в basis points, 10000 = 100% bool destroyOnFail; // сжигать при неудаче? } // Upgrade с риском уничтожения (Korean-MMO стиль) function upgradeItem( uint256 tokenId, uint256 itemTypeId, uint256 targetLevel ) external returns (bool success) { UpgradePath storage path = upgradePaths[itemTypeId][targetLevel]; // Забираем материалы _burnUpgradeMaterials(path); // Определяем успех (off-chain random или VRF) // Для простоты — pseudo-random через block hash uint256 rand = uint256(keccak256(abi.encodePacked( blockhash(block.number - 1), msg.sender, tokenId, block.timestamp ))) % 10000; success = rand < path.successRate; if (success) { gameItems.setItemLevel(tokenId, targetLevel); emit UpgradeSuccess(msg.sender, tokenId, targetLevel); } else if (path.destroyOnFail) { gameItems.burn(msg.sender, itemTypeId, 1); emit UpgradeFailed(msg.sender, tokenId, targetLevel, true); } else { // Просто неудача без потери предмета emit UpgradeFailed(msg.sender, tokenId, targetLevel, false); } } } 

Для upgrade с риском уничтожения VRF обязателен — игрок должен быть уверен, что казино не может манипулировать шансом.

Почему важна корректная валидация материалов?

Ошибка в логике consumeInputMaterials — одна из самых частых причин взлома крафтинга. Нужно проверять:

  • Соответствие адресов контрактов и разрешённых tokenId.
  • Баланс игрока перед переводом, особенно при burn-режиме (перевод сразу сжигает, а не временно холдит).
  • Отсутствие reentrancy — используйте OpenZeppelin ReentrancyGuard.
  • Правильную обработку ERC-1155 batchTransfer для многокомпонентных рецептов.

Согласно документации OpenZeppelin ReentrancyGuard, он предотвращает повторный вход, что критично для операций с сжиганием и чеканкой.

Что входит в разработку?

Мы предоставляем полный цикл:

  • Анализ игровой экономики и проектирование рецептов.
  • Смарт-контракты крафтинга (Solidity 0.8.x, модульная архитектура).
  • Интеграция с Chainlink VRF для рандома.
  • Разработка frontend UI (drag-and-drop слоты, preview результата, анимация).
  • Деплой на выбранную сеть (Ethereum, Polygon, Arbitrum, BNB Chain).
  • Полная документация (архитектура, интерфейсы, deploy-скрипты).
  • Аудит безопасности (Slither, Mythril, Echidna).
  • Гарантия на код — 6 месяцев баг-фиксов.

Закажите разработку системы крафтинга NFT и получите консультацию с прототипом на тестнете. Наш опыт: более 20 реализованных проектов, в том числе с интеграцией VRF и upgrad-системами. Мы гарантируем прозрачность кода, своевременную сдачу этапов и пост-релизную поддержку.

Процесс работы

Мы работаем по этапам:

  1. Аналитика — разбор вашей экономики и токеномики, формирование спецификации.
  2. Проектирование — архитектура смарт-контрактов, выбор стандартов, оценка газа.
  3. Разработка — написание контрактов, юнит-тесты (Foundry), интеграция с VRF.
  4. Аудит — внутренний и внешний код-ревью, исправление уязвимостей.
  5. Деплой и тестирование — testnet, симуляция нагрузок, коррекция.

Сроки и стоимость

Базовая система крафтинга (рецепты + fusion + детерминированный output) занимает от 3 до 4 недель. С VRF random crafting и upgrade системой — от 5 до 7 недель. Стоимость рассчитывается индивидуально на основе объёма рецептов и необходимой кастомизации. Свяжитесь с нами — мы оценим ваш проект и предложим оптимальное решение.

Crafting UI паттерны: Drag-and-drop слоты для материалов, preview результата до крафтинга, вероятности для random recipes, анимация крафтинга (прогресс бар или particle effect).