{"content":{"title":"Sui DeepBook 操作演示","body":"## 1. 介绍\r\n\r\n`DeepBook`是`Sui`推出的去中心化中央限价订单簿。如果你熟悉生活中的中心化交易所模式，那么你将很快熟悉`DeepBook`。\r\n\r\n`DeepBook`支持卖方以特定价格（通常称为限价单）或市场价格列出资产的市场，买家浏览 DeepBook 账本来查找他们想要购买的资产，这种模式使交易者可以自由地按自己选择的价格买卖。\r\n\r\n`DeepBook`的订单流程是透明的，所有人都可以无需许可查看订单流向、订单簿深度和订单撮合流程，任何人都可以自由买卖，没有任何限制。\r\n\r\n考虑到一个钱包地址并发操作的问题，这里设计了`custodian`模块。用户通过创建多个托管账户，由托管账户与订单簿池子交互。同时，`Move`合约的所有权特性又保证了托管账户的安全性。\r\n\r\n在订单簿这边，通过定义不同币种间的兑换创建对应的交易池，用户自由选择目标池子交互。\r\n\r\n![流程](https://d5805068.c-website-ac3.pages.dev/assets/images/img1-a0418a42d3c43add4a65ef1b7558e8ab.png)\r\n\r\n接下来，我们以`CoinA`与`Sui`代币创建一个池子，按照流程进行交互。\r\n\r\n## 2. 准备代币合约\r\n\r\n首先准备一个代币合约，部署到[测试网](https://suiexplorer.com/object/0xd1a5b6d0dc963c61e1f0115865fc71f5a54d7ca0ab256c2500263a0ecdad8b60?network=testnet)\r\n\r\n```rust\r\nmodule deepbookdemo::coinA {\r\n\r\n    use std::option;\r\n    use sui::coin;\r\n    use sui::coin::TreasuryCap;\r\n    use sui::transfer;\r\n    use sui::tx_context::{TxContext, sender};\r\n\r\n    struct COINA has drop {}\r\n\r\n    fun init(witness: COINA, ctx: &mut TxContext){\r\n        let (treasury, metada) = coin::create_currency(witness,6,b\"COINA\",b\"coina\",b\"for test\",option::none(),ctx);\r\n\r\n        transfer::public_freeze_object(metada);\r\n        transfer::public_transfer(treasury,sender(ctx));\r\n    }\r\n\r\n    public entry fun mint(\r\n        treasury_cap: &mut TreasuryCap<COINA>,\r\n        amount: u64,\r\n        recipient: address,\r\n        ctx: &mut TxContext,\r\n    ) {\r\n        coin::mint_and_transfer(treasury_cap, amount, recipient, ctx)\r\n    }\r\n}\r\n```\r\n\r\n接下来`mint`一些`CoinA`给钱包。这一步需要用到`TreasuryCap`，部署合约时生成并转移到创建者账户中。\r\n\r\n## 2. 创建托管账户\r\n\r\n接下来使用`TypeScript`实现交互代码，这里只说明关键代码。\r\n\r\n> `DeepBook`测试网的`package_id`是`0xdee9`，也就是这里的`DEEPBOOK_PACKAGE_ID`\r\n\r\n```tsx\r\nlet [cap] = txb.moveCall({\r\n  typeArguments: [],\r\n  target: `${DEEPBOOK_PACKAGE_ID}::clob_v2::create_account`,\r\n  arguments: [],\r\n})\r\ntxb.transferObjects([cap], txb.pure(currentAccount));\r\n```\r\n\r\n:::note \r\n这里要选择`clob_v2`\r\n:::\r\n\r\n通过调用`create_account`得到监管账户`Account_Cap`\r\n\r\n## 3. 创建交易池\r\n\r\n假设我们要创建一个交易池，`BaseCoin`选择`CoinA`，`QuoteCoin`选择`Sui`。\r\n\r\n```tsx\r\n// 100 sui to create a pool\r\nconst [fee] = txb.splitCoins(txb.gas, [txb.pure(100_000_000_000)]);\r\ntxb.moveCall({\r\n  typeArguments: [BaseCoin, QuoteCoin],\r\n  target: `${DEEPBOOK_PACKAGE_ID}::clob_v2::create_pool`,\r\n  arguments: [txb.pure(`${tickSize}`), txb.pure(`${lotSize}`), fee],\r\n});\r\n```\r\n\r\n:::tip \r\n创建池子需要100`Sui`，可以访问以下地址获取测试`https://getsui.com/<YOUR_WALLET_ADDRESS>`/100\r\n:::\r\n\r\n这里填入的参数：\r\n\r\n1. `BaseCoin: `0xd1a5b6d0dc963c61e1f0115865fc71f5a54d7ca0ab256c2500263a0ecdad8b60::coinA::COINA`\r\n2. `QuoteCoin: `0x2::sui::Sui`\r\n3. `tickSize`:  最小变动价位\r\n4. `lotSize`: 最小变动数量\r\n\r\n样例中生成的[`Pool`](0x4d22a7fbeb42efd6b923f7b07e631bab8f3e88caf566d68cb4600886f65ee6d7)\r\n\r\n## 4.  为委托账户充值\r\n\r\n 接下来需要为托管账户中充值，才能发布订单。\r\n\r\n```tsx\r\n// quote_coin\r\ntxb.moveCall({\r\n  typeArguments: [BaseCoin, QuoteCoin],\r\n  target: `${DEEPBOOK_PACKAGE_ID}::clob_v2::deposit_quote`,\r\n  arguments: [txb.pure(pool), quote_coin, txb.pure(account_cap)],\r\n})\r\n\r\n// 充值 base_coin\r\ntxb.moveCall({\r\n  typeArguments: [BaseCoin, QuoteCoin],\r\n  target: `${DEEPBOOK_PACKAGE_ID}::clob_v2::deposit_base`,\r\n  arguments: [txb.pure(pool), base_coin, txb.pure(account_cap)],\r\n})\r\n```\r\n\r\n## 5. 发布一个市价单\r\n\r\n选择发布一个市价单做演示\r\n\r\n```tsx\r\nconst [base_coin_ret, quote_coin_ret] = txb.moveCall({\r\n  typeArguments: [BaseCoin, QuoteCoin],\r\n  target: `${DEEPBOOK_PACKAGE_ID}::clob_v2::place_market_order`,\r\n  arguments: [\r\n    txb.object(pool),\r\n    txb.object(account_cap),\r\n    txb.pure.u64(client_order_id),\r\n    txb.pure.u64(quanity),\r\n    txb.pure.bool(is_bid),\r\n    txb.object(base_coin),\r\n    txb.object(quote_coin),\r\n    txb.object(CLOCK),\r\n  ],\r\n});\r\n\r\ntxb.transferObjects([base_coin_ret, quote_coin_ret], txb.pure.address(currentAccount));\r\n```\r\n\r\n在这个样例中，订单簿中并没有挂单存在，所以此交易并没有成交。\r\n\r\n这里的`base_coin_ret, quote_coin_ret`是交易结果，置换后的`quote_coin`和未用完的`base_coin`。\r\n\r\n## 6. 取出未用完的`Base_Coin`\r\n\r\n```tsx\r\nconst [base_coin_ret] = txb.moveCall({\r\n  typeArguments: [BaseCoin, QuoteCoin],\r\n  target: `${DEEPBOOK_PACKAGE_ID}::clob_v2::withdraw_base`,\r\n  arguments: [\r\n    txb.object(Shared_Pool),\r\n    txb.pure.u64(ret_amount),\r\n    txb.object(Account_Cap),\r\n  ],\r\n});\r\n\r\ntxb.transferObjects([base_coin_ret], txb.pure.address(current_account));\r\n```\r\n\r\n将未用完的代币转移到钱包地址中。\r\n\r\n---"},"author":{"user":"https://learnblockchain.cn/people/18893","address":null},"history":"bafkreidcs2uwf7ie53lgoqtexddoz654jxqilasfwubi5vgw3geszuollq","timestamp":1711416637,"version":1}