教程:使用 CoW Protocol 创建智能订单 - CoW DAO

  • CowSwap
  • 发布于 2025-01-23 20:49
  • 阅读 18

本文介绍了如何使用 CoW Protocol 创建智能订单,这种订单允许智能合约在结算时根据链上信息决定是否执行交易。文章详细解释了智能订单的原理,并通过一个 TradeAboveThreshold 的例子,展示了如何利用 Safe 作为托管解决方案,实现自动化的交易策略。文章还介绍了如何部署和配置智能订单,以及如何监控其执行情况。

教程:使用 CoW Protocol 创建智能订单

注意:本教程已过时。与本文中提到的不同,使用本教程创建的订单不会自动显示在 API 中。我们更改了在链上交易中提取订单时监听的事件。我们将尽快发布本指南的更新版本。

CoW Protocol 的原生订单类型仅限于部分可成交的限价买入限价卖出订单。虽然这种表达语言涵盖了大多数零售用例,但它缺少一些更强大的高级订单类型,例如:

  • 定时生效订单
  • 止损订单
  • 自动平衡投资组合订单

…等等。

向 CoW Protocol 添加新的原生订单类型将涉及更改和重新部署核心协议的智能合约逻辑,因此这是我们目前想要避免的事情。

虽然上述订单语义可以在不更改智能合约的情况下传达给协议/解决方(例如,通过在 app_data 中使用额外的字段),但它们不能通过结算逻辑来强制执行,因此会受到“链下共识”的约束(不当行为会导致 DAO 的 slashing)。这限制了可以使用这些订单类型交换的价值量,并给解决方带来了更多的风险和信任。

智能订单是一种巧妙的方式,可以在完全无需信任的情况下实现上述语义,而无需更改协议。智能订单基于 ERC1271 的合约签名方案,允许智能合约在结算时决定以其名义下的订单是否满足其交易偏好。

虽然常规订单由其所有者提前签名,并使用 ecrecover 进行静态验证,但智能合约订单通过在结算时询问作者是否接受拟议的交易来实现交互式签名验证。这种验证允许作者及时决定他们是否对拟议的交易感到满意,以便他们的批准可以取决于任何链上信息(例如,区块时间、预言机价格、当前余额等)。

本质上,这允许开发者创建智能自主代理,根据预定义的规则和策略,完全在链上进行交易。

例如,自动平衡投资组合订单(旨在使其所有代币具有相等 $ 价值的智能合约)可以执行以下检查:

def checkSignature(order):
    buyBalanceAfterTrade = order.buyToken.balanceOf(self) + order.buyAmount
    sellBalanceAfterTrade = order.sellToken.balanceOf(self) + order.sellAmount

    buyBalanceValue = oracle.value(order.buyToken, buyBalanceAfterTrade)
    sellBalanceValue = self.oracle.value(order.sellToken, sellBalanceAfterTrade)

    # 检查我们只交易投资组合代币
    assert(order.sellToken in portfolio and order.buyToken in portfolio)
    # 检查我们不过度平衡
    assert(sellBalanceValue >= buyBalanceValue)
    return  True

请注意,智能订单合约验证的具体的 CoW Protocol 订单符合原生 CoW Protocol 订单类型(即,它是部分可成交的限价订单)。

然而,通过将额外的信息纳入交互式验证步骤(例如,检查预言机价格,并且只有在 ETH 的交易价格低于 X 时才接受),智能订单可以向交易添加额外的条件。

事实上,“棘手”的部分是找到正确的原生 CoW Protocol 订单参数,该参数能够使智能合约的签名验证通过。为此,订单的放置可以通过以下方式发生:

  • 了解智能订单的解决方,以即时流动性的形式(订单不属于官方拍卖集,因此不会对目标值做出贡献)
  • 通过公共 CoW Protocol API 以 permissionless 的方式(由于 ERC1271 不需要私钥签名,因此任何人都可以代表智能合约下订单)

