Developing an NFT Crafting System on Smart Contracts

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 1All 1305 services
Developing an NFT Crafting System on Smart Contracts
Medium
~3-5 days
Frequently Asked Questions

Blockchain Development Services

Blockchain Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1349
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1247
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    949
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1183
  • image_logo-advance_0.webp
    B2B Advance company logo design
    642
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    921

You created an NFT collection; players are actively minting and trading — but what's next? Without a mechanism that consumes existing tokens and motivates interaction, the economy quickly stagnates. We encountered this in a P2E project with thousands of unclaimed items: players simply hoarded them without purpose. The solution was a crafting system — the ability to combine multiple NFTs or resources to create a new valuable item. This creates an economic cycle: a sink mechanism drains liquidity, and the reward retains players. In one project, we achieved a 70% reduction in turnover of low-level NFTs through well-designed crafting, and the average transaction cost on Polygon was just $0.02 — about 175 times cheaper than on Ethereum mainnet ($3.50). Gas savings with proper implementation can reach 40%.

How does an NFT crafting system work?

Crafting is not just a call to safeTransferFrom. Under the hood, there are clear patterns for burning, minting, and recipe validation. Let's look at the main types:

Type Description Example Randomness Notes
Fusion N tokens of the same type → 1 higher-tier token 3 Common swords → 1 Rare sword No Simplifies inventory, creates demand for low-level NFTs
Recipe Specific material combinations → specific result 1 Iron Ore + 2 Coal + 1 Fire Essence → Steel Ingot No Deterministic, suitable for limited-item crafting
Random Materials + VRF → result from a range Consumables → random item from pool (common to legendary) Yes (Chainlink VRF) Risk/reward; increases demand for materials
Upgrade Existing NFT + materials → same NFT with improved attributes Sword lvl 1 + 10 Essence → Sword lvl 2 Partial (success/failure) Korean-MMO style: can lose the item

Network comparison for crafting efficiency

Network Average gas cost per craft (USD) Block time L2 rollup Recommendation
Ethereum mainnet $3.50 12 s No Only for high-value items
Polygon (zkEVM) $0.02 2 s Yes Best balance of price and speed
Arbitrum One $0.15 0.25 s Yes For fast upgrade cycles
BNB Chain $0.05 3 s No Cost savings for frequent crafts

Example implementation in Solidity

For random crafts we use Chainlink VRF — each operation is confirmed by fair randomness. Below is a contract snippet supporting both deterministic recipes and random crafting. Full code is available in our repository.

// 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 material NFT contracts
        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 only consume
        bool requiresVRF;          // whether random is needed
        bool isActive;
        uint256 cooldown;          // seconds between crafting by the same 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 collect 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 burning)
                nft.safeTransferFrom(
                    msg.sender,
                    address(this),
                    inputTokenIds[i][0],
                    recipe.inputAmounts[i],
                    ""
                );
            }
        }
    }
}

Upgrade system (attribute advancement)

For games where items need improvement, we implement a separate contract supporting levels, materials, and success chance. Destruction-on-failure mechanics (Korean-MMO style) dramatically increase the value of high-level items.

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];
        
        // Collect 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 {
            // Simple failure without item loss
            emit UpgradeFailed(msg.sender, tokenId, targetLevel, false);
        }
    }
}

For upgrade with destruction risk, VRF is mandatory — the player must be confident that the casino cannot manipulate the odds.

Why is correct material validation important?

An error in the consumeInputMaterials logic is one of the most common causes of crafting hacks. You need to check:

  • Matching contract addresses and allowed tokenIds.
  • Player balance before transfer, especially in burn mode (transfer immediately burns, not temporarily holds).
  • Absence of reentrancy — use OpenZeppelin ReentrancyGuard.
  • Proper handling of ERC-1155 batchTransfer for multi-component recipes.

According to the OpenZeppelin ReentrancyGuard documentation, it prevents reentrancy, which is critical for operations involving burning and minting.

What's included in development?

We provide the full cycle:

  • Game economy analysis and recipe design.
  • Crafting smart contracts (Solidity 0.8.x, modular architecture).
  • Integration with Chainlink VRF for randomness.
  • Frontend UI development (drag-and-drop slots, result preview, animation).
  • Deployment to the chosen network (Ethereum, Polygon, Arbitrum, BNB Chain).
  • Full documentation (architecture, interfaces, deploy scripts).
  • Security audit (Slither, Mythril, Echidna).
  • Code warranty — 6 months of bug fixes.

