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