模块简介animal_crossing::wild_NFT是一个SuiMove模块,旨在创建、管理和操作与濒危动物相关的NFT系统。通过引入wild_coin和SUI,模块结合金融激励机制实现了NFT的铸造、购买、遗弃及空投等功能。主要结构体及功能2.1主要结构
animal_crossing::wild_NFT 是一个 Sui Move 模块,旨在创建、管理和操作与濒危动物相关的 NFT 系统。通过引入 wild_coin 和 SUI,模块结合金融激励机制实现了 NFT 的铸造、购买、遗弃及空投等功能。
2.1 主要结构体
以下是主要结构体的介绍以及相关功能的补充代码示例。
2.1.1 Animals
存储珍稀动物信息的结构体,每种动物包含唯一的 UID 和对应的详细信息表。
public struct Animals has key, store {
    id: UID,
    animal_infos: Table<u64, AnimalInfo>,
}功能:
添加动物信息(Admin 权限)
管理员可以向 Animals 添加新的动物信息。
示例代码:
public fun add_animal(
   _: &NFTAdminCap,
   animals: &mut Animals,
   name: String,
   species: String,
   habitat: String,
   status: u64,
   image_url: String,
   ctx: &mut TxContext,
) {
   let new_animal = AnimalInfo {
       id: object::new(ctx),
       name,
       species,
       habitat,
       status,
       image_url,
   };
   let key = table::length(&animals.animal_infos);
   table::add(&mut animals.animal_infos, key, new_animal);
}更新动物信息(Admin 权限)
根据给定的键更新指定的动物信息。
示例代码:
public fun update_animal(
   _: &NFTAdminCap,
   animals: &mut Animals,
   key: u64,
   new_name: String,
   new_status: u64,
   ctx: &mut TxContext,
) {
   assert!(table::contains(&animals.animal_infos, key), ERR_KEY_DOES_NOT_EXIST);
   let animal_info = table::borrow_mut(&mut animals.animal_infos, key);
   animal_info.name = new_name;
   animal_info.status = new_status;
}2.1.2 AnimalNFT
每个动物对应的 NFT 结构体,记录了动物的基本信息和收养人的地址。
public struct AnimalNFT has key, store {
    id: UID,
    name: String,
    animal_id: u64,
    species: String,
    habitat: String,
    adopted_by: address,
    image_url: String,
    create_time: u64,
}功能:
铸造 NFT(购买功能)
使用特定金额的 WILD_COIN 购买指定动物的 NFT。
示例代码:
public fun mint_nft(
   animals: &Animals,
   key: u64,
   inputcoin: Coin<wild_coin::WILD_COIN>,
   recipient: address,
   clock: &Clock,
   ctx: &mut TxContext,
) {
   assert!(coin::value(&inputcoin) == NFT_PRICE, ERR_NFT_PRICE_IS_EXACTLY_NFT_PRICE_WILD_COIN);
   let animal_info = &animals.animal_infos[key];
   let new_nft = AnimalNFT {
       id: object::new(ctx),
       name: animal_info.name,
       animal_id: key,
       species: animal_info.species,
       habitat: animal_info.habitat,
       adopted_by: recipient,
       image_url: animal_info.image_url,
       create_time: clock::timestamp_ms(clock),
   };
   transfer::public_transfer(new_nft, recipient);
}放弃 NFT(销毁功能)
用户可通过销毁 NFT 来收回一定的 SUI 或 WILD_COIN。
示例代码:
public fun abandon_nft(
   nft: AnimalNFT,
   vault: &mut WildVault,
   ctx: &mut TxContext,
) {
   let reward_coin = wild_coin::withdraw_wild_coin_from_vault(vault, NFT_PRICE, ctx);
   transfer::public_transfer(reward_coin, nft.adopted_by);
   object::delete(nft.id);
}2.1.3 MintRecord
记录 NFT 铸造的历史,包括每种动物的所有 NFT 数据。
public struct MintRecord has key, store {
    id: UID,
    record: LinkedTable<u64, LinkedTable<ID, u64>>, // 每种动物的 NFT 链接表
    count: u64,
}功能:
记录铸造历史
将 NFT 铸造记录加入到 MintRecord 中。
示例代码:
public fun record_minting(
   record: &mut MintRecord,
   nft_id: ID,
   animal_key: u64,
   clock: &Clock,
   ctx: &mut TxContext,
) {
   if (!linked_table::contains(&record.record, animal_key)) {
       let mut new_nft_table = linked_table::new<ID, u64>(ctx);
       linked_table::push_back(&mut new_nft_table, nft_id, clock::timestamp_ms(clock));
       linked_table::push_back(&mut record.record, animal_key, new_nft_table);
   } else {
       let nft_table = linked_table::borrow_mut(&mut record.record, animal_key);
       linked_table::push_back(nft_table, nft_id, clock::timestamp_ms(clock));
   };
   record.count = record.count + 1;
}移除铸造记录
在 NFT 被放弃时,将其从记录中移除。
示例代码:
public fun remove_mint_record(
   record: &mut MintRecord,
   nft_id: ID,
   animal_key: u64,
) {
   assert!(linked_table::contains(&record.record, animal_key), ERR_KEY_DOES_NOT_EXIST);
   let nft_table = linked_table::borrow_mut(&mut record.record, animal_key);
   linked_table::remove(nft_table, nft_id);
   if (linked_table::is_empty(nft_table)) {
       linked_table::remove(&mut record.record, animal_key);
   };
   record.count = record.count - 1;
}本节详细阐述系统核心逻辑“空头发放”的实现,包括数据收集、权重计算、分发奖励等核心步骤,结合代码示例展示具体实现。
以下是实现“空头发放”的完整代码及其功能分解。
public fun calculate_send_airdrop_distribution(
    _: &NFTAdminCap,             // 管理权限验证
    record: &MintRecord,         // 链上记录存储所有 NFT 信息
    animals: &Animals,           // 动物信息表
    vault: &mut WildVault,       // 系统资金库
    clock: &Clock,               // 当前时间
    ctx: &mut TxContext          // 交易上下文
) {
    let mut total_status_weight = 0u64;
    let mut total_time_weight = 0u64;
    let mut airdrop_table = linked_table::new<ID, u64>(ctx);
    // Step 1: 收集数据并计算总权重
    let current_time = clock::timestamp_ms(clock);
    let mut front_item = linked_table::front(&record.record);
    let mut nft_weights = linked_table::new<ID, Nft_weight>(ctx);
    while (option::is_some(front_item)) {
        let key = option::borrow(front_item);
        let nfts = linked_table::borrow(&record.record, *key);
        let animal_info = table::borrow(&animals.animal_infos, *key);
        let status_weight = animal_info.status;
        let mut front_nft = linked_table::front(nfts);
        while (option::is_some(front_nft)) {
            let nft_key = option::borrow<ID>(front_nft);
            let create_time = linked_table::borrow(nfts, *nft_key);
            // 计算持有时长的时间权重
            let time_held = current_time - *create_time;
            let time_weight = time_held / 86400000 + 1;
            total_status_weight += status_weight;
            total_time_weight += time_weight;
            linked_table::push_back(&mut nft_weights, *nft_key, Nft_weight {
                status_weight,
                time_weight,
            });
            front_nft = linked_table::next(nfts, *nft_key);
        };
        front_item = linked_table::next(&record.record, *key);
    };
    assert!(total_status_weight > 0, 1);
    assert!(total_time_weight > 0, 2);
    // Step 2: 基于权重计算空头分配
    let mut front_item = linked_table::front(&nft_weights);
    while (option::is_some(front_item)) {
        let nft_id = option::borrow(front_item);
        let Nft_weight { status_weight, time_weight } = linked_table::borrow(&nft_weights, *nft_id);
        let status_ratio = *status_weight * 1_000_000_000 / total_status_weight;
        let time_ratio = *time_weight * 1_000_000_000 / total_time_weight;
        // 自定义奖励分配公式
        let reward = status_ratio * 8 / 10 + time_ratio * 2 / 10;
        linked_table::push_back(&mut airdrop_table, *nft_id, reward);
        front_item = linked_table::next(&nft_weights, *nft_id);
    };
    // Step 3: 发放空头奖励
    wild_coin::distribute_airdrop(&airdrop_table, vault, ctx);
    linked_table::drop(airdrop_table);
    linked_table::drop(nft_weights);
}status_weight 和 time_weight。status_weight 根据动物的当前状态赋予不同权重。time_weight 根据 NFT 持有的天数计算,时间越长权重越高。wild_coin::distribute_airdrop 函数分发奖励。linked_table 实现 NFT 权重与奖励的高效存储和迭代。通过该设计,系统实现了一个公平、高效的空头发放机制,增强了用户参与的激励效果,为平台经济生态注入活力。
请用微信关注《HOH水分子》公众号,我们将持续分享和制作变成语言教程,让大家对编程产生化学反应。
 
                如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!