前一种选择更适合于非常复杂的订单类型,在这种订单类型中,正确的订单参数可能取决于优化问题本身的结果。解决方有动机包含这些订单,因为它们可能允许他们为公共用户订单产生更多的盈余。

然而,除了直接联系解决方之外,今天还没有一种很好的方式来告知解决方关于这种类型的自定义流动性。因此,出于本教程的目的,我们将重点关注更简单的订单放置类型:通过 CoW Protocol 的公共 API 包含的智能订单,并且默认对所有解决方可用。

如何构建智能订单?

我们开发了一个用于创建智能订单的实验性框架,该框架提出了一种用于条件智能订单的标准接口。实现此接口的订单可以被我们的支持基础设施自动拾取,以放置订单,而无需单独的运营维护:https://github.com/cowprotocol/conditional-smart-orders

核心思想是智能订单合约不仅会验证它是否乐于交易给定的订单。它还提出(通过单独的 view 方法)它愿意接受的具体 CoW Protocol 订单。

在实例化时,智能订单会触发一个事件。此事件被索引,并将此合约添加到注册表中,外部瞭望塔通过查询已实现的 view 方法不断监控该注册表。在看到订单候选时,瞭望塔会将此订单放入 CoW Protocol API 中。

从开发者的角度来看,你所需要做的就是实现一个方法(getTradableOrder),该方法提供逻辑,说明在给定链的当前状态下,你的合约将接受哪些订单参数。签名验证逻辑的默认实现将像检查给定的订单是否确实是由 getTradableOrder 返回的一样简单(当然,如果难以可靠地重现调用之间的确切订单参数,则更宽松的检查也是可能的)。

只要 getTradableOrder 返回一个订单,我们的瞭望塔就会将其转发到 CoW Protocol API,解决方会提取它,并通过结算逻辑,要求你的合约将其验证为结算交易的一部分。

我们使用两个 Tenderly Web3 Actions 实现了注册表索引和瞭望塔逻辑:

  1. 一个用于索引订单创建事件并将合约添加到监视注册表
  2. 另一个用于定期检查注册表中的合约,以确定它们是否愿意以当前区块进行交易

还有其他运行此链下基础设施的方法,但我们发现 Tenderly 的框架最方便,而无需我们自己的云设置。

该存储库还提供了一些建议的订单类型(使用风险自负)。我们将非常感谢对该存储库的贡献(你还可以为特定订单类型申请 Grants)。

如何使用 Safe 部署智能订单?

虽然条件订单框架可以非常容易地实现自定义验证逻辑,但通常涉及到需要在 such 合约中实现的一些托管开销逻辑(例如,当我想退出策略时,如何取回我的资金)。这种逻辑可能很复杂,审计成本很高,而且容易出错。值得庆幸的是,那里有一个经过验证的智能账户抽象标准(Safe),它允许非常灵活的托管解决方案,并且已经保护了数十亿美元的资金。

在本教程中,我们将使用 Safe 作为我们的主要“智能代理”合约,并且仅将条件智能订单逻辑委托用于签名验证。

Safe 开箱即用地支持 ERC1271 签名,但也允许所有者设置自定义 ERC1271 实现(例如,你的智能订单实现的那个)。Safe 通过所谓的“fallback handler”来实现 ERC1271,该组件在 Safe 上调用它未直接实现的方法(例如,isValidSignature)时调用。因此,通过将我们的智能订单实现设置为 Safe 的自定义 fallback handler,我们将默认 ERC1271 实现替换为我们自己的实现,并使我们的代理根据我们的自定义规则进行交易。请注意,具有 such fallback handler 的 Safe 将只能对 CoW Protocol 订单进行 ERC1271 签名(没有其他第三方 dApp 相关签名有效)。带有所有者签名的普通 Safe 交易将继续像往常一样工作。

