DEX事例
为了在 IC 上实现 DEFI 应用,合约罐需要与代币合约罐和账本合约罐互动。这个样本 dapp 说明了如何促进这些互动。你可以在YouTube上看到一个快速介绍。
这个样本交换是用Motoko和Rust实现的,可以看到在 IC 上运行。
架构
IC 的设计允许更复杂的链上计算。结合廉价的存储,有可能拥有链上订单簿。这个样本代码利用了这些功能,并将用户的余额和订单存储在交易所的合约罐里。样本交易所的功能可以浓缩为以下几个步骤。
交易所保管资金(代币和 ICP 的机制不同,见下文)。
交易所更新内部余额簿。
用户在交易所进行交易,导致交易所更新其内部余额簿。
从交易所提取资金,将保管权交还给用户。
实现接口
向交易所请求用户特定的分类账标识符。这个唯一的账户标识代表了交易所分类账中的一个用户专用子账户,使其能够区分用户的存款。
getDepositAddress: () -> (blob);
发起用户向交易所存款。如果用户想存入 ICP,交易所会将资金从用户特定的存款地址转移到其默认的子地址,并调整用户在 DEX 上的 ICP 余额。如果用户想存入 DIP 代币,交易所会尝试将批准的资金转移到其代币账户并调整用户的余额。
deposit: (Token) -> (DepositReceipt);
向交易所提出提现请求。如果用户有足够的余额,交易所会将资金送回给用户。
withdraw: (Token, nat, principal) -> (WithdrawReceipt);
向交易所下达新的订单。如果该订单与现有订单相匹配,它将被执行。
placeOrder: (Token, nat, Token, nat) -> (OrderPlacementReceipt);
允许用户取消已提交的订单。
cancelOrder: (OrderId) -> (CancelOrderReceipt);
请求用户在交易所的特定代币的余额。
getBalance: (Token) -> (nat) query;
费用
交易所有责任从交易中减去费用。这很重要,因为交易所必须为提款和内部转账支付费用。
通证交换演示
本节包含核心交易所功能的详细演练。大多数互动需要多个步骤,并通过使用提供的前端来简化。由于交易所的合约罐功能是公开的,高级用户可以使用dfx
来与交易所互动。
存放 ICP
账本罐提供了一个独特的接口,因此与 ICP 的互动需要单独解决。
用户调用
getDepositAddress
函数。响应包含一个唯一的账户标识符,代表一个由交易所控制的用户特定的子账户。交易所可以通过这个地址识别负责存款的用户。用户将 ICP 转移到获取的存款地址,并等待转移的完成。
为了通知交易所,用户用 ICP 代币本金调用
deposit
。交易所将查看用户的子账户并调整用户在交易所的余额。在第二步中,交易所将把用户子账户中的资金转移到其默认的子账户中,交易所将所有的 ICP 保存在这里。
存放代币
存放代币是比较直接的,因为 DIP20 提供了一个更丰富的交互界面。
用户调用代币罐的
approve
功能。这使交易所有能力代表用户向自己转移资金。与 ICP 存款类似,用户调用交易所的 "存款 "功能。交易所然后将批准的代币资金转移到自己身上,并调整用户的交易所余额。
下单
在向交易所存入资金后,用户可以下订单。一个订单由两个图元组成。from: (Token1, amount1)
和to: (Token2, amount2)
。这些订单被添加到交易所。发生在这些订单上的事情是特定于交易所的实现。这个例子提供了一个简单的交易所,只执行完全匹配的订单。请注意,这只是一个玩具交易所,交易所的功能只是为了完整。提示:交易所有时会很贪婪;)
提取资金
与存入资金相比,提取资金更简单。由于交易所拥有资金的保管权,交易所会在 "取款 "请求时将资金送回给用户。交易所的内部余额也会相应调整。
常见错误
并行执行。如果 canister 函数有
await
语句,就有可能出现执行交错的情况。为了避免 bug,有必要仔细考虑数据结构更新的位置,以防止双重花费的攻击。滑点。更高级的交换应该考虑到滑点,并确保限制的小数位。
异步后没有恐慌:当恐慌发生时,状态会被回滚。这可能会导致交换的正确性问题。
当前最好的 DEX
Sonic 是互联网计算机 DeFi 中心,满足您所有的交换、流动性池和交易需求。它建立在互联网计算机上,以利用无限的可扩展性和超音速的交易终结性。