本文介绍了 Paradigm 出品的 Artemis MEV 框架,该框架使用 Rust 语言编写,旨在帮助 MEV 搜索者更轻松地编写 MEV 机器人。文章详细说明了 Artemis 的架构,包括 Collectors、Strategies 和 Executors 三个主要组件,并提供了使用 Artemis 构建 MEV 机器人的步骤和建议。
发布于:2023 年 8 月 15 日 | 于晚上 11:57
Paradigm 的 Artemis MEV 框架对于希望使用 Rust 编写 MEV 机器人的 MEV 搜索者来说是一个有用的工具。
本指南将从高层次向你介绍如何使用 Artemis 框架。它将为你提供开始使用 Rust 编写自己的 MEV 机器人所需的一切。
绝大多数人没有成为有效搜索者的技能或智力。我编写 MEV 机器人是为了学习并与搜索者社区建立联系。
编写 MEV 机器人是一次很棒的学习体验,你将学习真实的、高风险、高回报的软件工程技能。你将学习如何优化程序,并且你将学习如何编写与 Ethereum 区块链交互的软件。我强烈建议任何程序员都尝试一下,但要避免任何盈利的期望。
在本节中,我将解释为什么你应该使用 Artemis 来编写你的下一个 MEV 机器人。
Artemis 构建在 Rust 编程语言之上。Rust 是一种快速、安全且并发的编程语言。这些品质使其成为编写 MEV 机器人的绝佳选择。Rust 社区也非常乐于助人。
Rust 对 Ethereum 的支持非常出色,以下是一些使用 Rust 进行 Ethereum 相关开发的项目:
Artemis dev telegram 频道 活跃且乐于助人。Artemis 的 issue 跟踪器 也很活跃。
自 Artemis 发布以来,MEV 活动显着增加,这表明它非常有效。
Artemis 并不完美。Artemis 为了开发者体验而牺牲了速度和效率。
实际上,这意味着短尾 MEV 机器人(需要毫秒级优化的机器人)不应使用 Artemis。
在使用 Artemis 和阅读本指南之前,你应该对以下内容有中级到高级的了解:
注意:你可以在我的 github 上找到 Artemis 入门模板
使用 Artemis 的第一步是安装 Rust。你可以在 此处 找到有关如何安装 Rust 的说明。
接下来,创建一个新文件夹并在该文件夹中打开一个终端。运行以下命令以创建一个新的 Rust 项目:
cargo new my_project
接下来,将以下内容添加到 Cargo.toml
文件中的 dependencies 部分:
artemis-core = { git = "https://github.com/paradigmxyz/artemis" }
这会将 Artemis 核心库添加到你的项目中。Artemis 核心库包含你需要使用 Artemis 作为框架的所有代码。
在我们开始编写 MEV 机器人之前,我们需要了解 Artemis 项目的结构。
来自 Artemis 主页:
Artemis 的核心架构是一个事件处理管道。该库由三个主要组件组成:
收集器:收集器接收外部事件(例如待处理的交易、新区块、市场订单等),并将它们转换为内部事件表示形式。
策略:策略包含每个 MEV 机会所需的核心逻辑。它们将事件作为输入,并计算是否有任何机会可用(例如,策略可能会监听市场订单流,以查看是否存在任何跨交易所套利)。策略产生动作。
执行器:执行器处理动作,并负责在不同领域执行它们(例如,提交交易、发布链下订单等)。
strategy.rs
文件这将是我们代码的主要部分。一个空的 strategy.rs
文件如下所示:
use super::types::{Action, Config, Event};
use anyhow::Result;
use artemis_core::types::Strategy;
use async_trait::async_trait;
use ethers::providers::Middleware;
use std::sync::Arc;
pub struct ExampleStrat<M> {
client: Arc<M>,
}
impl<M: Middleware + 'static> ExampleStrat<M> {
pub fn new(client: Arc<M>, config: Config) -> Self {
Self { client }
}
}
#[async_trait]
impl<M: Middleware + 'static> Strategy<Event, Action> for ExampleStrat<M> {
async fn sync_state(&mut self) -> Result<()> {
Ok(())
}
async fn process_event(&mut self, event: Event) -> Option<Action> {
match event {}
}
}
impl<M: Middleware + 'static> ExampleStrat<M> {}
types.rs
文件此文件将包含我们将在 MEV 机器人中使用的类型。一个空的 types.rs
文件如下所示:
#[derive(Debug, Clone)]
pub enum Event {}
#[derive(Debug, Clone)]
pub enum Action {}
#[derive(Debug, Clone)]
pub struct Config {}
Artemis 附带一组默认收集器:
BlockCollector
- 从区块链收集新区块LogCollector
- 从区块链收集所有新日志MempoolCollector
- 从内存池收集待处理的交易MevShareCollector
- 收集 MEV-Share SSE 事件OpenseaOrderCollector
- 收集 OpenSea 上的新订单和执行器:
FlashbotsExecutor
- 将 bundles 发送到 Flashbots 中继MempoolExecutor
- 将交易发送到内存池MevshareExecutor
- 将 bundles 发送到 MEV-Share 撮合器但我们也可以编写自己的自定义收集器和执行器。我建议为每个收集器/执行器创建一个单独的文件。
例如,这是我编写的一个将通知发送到 Telegram 频道的执行器(为了简洁而剪辑):
// Telegram Executor - telegram_executor.rs
// 导入
// --snip--
/// 一个将通知发送到 telegram 群组的执行器。
pub struct TGExecutor {
bot: Arc<Bot>,
}
#[derive(Debug, Clone)]
pub struct Notification {
// --snip--
}
impl TGExecutor {
pub async fn new(tg_token: String) -> Self {
let bot = Bot::new(tg_token);
Self { bot: Arc::new(bot) }
}
}
#[async_trait]
impl Executor<Notification> for TGExecutor {
/// 向 telegram 发送通知。
async fn execute(&self, action: Notification) -> Result<()> {
let text: String = action.into();
info!("发送通知: {:?}", text);
let message = self
.bot
.send_message("@<SNIPPED>".to_string(), text);
let res = message.parse_mode(ParseMode::MarkdownV2).send().await;
if let Err(e) = res {
error!("发送通知失败: {:?}", e);
}
Ok(())
}
}
impl From<Notification> for String {
fn from(notification: Notification) -> Self {
// --snip--
}
}
如果你使用的收集器/执行器与智能合约交互,那么使用 ethers-rs bindings 是一个好主意。
一旦我们有了收集器、执行器和策略,我们需要将它们协调在一起。我们在 main.rs
文件中执行此操作。
main.rs
文件每个 Artemis 项目都有一个 main.rs
文件。此文件将包含负责初始化我们的 MEV 机器人并运行它的代码。你可以在 此处 和 此处 找到示例。
这是 Artemis 文档中提供的 OpenSea Sudo Arb 策略示例中的 main.rs
文件的一部分:
// 设置引擎。
let mut engine: Engine<Event, Action> = Engine::default();
// 设置区块收集器。
let block_collector = Box::new(BlockCollector::new(provider.clone()));
let block_collector = CollectorMap::new(block_collector, Event::NewBlock);
engine.add_collector(Box::new(block_collector));
// 设置 opensea 收集器。
let opensea_collector = Box::new(OpenseaOrderCollector::new(args.opensea_api_key));
let opensea_collector =
CollectorMap::new(opensea_collector, |e| Event::OpenseaOrder(Box::new(e)));
engine.add_collector(Box::new(opensea_collector));
// 设置 opensea sudo arb 策略。
let config = Config {
arb_contract_address: H160::from_str(&args.arb_contract_address)?,
bid_percentage: args.bid_percentage,
};
let strategy = OpenseaSudoArb::new(Arc::new(provider.clone()), opensea_client, config);
engine.add_strategy(Box::new(strategy));
// 设置 flashbots 执行器。
let executor = Box::new(MempoolExecutor::new(provider.clone()));
let executor = ExecutorMap::new(executor, |action| match action {
Action::SubmitTx(tx) => Some(tx),
});
engine.add_executor(Box::new(executor));
// 启动引擎。
if let Ok(mut set) = engine.run().await {
while let Some(res) = set.join_next().await {
info!("res: {:?}", res);
}
}
在此示例中,我们可以看到 main.rs
文件负责:
现在我们已经看到了运行机器人所需的所有文件。我们的项目结构应如下所示:
project_name/
├── Cargo.lock // 一个锁文件,由 cargo 生成
├── Cargo.toml // 我们项目的清单,包括依赖项
├── main.rs // 我们机器人的入口点
└── src/
├── constants.rs // 我们可能需要的任何常量
├── custom_collector.rs // 我们的自定义收集器
├── custom_executor.rs // 我们的自定义执行器
├── lib.rs // 重新导出我们的模块
├── strategy.rs // 我们的自定义策略
└── types.rs // 我们的自定义类型,由 Artemis 使用
现在我们已经设置好了项目,我们可以开始编写我们的机器人了。
每个 MEV 机器人都利用特定的 MEV 机会。在编写机器人之前,我们需要找到一个可以利用的 MEV 机会。我还有其他关于此主题的文章。
一旦你想到了一个机会,你需要对其进行研究。你需要彻底了解这个机会。你需要了解风险、回报和机会的机制。
一旦你理解了一个机会,在纸上写下你的机器人将采取的所有步骤,将它们分解成越来越小的片段。例如,如果编写一个在小型协议 XYZ 上执行清算的机器人,你的图表可能如下所示:
- 每隔一个区块从 XYZ 检索所有活跃的仓位
- 生成一个多调合约调用,以从 XYZ 合约检索所有活跃的仓位
- 在本地使用注入的合约模拟调用
- 将结果存储在自定义数据结构中
- 分析所有活跃的仓位
- 检索/计算每个仓位的清算指标
- 检查是否可以清算该仓位
- 如果可以清算该仓位,则生成一个交易来清算该仓位
- 将交易发送到 Flashbots 中继,并提供动态贿赂
此外,记录你需要的任何收集器或执行器可能会有所帮助:
- BlockCollector
- XYZPositionCollector
- FlashbotsExecutor
一旦你起草了一个策略,你就可以开始编写你的机器人了。设置你的机器人会根据你利用的机会而有所不同,但这里有一些提示:
我coding的时候会听 Spotify 上的 Chill Instrumental Beats,它可以帮助我集中注意力。
一旦你的机器人编写和测试完毕,你就可以将其部署在服务器上。我没有任何具体的建议,但一些 MEV 机器人运行在 AWS、Google Cloud、Azure、Hetzner 和 Digital Ocean 上。
监控机器人的性能非常重要。你应该监控以下内容:
你可以设置一个监控系统,或者一开始只使用 etherscan。
我希望本指南对你有所帮助。如果你有任何问题,请随时通过 Discord 或 Telegram 与我联系。
- 原文链接: mteam.space/posts/how-to...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!