{"author":{"address":"0x99DD70Cb7d9F8B85EDeE2a454E56478Cd0b0EaEF","user":"https://learnblockchain.cn/people/23775"},"content":{"body":"今天我们来全新设计一个代币系统，实现功能如下：\r\n\r\n## 一、模块功能概述\r\n\r\n该模块实现了一个叫 WILD_COIN 的代币系统，支持以下功能：\r\n\r\n1. 创建和管理代币的发行和流通（init, mint_wild, increase_unfrozen_supply, decrease_unfrozen_supply 等）。\r\n2. 提供代币与SUI之间的互换功能（swap_wild_coin_for_sui）。\r\n3. 管理奖励池（claim_reward_from_lending_platform, deposit_sui_coin_to_reward, withdraw_sui_from_reward 等）。\r\n4. 集成去中心化借贷平台，支持存取 SUI（deposit_sui_to_lending_platform, withdraw_sui_from_lending_platform）。\r\n5. 支持捐赠池管理以及空投功能（distribute_airdrop）。\r\n\r\n## 二、主要数据结构\r\n\r\n模块定义了几种关键的数据结构，具体代码示例如下：\r\n\r\n### 1. WILD_COIN\r\n\r\n用于定义代币的基本属性和能力。\r\n\r\n```rust\r\nmodule WildCoin {\r\n    struct WILD_COIN has key, store, drop {}\r\n}\r\n```\r\n\r\n### 2. Wild_Supply\r\n\r\n追踪代币的供应状态。\r\n\r\n```rust\r\nmodule WildCoin {\r\n    struct Wild_Supply has key, store {\r\n        // 当前解冻的代币供应量\r\n        current_unfrozen_supply: u64,\r\n        // 已流通的供应量\r\n        circulating_supply: u64,\r\n    }\r\n}\r\n```\r\n\r\n### 3. WildVault\r\n\r\n存储代币和奖励池的余额，支持奖励和捐赠管理。\r\n\r\n```rust\r\npublic struct WildVault has key {\r\n    id: UID,\r\n    sui_balance: Balance\u003cSUI\u003e, // Use Balance type to store SUI\r\n    wild_coin_balance: Balance\u003cWILD_COIN\u003e, // Use Balance type to store WILD_COIN\r\n    reward_sui_blance: Balance\u003cSUI\u003e,\r\n    donation_balance: Balance\u003cSUI\u003e, // Use Balance type to store SUI donations\r\n    account_cap: AccountCap,\r\n    sui_index: u8,\r\n    usdc_index: u8,\r\n}\r\n```\r\n\r\n### 4. WILD_COIN_AdminCap\r\n\r\n定义管理员权限，确保只有授权用户可以执行敏感操作。\r\n\r\n```rust\r\npublic struct WILD_COIN_AdminCap has key {\r\n    id: UID,\r\n}\r\n```\r\n\r\n这些数据结构协同工作，形成一个完整的代币管理系统。例如，Wild_Supply 记录了解冻和流通供应状态，WildVault 管理金库余额，而 WILD_COIN_AdminCap 则提供权限管理。\r\n\r\n# 三、主要函数解析\r\n\r\n以下是主要函数的功能解析及对应代码示例：\r\n\r\n## 1. 初始化（init）\r\n\r\n创建代币的 treasury_cap，并初始化供应池、金库和管理员权限。\r\n\r\n```rust\r\nfun init(witness: WILD_COIN, ctx: \u0026mut TxContext) {\r\n    let (treasury, metadata) = coin::create_currency(\r\n        witness,\r\n        9,\r\n        b\"WILD\",\r\n        b\"wild coin\",\r\n        b\"wild coin\",\r\n        option::none(),\r\n        ctx,\r\n    );\r\n    let vault = WildVault {\r\n        id: object::new(ctx),\r\n        sui_balance: balance::zero\u003cSUI\u003e(),\r\n        wild_coin_balance: balance::zero\u003cWILD_COIN\u003e(),\r\n        reward_sui_blance: balance::zero\u003cSUI\u003e(),\r\n        donation_balance: balance::zero\u003cSUI\u003e(),\r\n        account_cap: lending::create_account(ctx),\r\n        sui_index: 0,\r\n        usdc_index: 1,\r\n    };\r\n    let supply = Wild_Supply {\r\n        id: object::new(ctx),\r\n        current_unfrozen_supply: 0,\r\n        circulating_supply: 0,\r\n    };\r\n    let admincap = WILD_COIN_AdminCap { id: object::new(ctx) };\r\n    share_object(supply);\r\n    share_object(vault);\r\n    transfer::public_freeze_object(metadata);\r\n    transfer::public_share_object(treasury);\r\n    transfer::transfer(admincap, ctx.sender());\r\n}\r\n```\r\n\r\n## 2. 增加和减少解冻供应量（increase_unfrozen_supply 和 decrease_unfrozen_supply）\r\n\r\n确保供应量变化的安全性。\r\n\r\n### 增加供应量\r\n\r\n```rust\r\npublic fun increase_unfrozen_supply(_: \u0026WILD_COIN_AdminCap, supply: \u0026mut Wild_Supply, amount: u64) {\r\n    assert!(\r\n        supply.current_unfrozen_supply + amount \u003c= TOTAL_SUPPLY,\r\n        ERR_CANNOT_INCREASE_UNFROZEN_SUPPLY_BEYOND_TOTAL_SUPPLY,\r\n    );\r\n    supply.current_unfrozen_supply += amount;\r\n}\r\n```\r\n\r\n### 减少供应量\r\n\r\n```rust\r\npublic fun decrease_unfrozen_supply(_: \u0026WILD_COIN_AdminCap, supply: \u0026mut Wild_Supply, amount: u64) {\r\n    assert!(\r\n        supply.current_unfrozen_supply \u003e= amount,\r\n        ERR_CANNOT_DECREASE_UNFROZEN_SUPPLY_BELOW_ZERO,\r\n    );\r\n    supply.current_unfrozen_supply -= amount;\r\n}\r\n```\r\n\r\n## 3. 代币铸造（mint_wild）\r\n\r\n用户使用 SUI 购买 WILD_COIN。\r\n\r\n```rust\r\npublic fun mint_wild(\r\n    treasury_cap: \u0026mut TreasuryCap\u003cWILD_COIN\u003e,\r\n    bank: \u0026mut WildVault,\r\n    supply: \u0026mut Wild_Supply,\r\n    inputcoin: Coin\u003cSUI\u003e,\r\n    recipient: address,\r\n    ctx: \u0026mut TxContext,\r\n) {\r\n    assert!(\r\n        supply.current_unfrozen_supply \u003c= TOTAL_SUPPLY,\r\n        ERR_CANNOT_UNFREEZE_BEYOND_TOTAL_SUPPLY,\r\n    );\r\n    let balance_dewrap = coin::into_balance(inputcoin);\r\n    assert!(\r\n        supply.circulating_supply + balance::value(\u0026balance_dewrap) \u003c= supply.current_unfrozen_supply,\r\n        ERR_PURCHASE_AMOUNT_EXCEEDS_UNFROZEN_SUPPLY,\r\n    );\r\n    let coin = coin::mint(treasury_cap, balance::value(\u0026balance_dewrap), ctx);\r\n    supply.circulating_supply += balance::value(\u0026balance_dewrap);\r\n    bank.sui_balance.join(balance_dewrap);\r\n    transfer::public_transfer(coin, recipient);\r\n}\r\n```\r\n\r\n## 4. 代币与 SUI 的互换（swap_wild_coin_for_sui）\r\n\r\n实现代币和 SUI 的互换。\r\n\r\n```rust\r\npublic fun swap_wild_coin_for_sui(\r\n    treasury_cap: \u0026mut TreasuryCap\u003cWILD_COIN\u003e,\r\n    supply: \u0026mut Wild_Supply,\r\n    vault: \u0026mut WildVault,\r\n    wild_coin: Coin\u003cWILD_COIN\u003e,\r\n    recipient: address,\r\n    ctx: \u0026mut TxContext,\r\n) {\r\n    let amount = coin::value(\u0026wild_coin);\r\n    assert!(supply.circulating_supply \u003e= amount, ERR_CANNOT_SWAP_MORE_THAN_CIRCULATING_SUPPLY);\r\n    burn_wild_coin(treasury_cap, supply, wild_coin);\r\n    let sui_coin = withdraw_sui_from_vault(vault, amount, ctx);\r\n    transfer::public_transfer(sui_coin, recipient);\r\n}\r\n```\r\n\r\n## 5. 奖励池管理（deposit_sui_coin_to_reward 和 withdraw_sui_from_reward）\r\n\r\n管理奖励池的存取操作。\r\n\r\n### 存入 SUI 到奖励池\r\n\r\n```rust\r\npublic fun deposit_sui_coin_to_reward(vault: \u0026mut WildVault, amount: u64) {\r\n    assert!(amount \u003e 0, \"Amount must be positive\");\r\n    vault.reward_sui_balance += amount;\r\n}\r\n```\r\n\r\n### 从奖励池提取 SUI\r\n\r\n```rust\r\npublic fun withdraw_sui_from_reward(vault: \u0026mut WildVault, amount: u64) {\r\n    assert!(vault.reward_sui_balance \u003e= amount, \"Insufficient reward balance\");\r\n    vault.reward_sui_balance -= amount;\r\n}\r\n```\r\n\r\n## 6. 借贷平台集成（deposit_sui_to_lending_platform 和 withdraw_sui_from_lending_platform）\r\n\r\n与去中心化借贷平台的集成操作。\r\n\r\n### 从借贷平台提取 SUI\r\n\r\n```rust\r\npublic(package) fun withdraw_sui_from_lending_platform(\r\n    vault: \u0026mut WildVault,\r\n    sui_withdraw_amount: u64,\r\n    storage: \u0026mut Storage,\r\n    pool_sui: \u0026mut Pool\u003cSUI\u003e,\r\n    inc_v1: \u0026mut IncentiveV1,\r\n    inc_v2: \u0026mut Incentive,\r\n    clock: \u0026Clock,\r\n    oracle: \u0026PriceOracle,\r\n    ctx: \u0026mut TxContext,\r\n) {\r\n    let withdrawn_balance = lending_core::incentive_v2::withdraw_with_account_cap(\r\n        clock, oracle, storage, pool_sui, vault.sui_index, sui_withdraw_amount, inc_v1, inc_v2, \u0026vault.account_cap\r\n    );\r\n    let withdrawn_coin = coin::from_balance(withdrawn_balance, ctx);\r\n    deposit_sui_to_vault(vault, withdrawn_coin);\r\n}\r\n```\r\n\r\n### 将 SUI 存入借贷平台\r\n\r\n```rust\r\npublic(package) fun deposit_sui_to_lending_platform(\r\n    clock: \u0026Clock,\r\n    storage: \u0026mut Storage,\r\n    pool_a: \u0026mut Pool\u003cSUI\u003e,\r\n    vault: \u0026WildVault,\r\n    deposit_coin: Coin\u003cSUI\u003e,\r\n    inc_v1: \u0026mut IncentiveV1,\r\n    inc_v2: \u0026mut Incentive,\r\n) {\r\n    lending_core::incentive_v2::deposit_with_account_cap\u003cSUI\u003e(clock, storage, pool_a, vault.sui_index, deposit_coin, inc_v1, inc_v2, \u0026vault.account_cap);\r\n}\r\n```\r\n\r\n### 从借贷平台领取奖励\r\n\r\n```rust\r\npublic fun claim_reward_from_lending_platform(\r\n    _: \u0026WILD_COIN_AdminCap,\r\n    clock: \u0026Clock,\r\n    storage: \u0026mut Storage,\r\n    pool_sui: \u0026mut IncentiveFundsPool\u003cSUI\u003e,\r\n    vault: \u0026mut WildVault,\r\n    inc_v2: \u0026mut Incentive,\r\n    ctx: \u0026mut TxContext,\r\n) {\r\n    let reward_balance = lending_core::incentive_v2::claim_reward_with_account_cap\u003cSUI\u003e(\r\n        clock, \r\n        inc_v2, \r\n        pool_sui, \r\n        storage, \r\n        vault.sui_index, \r\n        0, \r\n        \u0026vault.account_cap\r\n    );\r\n    let reward_coin = coin::from_balance(reward_balance, ctx);\r\n    deposit_reward_sui_to_vault(vault, reward_coin);\r\n}\r\n```\r\n\r\n7. 空投功能（distribute_airdrop）\r\n\r\n向 NFT 持有者分发奖励。\r\n```rust\r\nppublic(package) fun distribute_airdrop(\r\n    airdrop_table: \u0026LinkedTable\u003cID, u64\u003e,\r\n    vault: \u0026mut WildVault,\r\n    ctx: \u0026mut TxContext\r\n) {\r\n    // Calculate the total amount of SUI to be distributed\r\n    let total_reward = vault.reward_sui_blance.value();\r\n    // Calculate the donation amount (20% of total reward)\r\n    let donation_amount = total_reward * 20 / 100;\r\n\r\n    // Calculate the remaining amount for distribution (80% of total reward)\r\n    let distribution_amount = total_reward - donation_amount;\r\n\r\n    // Withdraw the donation amount from the vault and add it to the donation balance\r\n    let donation_coin = withdraw_sui_from_vault_reward(vault, donation_amount, ctx);\r\n    balance::join(\u0026mut vault.donation_balance, coin::into_balance(donation_coin));\r\n\r\n    // Withdraw the remaining reward amount from the vault and add it to the sui_balance\r\n    let remaining_reward_coin = withdraw_sui_from_vault_reward(vault, distribution_amount, ctx);\r\n    balance::join(\u0026mut vault.sui_balance, coin::into_balance(remaining_reward_coin));\r\n\r\n    // Update the total reward to reflect the remaining amount for distribution\r\n    let total_reward = distribution_amount;\r\n\r\n    // Iterate over the airdrop table to distribute the SUI\r\n    let mut front_item = linked_table::front(airdrop_table);\r\n    while (option::is_some(front_item)) {\r\n        let nft_id = option::borrow(front_item);\r\n        let reward_ratio = linked_table::borrow(airdrop_table, *nft_id);\r\n        let reward_amount = (total_reward * *reward_ratio) / 1_000_000_000;\r\n\r\n        // Ensure the reward amount is greater than zero\r\n        if (reward_amount \u003e 0) {\r\n            // Withdraw the reward amount from the vault\r\n            let reward_coin = withdraw_sui_from_vault(vault, reward_amount, ctx);\r\n\r\n            // Transfer the reward coin to the NFT's address\r\n            let nft_address = nft_id.to_address();\r\n            transfer::public_transfer(reward_coin, nft_address);\r\n        };\r\n\r\n        front_item = linked_table::next(airdrop_table, *nft_id);\r\n    }\r\n}\r\n```\r\n\r\n# 四、关键实现要点\r\n\r\n## 1. 安全性\r\n\r\n安全性是设计链上代币系统的核心，以下是模块实现安全性的具体措施：\r\n\r\n- **前提条件检查**：\r\n  - 使用 `assert!` 确保所有操作的前提条件满足，以避免逻辑错误或恶意操作。例如：\r\n    - 供应量检查：防止解冻供应量超出最大供应量。\r\n    - 余额检查：在提取或交换代币时，确保金额不超过余额或流通供应量。\r\n    - 空值检查：操作对象（如金库或管理员权限）必须有效。\r\n  \r\n  **示例代码**：\r\n  ```rust\r\n  public fun increase_unfrozen_supply(admin_cap: \u0026WILD_COIN_AdminCap, supply: \u0026mut Wild_Supply, amount: u64) {\r\n      assert!(admin_cap.active, \"AdminCap is not active\");\r\n      assert!(supply.current_unfrozen_supply + amount \u003c= supply.circulating_supply, \r\n          \"ERR_CANNOT_INCREASE_UNFROZEN_SUPPLY_BEYOND_TOTAL_SUPPLY\");\r\n  }\r\n  ```\r\n\r\n- **错误码设计**：\r\n  - 模块定义了一组错误码以提高代码的可读性和可维护性。这些错误码通过错误信息清晰地描述了违反的条件或操作失败的原因，例如：\r\n    - `ERR_INSUFFICIENT_BALANCE`: 表示余额不足。\r\n    - `ERR_INVALID_SWAP_AMOUNT`: 表示交换金额无效。\r\n  \r\n  **示例代码**：\r\n  ```rust\r\n  public fun swap_wild_coin_for_sui(vault: \u0026mut WildVault, amount: u64) {\r\n      assert!(vault.wild_coin_balance \u003e= amount, \"ERR_INSUFFICIENT_WILD_COIN_BALANCE\");\r\n      assert!(vault.sui_balance \u003e= amount, \"ERR_INSUFFICIENT_SUI_BALANCE\");\r\n  }\r\n  ```\r\n\r\n## 2. 对象共享与权限管理\r\n\r\nSui Move 提供了丰富的对象管理机制，模块通过这些机制实现了代币和金库的共享与权限管理。\r\n\r\n- **共享对象权限 (share_object)**：\r\n  - 将代币、供应池和金库对象的访问权限共享给特定的地址或模块，允许它们调用相关操作，同时防止未经授权的修改。\r\n  \r\n  **示例代码**：\r\n  ```rust\r\n  public fun init(admin: \u0026signer) {\r\n      let wild_coin = WILD_COIN { id: object::new(), total_supply: 1_000_000 };\r\n      transfer::share_object(admin, \u0026wild_coin);\r\n  }\r\n  ```\r\n\r\n- **转移对象所有权 (transfer)**：\r\n  - 在需要完全转移对象控制权时使用 `transfer`。例如，空投功能将代币转移给指定的 NFT 持有者。\r\n  \r\n  **示例代码**：\r\n  ```rust\r\n  public fun distribute_airdrop(vault: \u0026mut WildVault, owner: address, reward: u64) {\r\n      assert!(vault.wild_coin_balance \u003e= reward, \"ERR_INSUFFICIENT_BALANCE\");\r\n      coin::transfer(owner, reward);\r\n      vault.wild_coin_balance = vault.wild_coin_balance - reward;\r\n  }\r\n  ```\r\n\r\n- **对象能力管理**：\r\n  - 对象的能力（如 drop、key 和 store）控制了对象在模块内外的行为。模块设计时明确了对象能力以避免误操作。\r\n  \r\n  **示例代码**：\r\n  ```rust\r\n  struct WILD_COIN has drop, key {\r\n      id: u64,\r\n      total_supply: u64,\r\n  }\r\n  ```\r\n\r\n## 3. 模块化设计\r\n\r\n模块化设计使得功能划分清晰、逻辑独立，增强了代码的易维护性和可扩展性。\r\n\r\n- **功能划分清晰**：\r\n  - 模块将供应管理、奖励管理和借贷集成分别实现，各自专注于一组相关操作，避免了功能之间的耦合。\r\n    - 供应管理：负责代币发行和流通控制（如 `mint_wild`, `increase_unfrozen_supply`）。\r\n    - 奖励管理：处理奖励池和空投功能（如 `deposit_sui_coin_to_reward`, `distribute_airdrop`）。\r\n    - 借贷集成：实现去中心化借贷功能（如 `deposit_sui_to_lending_platform`, `withdraw_sui_from_lending_platform`）。\r\n\r\n- **集成外部模块**：\r\n  - 利用外部模块增强功能性，如 `sui::coin` 模块处理 SUI 的存取操作，`lending_core` 模块实现去中心化借贷集成。\r\n  \r\n  **示例代码**：\r\n  ```rust\r\n  use sui::coin;\r\n  use lending_core::{deposit, withdraw};\r\n\r\n  public fun deposit_sui_to_lending_platform(vault: \u0026mut WildVault, amount: u64) {\r\n      assert!(vault.sui_balance \u003e= amount, \"ERR_INSUFFICIENT_SUI_BALANCE\");\r\n      lending_core::deposit(amount);\r\n      vault.sui_balance = vault.sui_balance - amount;\r\n  }\r\n  ```\r\n\r\n- **高扩展性**：\r\n  - 模块设计易于扩展，例如：\r\n    - 支持更多的代币类型或资产类型。\r\n    - 集成更多的外部 DeFi 协议（如流动性挖矿或收益聚合器）。\r\n  \r\n  **扩展示例**：\r\n  ```rust\r\n  public fun integrate_new_protocol(vault: \u0026mut WildVault, amount: u64) {\r\n      // 模拟集成新协议逻辑\r\n      new_protocol::deposit(amount);\r\n      vault.sui_balance = vault.sui_balance - amount;\r\n  }\r\n  ```\r\n\u003e **请用微信关注《HOH水分子》公众号，我们将持续分享和制作变成语言教程，让大家对编程产生化学反应。**\r\n![HOH_QR.jpg](https://img.learnblockchain.cn/attachments/2024/11/4h04Aovz6738b68758d43.jpg)","title":"（十九）WILD Coin 模块设计与实现解析"},"history":null,"timestamp":1734013644,"version":1}