Skip to content

maverick-trinh/move-function-challenge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📚 Sharded Assets Smart Contract Documentation

🎯 Contract Overview

Purpose

The Sharded Assets smart contract is a scalable item management system for blockchain games and applications that need to handle large collections of digital assets efficiently on the Sui blockchain.

Core Components

1. Player Structure

public struct Player has key {
    id: UID,              // Unique identifier
    owner: address,       // Owner's wallet address
    total_items: u64,     // Total items across all shards
}

2. ItemShard Structure

public struct ItemShard has key, store {
    id: UID,                    // Unique shard identifier
    items: Bag,                 // Storage container for items
    item_count: u64,            // Number of items in this shard
    id_to_key: Table<ID, u64>,  // Maps item ID to storage key
}

Key Features

  • Automatic Sharding: Items distributed across 10 shards using hash-based algorithm
  • Capacity Management: Maximum 200 items per shard to avoid gas limits
  • Efficient Lookup: O(1) item retrieval using ID-to-key mapping
  • Security: Owner-only access controls
  • Scalability: Supports up to 2,000 items per player (10 shards × 200 items)

🤔 Problem & Solution

The Problem

Traditional blockchain applications face several limitations when managing large collections:

  1. Gas Limits: Reading/writing too many items in one transaction hits gas limits
  2. Storage Constraints: Single containers become inefficient with large datasets
  3. Performance Degradation: Linear searches become slow with many items
  4. Scalability Issues: Adding items becomes expensive as collection grows

Real-World Analogy

Think of a traditional approach like storing all your files in one giant folder:

📁 PlayerItems/
   📄 Item1.txt
   📄 Item2.txt
   📄 Item3.txt
   ... (thousands of files)
   📄 Item9999.txt

Finding a specific file becomes slow, and operations on the folder become sluggish.

The Solution: Sharding

Our contract is like organizing files into categorized folders:

📁 Player/
   📁 Shard0/ (200 items max)
   📁 Shard1/ (200 items max)
   📁 Shard2/ (200 items max)
   ...
   📁 Shard9/ (200 items max)

Benefits

  • 🚀 Performance: Operations remain fast regardless of total items
  • ⛽ Gas Efficiency: Lower gas costs for individual operations
  • 📈 Scalability: Easy to add more shards if needed
  • 🔍 Quick Lookup: Direct shard access via hash function

🔧 Technical Implementation

1. Hash-Based Distribution Algorithm

fun get_shard_index(item_id: ID): u64 {
    let id_bytes = object::id_to_bytes(&item_id);
    let mut hash: u64 = 0;
    let mut i = 0;
    
    // Create hash from first 8 bytes of item ID
    while (i < 8 && i < std::vector::length(&id_bytes)) {
        hash = hash * 256 + (*std::vector::borrow(&id_bytes, i) as u64);
        i = i + 1;
    };
    
    hash % NUM_SHARDS  // Returns 0-9
}

How it works:

  • Takes item's unique ID (32 bytes)
  • Uses first 8 bytes to create a hash number
  • Uses modulo operation to get shard index (0-9)
  • Same item ID always maps to same shard

2. Dynamic Field Storage

// Store shards as dynamic fields on Player object
df::add(&mut player.id, shard_index, shard);

// Access specific shard
let shard: &mut ItemShard = df::borrow_mut(&mut player.id, shard_index);

3. Dual Storage System

Each shard maintains two data structures:

  • Bag: Stores actual items with sequential keys (0, 1, 2...)
  • Table: Maps item IDs to bag keys for fast lookup
// Add item to shard
let item_key = shard.item_count;
table::add(&mut shard.id_to_key, item_id, item_key);  // ID → Key mapping
bag::add(&mut shard.items, item_key, item);           // Store actual item

4. Core Operations Flow

Adding an Item:

1. Get item ID → 0x123abc...
2. Calculate shard → hash(0x123abc...) % 10 = 3
3. Access shard 3 → df::borrow_mut(&player.id, 3)
4. Check capacity → assert!(count < 200)
5. Store item → bag[next_key] = item
6. Store mapping → table[item_id] = next_key
7. Update counters

Finding an Item:

1. Get item ID → 0x123abc...
2. Calculate shard → hash(0x123abc...) % 10 = 3  
3. Access shard 3 → df::borrow(&player.id, 3)
4. Lookup key → table[item_id] = 5
5. Return location → (shard: 3, key: 5)

🎮 EXAMPLE USE CASES