Order the development of an NFT crafting system and receive a consultation with a prototype on testnet. Our experience: over 20 implemented projects, including integration with VRF and upgrade systems. We guarantee code transparency, timely milestone delivery, and post-release support.

Process

We work in stages:

  1. Analytics — review of your economy and tokenomics, specification formation.
  2. Design — smart contract architecture, standard selection, gas estimation.
  3. Development — writing contracts, unit tests (Foundry), VRF integration.
  4. Audit — internal and external code review, vulnerability fixes.
  5. Deployment and testing — testnet, load simulation, adjustments.

Timelines and cost

A basic crafting system (recipes + fusion + deterministic output) takes 3 to 4 weeks. With VRF random crafting and upgrade system — 5 to 7 weeks. Cost is calculated individually based on the number of recipes and required customization. Contact us — we will evaluate your project and propose the optimal solution.

Crafting UI patterns: drag-and-drop slots for materials, result preview before crafting, probabilities for random recipes, crafting animation (progress bar or particle effect).

Game Economy, Contracts, and On-Chain Mechanics

We’ve seen this scenario multiple times. Axie Infinity generated substantial revenue monthly at its peak, but within 18 months the token crashed by 98% and the audience by 95%. The cause—lack of sinks: players earned SLP and cashed out, while burn mechanisms were insufficient. An analysis of Axie’s economy (Collins Dictionary) confirmed the model turned into a Ponzi scheme. We provide end-to-end GameFi development: from tokenomics to smart contracts, so your economy doesn’t repeat this mistake. Let’s evaluate your project at a meetup or online.

Play-to-Earn Economy Break Points

Inflationary tokenomics without sinks. Players earn tokens through gameplay. If sinks (burn or consumption mechanisms) are insufficient, supply outpaces demand. Price drops. Player fiat income declines. Players leave. A death spiral.

The right structure is a dual-token model with clear separation: a governance/value token with limited supply and a utility/reward token for in-game economy. The utility token must be actively consumed: item crafting, upgrades, entry fees, breeding. Examples: GODS/FLUX in Gods Unchained, AXS/SLP in Axie (though sinks were insufficient there). Historical data shows that without sinks, token supply inflates by 5–10% monthly, leading to price collapse within 6–9 months.

Effective Sink Mechanisms

  • Breeding/crafting — burning utility token to create a new NFT (e.g., Axie). Typical burn costs range from $5–$15 per action, removing 0.5–2% of total supply annually.
  • Character upgrades — each evolution requires token burning, consuming 0.1–0.3% of circulating supply per upgrade cycle.
  • PvP entry fee — token burn for tournament entry, part goes to prize pool. This can burn up to 0.5% of supply per week in active games.
  • Item durability — item breaks after N battles, token spent on repair. Cost per repair ~$0.50–$2.
  • Financial mechanics — staking with lock-up, removing tokens from circulation for a period. Typical lock-up periods of 30–90 days reduce circulating supply by 15–25%.

On-Chain vs Off-Chain: Boundary and Trade-offs

It’s not necessary to put all game logic on-chain—each transaction costs gas and takes 12 seconds. A game cycle is milliseconds. Balance:

Component On-chain Off-chain Examples
Asset Ownership + NFT items, land
Transfer/Trading + Marketplaces
Finance (staking, rewards) + Staking vaults, DAO
Random generation + (via VRF) Chainlink VRF
Gameplay + Battle system, movement
Game world state + Coordinates, health points
Matchmaking + Server-side logic

Gameplay results are transferred to blockchain via signed messages from server or ZK-proof. Verifiable off-chain with ZK: game server generates ZK-proof of session correctness, contract verifies proof and issues rewards. Implementations: Cartridge (Starknet), zkSync game rollups. Gas savings from batching proofs can reach 90% compared to per-action on-chain validation.

How Does Dual-Token Model Prevent Economic Collapse?

Governance token (limited supply) acts as value store and is used for major decisions. Utility token (minted via gameplay) is consumed by sink mechanisms, ensuring deflationary pressure. The ratio of governance to utility tokens in the initial pool should be 1:10 to 1:20. Simulation shows that a 30% burn rate on utility token keeps supply growth below 3% per year, preserving player income and token price.

Implementation of NFT Game Items

Standard: ERC-1155 for fungible items (resources, consumables) + ERC-721 for unique (characters, land). ERC-1155 provides up to 60% gas savings on batch transfers.

How to Implement Dynamic NFTs Without Overloading the Blockchain?