所以让我们开始吧!我们条件智能订单框架中的大多数智能订单都带有一个 factory,允许直接从 Safe UI 实例化新实例。因此,攻击计划是:

  1. 创建一个新的 Safe
  2. 在 CoW Swap APP 中批准代币
  3. 创建一个新的智能订单实例(专门针对此 Safe)
  4. 将上一步中智能订单的地址设置为 Safe 的 fallback handler
  5. 使用要交易的代币为其注资。等待并观看 Safe 自动交易

逐步指南

1. 创建一个新的 Safe

前往 https://app.safe.global/welcome 并按照提示“创建新的 Safe”。随意将所有者结构保持简单,例如 1/1 签名者。

1-create-new-safe.webp

2. 在 CoW Swap APP 中批准代币

在你的 Safe 中,前往 Apps → CoW Swap。在 APP 的左上方,单击 Account → Tokens 并选择需要启用的代币。Swap 换成任何其他代币并批准你打算使用此合约交易的代币。

在此示例中,我们将交易 Wrapped XDAI:

2-approve-tokens-in-cow-swap-app.webp

3. 创建一个新的智能订单实例

在此示例中,我们将部署 TradeAboveThreshold 订单,只要持有超过 X 的某种代币,它就会自动出售。

Gnosis Chain 上此合约的 厂位于 0xd20a99e3c6c103108d74e241908e00ef4db447fb(如果你找不到 厂,可以使用 Foundry 部署一个新的 厂)。要创建新实例,请前往你的 Safe 并创建新交易合约交互并从 厂地址加载合约 ABI。

我们要调用 create。填写所需的参数(目标是你当前的 Safe)。在本例中,只要合约持有 1 美元或更多,我们就会将 wxDAI 出售为 USDC:

3-create-a-new-smart-order-instance.webp

添加交易,创建批处理并执行。执行交易后,在区块浏览器中打开交易哈希,以查找 厂创建的智能订单实例的地址(例如,从查看内部交易中)。

3-1-create-a-new-smart-order-instance.webp

在这里,我们创建了 https://gnosisscan.io/address/0xdf724fdbaef2419f1af895f494bd8969ec433d01

4. 设置自定义 Fallback handler

返回 Safe 创建新交易合约交互,这次是在 Safe 本身上(输入 Safe 的地址)。

出现提示时,选择使用 Implementation ABI

4-set-custom-fallback-handler.webp

我们要调用的合约方法选择器是 setFallbackHandler,地址应该是上一步中创建的合约:

4-1-set-custom-fallback-handler.webp

在添加和执行此交易后,你将把智能订单设置为 Safe 的 ERC1271 实现。

5. 资助 Safe

现在,当 Safe 收到 1 wxDAI 时,它应该自动下一个订单,将其出售为 USDC。让我们试试:

5-fund-the-safe.webp

在挖掘转移之后不久,如果我们检查 https://explorer.cow.fi/ 的 Safe 地址,我们应该会看到一个挂起的订单,试图将 wxDAI 出售为 USDC

5-1-fund-the-safe.webp

而且,经过短暂的时间后,订单应该已完成。

你可以通过向 Safe 发送更多资金来根据需要重复此过程。为了提取收益,你可以使用标准的 Safe 功能。

结论

在本教程中,我们描述并暗示了智能订单在智能合约成为自主交易代理的背景下可能具有的力量,讨论了如何通过几行 Solidity 代码创建一个简单的“条件订单”类型,并逐步介绍了如何使用 Safe 作为托管解决方案部署智能订单的示例。

我们希望本文能激发你尝试智能订单,甚至在 CoW Protocol 之上构建自己的智能订单。请联系我们提出建议和想法。我们期待看到使用此范例可以构建哪些类型的订单。

立即试用 ERC1271 订单,并通过在 TwitterDiscord 上联系我们来告诉我们你的想法!

  • 原文链接: cow.fi/learn/tutorial-cr...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
CowSwap
CowSwap
江湖只有他的大名,没有他的介绍。