Sui Move 实现一个简单的流动性资金池 —— Simple Swap
流动性资金池的本质是一个智能合约,允许用户在不需要中介或中心化交易所的情况下交易加密货币。
用户可以提供一定比例的两种货币成为流动性提供者,这个比例必须与池子中的比例相同,以稳定两种货币的价值,否则可能出现利套利的情况。<br>流动性提供者将收到 $\mathit {LP}$ 权益代币,其作用类似于收据证明,只有凭借它才能解除流动性(将自己投入的两种货币取出)。
交易者可以用其中一种货币,在池子当中交换另一种货币。<br>每一笔交易都将产生手续费,而手续费将按照流动性提供者的贡献大小分配给他们。
一个简单的流动性资金池当然不需要那么多专业的金融知识,仅作为初学者学习使用,我们不妨设两种货币的价值之比永远是 $\text 1\ \mathit :\ \text 1$,不论流动性提供者提供什么比例的两种货币,都不会改变这一点,也就是说,我们也放开了对投入货币比值的限制,当然,整个过程也不再收取手续费。
我们自定义两种货币来模拟,具体的分析在前篇已经给出,这里也就不再赘述,想了解的自行翻阅。<br>两种货币都不需要太多的功能,只需要给出其定义以及铸造函数即可,更深层次的实现都已经封装好了,直接调用即可。<br>代码极度相似,这里就以coin_a
为例:
module simple_swap::coin_a {
use sui::coin::{Self, TreasuryCap};
public struct COIN_A has drop {}
fun init(otw: COIN_A, ctx: &mut TxContext) {
let (treasury_cap, metadata) = coin::create_currency(
otw,
9,
b"coin_a",
b"CA",
b"coin_a to study simple swap",
option::none(),
ctx,
);
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury_cap, tx_context::sender(ctx));
}
entry fun mint(treasury_cap: &mut TreasuryCap<COIN_A>, amount: u64, recipient: address, ctx: &mut TxContext) {
coin::mint_and_transfer(treasury_cap, amount, recipient, ctx);
}
}
$\mathit {LP}$ 权益代币只是一个凭证,内部并不需要存储什么额外的东西,所以可以当做Coin<T>
的一个泛型类型 $\mathit T$ 来处理,对于它的结构定义也十分简单:
public struct LP<phantom COINA, phantom COINB> has drop {}
public
是新版本 $\mathit {Sui\ Move}$ 的语法要求,为了以后支持类似private
等功能做铺垫。<br>phantom
特殊关键字是为了让泛型COINA, COINB
达到以下目的:让容器(结构体)可以包含不遵循它所遵循的相同规则的类型。
池子当中最为关键的当然就是两种货币各自的量,类似于Coin<SUI>
和Balance<SUI>
之间的关系,我们这里用Balance<COINA>, Balance<COINB>
记录它们的数量。
由于我们这个池做了很多限制,所以供应量Supply
就变成了一个可有可无的数据,因为在本篇的限制之下,它一定等于两种货币的数量之和,但是为了演示相关函数的使用,我们这里还是将这个数据加上。<br>如果想知道在正常的流动性资金池当中Supply
有什么作用,可以查看官方给出的示例,它将不再忽略比例、交易费等关系,而Supply
与用户手中的LP
对应的量,也成为了具体能够取出多少货币的关键,如果是初学者建议先将本篇的简易版弄明白,再梳理清楚其中的数学关系再去看官方示例,体验会好很多。
根据以上信息,我们可以简单地将其结构定义如下:
public struct Pool<phantom COINA, phantom COINB> has key {
id: UID,
balance_a: Balance<COINA>,
balance_b: Balance<COINB>,
lp_supply: Supply<LP<COINA, COINB>>,
}
为了保证用户提供的凭证LP
的有效性和真实性,再用一个结构来存储合约给出的凭证相关信息,以ID
作为 $\mathit {Key}$,vector<u64>
作为 $\mathit {Value}$,来组建一个Table
数据结构,其中vector
里的第一个值是第一种货币的提供量,第二个值是第二种货币的提供量。
public struct Pocket has key {
id: UID,
id_to_vec: Table<ID, vector<u64>>,
}
包含泛型签名的函数,需要在函数名后用尖括号依次将其列出,该函数的关键是如何创建一个空的balance
和supply
,最后将其可变共享给所有人。
entry fun create_pool<COINA, COINB>(ctx: &mut TxContext) {
let pool = Pool<COINA, COINB> {
id: object::new(ctx),
balance_a: balance::zero(),
balance_b: balance::zero(),
lp_supply: balance::create_supply<LP<COINA, COINB>>(LP<COINA, COINB> {}),
};
transfer::share_object(pool);
}
传入两种货币,投入流动池,将凭证LP
所有权传回给该流动性提供者,同时在Pocket
当中存储相关的信息。
在新版本 $\mathit {Sui\ Move}$ 当中,对应类型的变量可以通过.
来调用其模块内部的函数,如果第一个参数是自身,那么会根据情况自动引用或可变引用。
entry fun add_liquidity<COINA, COINB>(pool: &mut Pool<COINA, COINB>, coin_a: Coin<COINA>, coin_b: Coin<COINB>, pocket: &mut Pocket, ctx: &mut TxContext) {
let coin_a_amount = coin_a.value();
let coin_b_amount = coin_b.value();
pool.balance_a.join(coin_a.into_balance());
pool.balance_b.join(coin_b.into_balance());
let lp_balance = pool.lp_supply.increase_supply(coin_a_amount + coin_b_amount);
let lp_coin = coin::from_balance(lp_balance, ctx);
let lp_id = object::id(&lp_coin);
let mut vec = vector::empty<u64>();
vec.push_back(coin_a_amount);
vec.push_back(coin_b_amount);
pocket.id_to_vec.add(lp_id, vec);
transfer::public_transfer(lp_coin, tx_context::sender(ctx));
}
通过自身持有的凭证LP
,从池中取出对应数量的两种货币,当然,这张凭证需要通过Pocket
认证。
在新版本 $\mathit {Sui\ Move}$ 当中,可以通过[index]
来取值,如果加前缀&
或者&mut
可以达到borrow
或者borrow_mut
的功能。
entry fun remove_liquidity<COINA, COINB>(pool: &mut Pool<COINA, COINB>, lp: Coin<LP<COINA, COINB>>, pocket: &mut Pocket, ctx: &mut TxContext) {
let lp_id = object::id(&lp);
assert!(pocket.id_to_vec.contains(lp_id), ErrNotContainLP);
let vec = pocket.id_to_vec.remove(lp_id);
let coin_a_amount = vec[0];
let coin_b_amount = vec[1];
assert!(coin_a_amount <= pool.balance_a.value() && coin_b_amount <= pool.balance_b.value(), ErrNotEnoughBalance);
pool.lp_supply.decrease_supply(lp.into_balance());
let sender = tx_context::sender(ctx);
transfer::public_transfer(coin::take(&mut pool.balance_a, coin_a_amount, ctx), sender);
transfer::public_transfer(coin::take(&mut pool.balance_b, coin_b_amount, ctx), sender);
}
两种货币之间的交换都是类似的,我们这里以a_swap_b
为例。
由于本篇的限制,不需要考虑升值贬值以及手续费等情况,所以就是一个 $\text 1\ \mathit :\ \text 1$ 的等值置换,只要池子当中对应数量的另一种货币数量足够即可,函数实现也就很简单。
entry fun a_swap_b<COINA, COINB>(pool: &mut Pool<COINA, COINB>, coin_a: Coin<COINA>, ctx: &mut TxContext) {
let amount = coin_a.value();
assert!(amount <= pool.balance_b.value(), ErrNotEnoughBalance);
pool.balance_a.join(coin_a.into_balance());
transfer::public_transfer(coin::take(&mut pool.balance_b, amount, ctx), tx_context::sender(ctx));
}
sui client publish --gas-budget 100000000
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0x587fbe3bbc2c349750a8f53e9211f6a8ac210191e77d1ef5d71c4b568ec56120 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::TreasuryCap<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A> │
│ │ Version: 81313261 │
│ │ Digest: 92pGs77tf5fxN3VmywZfALAnNcJ6enA9cNxsCB4rj7no │
│ └── │
│ ┌── │
│ │ ObjectID: 0x6c862ef9962fc9942738b32fa8fec7046c0013ece24452a050eae2f6b3409edc │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::TreasuryCap<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313261 │
│ │ Digest: 5Atz9ipb18wAWFszNFS2BeKCCCHgSj8gYCyqP3JXViEg │
│ └── │
│ ┌── │
│ │ ObjectID: 0xb4e570db968ca1791d02e451924316f7df1c5a365968e78716a7fc2d640403d3 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Immutable │
│ │ ObjectType: 0x2::coin::CoinMetadata<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313261 │
│ │ Digest: 4DBC25ieXRYXfsrQtFsDwN5c49nUwB9ipr2ySvGv7VZj │
│ └── │
│ ┌── │
│ │ ObjectID: 0xc5516876817e2464633b0a39de3c08a59f64e28c839288b74df5e23fa6783b5e │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::package::UpgradeCap │
│ │ Version: 81313261 │
│ │ Digest: 9ycDj4HxDAZPFDaRqzZiVz4R5gjLRMnMqADm72b5kEq │
│ └── │
│ ┌── │
│ │ ObjectID: 0xd009d623e1aa706cc66f84716e994862ecd851eca618b7fc020ac8f50cc326d6 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Immutable │
│ │ ObjectType: 0x2::coin::CoinMetadata<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A> │
│ │ Version: 81313261 │
│ │ Digest: 5WtgpKKieZNKmBs9wKHtUTt66bCGfkS6596wpLU79Gf8 │
│ └── │
│ ┌── │
│ │ ObjectID: 0xdd96634447f2657e360955f7a2497d247288fb8c0dec92214563770361e562f0 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::swap::Pocket │
│ │ Version: 81313261 │
│ │ Digest: 5FnBPS8GcSJQW27WH9R3L59UtB4XgZcnpZg6sKchbqKV │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313261 │
│ │ Digest: 3XgtgunRHMgL7jGkQfUSUxxnzgSpSTnb4nYm8LdW4dk2 │
│ └── │
│ Published Objects: │
│ ┌── │
│ │ PackageID: 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef │
│ │ Version: 1 │
│ │ Digest: 64Zp8BRcxAgfnHvUgi5jF9DJRrmyxwiQPdje6PK7MmFb │
│ │ Modules: coin_a, coin_b, swap │
│ └── │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
export PACKAGE_ID=0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef
export COIN_A_TREASURY_CAP=0x587fbe3bbc2c349750a8f53e9211f6a8ac210191e77d1ef5d71c4b568ec56120
export COIN_B_TREASURY_CAP=0x6c862ef9962fc9942738b32fa8fec7046c0013ece24452a050eae2f6b3409edc
export COIN_A_TYPE=0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A
export COIN_B_TYPE=0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B
export POCKET=0xdd96634447f2657e360955f7a2497d247288fb8c0dec92214563770361e562f0
export OWNER=0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67(这是你自己的地址,用来接收铸造的币)
其中,COIN_A_TYPE, COIN_B_TYPE
是两种货币的类型,这在后续调用含有对应泛型的函数时需要通过--type-args
传入,先后顺序必须严格一致。
coin_a
sui client call --package $PACKAGE_ID --module coin_a --function mint --args $COIN_A_TREASURY_CAP 100 $OWNER --gas-budget 10000000
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0xa9f409565a3a7dd7a58560eeee6865d76e1658c787232ff8d7e2f2fb1226d782 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A> │
│ │ Version: 81313262 │
│ │ Digest: 2Kvdo72b6od1Cpn9XMSYJPWp9UQ4LGJJoUznYPPpiEra │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x587fbe3bbc2c349750a8f53e9211f6a8ac210191e77d1ef5d71c4b568ec56120 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::TreasuryCap<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A> │
│ │ Version: 81313262 │
│ │ Digest: Cw3cfPmbhk1qnioEhKQGwvBaDkRNgoTjZ5zEQw25w8WG │
│ └── │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313262 │
│ │ Digest: EBJJb1fFgdrhMreJxhJnoaD8Ena68XjGdtkik4jNYRgj │
│ └── │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
coin_a
export COIN_A=0xa9f409565a3a7dd7a58560eeee6865d76e1658c787232ff8d7e2f2fb1226d782
coin_b
sui client call --package $PACKAGE_ID --module coin_b --function mint --args $COIN_B_TREASURY_CAP 200 $OWNER --gas-budget 10000000
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0x114d021d7e1f721c17f5ffa131a2995931165eb8283e5613f517748abee066a5 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313263 │
│ │ Digest: DD387HJxwCZahbW4QcnJUWExuVVtQzU291gbuvb6nCmZ │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313263 │
│ │ Digest: BJixrnoUgVbtjwisNiQpne8brq4o5Lun2tjmUyhUj8X5 │
│ └── │
│ ┌── │
│ │ ObjectID: 0x6c862ef9962fc9942738b32fa8fec7046c0013ece24452a050eae2f6b3409edc │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::TreasuryCap<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313263 │
│ │ Digest: 4YEb9ZGjSWWFrvwgkJ7KJka3rHjCi5ughyQMyGyPmVdt │
│ └── │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
coin_b
export COIN_B=0x114d021d7e1f721c17f5ffa131a2995931165eb8283e5613f517748abee066a5
coin_a
用于后续交换sui client call --package $PACKAGE_ID --module coin_a --function mint --args $COIN_A_TREASURY_CAP 66 $OWNER --gas-budget 10000000
export COIN_A_66=0x81c81c690666951beb2e7fdcf286ff881807cb36a8d8d5f31d25542dc362fecf
sui client call --package $PACKAGE_ID --module swap --function create_pool --type-args $COIN_A_TYPE $COIN_B_TYPE --gas-budget 10000000
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0xf83639e335568f300f1b20de7a28100d22ed4f51db8dde1c28243ca0a8ae00fb │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::swap::Pool<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A, 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313264 │
│ │ Digest: GLZVie6q2pFiawSFPW2Ge29C3A7Z5rwuQdK6gqSEjB5e │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313264 │
│ │ Digest: 6B3GUPLHzgKFZe9g53Pgx6r77jxvMT5FmPt8BJsfD4NN │
│ └── │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
pool
export POOL=0xf83639e335568f300f1b20de7a28100d22ed4f51db8dde1c28243ca0a8ae00fb
sui client call --package $PACKAGE_ID --module swap --function add_liquidity --args $POOL $COIN_A $COIN_B $POCKET --type-args $COIN_A_TYPE $COIN_B_TYPE --gas-budget 10000000
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0xc056f26580a91e218a709fe5f65543d3dc0cc929ce50e9fe8089a91c4117a922 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Object ID: ( 0x0defc7f7c00f14a037ddfebc8f1daec85865cb2592c5c4d63b18f645d2e4eeb4 ) │
│ │ ObjectType: 0x2::dynamic_field::Field<0x2::object::ID, vector<u64>> │
│ │ Version: 81313265 │
│ │ Digest: 8NbaKcfovGKkoikEcpAvzoWw12zcYUhYSmG8ws98PpG4 │
│ └── │
│ ┌── │
│ │ ObjectID: 0xe38a2a034439e631e57319fb6eb8755a8adaaa780bbcf2deb0e9bb9bfcfc8dd8 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::swap::LP<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A, 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B>> │
│ │ Version: 81313265 │
│ │ Digest: GgyDsa8VzftrYYMjX2ipeoGwYMJs5T1aCxVHPtATi8Tk │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313265 │
│ │ Digest: AAgpsMXGqXZRwLRkaQhRxRK5na3ztiNCGv5thVxavQM │
│ └── │
│ ┌── │
│ │ ObjectID: 0xdd96634447f2657e360955f7a2497d247288fb8c0dec92214563770361e562f0 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::swap::Pocket │
│ │ Version: 81313265 │
│ │ Digest: 8RQbDQJhMY2BfSF6ZmPDJrkvgT74cBUghVi3NWfxKyM7 │
│ └── │
│ ┌── │
│ │ ObjectID: 0xf83639e335568f300f1b20de7a28100d22ed4f51db8dde1c28243ca0a8ae00fb │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::swap::Pool<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A, 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313265 │
│ │ Digest: 2dbQk5zqyGqLfzmQiCMWdDo2EjCNugZPLvswjirQhpVe │
│ └── │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
LP
凭证export LP=0xe38a2a034439e631e57319fb6eb8755a8adaaa780bbcf2deb0e9bb9bfcfc8dd8
a_swap_b
sui client call --package $PACKAGE_ID --module swap --function a_swap_b --args $POOL $COIN_A_66 --type-args $COIN_A_TYPE $COIN_B_TYPE --gas-budget 10000000
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0x87817b79aa58ac430db3a18b6f10e03971cd9391351a0ba1563d3f9de3201efc │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313267 │
│ │ Digest: 2fggJ68UwAyzCgGjFb548JYFwXsawwdXLfJHKgU2Pxs3 │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313267 │
│ │ Digest: 5vy2BfWfQRozPV7AeTuwPeG7AR2fbwZEbauGYKQpVw83 │
│ └── │
│ ┌── │
│ │ ObjectID: 0xf83639e335568f300f1b20de7a28100d22ed4f51db8dde1c28243ca0a8ae00fb │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::swap::Pool<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A, 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313267 │
│ │ Digest: 2fTv4nDyffbJpgcwnKGcWRvErDjAPDFMm8nv9Dbpj5Zz │
│ └── │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
coin_b
export COIN_B_66=0x87817b79aa58ac430db3a18b6f10e03971cd9391351a0ba1563d3f9de3201efc
b_swap_a
sui client call --package $PACKAGE_ID --module swap --function b_swap_a --args $POOL $COIN_B_66 --type-args $COIN_A_TYPE $COIN_B_TYPE --gas-budget 10000000
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0xcc96a577a2c35005317887f5a78cf6743844eba300d65b529e01cefde7d1e7c6 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A> │
│ │ Version: 81313268 │
│ │ Digest: 6k8VGvTx6H85d1es6Z4LQn2mMGWtPVpbGXDniajxJ3Gn │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313268 │
│ │ Digest: 8tkSck8BTDRWSH3rzp3EcfDTcyEcN9Rjo8CqED5H74Pp │
│ └── │
│ ┌── │
│ │ ObjectID: 0xf83639e335568f300f1b20de7a28100d22ed4f51db8dde1c28243ca0a8ae00fb │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::swap::Pool<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A, 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313268 │
│ │ Digest: 346CyHqpErTJS6n82XG5qeBx7oHX9Exv1sR84cDEo9We │
│ └── │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
不难发现,又交换得到了 $\text {66}$ 个coin_a
。
sui client call --package $PACKAGE_ID --module swap --function remove_liquidity --args $POOL $LP $POCKET --type-args $COIN_A_TYPE $COIN_B_TYPE --gas-budget 10000000
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0x7072fdece5348de2f26b83902ee83c7e70561a8fc2d6b94e3fb42c7b89d39bfc │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A> │
│ │ Version: 81313269 │
│ │ Digest: 3E68itKJj3XBSyjb2oj7ZP4fkjHVSPb29s9ToGo1pAtU │
│ └── │
│ ┌── │
│ │ ObjectID: 0xc28256a019c2e47f2cc73bc7ccf5938d3294dab2af1d7a10c1576826edea6253 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313269 │
│ │ Digest: 3ajwizt7RbP42KhtL4msnNAJzeT1pBEvQh369zJV2nDo │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313269 │
│ │ Digest: GGiorjizQr2aSoYddyhT7N4WX2vcF2a6C5DUr6YWTdRE │
│ └── │
│ ┌── │
│ │ ObjectID: 0xdd96634447f2657e360955f7a2497d247288fb8c0dec92214563770361e562f0 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::swap::Pocket │
│ │ Version: 81313269 │
│ │ Digest: GGbTzeBf3rs5Lus3vepUBrFckiwFTDrfkC5wHxFxZF91 │
│ └── │
│ ┌── │
│ │ ObjectID: 0xf83639e335568f300f1b20de7a28100d22ed4f51db8dde1c28243ca0a8ae00fb │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::swap::Pool<0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_a::COIN_A, 0xbf3da4e4174fda08f963abf9380e64aedec4d310dbd4a8e03ed4f653c05452ef::coin_b::COIN_B> │
│ │ Version: 81313269 │
│ │ Digest: 8zbsSupzxaftBY3PDCshzvHFxXWavcr49W8Tkk6cGREJ │
│ └── │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
不难发现,凭借着凭证LP
赎回了 $\text {100}$ 个coin_a
和 $\text {200}$ 个coin_b
。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!