Item attributes change during gameplay (experience, durability, upgrades). Two approaches:

  • Fully on-chain: attributes stored in contract mapping, tokenURI generated from attributes via SVG/JSON encoding. Expensive in gas with frequent updates (e.g., $0.50 per update). Used for land and key assets.
  • Hybrid: attributes stored off-chain, tokenURI contains state hash. Updates signed by server, verified on-chain during transfer or sale. Cheaper ($0.02 per update) but requires server trust or ZK.

Breeding and crafting. Contract: two parent NFTs → pay utility token (burn) → mint new NFT with attributes dependent on parents + Chainlink VRF for randomness. Without VRF, miners can manipulate randomness via block selection.

// Simplified breeding with Chainlink VRF
function breed(uint256 parent1Id, uint256 parent2Id) external {
    require(ownerOf(parent1Id) == msg.sender);
    require(ownerOf(parent2Id) == msg.sender);
    require(breedingToken.burnFrom(msg.sender, BREEDING_COST));

    uint256 requestId = vrfCoordinator.requestRandomWords(...);
    pendingBreeds[requestId] = BreedRequest(parent1Id, parent2Id, msg.sender);
}

function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
    BreedRequest memory req = pendingBreeds[requestId];
    uint256 childAttributes = deriveAttributes(req.parent1Id, req.parent2Id, randomWords[0]);
    _mintWithAttributes(req.requester, childAttributes);
}

Marketplace and Royalties

An integrated marketplace gives control over fee structure and custom logic (e.g., banning item trading below a certain level). Royalties per EIP-2981 are standard but not enforceable: Blur and other marketplaces ignore on-chain royalties. For enforcement—whitelist-only transfer (only through contracts that pay royalties). Sacrifice composability for rights protection. Typical marketplace fee is 2.5–5% per transaction, generating recurring revenue.

Staking and Rewards Distribution

Staking NFTs is a mechanic for player retention. Problem: distributing rewards with thousands of stakers requires constant transactions (expensive). Solution—reward-per-share pattern (as in MasterChef from SushiSwap): global accRewardPerShare, upon claim or state change, debt is recalculated by formula pendingReward = stakedAmount * (accRewardPerShare - userRewardDebt). O(1) complexity regardless of staker count. Gas savings up to 70% compared to per-element distribution. Over a year with 10,000 stakers, this translates to roughly $40,000 saved in gas.

Why Is Reward-Per-Share Pattern Critical for Scalability?

Direct per-user reward updates cost O(n) per block, consuming more than 200,000 gas for 1,000 stakers. Reward-per-share reduces this to 30,000–50,000 gas per user claim, enabling thousands of stakers. Many early P2E games collapsed under gas costs that exceeded reward value. This pattern scales to tens of thousands without infrastructure overhead.

Process and Timelines

We start with a game economics document: token flows, mint/burn mechanics, projected supply schedule, sink analysis. Before writing code, the economy is modeled (Cadence, Python simulation).

GameFi Building Process: 5 Stages

  1. Economic modeling — 1–2 weeks. Develop dual-token model, calculate sinks, outline incentives for long-term holding.
  2. Token contract development — 2–3 weeks. ERC-20 for governance, ERC-20 for utility, with configurable mint/burn policy.
  3. NFT smart contracts — 3–5 weeks. ERC-721 / ERC-1155 with dynamic metadata, breeding/crafting, Chainlink VRF.
  4. Staking + rewards — 2–3 weeks. Contract based on reward-per-share, interfaces for frontend.
  5. Marketplace (optional) — 2–4 weeks. Custom marketplace with enforced royalty.

Work Deliverables

  • Source code for all smart contracts with tests (Foundry/Hardhat)
  • Architecture and economics documentation
  • Integration with Chainlink, Tenderly for monitoring
  • Code audit and formal verification (Slither, Mythril, Echidna)
  • Team training on contract interaction
  • Post-deployment support (3 months)

Basic GameFi stack (tokens + NFTs + staking + marketplace) — 8 to 16 weeks. Full game with on-chain randomness, breeding, dynamic NFTs — 4–8 months. ZK-based verifiable gameplay — a separate project from 6 months.

Contact us for an audit of your tokenomics—we’ll assess risks and refine sink mechanisms. Order GameFi project development—receive a ready product with proven economy. We guarantee contract stability and code transparency. Our experience includes dozens of implemented Web3 projects, including audits of 15+ P2E games. Get a consultation to start your project.