1. Blockchain Gaming - RPG Inventory

// Game: "Crypto Adventures"
// Player collects items throughout the game

#[test]
fun rpg_inventory_example() {
    let mut scenario = test_scenario::begin(@0xPlayer);
    
    // Player starts their adventure
    sharded_player::create_player(scenario.ctx());
    scenario.next_tx(@0xPlayer);
    
    {
        let mut player = scenario.take_from_sender<Player>();
        
        // Player finds various items during gameplay
        let sword = item::create(100, b"Fire Sword", scenario.ctx());
        let shield = item::create(50, b"Iron Shield", scenario.ctx());
        let potion = item::create(25, b"Health Potion", scenario.ctx());
        let armor = item::create(75, b"Leather Armor", scenario.ctx());
        
        // Add items to inventory (auto-distributed across shards)
        sharded_player::add_item(&mut player, sword, scenario.ctx());
        sharded_player::add_item(&mut player, shield, scenario.ctx());
        sharded_player::add_item(&mut player, potion, scenario.ctx());
        sharded_player::add_item(&mut player, armor, scenario.ctx());
        
        // Player now has 4 items distributed across shards
        assert!(sharded_player::get_total_items(&player) == 4, 0);
        
        scenario.return_to_sender(player);
    };
    
    scenario.end();
}

2. NFT Marketplace - Collection Management

// Use Case: Art collector managing large NFT portfolio

public entry fun add_nft_collection(
    player: &mut Player,
    nfts: vector<Item>,
    ctx: &mut TxContext
) {
    let mut i = 0;
    while (i < vector::length(&nfts)) {
        let nft = vector::pop_back(&mut nfts);
        
        // Each NFT automatically goes to appropriate shard
        add_item(player, nft, ctx);
        i = i + 1;
    };
    vector::destroy_empty(nfts);
}

// Collector can efficiently manage thousands of NFTs
// - Rare Art Collection: Shard 0-2
// - Digital Music: Shard 3-5  
// - Virtual Land: Shard 6-9

3. DeFi Platform - Asset Portfolio

// Use Case: DeFi user managing multiple token positions

public entry fun deposit_tokens(
    player: &mut Player,
    tokens: vector<Item>,  // Various token types
    ctx: &mut TxContext
) {
    // Tokens automatically distributed based on their contract addresses
    // - Stablecoin positions → Certain shards
    // - Governance tokens → Other shards
    // - LP tokens → Remaining shards
    
    let mut i = 0;
    while (i < vector::length(&tokens)) {
        let token = vector::pop_back(&mut tokens);
        add_item(player, token, ctx);
        i = i + 1;
    };
    vector::destroy_empty(tokens);
}

4. Real-World Business Logic

// Game Studio: "MegaRPG" with 100,000 players
// Each player can have up to 2,000 items
// Total system capacity: 200 million items efficiently managed

public entry fun battle_loot_system(
    player: &mut Player,
    defeated_monster_id: u64,
    ctx: &mut TxContext
) {
    // Generate random loot based on monster
    let loot_items = generate_monster_loot(defeated_monster_id, ctx);
    
    // Add all loot to player's sharded inventory
    let mut i = 0;
    while (i < vector::length(&loot_items)) {
        let item = vector::pop_back(&mut loot_items);
        add_item(player, item, ctx);
        i = i + 1;
    };
    
    vector::destroy_empty(loot_items);
}

// Player inventory remains performant even with 1,000+ items
// Gas costs stay reasonable for all operations
// No blockchain congestion issues

📊 Performance Characteristics

Operation Traditional Sharded Improvement
Add Item O(n) O(1) 🚀 Constant time
Find Item O(n) O(1) 🔍 Instant lookup
Gas Cost Increases with size Constant ⛽ Predictable
Max Items ~100-500 2,000+ 📈 4x+ capacity

🎯 Business Value

For Game Developers

  • Scalable: Handle millions of in-game items
  • Cost-Effective: Predictable gas costs
  • User-Friendly: Fast inventory operations

For NFT Platforms

  • Portfolio Management: Organize large collections
  • Market Efficiency: Quick trading operations
  • Collector Experience: Smooth browsing/searching

For DeFi Protocols

  • Asset Management: Handle complex portfolios
  • Liquidity Operations: Efficient token swaps
  • Yield Farming: Manage multiple positions

This sharded architecture provides the foundation for building scalable, production-ready applications that can handle real-world usage without hitting blockchain limitations.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages