Contract 2: TraitFusion - The Smart Storage System

Purpose: Decentralized storage system for dynamic NFT traits

Key Innovation: Unlike traditional NFTs with static metadata, this system allows traits to be modified post-mint, enabling true evolution.

// NFT contract => tokenId => traitKey => value
mapping(address => mapping(uint256 => mapping(string => bytes))) private traits;

What's happening here?

  • This is a triple-nested mapping - the core of the dynamic trait system

  • First level: NFT contract address (which collection)

  • Second level: Token ID (which specific NFT)

  • Third level: Trait name (like "strength", "level", etc.)

  • Value: Raw bytes data (can store any type of data)

function setTraitUint(address nft, uint256 tokenId, string calldata traitKey, uint256 value) 
    external 
    onlyRole(GAME_ENGINE_ROLE) 
{
    traits[nft][tokenId][traitKey] = abi.encode(value);
    emit TraitUpdated(nft, tokenId, traitKey, abi.encode(value));
}

What's happening here?

  • Takes a number (uint256) and stores it as bytes using abi.encode

  • Only game engine can modify traits (security)

  • Emits event for tracking changes

  • Example: Setting strength to 50 would encode the number 50 as bytes

function getTraitAsUint(address nft, uint256 tokenId, string calldata traitKey) 
    external 
    view 
    returns (uint256) 
{
    bytes memory data = traits[nft][tokenId][traitKey];
    if (data.length == 0) return 0;
    return abi.decode(data, (uint256));
}

What's happening here?

  • Retrieves bytes data and converts back to a number

  • If no data exists, returns 0 (default)

  • Uses abi.decode to convert bytes back to uint256

Last updated