{"author":{"address":null,"user":"https://learnblockchain.cn/people/23814"},"content":{"body":"如果你是初学者，强烈建议看下前几节内容：\r\n\r\n[入门 Sui Move 开发：1. 环境安装](https://learnblockchain.cn/article/9814) \r\n\r\n[ 入门 Sui Move 开发：2. 常用命令、编写并发布 Hello World 合约](https://learnblockchain.cn/article/9839)\r\n\r\n[入门 Sui Move 开发：3. Sui Move 语法和设计模式](https://learnblockchain.cn/article/9866) \r\n\r\n[入门 Sui Move 开发：4. Sui Move 中集合、对象、泛型、动态字段](https://learnblockchain.cn/article/9876)\r\n\r\n[入门 Sui Move 开发：5. 发布同质化代币 — NFT](https://learnblockchain.cn/article/9925)\r\n\r\n[入门 Sui Move 开发：6. 发布一个小游戏合约](https://learnblockchain.cn/article/12119)\r\n\r\n\r\n### 内容概览\r\n本节将完成一组固定币对兑换的合约。代码方面主要还是 `coin`、`balance` 模块的使用。更多细节可以看以下代码注释。\r\n\r\n\r\n### 兑换步骤\r\n以现实生活中去银行换美元为例，需要有以下步骤：\r\n\r\n| 现实兑换 |  合约兑换 |\r\n| --- | --- |\r\n| 预约换汇 |  创建池子|\r\n| 银行准备美元 | 池子中添加币 |\r\n| 人到银行，给出人民币并得到等值美元 | 将币种 A 放入池子，池子将等值的币种 B 转出给用户 |\r\n\r\n通过以上步骤，我们的合约中大概需要：\r\n* 兑换池-- 包含可以兑换的币种数量\r\n* 给兑换池中添加币\r\n* 币种的兑换汇率\r\n* 兑换币种\r\n* 从池子里提取币种\r\n\r\n### 合约代码\r\n\r\n*下面合约中可以兑换的币对可以替换成自己的币合约。*\r\n\r\n``` \r\n/// Module: swap_greyhao\r\n/// A SAMPLE SWAP CONTRACT\r\nmodule swap_greyhao::swap_greyhao {\r\n  /*\r\n  实现思路：\r\n  兑换需要有兑换池；兑换池包含可以兑换的coin；---》 所以需要 SwapPool 结构体\r\n  池子默认需要添加一些币，然后才能正常兑换；---》所以需要 add_xx_to_pool 方法\r\n  任何人都可以加池子或在池子里兑换，但是只有管理员可以提取（真实合约并不是这样）；---》所以需要 Admin 结构体，提现的时候检验权限\r\n  管理员可以从池子里提取；---》 withdraw_xx_from_pool 方法\r\n  初始化的时候需要创建好池子；---》 init 方法中初始化 SwapPool、Admin\r\n  兑换有汇率可以先固定值 5；\r\n  兑换：根据汇率将 A 兑换成等值的 B，并转给兑换者；---》 swap_xx 方法\r\n*/\r\n\r\n  use coin_greyhao::greyhaocoin::GREYHAOCOIN;\r\n  use coin_greyhao::greyhaofaucet::GREYHAOFAUCET;\r\n  use sui::balance::{Balance, zero};\r\n  use sui::coin::{Coin, from_balance};\r\n  use sui::transfer::{share_object, transfer, public_transfer};\r\n\r\n  const EPOOLINSUFFICIENTBALANCE: u64 = 0;\r\n  const EUSERINSUFFICIENTBALANCE: u64 = 1;\r\n\r\n  public struct SwapPool has key {\r\n    id: UID,\r\n    coin: Balance\u003cGREYHAOCOIN\u003e,\r\n    faucet_coin: Balance\u003cGREYHAOFAUCET\u003e\r\n  }\r\n\r\n  public struct Admin has key {\r\n    id: UID,\r\n  }\r\n\r\n  // 初始化\r\n  fun init(ctx: \u0026mut TxContext) {\r\n    // 创建池子\r\n    let swapPool = SwapPool {\r\n      id: object::new(ctx),\r\n      coin: zero(),\r\n      faucet_coin: zero(),\r\n    };\r\n    share_object(swapPool);\r\n\r\n    // 设置提现权限\r\n    let admin = Admin {\r\n      id: object::new(ctx)\r\n    };\r\n    transfer(admin, ctx.sender());\r\n  }\r\n\r\n  // 添加 coin 到池子\r\n  public entry fun add_coin_to_pool(swap_pool: \u0026mut SwapPool, in_coin: \u0026mut Coin\u003cGREYHAOCOIN\u003e, amount: u64, ctx: \u0026mut TxContext) {\r\n    let in_obj = in_coin.split(amount, ctx);\r\n    swap_pool.coin.join(in_obj.into_balance());\r\n  }\r\n\r\n  public entry fun add_faucet_to_pool(swap_pool: \u0026mut SwapPool, in_coin: \u0026mut Coin\u003cGREYHAOFAUCET\u003e, amount: u64, ctx: \u0026mut TxContext) {\r\n    let in_obj = in_coin.split(amount, ctx);\r\n    swap_pool.faucet_coin.join(in_obj.into_balance());\r\n  }\r\n\r\n  // 币兑换水龙头币\r\n  public entry fun swap_to_faucet(swap_pool: \u0026mut SwapPool, in_coin: \u0026mut Coin\u003cGREYHAOCOIN\u003e, amount: u64, ctx: \u0026mut TxContext) {\r\n    assert!(in_coin.value() \u003e= amount, EUSERINSUFFICIENTBALANCE);\r\n    let swap_obj = in_coin.split(amount, ctx);\r\n    // 需要转出的数量\r\n    let out_amount = amount * 5;\r\n    assert!(swap_pool.faucet_coin.value() \u003e= out_amount, EPOOLINSUFFICIENTBALANCE);\r\n    // 用户的币转入池子\r\n    swap_pool.coin.join(swap_obj.into_balance());\r\n    // 池子的币转给用户\r\n    let out_balance = swap_pool.faucet_coin.split(out_amount);\r\n    public_transfer(from_balance(out_balance, ctx), ctx.sender());\r\n  }\r\n\r\n  // 水龙头币兑换币\r\n  public entry fun swap_to_coin(swap_pool: \u0026mut SwapPool, in_coin: \u0026mut Coin\u003cGREYHAOFAUCET\u003e, amount: u64, ctx: \u0026mut TxContext) {\r\n    assert!(in_coin.value() \u003e= amount, EUSERINSUFFICIENTBALANCE);\r\n    //分割要兑换的币（真实情况可能是前端处理好）\r\n    let in_obj = in_coin.split(amount, ctx);\r\n    // 需要转出的数量\r\n    let out_amount = amount / 5;\r\n    assert!(swap_pool.coin.value() \u003e= out_amount, EPOOLINSUFFICIENTBALANCE);\r\n    // 用户的币转入池子\r\n    swap_pool.faucet_coin.join(in_obj.into_balance());\r\n    // 池子的币转给用户\r\n    let out_balance = swap_pool.coin.split(out_amount);\r\n    let out_coin = from_balance(out_balance, ctx);\r\n    public_transfer(out_coin, ctx.sender());\r\n  }\r\n\r\n  // 管理员从池子里提取\r\n  public entry fun withdraw_coin_from_pool(_: \u0026Admin, swap_pool: \u0026mut SwapPool, amount: u64, ctx: \u0026mut TxContext) {\r\n    assert!(swap_pool.coin.value() \u003e= amount, EUSERINSUFFICIENTBALANCE);\r\n    let outBalance = swap_pool.coin.split(amount);\r\n    public_transfer(from_balance(outBalance, ctx), ctx.sender());\r\n  }\r\n\r\n  public entry fun withdraw_faucet_from_pool(_: \u0026Admin, swap_pool: \u0026mut SwapPool, amount: u64, ctx: \u0026mut TxContext) {\r\n    assert!(swap_pool.faucet_coin.value() \u003e= amount, EUSERINSUFFICIENTBALANCE);\r\n    let out_b = swap_pool.faucet_coin.split(amount);\r\n    let out_c = from_balance(out_b, ctx);\r\n    public_transfer(out_c, ctx.sender());\r\n  }\r\n\r\n}\r\n\r\n```\r\n\r\n如果觉得本节内容对你有所帮助，可以点赞鼓励下。\r\n\r\n如果你对文章中内容有任何疑问可以留言。","title":"入门 Sui Move 开发：7. 实现一个简单的兑换合约"},"history":null,"timestamp":1741751897,"version":1}