NFT Crafting System Development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
NFT Crafting System Development
Medium
~3-5 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1215
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1043
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

NFT Crafting System Development

NFT crafting is a mechanic where multiple NFTs or resources combine to create a new NFT. It's simultaneously a sink mechanism (consumes or burns NFT/tokens) and source of new valuable items. Properly implemented crafting system creates economic cycle and retains players.

Types of Crafting

Fusion (merger): N tokens of one type → 1 token of higher tier. Classic example: 3 Common swords → 1 Rare sword. Simplifies inventory, creates demand for low-tier NFTs.

Recipe crafting: specific material combinations → specific result. Alchemist recipe book: 1 Iron Ore + 2 Coal + 1 Fire Essence → Steel Ingot.

Random crafting: materials + randomness → result from possible range. Risk/reward: can get legendary, can get common.

Upgrade (leveling): existing NFT + materials → same NFT with improved attributes.

Smart Contract Implementation

// 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;
        // Input materials
        address[] inputContracts;   // addresses of NFT contracts for materials
        uint256[] inputTokenIds;    // tokenId (0 = any from collection)
        uint256[] inputAmounts;     // quantity (for ERC-1155)
        // Input ERC-20 tokens
        address[] tokenInputs;
        uint256[] tokenAmounts;
        // Output
        address outputContract;
        uint256 outputTokenId;     // 0 = random from range
        uint256 minOutputId;       // for random: minimum tokenId
        uint256 maxOutputId;       // for random: maximum tokenId
        bool burnInputs;           // burn or just consume
        bool requiresVRF;          // need random?
        bool isActive;
        uint256 cooldown;          // seconds between crafts by one address
    }
    
    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;
        
        // Validate and consume materials
        _consumeInputMaterials(recipe, inputTokenIds);
        _consumeInputTokens(recipe);
        
        if (recipe.requiresVRF) {
            // For random crafting—request VRF
            requestId = _requestRandomWords(1);
            pendingCrafts[requestId] = PendingCraft({
                crafter: msg.sender,
                recipeId: recipeId,
                fulfilled: false,
            });
            emit CraftingInitiated(msg.sender, recipeId, requestId);
        } else {
            // Deterministic crafting—mint immediately
            _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) {
            // Deterministic output
            outputTokenId = recipe.outputTokenId;
        } else {
            // Random output in range [minOutputId, maxOutputId]
            outputTokenId = recipe.minOutputId + (random % (recipe.maxOutputId - recipe.minOutputId + 1));
        }
        
        // Mint result
        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 materials
                IERC1155Burnable(recipe.inputContracts[i]).burn(
                    msg.sender,
                    inputTokenIds[i][0],
                    recipe.inputAmounts[i]
                );
            } else {
                // Transfer to contract (without burn)
                nft.safeTransferFrom(
                    msg.sender,
                    address(this),
                    inputTokenIds[i][0],
                    recipe.inputAmounts[i],
                    ""
                );
            }
        }
    }
}

Upgrade System (Leveling)

contract NFTUpgradeSystem {
    struct UpgradePath {
        uint256 itemTypeId;
        uint256 currentLevel;
        uint256 maxLevel;
        uint256[] materialCosts;  // materials for each level
        uint256[] tokenCosts;
        uint256 successRate;      // in basis points, 10000 = 100%
        bool destroyOnFail;       // burn on failure?
    }
    
    // Upgrade with destruction risk (Korean-MMO style)
    function upgradeItem(
        uint256 tokenId,
        uint256 itemTypeId,
        uint256 targetLevel
    ) external returns (bool success) {
        UpgradePath storage path = upgradePaths[itemTypeId][targetLevel];
        
        // Consume materials
        _burnUpgradeMaterials(path);
        
        // Determine success (off-chain random or VRF)
        // For simplicity—pseudo-random via 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 {
            // Just failure without item loss
            emit UpgradeFailed(msg.sender, tokenId, targetLevel, false);
        }
    }
}

Important: for upgrade with destruction risk, VRF is necessary—player must be sure casino can't manipulate odds.

Crafting UI Patterns

Drag-and-drop slots for materials, result preview before crafting, probabilities for random recipes, crafting animation (progress bar or particle effect).

Developing basic crafting system (recipes + fusion + deterministic output)—3-4 weeks. With VRF random crafting and upgrade system—5-7 weeks.