<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title/><link>https://blogs.12ms.xyz/</link><description>Recent content on</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><copyright>This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.</copyright><atom:link href="https://blogs.12ms.xyz/index.xml" rel="self" type="application/rss+xml"/><item><title>我们是不是已经进入了一个"魔法时代"</title><link>https://blogs.12ms.xyz/posts/2025/12/%E6%88%91%E4%BB%AC%E6%98%AF%E4%B8%8D%E6%98%AF%E5%B7%B2%E7%BB%8F%E8%BF%9B%E5%85%A5%E4%BA%86%E4%B8%80%E4%B8%AA%E9%AD%94%E6%B3%95%E6%97%B6%E4%BB%A3/</link><pubDate>Sun, 07 Dec 2025 00:00:00 +0000</pubDate><guid>https://blogs.12ms.xyz/posts/2025/12/%E6%88%91%E4%BB%AC%E6%98%AF%E4%B8%8D%E6%98%AF%E5%B7%B2%E7%BB%8F%E8%BF%9B%E5%85%A5%E4%BA%86%E4%B8%80%E4%B8%AA%E9%AD%94%E6%B3%95%E6%97%B6%E4%BB%A3/</guid><description>&lt;h1 id="前"&gt;前&lt;/h1&gt;
&lt;p&gt;2022 年底，ChatGPT 横空出世。短短几个月内，这个能写代码、能写论文、能陪你聊天的 AI，席卷了整个互联网。&lt;/p&gt;
&lt;p&gt;身边很多非技术圈的朋友问我：这玩意儿是怎么做到的？我尝试解释神经网络、大模型训练&amp;hellip;&amp;hellip;他们的眼神从好奇变成茫然，最后只剩下一句：&amp;ldquo;太神奇了，简直像魔法一样。&amp;rdquo;&lt;/p&gt;
&lt;p&gt;这让我想起英国科幻作家阿瑟·克拉克（Arthur C. Clarke）的那句：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Any sufficiently advanced technology is indistinguishable from magic.
（任何足够先进的技术，初看都与魔法无异。）&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;AI 时代的加速到来，让这句话从科幻预言变成了现实写照。当大多数人只知道&amp;quot;对话框里打字就能得到答案&amp;quot;，却完全不理解背后发生了什么——我们是不是已经进入了一个&amp;quot;魔法时代&amp;quot;？&lt;/p&gt;
&lt;h2 id="魔法结界正在形成"&gt;魔法结界正在形成&lt;/h2&gt;
&lt;p&gt;回望人类历史，技术从来都是少数人的专利。但过去的技术壁垒，至少还是&amp;quot;可见&amp;quot;的：你不会铸剑，但你能看到铁匠挥锤；你不会织布，但你能理解经纬交错的原理。&lt;/p&gt;
&lt;p&gt;而现在，壁垒正在变得隐形。&lt;/p&gt;
&lt;p&gt;当你对着手机说一句话，信息穿越数千公里到达另一个人的耳边——这中间发生了什么？电磁波、基站、光纤、服务器、加密协议&amp;hellip;&amp;hellip;对于绝大多数人来说，这些词汇和&amp;quot;魔法咒语&amp;quot;没有本质区别。&lt;/p&gt;
&lt;p&gt;更关键的是，这种&amp;quot;不理解&amp;quot;正在成为常态，甚至被鼓励。&lt;/p&gt;
&lt;p&gt;产品设计追求&amp;quot;无感&amp;quot;体验，用户不需要知道背后的原理，只需要享受结果。技术栈越堆越高，即便是专业开发者，也只能精通其中一小块领域。AI 的崛起更是加速了这个进程——当机器可以自己写代码、自己做决策，人类对技术的理解反而在后退。&lt;/p&gt;
&lt;p&gt;我把这种现象称为&amp;quot;魔法结界&amp;quot;的形成：技术创造者与使用者之间，正在出现一道越来越难以跨越的认知鸿沟。&lt;/p&gt;
&lt;h2 id="若干年后的世界"&gt;若干年后的世界&lt;/h2&gt;
&lt;p&gt;让我们大胆畅想一下，当这道结界彻底成型，世界会变成什么样？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;场景一：魔法师与麻瓜&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;懂技术的人成为新时代的&amp;quot;魔法师&amp;quot;，他们能够调用 AI、操控数据、构建系统。而不懂技术的人则成为&amp;quot;麻瓜&amp;quot;，他们生活在魔法师构建的世界里，享受便利，却对运行规则一无所知。&lt;/p&gt;
&lt;p&gt;这不是歧视，而是一种客观的分层。就像今天，绝大多数人不知道电是怎么发出来的，但这并不影响他们用电。未来，绝大多数人可能也不知道 AI 是怎么思考的，但这不影响他们让 AI 帮自己工作。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;场景二：新型祭司阶层&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;历史上，掌握文字的祭司曾是知识的垄断者。未来，掌握技术的工程师会不会成为新的祭司阶层？&lt;/p&gt;
&lt;p&gt;他们解释世界如何运转，制定数字世界的规则，甚至决定哪些信息可以被看到、哪些声音可以被听到。普通人对他们的依赖，可能比古人对祭司的依赖更深。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;场景三：魔法的民主化 vs 集中化&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这里存在两条可能的路径：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;民主化&lt;/strong&gt;：AI 工具变得足够简单，人人都能&amp;quot;施法&amp;quot;。就像今天人人都能用手机拍照，不需要理解光学原理。技术壁垒被工具消解，魔法结界反而被打破。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;集中化&lt;/strong&gt;：核心技术被少数巨头垄断，普通人只能使用被允许的&amp;quot;魔法道具&amp;quot;。你可以用 AI，但你无法理解它、无法修改它、无法拥有它。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前来看，两条路径都在同时发生。问题是，哪一条会成为主流？&lt;/p&gt;
&lt;h2 id="技术不是一切但决定了很多"&gt;技术不是一切，但决定了很多&lt;/h2&gt;
&lt;p&gt;当然，这里不是说技术就是一切。&lt;/p&gt;
&lt;p&gt;掌握技术的人成为&amp;quot;魔法师&amp;quot;，但不一定能用好这个魔法。历史反复证明，力量本身是中性的，真正决定结果的是运用力量的人。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文化和哲学，决定了魔法如何被使用。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一个只懂技术却不懂人性的工程师，可能会设计出监控一切的系统；一个只追求效率却不考虑公平的算法，可能会加剧社会的撕裂；一个只看数据却不理解语境的 AI，可能会制造更多的误解。&lt;/p&gt;
&lt;p&gt;所以，未来真正重要的，或许不是&amp;quot;谁掌握了魔法&amp;quot;，而是&amp;quot;魔法师们信仰什么&amp;quot;。&lt;/p&gt;
&lt;p&gt;他们是追求开放还是封闭？是服务于人还是控制人？是让技术为所有人所用，还是让技术成为新的权力工具？&lt;/p&gt;
&lt;p&gt;而这些问题，技术本身回答不了。&lt;/p&gt;
&lt;h2 id="后"&gt;后&lt;/h2&gt;
&lt;p&gt;我们正站在魔法时代的入口，作为一个技术从业者，我时常有一种矛盾的感受：一方面，我为技术的进步感到兴奋；另一方面，我也担忧这种进步带来的认知割裂。&lt;/p&gt;
&lt;p&gt;或许有一天，当后人回顾我们这个时代，他们会看到一群对着屏幕敲击奇怪符号的人。希望他们评价我们时，不是说&amp;quot;这群人制造了无法理解的黑箱&amp;quot;，而是说&amp;quot;这群魔法师用智慧和责任，构建了一个开放而有序的数字世界&amp;quot;。&lt;/p&gt;
&lt;p&gt;魔法结界正在形成，但结界的形状，取决于我们现在的选择？&lt;/p&gt;</description></item><item><title>从 SEO 到 GEO：AI 时代的广告革命</title><link>https://blogs.12ms.xyz/posts/2025/11/%E6%9C%AA%E6%9D%A5%E6%97%B6%E4%BB%A3%E5%B9%BF%E5%91%8A/</link><pubDate>Thu, 13 Nov 2025 00:00:00 +0000</pubDate><guid>https://blogs.12ms.xyz/posts/2025/11/%E6%9C%AA%E6%9D%A5%E6%97%B6%E4%BB%A3%E5%B9%BF%E5%91%8A/</guid><description>&lt;h1 id="前"&gt;前&lt;/h1&gt;
&lt;p&gt;果然来了，AI 广告的新方向。&lt;/p&gt;
&lt;p&gt;前段时间有个奇思妙想：AI 时代的广告平台会是什么样？广告商疯狂地卷自己产品的资料内容，然后把这些资料使用类似 RAG 的方式喂给 AI。但前提是广告必须是真实的、符合 AI 广告法的。比如药品说明书，在 AI 时代就是一个很好的广告形式——详尽、准确、结构化。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;赛博朋克世界最不缺的是什么？广告！广告还是广告！&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;只不过这次不是铺天盖地的显示屏，而是无处不在的大模型推荐。关注 AI 广告部分的投资机会，这可能是未来的新方向。&lt;/p&gt;
&lt;h2 id="从-seo-到-geo游戏规则变了"&gt;从 SEO 到 GEO：游戏规则变了&lt;/h2&gt;
&lt;p&gt;过去二十年，SEO 是互联网流量的核心玩法。&lt;/p&gt;
&lt;p&gt;关键词密度、外链建设、页面结构优化，本质是在迎合搜索引擎的算法偏好。整个行业围绕着&amp;quot;如何让爬虫喜欢你&amp;quot;展开。&lt;/p&gt;
&lt;p&gt;现在游戏规则变了。&lt;/p&gt;
&lt;p&gt;用户不再只是在 Google 搜索框里输入关键词，而是在和 ChatGPT、Claude、Perplexity 对话。问题从&amp;quot;最好的降噪耳机&amp;quot;变成&amp;quot;我通勤一小时，预算 2000，推荐一款舒适的降噪耳机&amp;quot;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;搜索引擎返回的是链接列表，生成式 AI 返回的是直接答案。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这意味着什么？传统 SEO 优化的那些内容，AI 可能根本不会推荐给用户。因为 AI 不是爬虫，它是理解语义、综合信息、生成回答的智能体。&lt;/p&gt;
&lt;p&gt;GEO（Generative Engine Optimization）应运而生。&lt;/p&gt;
&lt;h2 id="geo从流量思维到信任思维"&gt;GEO：从流量思维到信任思维&lt;/h2&gt;
&lt;p&gt;核心逻辑不再是&amp;quot;让搜索引擎找到你&amp;quot;，而是&amp;quot;让 AI 引用你&amp;quot;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一个从流量思维到信任思维的转变。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;具体来说，GEO 的内容策略完全不同：&lt;/p&gt;
&lt;h3 id="seo-vs-geo-的策略对比"&gt;SEO vs GEO 的策略对比&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;SEO&lt;/th&gt;
&lt;th&gt;GEO&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;核心目标&lt;/td&gt;
&lt;td&gt;让搜索引擎找到你&lt;/td&gt;
&lt;td&gt;让 AI 引用你&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内容形式&lt;/td&gt;
&lt;td&gt;堆砌关键词&lt;/td&gt;
&lt;td&gt;结构化、高质量信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;优化对象&lt;/td&gt;
&lt;td&gt;爬虫和算法&lt;/td&gt;
&lt;td&gt;LLM 上下文窗口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;评价标准&lt;/td&gt;
&lt;td&gt;排名第一&lt;/td&gt;
&lt;td&gt;成为可信来源&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;技术手段&lt;/td&gt;
&lt;td&gt;meta 标签、外链&lt;/td&gt;
&lt;td&gt;RAG 系统、知识图谱&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="geo-的三个核心原则"&gt;GEO 的三个核心原则&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;不是堆砌关键词&lt;/strong&gt;，而是提供结构化、高质量、可被 AI 理解和信任的信息&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不是为爬虫优化 meta 标签&lt;/strong&gt;，而是为 LLM 的上下文窗口提供清晰的知识图谱&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不是追求排名第一&lt;/strong&gt;，而是成为 AI 训练数据和检索增强生成（RAG）系统中的可信来源&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="内容质量的回归"&gt;内容质量的回归&lt;/h2&gt;
&lt;p&gt;有意思的地方在于：这其实是内容质量的回归。&lt;/p&gt;
&lt;p&gt;SEO 时代催生了大量为算法而生的垃圾内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;标题党横行&lt;/li&gt;
&lt;li&gt;关键词堆砌&lt;/li&gt;
&lt;li&gt;采集站泛滥&lt;/li&gt;
&lt;li&gt;低质量内容农场&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为只要能骗过爬虫，就能获得流量。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;但 AI 不吃这一套。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;LLM 的判断标准更接近人类：内容是否有价值、逻辑是否清晰、信息是否准确。低质量内容在生成式回答中被边缘化是必然的。&lt;/p&gt;
&lt;p&gt;从这个角度看，GEO 不是新的作弊手段，而是让内容创作回到本质的一次纠偏。&lt;/p&gt;
&lt;h2 id="广告逻辑的彻底改变"&gt;广告逻辑的彻底改变&lt;/h2&gt;
&lt;p&gt;当然，这也意味着广告的逻辑彻底改变了。&lt;/p&gt;
&lt;h3 id="传统广告模式"&gt;传统广告模式&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;买流量&lt;/li&gt;
&lt;li&gt;买位置&lt;/li&gt;
&lt;li&gt;买曝光&lt;/li&gt;
&lt;li&gt;打断用户注意力&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="geo-时代的广告模式"&gt;GEO 时代的广告模式&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;让 AI 主动为你背书&lt;/li&gt;
&lt;li&gt;产品信息、技术文档、用户评价足够优质&lt;/li&gt;
&lt;li&gt;AI 在合适的场景下主动推荐&lt;/li&gt;
&lt;li&gt;在用户需要的时候精准出现&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一种更高维度的营销：不是打断用户，而是在用户需要的时候精准出现。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id="geo-产业的雏形"&gt;GEO 产业的雏形&lt;/h2&gt;
&lt;p&gt;GEO 现在已经是一个初有雏形的行业了。&lt;/p&gt;
&lt;p&gt;一些公司开始专门为企业提供 AI 友好的内容优化服务，甚至有人在研究如何让自己的内容更容易被 GPT-4 或 Claude 引用。&lt;/p&gt;
&lt;p&gt;这个趋势才刚刚开始。&lt;/p&gt;
&lt;h1 id="后"&gt;后&lt;/h1&gt;
&lt;p&gt;随着越来越多人把 AI 当作信息获取的第一入口，GEO 的价值会指数级上升。&lt;/p&gt;
&lt;p&gt;那些早期布局高质量内容的品牌，会在这波转变中占据先发优势。而那些还停留在 SEO 时代的玩家，可能会发现自己的流量正在被无声地蚕食。&lt;/p&gt;
&lt;p&gt;不是被竞争对手抢走的，是被 AI 过滤掉的。&lt;/p&gt;
&lt;p&gt;从搜索引擎到生成式 AI，不仅仅是技术的迭代，更是整个信息分发逻辑的重构。适应这个变化，不是选择题，而是生存题。&lt;/p&gt;</description></item><item><title>写在 Balancer 被盗后：Code is Law 的边界</title><link>https://blogs.12ms.xyz/posts/2025/11/%E5%86%99%E5%9C%A8balancer%E8%A2%AB%E7%9B%97%E5%90%8E/</link><pubDate>Tue, 04 Nov 2025 00:00:00 +0000</pubDate><guid>https://blogs.12ms.xyz/posts/2025/11/%E5%86%99%E5%9C%A8balancer%E8%A2%AB%E7%9B%97%E5%90%8E/</guid><description>&lt;h1 id="前"&gt;前&lt;/h1&gt;
&lt;p&gt;Balancer 是 DeFi 兴起时代最早期的玩家之一，甚至早于 Uniswap V2，跟 Aave 时间差不多。2020 年上半年，在 Balancer 一推出时候就玩过，当时使用频繁，印象也深。&lt;/p&gt;
&lt;p&gt;这次被盗 1.3 亿美金，又是一个典型的 DeFi 黑客事件。但这次引发的讨论有些不同——在传统金融机构尝试 DeFi 的关键时期，这次被盗挖出了一个核心问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Code is Law 这个理念，在金融场景下是否真的成立？&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id="code-is-law信仰与现实的碰撞"&gt;Code is Law：信仰与现实的碰撞&lt;/h2&gt;
&lt;p&gt;早期加密圈把&amp;quot;不可篡改&amp;quot;当作信仰。链上执行的就是绝对真理，没有回滚，没有仲裁，代码即法律。这是对传统金融体系&amp;quot;人治&amp;quot;的反抗，也是去中心化的哲学基础。&lt;/p&gt;
&lt;p&gt;但理想和现实总是有差距的。&lt;/p&gt;
&lt;h3 id="传统金融的容错机制"&gt;传统金融的&amp;quot;容错机制&amp;quot;&lt;/h3&gt;
&lt;p&gt;传统金融系统不是完美的，但它有容错机制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;信用卡被盗刷可以追回&lt;/li&gt;
&lt;li&gt;银行转账错误可以撤销&lt;/li&gt;
&lt;li&gt;诈骗案件可以冻结资产&lt;/li&gt;
&lt;li&gt;金融机构破产有存款保险&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些&amp;quot;人为干预&amp;quot;被视为中心化的弊病，但同时也是金融系统稳定运行的保障。&lt;/p&gt;
&lt;h3 id="公链的不可篡改困境"&gt;公链的&amp;quot;不可篡改&amp;quot;困境&lt;/h3&gt;
&lt;p&gt;公链的完全不可篡改性，在理论上很优雅。但在实践中，它意味着：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个智能合约漏洞可以导致不可挽回的损失&lt;/li&gt;
&lt;li&gt;一次私钥泄露可以让所有资产归零&lt;/li&gt;
&lt;li&gt;一个黑客攻击可以&amp;quot;合法地&amp;quot;掠夺数亿资金&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;问题在于：金融系统的本质是什么？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;是追求绝对的规则确定性，还是在确定性和容错性之间找到平衡？&lt;/p&gt;
&lt;h2 id="联盟链实用主义的妥协"&gt;联盟链：实用主义的妥协？&lt;/h2&gt;
&lt;p&gt;这让我想到另一个方向：是否未来的主流方案是有准入规则、有审查能力的联盟链？&lt;/p&gt;
&lt;p&gt;设想一下这样的架构：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;由主流国家或金融机构部署超级节点&lt;/li&gt;
&lt;li&gt;保留区块链的技术优势（透明、可追溯、分布式）&lt;/li&gt;
&lt;li&gt;具备必要的监管和追回机制（KYC/AML、资产冻结）&lt;/li&gt;
&lt;li&gt;关键时刻可以人为干预（类似传统金融的仲裁机制）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这听起来像是对去中心化理念的背叛。但可能这才是金融体系能够接受的形态。&lt;/p&gt;
&lt;p&gt;完全去中心化和完全中心化之间，或许存在一个实用主义的中间地带：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;可审计、可追踪、关键时刻可干预，但日常运行依然是代码驱动。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id="场景化的法律"&gt;场景化的&amp;quot;法律&amp;quot;&lt;/h2&gt;
&lt;p&gt;Code is Law 不是错的，但可能需要加一个前提：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;在什么场景下，法律需要是绝对的？&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在什么场景下，我们需要为人为判断留出空间？&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;金融可能恰恰属于后者。&lt;/p&gt;
&lt;p&gt;不同的应用场景对&amp;quot;不可篡改&amp;quot;的需求是不同的：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景类型&lt;/th&gt;
&lt;th&gt;对不可篡改的需求&lt;/th&gt;
&lt;th&gt;是否需要人为干预&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;数字艺术/NFT&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;供应链溯源&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;金融交易&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;身份认证&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;社交应用&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="后"&gt;后&lt;/h1&gt;
&lt;p&gt;DeFi 已经走过了野蛮生长的阶段，现在面临的是如何与现实世界接轨的问题。&lt;/p&gt;
&lt;p&gt;Balancer 的这次被盗，不仅仅是一次技术事故，更是一次对行业理念的拷问。&lt;/p&gt;
&lt;p&gt;我们需要思考的不是放弃去中心化，而是如何在保留区块链技术优势的同时，建立必要的安全机制和容错能力。&lt;/p&gt;
&lt;p&gt;完全的去中心化可能永远存在于理想主义者的乌托邦中，但在金融这个关乎无数人财产安全的领域，实用主义的妥协或许才是可持续的道路。&lt;/p&gt;
&lt;p&gt;Code is Law，但 Law 需要为不同的场景定制。&lt;/p&gt;
&lt;p&gt;区块链真的可以用于金融世界吗？ 这个问题又一次被震耳欲聋的提出&lt;/p&gt;</description></item><item><title>标签爆炸：信息过载时代的自我救赎</title><link>https://blogs.12ms.xyz/posts/2025/02/%E6%A0%87%E7%AD%BE%E7%88%86%E7%82%B8/</link><pubDate>Tue, 04 Feb 2025 00:00:00 +0000</pubDate><guid>https://blogs.12ms.xyz/posts/2025/02/%E6%A0%87%E7%AD%BE%E7%88%86%E7%82%B8/</guid><description>&lt;h2 id="前"&gt;前&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;这篇文章是一次自我救赎。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;打开浏览器，30个、50个、甚至100个标签页密密麻麻地排列在顶部，每个都代表着一篇&amp;quot;想看但还没看&amp;quot;的文章。打开电脑桌面，各种&amp;quot;稍后阅读&amp;quot;的链接堆积如山。我们生活在一个知识爆炸的时代，也生活在一个标签爆炸的时代。&lt;/p&gt;
&lt;p&gt;在某个周五的晚上，看着浏览器顶部那些已经看不清标题的标签，我意识到一个问题：&lt;strong&gt;我不是在管理知识，而是在被信息淹没。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这篇文章想聊聊标签爆炸背后的焦虑，以及我找到的一些应对方法。&lt;/p&gt;
&lt;h2 id="标签爆炸的本质"&gt;标签爆炸的本质&lt;/h2&gt;
&lt;h3 id="为什么我们不愿意关闭标签"&gt;为什么我们不愿意关闭标签&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.zhihu.com/question/532775936/answer/2489859311"&gt;知乎上有个问题&lt;/a&gt;很有意思：为什么有些人浏览器要开30个以上标签页，也不愿意关呢？&lt;/p&gt;
&lt;p&gt;仔细算一下就会发现问题：30个标签页，哪怕每个标签页只看一分钟也需要半个小时。但我们依然不愿意关闭，背后的原因是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;害怕错过的焦虑&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;担心关闭后就再也找不到这篇文章&lt;/li&gt;
&lt;li&gt;认为每篇文章都&amp;quot;可能有用&amp;quot;&lt;/li&gt;
&lt;li&gt;希望&amp;quot;有时间的时候&amp;quot;能回来看&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;收集的错觉&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开标签页=获取了知识&lt;/li&gt;
&lt;li&gt;保存链接=完成了学习&lt;/li&gt;
&lt;li&gt;标签数量=知识储备&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;决策的疲劳&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不知道哪些该留哪些该关&lt;/li&gt;
&lt;li&gt;没有明确的筛选标准&lt;/li&gt;
&lt;li&gt;做决定比保持现状更累&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="信息过载的代价"&gt;信息过载的代价&lt;/h3&gt;
&lt;p&gt;但这种&amp;quot;开了不关&amp;quot;的习惯带来的问题远比我们想象的严重：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;认知负担&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每次打开浏览器都看到密密麻麻的标签，产生压力&lt;/li&gt;
&lt;li&gt;找不到想要的标签，导致重复打开&lt;/li&gt;
&lt;li&gt;大量标签占用内存，电脑变慢&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;虚假的安全感&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;以为保存了就等于掌握了&lt;/li&gt;
&lt;li&gt;实际上从未真正阅读和思考&lt;/li&gt;
&lt;li&gt;知识没有进入大脑，只是堆在浏览器里&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;行动的瘫痪&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;面对100个标签不知从何看起&lt;/li&gt;
&lt;li&gt;最终一个都不看，继续打开新标签&lt;/li&gt;
&lt;li&gt;陷入&amp;quot;收集-焦虑-再收集&amp;quot;的恶性循环&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="我的应对策略"&gt;我的应对策略&lt;/h2&gt;
&lt;p&gt;在意识到这个问题后，我开始尝试一些方法来打破这个循环。&lt;/p&gt;
&lt;h3 id="策略一建立聚合思维"&gt;策略一：建立聚合思维&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;知识很迷人，但你的时间有限。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;这是我给自己的第一个提醒。我们需要从&amp;quot;收集者&amp;quot;转变为&amp;quot;策展人&amp;quot;，学会聚合而不是堆积。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心原则&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不是所有信息都值得你的时间&lt;/li&gt;
&lt;li&gt;深度理解10篇文章比浅尝100篇更有价值&lt;/li&gt;
&lt;li&gt;聚焦于你真正关心的领域&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;实践方法&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在打开新标签前问自己：这篇文章能解决我当下的什么问题？&lt;/li&gt;
&lt;li&gt;如果答案是&amp;quot;可能以后有用&amp;quot;，那就不要打开&lt;/li&gt;
&lt;li&gt;专注于当下需要的知识，而不是可能需要的知识&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="策略二周五只关不开"&gt;策略二：周五只关不开&lt;/h3&gt;
&lt;p&gt;给自己定一个简单的规则：&lt;strong&gt;每周五只关闭标签，不打开新标签。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个规则的好处：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;强制清理&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每周至少有一次系统性清理的机会&lt;/li&gt;
&lt;li&gt;形成固定习惯，降低决策成本&lt;/li&gt;
&lt;li&gt;一周的时间足够判断哪些标签是真需要的&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;优先级显现&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一周都没打开的标签，大概率不会再打开&lt;/li&gt;
&lt;li&gt;真正重要的内容会自然浮现&lt;/li&gt;
&lt;li&gt;不重要的信息自然沉淀&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;心理解脱&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;设定固定时间节点，减少日常决策压力&lt;/li&gt;
&lt;li&gt;周五清理后的周末更轻松&lt;/li&gt;
&lt;li&gt;新的一周从干净的浏览器开始&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="策略三相信重复出现定律"&gt;策略三：相信重复出现定律&lt;/h3&gt;
&lt;p&gt;这是我用来对抗&amp;quot;害怕错过&amp;quot;焦虑的核心理念：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不要怕忽略了有用的知识，因为真正有用的东西，有100%的概率你还会再次看到它。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;为什么这个定律有效&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;信息传播的规律&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;真正重要的信息会在多个渠道反复出现&lt;/li&gt;
&lt;li&gt;多次遇到说明它确实重要，值得你的时间&lt;/li&gt;
&lt;li&gt;一次出现就消失的信息通常不是核心知识&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;认知的成熟度&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一次看到可能还没准备好理解&lt;/li&gt;
&lt;li&gt;再次遇到时可能正好是你需要的时候&lt;/li&gt;
&lt;li&gt;重复出现本身就是一种筛选机制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;实践经验&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我关闭的95%的标签从未再想起&lt;/li&gt;
&lt;li&gt;真正需要的内容总会以某种形式回来&lt;/li&gt;
&lt;li&gt;这种信任让我更敢于关闭标签&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="策略四即时记录精华"&gt;策略四：即时记录精华&lt;/h3&gt;
&lt;p&gt;虽然我们要勇于关闭标签，但也不能完全被动。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不要忘了个别文章中的宝藏，及时把它记录下来。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;使用Memo式记录&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不是保存整篇文章，而是记录核心要点：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;记录什么&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;触动你的观点或论述&lt;/li&gt;
&lt;li&gt;可以立即应用的方法&lt;/li&gt;
&lt;li&gt;改变你认知的新视角&lt;/li&gt;
&lt;li&gt;值得深入研究的方向&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;记录格式&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用自己的话总结（强制思考）&lt;/li&gt;
&lt;li&gt;标注信息来源（便于回溯）&lt;/li&gt;
&lt;li&gt;添加个人思考（建立连接）&lt;/li&gt;
&lt;li&gt;打上相关标签（方便检索）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;工具推荐&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Obsidian：本地存储，支持双向链接&lt;/li&gt;
&lt;li&gt;Notion：云端同步，灵活的数据库&lt;/li&gt;
&lt;li&gt;Apple Notes：简单轻量，随手记录&lt;/li&gt;
&lt;li&gt;Logseq：大纲式笔记，适合知识管理&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="本质的思考"&gt;本质的思考&lt;/h2&gt;
&lt;p&gt;在实践这些方法几个月后，我对标签爆炸有了更深的理解。&lt;/p&gt;
&lt;h3 id="这不只是管理问题"&gt;这不只是管理问题&lt;/h3&gt;
&lt;p&gt;标签爆炸的本质不是工具问题，而是心态问题：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;收集≠学习&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;保存链接只是第一步&lt;/li&gt;
&lt;li&gt;真正的学习发生在阅读、思考、实践中&lt;/li&gt;
&lt;li&gt;没有内化的信息不是知识&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;多≠好&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;接触100个概念不如深入理解1个&lt;/li&gt;
&lt;li&gt;广度建立在深度的基础上&lt;/li&gt;
&lt;li&gt;专注比博学更重要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;焦虑的根源&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不是害怕错过信息&lt;/li&gt;
&lt;li&gt;而是不确定自己的方向&lt;/li&gt;
&lt;li&gt;明确目标是解决焦虑的根本&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="从被动接收到主动选择"&gt;从被动接收到主动选择&lt;/h3&gt;
&lt;p&gt;改变的关键是转变角色：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;旧模式：信息的被动接收者&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;看到什么就收集什么&lt;/li&gt;
&lt;li&gt;被信息流推着走&lt;/li&gt;
&lt;li&gt;永远在追赶，永远焦虑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;新模式：知识的主动策展人&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;明确自己当下的需求和方向&lt;/li&gt;
&lt;li&gt;主动筛选对自己有价值的信息&lt;/li&gt;
&lt;li&gt;为信息设定优先级&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="后"&gt;后&lt;/h2&gt;
&lt;p&gt;写完这篇文章后，我做的第一件事就是关闭了浏览器里的42个标签页。&lt;/p&gt;
&lt;p&gt;几个月后回头看，我发现自己记不起任何一个被关闭的标签的内容。但我记得那些真正读过、思考过、记录过的文章。&lt;/p&gt;
&lt;p&gt;标签爆炸的问题不会自己消失，它需要我们主动改变。从今天开始，试试这些方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;设定周五清理日&lt;/strong&gt;：每周五只关不开&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;相信重复定律&lt;/strong&gt;：重要的信息会再次出现&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;即时记录精华&lt;/strong&gt;：用Memo记录真正的宝藏&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;问自己问题&lt;/strong&gt;：这个信息对当下的我有什么价值？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最后，如果你也有100个标签等待关闭，不妨从现在开始。你会发现，失去的只是焦虑，得到的是清晰和专注。&lt;/p&gt;
&lt;p&gt;希望这篇文章能够帮助你从标签爆炸中解脱出来，找到属于自己的信息管理节奏。&lt;/p&gt;</description></item><item><title>信息焦虑：从社交媒体重度用户到主动信息消费者</title><link>https://blogs.12ms.xyz/posts/2025/01/%E4%BF%A1%E6%81%AF%E7%84%A6%E8%99%91/</link><pubDate>Fri, 31 Jan 2025 00:00:00 +0000</pubDate><guid>https://blogs.12ms.xyz/posts/2025/01/%E4%BF%A1%E6%81%AF%E7%84%A6%E8%99%91/</guid><description>&lt;h1 id="前"&gt;前&lt;/h1&gt;
&lt;p&gt;前段时间，我的X（Twitter）账号因为出口IP可疑的问题被莫名封禁。在申诉等待的那几天，我突然意识到一个问题：为什么我会因为无法访问一个社交平台而感到如此焦虑？这促使我开始重新审视自己与信息的关系。&lt;/p&gt;
&lt;p&gt;曾经，信息是稀缺和珍贵的。而现在，信息如潮水般涌入我们的大脑。我们每天被推送、被通知、被算法投喂，却越来越少地主动思考。这篇文章是我对信息焦虑的一些反思，也是我尝试改变信息消费习惯的记录。&lt;/p&gt;
&lt;h1 id="噪音与信号"&gt;噪音与信号&lt;/h1&gt;
&lt;h2 id="99的信息都是噪音"&gt;99%的信息都是噪音&lt;/h2&gt;
&lt;p&gt;在思考这个问题的过程中，我得出了一个结论：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;做很多事情只需要坚定自己的思路，加上一定的灵感，而不要被身边所有的噪音所影响。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;以投资为例，你身边99%的新闻、推送、热点讨论，本质上都是噪音。它们会干扰你的判断，让你偏离既定的策略，在情绪的驱动下做出冲动决策。&lt;/p&gt;
&lt;p&gt;这个规律不仅适用于投资，也适用于技术学习、职业发展、个人成长等几乎所有领域：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;技术学习&lt;/strong&gt;：每天都有新框架、新工具发布，但大多数与你当前的学习路径无关&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;职业发展&lt;/strong&gt;：各种成功学、职场攻略充斥网络，但真正适合你的路径需要自己探索&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;个人生活&lt;/strong&gt;：铺天盖地的消费主义内容，让你觉得不买就会错过&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;真正重要的信息永远只占少数，而这些信息不需要你刷屏去寻找——当它足够重要时，会以某种方式自然地到达你面前。&lt;/p&gt;
&lt;h2 id="主动获取-vs-被动接收"&gt;主动获取 vs 被动接收&lt;/h2&gt;
&lt;p&gt;我逐渐意识到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;信息的获取应该是一个主动发现的过程，而不是被动接受各种别人想让你看到的东西。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;被动接收信息会导致两个严重问题：&lt;/p&gt;
&lt;h3 id="1-丧失思考能力"&gt;1. 丧失思考能力&lt;/h3&gt;
&lt;p&gt;当你习惯了被算法投喂内容，你会逐渐失去主动思考的能力。你的注意力被一条条精心设计的内容牵引，大脑陷入&amp;quot;浅层思考&amp;quot;模式——不断接收、快速反应、立即遗忘。&lt;/p&gt;
&lt;h3 id="2-陷入信息焦虑"&gt;2. 陷入信息焦虑&lt;/h3&gt;
&lt;p&gt;你会生怕错过什么关键内容，于是一次次刷新屏幕。这种FOMO（Fear of Missing Out，错失恐惧症）让你：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每隔几分钟就想看看手机&lt;/li&gt;
&lt;li&gt;看到未读通知就感到不安&lt;/li&gt;
&lt;li&gt;即使在做其他事情，注意力也被社交媒体分散&lt;/li&gt;
&lt;li&gt;无法长时间专注于一件事&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但实际上，你并不需要这样。重要的信息会以某种形式到达，而不需要你通过一次次刷屏去捕捉。&lt;/p&gt;
&lt;h1 id="不要做信息的路由器"&gt;不要做信息的路由器&lt;/h1&gt;
&lt;h2 id="转发的快感"&gt;转发的快感&lt;/h2&gt;
&lt;p&gt;我观察到一个现象：很多人热衷于分享信息——看到一条新闻马上转发，发现一个热点立即评论。这种行为背后是什么？&lt;/p&gt;
&lt;p&gt;是获得&amp;quot;我知道最新信息&amp;quot;的优越感，是向他人展示&amp;quot;我有价值&amp;quot;的需求，是通过传播信息来获取社交认同的快感。&lt;/p&gt;
&lt;p&gt;但我并不认为这是一种好的行为或特质。原因很简单：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你成为了信息传播链中的一个工具，传播的是没有经过你思考的东西。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;你像一个路由器一样，把信息收集起来，然后转发到另一个地方。虽然这是一种&amp;quot;分享精神&amp;quot;，但它既没有让你进步，也没有真正帮助到被分享者。&lt;/p&gt;
&lt;h2 id="真正有价值的分享"&gt;真正有价值的分享&lt;/h2&gt;
&lt;p&gt;什么才是有价值的分享？&lt;/p&gt;
&lt;p&gt;我的想法是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;分享你的思考&lt;/strong&gt;：读完一篇文章后，分享你的理解、感悟和批判性思考&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分享你的实践&lt;/strong&gt;：亲自验证过的方案、踩过的坑、总结的经验&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分享你的创造&lt;/strong&gt;：基于多个信息源的综合分析、自己的原创观点&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这些过程中，分享的是属于你自己的东西。你在整理思路时进步，别人在阅读时也有收获。&lt;/p&gt;
&lt;p&gt;而单纯的转发和搬运，只是在制造更多的信息噪音。&lt;/p&gt;
&lt;h1 id="我的改变"&gt;我的改变&lt;/h1&gt;
&lt;h2 id="从重度用户到主动消费者"&gt;从重度用户到主动消费者&lt;/h2&gt;
&lt;p&gt;曾经我也是X的重度用户，每天刷屏幕可能十几次甚至几十次，生怕错过什么新鲜事。但越往后越发现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;身体上很累&lt;/strong&gt;：眼睛酸痛，颈椎不适，睡眠质量下降&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;精神上很空虚&lt;/strong&gt;：每次刷完都是空虚感，而不是获得感&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;时间在流失&lt;/strong&gt;：一天结束回顾，发现大量时间消耗在无意义的浏览上&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;思维在变浅&lt;/strong&gt;：习惯了短平快的碎片信息，越来越难以进行深度思考&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我意识到，我迷失在了信息的荒野中。&lt;/p&gt;
&lt;h2 id="具体的改变措施"&gt;具体的改变措施&lt;/h2&gt;
&lt;p&gt;经过这次账号被封的事件，我开始尝试改变：&lt;/p&gt;
&lt;h3 id="1-关闭推送通知"&gt;1. 关闭推送通知&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;手机设置：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 关闭所有社交媒体的推送通知
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 关闭新闻类App的通知
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 只保留即时通讯和日历提醒
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;让信息的获取回归到&amp;quot;我主动打开&amp;quot;而非&amp;quot;它来打扰我&amp;quot;。&lt;/p&gt;
&lt;h3 id="2-设定固定的信息消费时间"&gt;2. 设定固定的信息消费时间&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;每天的信息消费时间：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 早上9:00-9:30：浏览重要新闻和行业动态
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 晚上8:00-8:30：阅读技术文章和博客
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 其他时间：专注于工作和深度学习
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;把碎片化的&amp;quot;随时刷&amp;quot;变成结构化的&amp;quot;定时看&amp;quot;。&lt;/p&gt;
&lt;h3 id="3-建立信息筛选机制"&gt;3. 建立信息筛选机制&lt;/h3&gt;
&lt;p&gt;我开始使用RSS订阅代替算法推荐：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;精选10-15个高质量的信息源（技术博客、行业专家）&lt;/li&gt;
&lt;li&gt;每天浏览标题，只深入阅读真正相关的内容&lt;/li&gt;
&lt;li&gt;用Pocket或Notion保存值得反复阅读的文章&lt;/li&gt;
&lt;li&gt;定期清理订阅源，保持信息流的高质量&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4-培养深度阅读习惯"&gt;4. 培养深度阅读习惯&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;阅读清单优先级：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 书籍（技术书、非虚构类）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 长文（深度分析、技术文档）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 短文（博客、论文摘要）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. 碎片（社交媒体、新闻）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;每周至少：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 1本书的进展（每天30-60分钟）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 2-3篇长文的精读
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 写1篇总结或思考
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="5-输出倒逼输入"&gt;5. 输出倒逼输入&lt;/h3&gt;
&lt;p&gt;我开始强制自己输出：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;读完技术文章后，写笔记总结&lt;/li&gt;
&lt;li&gt;实践新技术后，写博客记录&lt;/li&gt;
&lt;li&gt;有新想法时，先写下来再去搜索验证&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个过程让我对信息的需求变得明确——我不再漫无目的地浏览，而是带着问题去寻找答案。&lt;/p&gt;
&lt;h2 id="改变后的效果"&gt;改变后的效果&lt;/h2&gt;
&lt;p&gt;实践两个月后，我的感受：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;积极方面&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注意力集中时间显著增加（从30分钟到2小时+）&lt;/li&gt;
&lt;li&gt;对技术的理解更深入（有时间系统学习而非浅尝辄止）&lt;/li&gt;
&lt;li&gt;焦虑感大幅降低（不再担心&amp;quot;错过&amp;quot;什么）&lt;/li&gt;
&lt;li&gt;产出质量提升（博客文章更有深度）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;挑战方面&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;初期会有戒断反应（总想打开手机）&lt;/li&gt;
&lt;li&gt;偶尔会真的错过一些热点讨论&lt;/li&gt;
&lt;li&gt;需要更强的自律来维持新习惯&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但总的来说，这是一个正向的改变。我重新获得了对时间和注意力的掌控权。&lt;/p&gt;
&lt;h1 id="后"&gt;后&lt;/h1&gt;
&lt;p&gt;这次X账号被封，虽然一开始让我焦虑，但回过头看，反而是一个契机。它让我意识到，我对社交媒体的依赖已经到了不健康的程度。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;人生其实是一片旷野，并没有什么条条框框，也不需要按照某个标准去活。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;信息的消费方式也是如此。你不必追随所有人都在用的平台，不必订阅所有热门的博客，不必参与所有火热的讨论。找到适合自己的节奏，建立自己的信息生态，才能在信息洪流中保持清醒。&lt;/p&gt;
&lt;h2 id="我的建议"&gt;我的建议&lt;/h2&gt;
&lt;p&gt;如果你也感到信息焦虑，不妨尝试：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;审视自己的信息消费习惯&lt;/strong&gt;：记录一周的时间使用，看看有多少时间花在了无意义的浏览上&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主动减少信息源&lt;/strong&gt;：取关、取消订阅那些并不真正有价值的内容&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;建立输入-输出循环&lt;/strong&gt;：每消费一定量的信息，就强制自己输出一些思考&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;培养一个深度爱好&lt;/strong&gt;：读书、写作、编程、运动&amp;hellip;任何需要长时间专注的事情&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接受错过&lt;/strong&gt;：接受你会错过一些热点，接受你不需要知道所有事情&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;信息时代，真正稀缺的不是信息，而是注意力和思考能力。保护好它们。&lt;/p&gt;
&lt;h2 id="延伸阅读"&gt;延伸阅读&lt;/h2&gt;
&lt;p&gt;如果你对这个话题感兴趣，推荐以下资源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;《深度工作》by Cal Newport - 关于如何在碎片化时代保持专注&lt;/li&gt;
&lt;li&gt;《数字极简主义》by Cal Newport - 如何理性使用数字技术&lt;/li&gt;
&lt;li&gt;《娱乐至死》by Neil Postman - 关于信息洪流对思考的影响&lt;/li&gt;
&lt;li&gt;Digital Minimalism实践社区 - 一群追求信息极简的实践者&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就这样！希望这篇文章能帮到同样在信息焦虑中挣扎的你。记住，你不需要知道所有事情，你只需要知道对你真正重要的事情。&lt;/p&gt;</description></item><item><title>123 陷阱：为什么你总觉得自己什么都没学会</title><link>https://blogs.12ms.xyz/posts/2024/12/123%E9%99%B7%E9%98%B1/</link><pubDate>Wed, 04 Dec 2024 00:00:00 +0000</pubDate><guid>https://blogs.12ms.xyz/posts/2024/12/123%E9%99%B7%E9%98%B1/</guid><description>&lt;h2 id="前"&gt;前&lt;/h2&gt;
&lt;p&gt;最近在整理学习笔记时，我发现了一个尴尬的现象：去年收藏的 50+ 个技术教程，完整看完的不到 5 个；购买的 10+ 门在线课程，学完的只有 1 门；下载的几十本技术书籍，读完的寥寥无几。&lt;/p&gt;
&lt;p&gt;更糟糕的是，当别人问我&amp;quot;你会 XXX 吗？&amp;ldquo;时，我的回答往往是&amp;quot;学过，但不太熟&amp;rdquo;。明明花了很多时间学习，为什么总觉得自己什么都没学会？&lt;/p&gt;
&lt;p&gt;后来我意识到，自己掉进了一个我称之为 &lt;strong&gt;&amp;ldquo;123 陷阱&amp;rdquo;&lt;/strong&gt; 的学习误区。&lt;/p&gt;
&lt;h2 id="什么是-123-陷阱"&gt;什么是 123 陷阱&lt;/h2&gt;
&lt;h3 id="现象描述"&gt;现象描述&lt;/h3&gt;
&lt;p&gt;123 陷阱指的是这样一种学习模式：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;学习 Go → 感觉没学会 → 学习 Rust → 感觉没学会 → 学习 Zig → 感觉没学会 → ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 1 2 3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;你不断地学习新东西（1、2、3&amp;hellip;），但每次都浅尝辄止：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;看了几节课就觉得枯燥，转向下一个&lt;/li&gt;
&lt;li&gt;跟着教程做了 Hello World，就以为学会了&lt;/li&gt;
&lt;li&gt;遇到难点就放弃，去找&amp;quot;更简单&amp;quot;的替代品&lt;/li&gt;
&lt;li&gt;总觉得自己学得不够深，要继续学更多&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;结果就是：&lt;strong&gt;看起来学了很多，实际上什么都没真正掌握。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="我的真实案例"&gt;我的真实案例&lt;/h3&gt;
&lt;p&gt;回顾我的学习历程，典型的 123 陷阱场景：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;编程语言方面&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;学 Python：写了几个小脚本，遇到类和装饰器就卡住了&lt;/li&gt;
&lt;li&gt;转学 Go：写了个 HTTP server，遇到 channel 和 goroutine 又懵了&lt;/li&gt;
&lt;li&gt;再学 Rust：被所有权和生命周期劝退&lt;/li&gt;
&lt;li&gt;又去看 TypeScript：发现类型系统也很复杂&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一年过去了，结果是：Python 不熟练，Go 不会用，Rust 看不懂，TypeScript 只会基础语法。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;前端框架方面&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React：学到 Hooks 就没继续&lt;/li&gt;
&lt;li&gt;Vue：看了文档没做项目&lt;/li&gt;
&lt;li&gt;Svelte：觉得新鲜，看了几个例子就没了&lt;/li&gt;
&lt;li&gt;Next.js、Nuxt.js：收藏了教程从未打开&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;问题很明显：&lt;strong&gt;我在收集知识，而不是掌握技能。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="为什么会掉进这个陷阱"&gt;为什么会掉进这个陷阱&lt;/h2&gt;
&lt;h3 id="原因一学习的即时满足感"&gt;原因一：学习的即时满足感&lt;/h3&gt;
&lt;p&gt;学习新东西有一种天然的愉悦感：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开一个新教程：充满期待&lt;/li&gt;
&lt;li&gt;看懂前几章：感觉良好&lt;/li&gt;
&lt;li&gt;了解新概念：觉得自己在进步&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但这种满足感是廉价的，就像刷短视频一样：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你获得了&amp;quot;学习&amp;quot;的感觉&lt;/li&gt;
&lt;li&gt;但没有真正的能力提升&lt;/li&gt;
&lt;li&gt;只是在满足&amp;quot;我在学习&amp;quot;的心理需求&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="原因二逃避深度思考"&gt;原因二：逃避深度思考&lt;/h3&gt;
&lt;p&gt;真正的学习是痛苦的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要反复练习&lt;/li&gt;
&lt;li&gt;要面对自己的不足&lt;/li&gt;
&lt;li&gt;必须克服理解上的障碍&lt;/li&gt;
&lt;li&gt;要投入大量时间深挖&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而切换到新主题可以让你：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;回到舒适的&amp;quot;入门&amp;quot;阶段&lt;/li&gt;
&lt;li&gt;避免面对当前主题的难点&lt;/li&gt;
&lt;li&gt;用&amp;quot;学习新东西&amp;quot;来掩盖&amp;quot;学不会旧东西&amp;quot;的事实&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;切换学习主题是一种伪装成勤奋的逃避。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3 id="原因三错误的学习目标"&gt;原因三：错误的学习目标&lt;/h3&gt;
&lt;p&gt;我发现自己经常陷入这样的思维误区：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;我要学会所有流行的技术&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;不懂 XXX 就落伍了&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;多学一门语言就多一个选择&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但从来没问过自己：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;学这个要解决什么问题？&lt;/li&gt;
&lt;li&gt;这个技术对我的工作有什么帮助？&lt;/li&gt;
&lt;li&gt;我有时间深入学习吗？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;没有明确的目标，学习就变成了盲目的收集。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="原因四完美主义作祟"&gt;原因四：完美主义作祟&lt;/h3&gt;
&lt;p&gt;很多时候觉得&amp;quot;没学会&amp;quot;，其实是完美主义在作祟：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;看了一本书，但没看完所有章节 → &amp;ldquo;还没学会&amp;rdquo;&lt;/li&gt;
&lt;li&gt;会用基本功能，但不懂底层原理 → &amp;ldquo;还没学会&amp;rdquo;&lt;/li&gt;
&lt;li&gt;能写代码，但写得不够优雅 → &amp;ldquo;还没学会&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种心态导致：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;永远觉得自己准备不足&lt;/li&gt;
&lt;li&gt;不敢真正开始实践&lt;/li&gt;
&lt;li&gt;陷入无休止的&amp;quot;学习准备期&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="如何跳出-123-陷阱"&gt;如何跳出 123 陷阱&lt;/h2&gt;
&lt;h3 id="策略一项目驱动学习"&gt;策略一：项目驱动学习&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;不要为了学而学，而要为了用而学。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我的转变过程：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;以前的学习路径&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;看 Docker 教程 → 学 K8s → 研究 Service Mesh → ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;现在的学习路径&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;需要部署个人博客 → 学习 Docker 基础 → 写 Dockerfile → 成功部署
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 遇到多容器管理问题 → 学习 docker-compose → 解决问题
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 需要自动扩缩容 → 学习 K8s 的相关概念 → 在项目中实践
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;关键区别&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;以前：漫无目的地学习概念&lt;/li&gt;
&lt;li&gt;现在：为了解决具体问题而学习&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;实践方法&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想学某个技术前，先找一个要做的项目&lt;/li&gt;
&lt;li&gt;以项目需求为导向，只学必要的部分&lt;/li&gt;
&lt;li&gt;遇到问题再深入学习，而不是预先学所有东西&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="策略二20-法则"&gt;策略二：20% 法则&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;20% 的知识可以解决 80% 的问题。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;核心原则&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先掌握最核心的 20%&lt;/li&gt;
&lt;li&gt;用这 20% 去解决实际问题&lt;/li&gt;
&lt;li&gt;在实践中遇到瓶颈时，再学习下一个 20%&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;以学 Python 为例&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一个 20%（优先掌握）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;基本语法：变量、条件、循环&lt;/li&gt;
&lt;li&gt;常用数据结构：列表、字典&lt;/li&gt;
&lt;li&gt;函数定义和调用&lt;/li&gt;
&lt;li&gt;基本文件操作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用这些知识就可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;写数据处理脚本&lt;/li&gt;
&lt;li&gt;做简单的自动化任务&lt;/li&gt;
&lt;li&gt;解决日常工作中的小问题&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;不要一开始就学&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;装饰器&lt;/li&gt;
&lt;li&gt;元类&lt;/li&gt;
&lt;li&gt;协程&lt;/li&gt;
&lt;li&gt;类型标注&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些是高级特性，等你真正需要时再学。&lt;/p&gt;
&lt;h3 id="策略三深度优先而非广度优先"&gt;策略三：深度优先而非广度优先&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;广度优先（123 陷阱）&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Python 基础 → Go 基础 → Rust 基础 → TypeScript 基础
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;都学了一点，都不精通
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;深度优先（推荐）&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Python 基础 → Python 项目 → Python 高级特性 → 生产环境实践
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ ↓ ↓ ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 会写代码 能做东西 代码质量提升 解决真实问题
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;实践建议&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选择一门语言/技术深入学习&lt;/li&gt;
&lt;li&gt;至少做 3 个以上的项目&lt;/li&gt;
&lt;li&gt;在生产环境中使用过&lt;/li&gt;
&lt;li&gt;读过相关的源码或深度文章&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只有真正掌握一门技术后，再去学第二门，才会发现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;学第二门时快很多（很多概念是相通的）&lt;/li&gt;
&lt;li&gt;更容易理解底层原理&lt;/li&gt;
&lt;li&gt;能主动对比不同技术的优劣&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="策略四建立反馈循环"&gt;策略四：建立反馈循环&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;问题：学了没有反馈，不知道是否真的掌握&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决方案：建立多个反馈节点&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;即时反馈&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;跟着教程写代码时，每个例子都运行一遍&lt;/li&gt;
&lt;li&gt;不要只是看，一定要自己敲一遍&lt;/li&gt;
&lt;li&gt;尝试修改参数，观察结果变化&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;短期反馈&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;学完一个模块，用它做个小项目&lt;/li&gt;
&lt;li&gt;不用复杂，能跑起来就行&lt;/li&gt;
&lt;li&gt;用自己的话写一篇总结笔记&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;中期反馈&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;教别人你学到的东西&lt;/li&gt;
&lt;li&gt;回答社区里的相关问题&lt;/li&gt;
&lt;li&gt;给开源项目提 PR&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;长期反馈&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在工作中应用学到的技术&lt;/li&gt;
&lt;li&gt;承担相关的技术任务&lt;/li&gt;
&lt;li&gt;成为团队里这个技术的 go-to person&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="策略五允许自己不完美"&gt;策略五：允许自己&amp;quot;不完美&amp;quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;转变心态&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;以前&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;还没学完全部章节，不能说自己会&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;还没看源码，不敢说自己懂&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;还有很多高级特性不会，不能用在项目里&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;现在&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;能解决实际问题就够了&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;遇到问题再深入学习也不迟&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;先用起来，在实践中提升&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;实践原则&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;会用 &amp;gt; 懂原理 &amp;gt; 精通（按顺序来）&lt;/li&gt;
&lt;li&gt;能解决 80% 的问题就够格说&amp;quot;会&amp;quot;&lt;/li&gt;
&lt;li&gt;精通是长期实践的结果，不是学完教程的结果&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="一些建立的实践"&gt;一些建立的实践&lt;/h2&gt;
&lt;h3 id="我的当前学习清单"&gt;我的当前学习清单&lt;/h3&gt;
&lt;p&gt;以前我的学习列表是这样的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 学 Go&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 学 Rust&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 学 K8s&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 学 React&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 学机器学习&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &amp;hellip;（还有 20+ 项）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现在我只保留 3 个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked="" disabled="" type="checkbox"&gt; &lt;strong&gt;深入 Python&lt;/strong&gt;（当前工作语言，90% 精力）
&lt;ul&gt;
&lt;li&gt;完成 3 个实际项目&lt;/li&gt;
&lt;li&gt;阅读优秀开源项目源码&lt;/li&gt;
&lt;li&gt;在生产环境中优化性能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;学习 Go&lt;/strong&gt;（10% 精力，只学基础）
&lt;ul&gt;
&lt;li&gt;只是为了能看懂公司的 Go 项目&lt;/li&gt;
&lt;li&gt;不求精通，能改小 bug 就够&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;K8s 基础&lt;/strong&gt;（根据需要学习）
&lt;ul&gt;
&lt;li&gt;暂时不学，等部署需求出现时再学&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="我的项目列表"&gt;我的项目列表&lt;/h3&gt;
&lt;p&gt;现在每学一个技术，都会同步创建至少一个项目：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;学 Docker 时做的项目&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;容器化个人博客&lt;/li&gt;
&lt;li&gt;搭建开发环境&lt;/li&gt;
&lt;li&gt;部署数据库和 Redis&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;学 Python 时做的项目&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;数据分析脚本（处理工作中的 Excel）&lt;/li&gt;
&lt;li&gt;API 服务（为前端提供接口）&lt;/li&gt;
&lt;li&gt;爬虫工具（收集资料）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;每个项目都很小，但都是真实可用的。&lt;/p&gt;
&lt;h3 id="我的学习笔记结构"&gt;我的学习笔记结构&lt;/h3&gt;
&lt;p&gt;以前的笔记：按教程章节记录，很少回看&lt;/p&gt;
&lt;p&gt;现在的笔记：按问题和解决方案记录&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# Python 学习笔记
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 问题：如何读取大文件不会内存溢出？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;解决方案：使用生成器逐行读取
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[代码示例]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[使用场景]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[踩过的坑]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 问题：如何处理 JSON 中的日期格式？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;[解决方案]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[代码示例]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 项目：数据处理工具
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;[需求描述]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[技术选型]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[核心代码]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[遇到的问题和解决方案]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样的笔记结构让知识更容易被检索和应用。&lt;/p&gt;
&lt;h2 id="后"&gt;后&lt;/h2&gt;
&lt;p&gt;写完这篇文章，我翻了翻自己的学习记录。过去一年，我学了不少东西，但真正能用的只有那几个做过项目的技术。&lt;/p&gt;
&lt;p&gt;123 陷阱的本质是：&lt;strong&gt;把学习当成了目的，而不是手段。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;真正的学习应该是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有明确的目标（解决什么问题）&lt;/li&gt;
&lt;li&gt;聚焦核心知识（20% 法则）&lt;/li&gt;
&lt;li&gt;立即实践（做项目）&lt;/li&gt;
&lt;li&gt;深度优先（一个一个来）&lt;/li&gt;
&lt;li&gt;持续反馈（在使用中提升）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你也觉得自己学了很多但什么都不会，不妨问自己几个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我为什么要学这个？&lt;/li&gt;
&lt;li&gt;我打算用它做什么？&lt;/li&gt;
&lt;li&gt;我是否有时间深入学习？&lt;/li&gt;
&lt;li&gt;我能否现在就开始做个小项目？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果答案都是否定的，那这个技术可能只需要&amp;quot;了解&amp;quot;而不是&amp;quot;学习&amp;quot;。&lt;/p&gt;
&lt;p&gt;最后，分享一句我很认同的话：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;真正的学习不是收集知识，而是改变行为。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;如果学了一个技术后，你的工作方式、解决问题的能力没有任何改变，那这次学习就是无效的。&lt;/p&gt;
&lt;p&gt;停止无意义的 1、2、3，选一个真正需要的技术，深入进去，做几个项目，用它解决真实的问题。这才是跳出 123 陷阱的唯一方法。&lt;/p&gt;
&lt;p&gt;希望这篇文章能够帮助你重新审视自己的学习方法，找到真正有效的学习路径。&lt;/p&gt;</description></item><item><title>MEV深度学习：从原理到实战</title><link>https://blogs.12ms.xyz/posts/2024/12/mev%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/</link><pubDate>Wed, 04 Dec 2024 00:00:00 +0000</pubDate><guid>https://blogs.12ms.xyz/posts/2024/12/mev%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/</guid><description>&lt;h1 id="前"&gt;前&lt;/h1&gt;
&lt;p&gt;在研究DeFi协议的过程中，我注意到一个有趣的现象：很多大额交易在链上执行前后，总会出现一些&amp;quot;神秘&amp;quot;的交易——它们精确地出现在目标交易的前后，获取无风险套利收益。这就是MEV（Maximal Extractable Value，最大可提取价值）的世界。&lt;/p&gt;
&lt;p&gt;MEV是区块链中一个既迷人又危险的领域。据统计，以太坊上的MEV提取总额已经超过6亿美元，而这个数字还在持续增长。作为一个技术研究者，我花了两周时间深入学习MEV的原理和实现，本文是我的学习笔记和实践总结。&lt;/p&gt;
&lt;h2 id="什么是mev"&gt;什么是MEV&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;MEV（Maximal Extractable Value）是指通过在区块中包含、排除或重新排序交易，超出标准区块奖励和gas费用之外可以提取的利润。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;简单来说，当你在以太坊上发送一笔交易时，从广播到被打包入块之间会有一段延迟。在这期间，交易会停留在mempool（内存池）中等待被矿工/验证者打包。关键点在于：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;mempool是公开的&lt;/strong&gt;：任何人都能看到待处理的交易&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;交易顺序可控&lt;/strong&gt;：矿工/验证者可以决定区块内的交易顺序&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存在套利空间&lt;/strong&gt;：通过抢先或尾随特定交易可以获利&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这就创造了一个博弈空间：谁能更快发现机会、更好地出价、更巧妙地构造交易，谁就能提取MEV。&lt;/p&gt;
&lt;h1 id="mev的核心机制"&gt;MEV的核心机制&lt;/h1&gt;
&lt;h2 id="mempool的工作原理"&gt;mempool的工作原理&lt;/h2&gt;
&lt;p&gt;要理解MEV，首先要理解mempool的运作方式。&lt;/p&gt;
&lt;h3 id="交易的生命周期"&gt;交易的生命周期&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户发起交易 → 广播到网络 → 进入mempool → 矿工选择打包 → 执行上链 → 最终确认
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 所有人可见（公开信息）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当交易在mempool中时，其完整内容对所有节点可见，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;目标地址和调用数据&lt;/li&gt;
&lt;li&gt;gas price（出价）&lt;/li&gt;
&lt;li&gt;交易价值&lt;/li&gt;
&lt;li&gt;函数参数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种透明性是MEV存在的根本原因。&lt;/p&gt;
&lt;h3 id="mempool监控"&gt;mempool监控&lt;/h3&gt;
&lt;p&gt;使用Web3.js监控mempool中的待处理交易：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Web3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;web3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;web3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wss://mainnet.infura.io/ws/v3/YOUR_API_KEY&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 订阅待处理交易
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pendingTransactions&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;txHash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;txHash&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Pending TX:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromWei&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;ether&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gasPrice&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromWei&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gasPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;gwei&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 函数选择器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这段代码实时监控所有待处理交易，是MEV机器人的第一步。&lt;/p&gt;
&lt;h2 id="区块构建与交易排序"&gt;区块构建与交易排序&lt;/h2&gt;
&lt;p&gt;在以太坊合并（The Merge）后，区块构建机制发生了变化：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;合并前（PoW）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;矿工完全控制区块内容和交易顺序&lt;/li&gt;
&lt;li&gt;交易按gas price排序（高gas price优先）&lt;/li&gt;
&lt;li&gt;矿工可以插入自己的交易&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;合并后（PoS）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;引入了PBS（Proposer-Builder Separation）机制&lt;/li&gt;
&lt;li&gt;Block Builder专门负责构建区块&lt;/li&gt;
&lt;li&gt;Proposer选择最有利可图的区块提案&lt;/li&gt;
&lt;li&gt;通过MEV-Boost等基础设施实现&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种分离使得MEV提取变得更加专业化和竞争激烈。&lt;/p&gt;
&lt;h1 id="mev的主要类型"&gt;MEV的主要类型&lt;/h1&gt;
&lt;h2 id="1-dex套利arbitrage"&gt;1. DEX套利（Arbitrage）&lt;/h2&gt;
&lt;p&gt;这是最常见的MEV类型。当不同DEX之间存在价格差异时，套利者可以同时在两个DEX上进行交易获利。&lt;/p&gt;
&lt;h3 id="经典场景"&gt;经典场景&lt;/h3&gt;
&lt;p&gt;假设：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uniswap上 ETH/USDC = 1800 USDC&lt;/li&gt;
&lt;li&gt;Sushiswap上 ETH/USDC = 1820 USDC&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;套利流程：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 在Uniswap买入1 ETH，花费1800 USDC
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 在Sushiswap卖出1 ETH，获得1820 USDC
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 净利润：20 USDC（未计gas费）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="实现代码框架"&gt;实现代码框架&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 简化的套利合约
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kd"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;ArbitrageBot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;constant&lt;/span&gt; &lt;span class="n"&gt;UNISWAP_ROUTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;constant&lt;/span&gt; &lt;span class="n"&gt;SUSHISWAP_ROUTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;executeArbitrage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 1. 在DEX1买入
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="n"&gt;IUniswapV2Router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UNISWAP_ROUTER&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;swapExactTokensForTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 最小输出（实际需要计算）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="n"&gt;getPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 2. 在DEX2卖出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;receivedAmount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IERC20&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IUniswapV2Router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SUSHISWAP_ROUTER&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;swapExactTokensForTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;receivedAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 最小要收回本金
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="n"&gt;getPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 利润发送给调用者
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;internal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;pure&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;[](&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里需要注意的是，实际的套利合约要复杂得多，需要考虑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;价格滑点计算&lt;/li&gt;
&lt;li&gt;Gas成本优化&lt;/li&gt;
&lt;li&gt;闪电贷集成&lt;/li&gt;
&lt;li&gt;多路径优化&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2-抢先交易front-running"&gt;2. 抢先交易（Front-running）&lt;/h2&gt;
&lt;p&gt;抢先交易是指在目标交易之前插入自己的交易，利用目标交易造成的价格变化获利。&lt;/p&gt;
&lt;h3 id="攻击流程"&gt;攻击流程&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 监控mempool，发现大额买单（如100 ETH买USDC）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 立即发送更高gas的买单，抢在目标交易前执行
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 目标交易执行后，价格上涨
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. 以更高价格卖出，获取差价
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="实际案例"&gt;实际案例&lt;/h3&gt;
&lt;p&gt;监控并抢跑大额Uniswap交易的脚本：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ethers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WebSocketProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WS_URL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Uniswap V2 Router地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UNISWAP_ROUTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 监听mempool
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pending&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;txHash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;txHash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;UNISWAP_ROUTER&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 解析交易数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iface&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Interface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UNISWAP_V2_ROUTER_ABI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;iface&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseTransaction&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 检查是否为大额swap
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;swapExactETHForTokens&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;10&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;发现大额交易:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;txHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formatEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gasPrice&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formatUnits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gasPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;gwei&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 构造抢跑交易（更高gas price）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;frontRunTx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UNISWAP_ROUTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 相同的交易数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;calculateOptimalAmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// 计算最优金额
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;gasPrice&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gasPrice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mul&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// 比目标交易高10%
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;gasLimit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 发送交易
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PRIVATE_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;frontRunTx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;抢跑交易已发送:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 忽略解析错误
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;calculateOptimalAmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;targetValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 这里需要复杂的数学计算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="c1"&gt;// 基于AMM曲线计算最优抢跑金额
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;targetValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mul&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 简化版：目标金额的20%
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;道德警告&lt;/strong&gt;：Front-running在很多场景下被视为不道德行为，某些司法管辖区甚至将其定性为操纵市场。上述代码仅用于教育目的。&lt;/p&gt;
&lt;h2 id="3-三明治攻击sandwich-attack"&gt;3. 三明治攻击（Sandwich Attack）&lt;/h2&gt;
&lt;p&gt;三明治攻击是front-running的升级版，在目标交易前后各插入一笔交易。&lt;/p&gt;
&lt;h3 id="攻击结构"&gt;攻击结构&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;区块内交易顺序：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 攻击者买入（抬高价格）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 受害者买入（在更高价格执行）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 攻击者卖出（在更高价格获利）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="收益计算"&gt;收益计算&lt;/h3&gt;
&lt;p&gt;假设在Uniswap池子中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;初始价格：1 ETH = 1800 USDC&lt;/li&gt;
&lt;li&gt;攻击者买入10 ETH，价格涨到1820 USDC&lt;/li&gt;
&lt;li&gt;受害者买入100 ETH，价格涨到1950 USDC&lt;/li&gt;
&lt;li&gt;攻击者卖出10 ETH，获得19500 USDC&lt;/li&gt;
&lt;li&gt;利润：19500 - 18200 = 1300 USDC（未计gas费）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="防御措施"&gt;防御措施&lt;/h3&gt;
&lt;p&gt;作为用户，可以通过以下方式防御三明治攻击：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 设置合理的滑点保护
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="n"&gt;IUniswapV2Router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;swapExactETHForTokens&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;minAmountOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 计算合理的最小输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;deadline&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 使用私有mempool（如Flashbots Protect）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 或使用聚合器（如1inch）的保护机制
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="4-清算mevliquidation"&gt;4. 清算MEV（Liquidation）&lt;/h2&gt;
&lt;p&gt;在借贷协议（如Aave、Compound）中，当用户的抵押率低于清算线时，清算者可以获得清算奖励。&lt;/p&gt;
&lt;h3 id="清算机制"&gt;清算机制&lt;/h3&gt;
&lt;p&gt;以Aave为例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;抵押率 = 抵押品价值 / 借款价值
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;当抵押率 &amp;lt; 清算阈值（如125%）时：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 清算者可以偿还部分债务
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 获得对应的抵押品 + 清算奖励（如5-10%）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="监控清算机会"&gt;监控清算机会&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ethers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;monitorLiquidations&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AAVE_LENDING_POOL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ABI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 获取所有借款人
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getUsersWithLoans&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accountData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;aave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getUserAccountData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;healthFactor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;parseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formatEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accountData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;healthFactor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 健康因子 &amp;lt; 1 意味着可以清算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;healthFactor&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;发现清算机会:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;healthFactor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;healthFactor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;totalDebt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formatEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accountData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalDebtETH&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;totalCollateral&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formatEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accountData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalCollateralETH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 执行清算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;executeLiquidation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accountData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;executeLiquidation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accountData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 计算可清算的最大金额（通常为债务的50%）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maxLiquidatable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;accountData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalDebtETH&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mul&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;aave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;liquidationCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;accountData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collateralAsset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;accountData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;debtAsset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;maxLiquidatable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="c1"&gt;// receiveAToken
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;清算交易已提交:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 每个区块检查一次
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;block&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;monitorLiquidations&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="5-时间盗匪攻击time-bandit-attack"&gt;5. 时间盗匪攻击（Time-Bandit Attack）&lt;/h2&gt;
&lt;p&gt;这是一种更高级的MEV攻击，矿工/验证者会重组已确认的区块来获取更大的MEV。&lt;/p&gt;
&lt;h3 id="攻击场景"&gt;攻击场景&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;区块 N: 包含一笔高价值MEV机会（如100 ETH套利）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;区块 N+1: 已被确认
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;如果重组区块N的MEV收益 &amp;gt; 放弃区块N+1的奖励：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;验证者可能会选择重组链，插入自己的MEV交易
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这种攻击威胁到区块链的最终性，在PoS以太坊中通过更严格的共识规则得到缓解。&lt;/p&gt;
&lt;h1 id="mev基础设施"&gt;MEV基础设施&lt;/h1&gt;
&lt;h2 id="flashbots"&gt;Flashbots&lt;/h2&gt;
&lt;p&gt;Flashbots是MEV领域最重要的基础设施，它提供了一个私有通道让用户和区块构建者直接沟通。&lt;/p&gt;
&lt;h3 id="核心组件"&gt;核心组件&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Flashbots Auction&lt;/strong&gt;：私有交易池，交易不会在公共mempool中广播&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MEV-Boost&lt;/strong&gt;：连接验证者和区块构建者的中继系统&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MEV-Share&lt;/strong&gt;：让用户也能分享MEV收益的机制&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="使用flashbots发送交易"&gt;使用Flashbots发送交易&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FlashbotsBundleProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;@flashbots/ethers-provider-bundle&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sendFlashbotsBundle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authSigner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FLASHBOTS_AUTH_KEY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;flashbotsProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;FlashbotsBundleProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;authSigner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;https://relay.flashbots.net&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PRIVATE_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 构造bundle（一组交易）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bundle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TARGET_ADDRESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TRANSACTION_DATA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gasLimit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gasPrice&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;// Flashbots不需要gas price
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 提交bundle到下一个区块
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetBlockNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getBlockNumber&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;simulation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;flashbotsProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;simulate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetBlockNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;模拟结果:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;simulation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;simulation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstRevert&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;交易会revert，取消提交&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 发送bundle
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bundleSubmission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;flashbotsProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendRawBundle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;targetBlockNumber&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Bundle已提交:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bundleSubmission&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bundleHash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 等待结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;waitResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bundleSubmission&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Bundle状态:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;waitResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="flashbots的优势"&gt;Flashbots的优势&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;防止被抢跑&lt;/strong&gt;：交易在私有池中，不会被front-run&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;零gas成本（失败时）&lt;/strong&gt;：只有成功的交易才支付费用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原子性&lt;/strong&gt;：bundle中的所有交易要么全部执行，要么全部回滚&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;收益最大化&lt;/strong&gt;：直接向区块构建者支付，没有中间损耗&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="mev-boost架构"&gt;MEV-Boost架构&lt;/h2&gt;
&lt;p&gt;MEV-Boost是以太坊PoS中的区块构建市场：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; MEV-Boost架构
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Searchers → Bundle → Builders → Relays → Proposers
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(搜索者) (交易包) (构建者) (中继) (验证者)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. Searchers发现MEV机会，构造bundle
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. Builders竞争构建最有价值的区块
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. Relays验证区块并转发给Proposers
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. Proposers选择收益最高的区块提案
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这种PBS（Proposer-Builder Separation）机制的好处：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;专业化分工：Builder专注于MEV提取，Proposer专注于网络安全&lt;/li&gt;
&lt;li&gt;民主化：小型验证者也能获得MEV收益&lt;/li&gt;
&lt;li&gt;透明度：通过中继层实现可审计性&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="实战构建简单的mev机器人"&gt;实战：构建简单的MEV机器人&lt;/h1&gt;
&lt;h2 id="目标dex套利监控"&gt;目标：DEX套利监控&lt;/h2&gt;
&lt;p&gt;我构建了一个监控Uniswap和Sushiswap价格差异的套利机器人。&lt;/p&gt;
&lt;h3 id="系统架构"&gt;系统架构&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;价格监控模块 → 套利计算模块 → 交易执行模块 → 利润分析模块
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ ↓ ↓ ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; WebSocket 数学模型 Flashbots 数据库
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="核心代码实现"&gt;核心代码实现&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ethers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FlashbotsBundleProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;@flashbots/ethers-provider-bundle&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ArbitrageBot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WebSocketProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wsUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;privateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minProfitWei&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minProfit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uniswap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uniswapRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;UNISWAP_ABI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sushiswap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sushiswapRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;SUSHISWAP_ABI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;monitorPrices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`开始监控 &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt; 套利机会...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 每个区块检查一次
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;block&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blockNumber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findArbitrage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profit&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minProfitWei&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;发现套利机会:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;profit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formatEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profit&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;buyDex&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buyDex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sellDex&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sellDex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formatEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;executeArbitrage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;检查套利机会时出错:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;findArbitrage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 获取两个DEX的价格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uniswapPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uniswap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sushiswapPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sushiswap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 计算价差百分比
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;priceDiff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uniswapPrice&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;sushiswapPrice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uniswapPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sushiswapPrice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;priceDiff&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.005&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;profit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// 价差小于0.5%，忽略
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 确定买卖方向
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buyDex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uniswapPrice&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;sushiswapPrice&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;uniswap&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;sushiswap&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sellDex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;buyDex&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;uniswap&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;sushiswap&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;uniswap&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 计算最优套利金额（考虑滑点和流动性）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;optimalAmount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculateOptimalAmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;buyDex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sellDex&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 计算预期利润
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;profit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculateProfit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;optimalAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;buyDex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sellDex&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;profit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;optimalAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;buyDex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sellDex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;getPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dexRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;amounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dexRouter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAmountsOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;parseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formatEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amounts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;calculateOptimalAmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buyDex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sellDex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 这里需要复杂的数学计算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="c1"&gt;// 基于AMM的恒定乘积公式计算最优金额
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="c1"&gt;// 简化版本：使用固定金额
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;10&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;calculateProfit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buyDex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sellDex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buyRouter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;buyDex&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;uniswap&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uniswap&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sushiswap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sellRouter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sellDex&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;uniswap&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uniswap&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sushiswap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 获取买入后的数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buyAmounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;buyRouter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAmountsOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;receivedAmount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;buyAmounts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 获取卖出后的数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sellAmounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sellRouter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAmountsOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;receivedAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;finalAmount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sellAmounts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 计算利润（减去gas成本）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gasCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0.01&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 估算的gas成本
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;finalAmount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gasCost&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;executeArbitrage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;执行套利交易...&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 使用Flashbots发送交易避免被抢跑
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;flashbotsProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;FlashbotsBundleProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;https://relay.flashbots.net&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 构造套利交易
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buyTx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buildSwapTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buyDex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sellTx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buildSwapTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sellDex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="c1"&gt;// 这里应该用实际收到的金额
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 创建bundle
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bundle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;buyTx&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sellTx&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 提交bundle
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetBlock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getBlockNumber&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bundleSubmission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;flashbotsProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendRawBundle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;targetBlock&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Bundle已提交:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bundleSubmission&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bundleHash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;waitResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bundleSubmission&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;waitResponse&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;套利成功！&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;套利失败，bundle未被包含&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;执行套利时出错:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;buildSwapTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dex&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;uniswap&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uniswap&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sushiswap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;encodeFunctionData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;swapExactTokensForTokens&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// minAmountOut
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tokenIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenOut&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt; &lt;span class="c1"&gt;// 5分钟deadline
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;]),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gasLimit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gasPrice&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;// Flashbots
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 使用示例
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ArbitrageBot&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;wsUrl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;wss://mainnet.infura.io/ws/v3/YOUR_KEY&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;privateKey&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;YOUR_PRIVATE_KEY&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;minProfit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;0.05&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 最小利润0.05 ETH
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;uniswapRouter&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sushiswapRouter&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 监控WETH/USDC套利
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="nx"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;monitorPrices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// WETH
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&amp;#39;&lt;/span&gt; &lt;span class="c1"&gt;// USDC
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="实战经验总结"&gt;实战经验总结&lt;/h2&gt;
&lt;p&gt;在运行这个机器人一个月后，我得出以下经验：&lt;/p&gt;
&lt;h3 id="成功因素"&gt;成功因素&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;速度至关重要&lt;/strong&gt;：使用专用RPC节点（而非公共节点）延迟降低80%&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gas优化&lt;/strong&gt;：优化合约代码可以节省30-40%的gas&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;资金效率&lt;/strong&gt;：使用闪电贷可以在零本金情况下套利&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网络选择&lt;/strong&gt;：在L2（如Arbitrum）上竞争更小，机会更多&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="踩过的坑"&gt;踩过的坑&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;滑点估算不准&lt;/strong&gt;：最初没有正确计算滑点，导致多次交易失败&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gas价格战&lt;/strong&gt;：在公共mempool中，经常被其他机器人用更高gas抢先&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;闪电贷费用&lt;/strong&gt;：Aave闪电贷收取0.09%费用，需要计入成本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网络拥堵&lt;/strong&gt;：Gas价格飙升时，小额套利变得无利可图&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="收益数据"&gt;收益数据&lt;/h3&gt;
&lt;p&gt;在一个月的测试期内（使用小额资金）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;成功套利次数：127次&lt;/li&gt;
&lt;li&gt;成功率：38%（很多机会被其他机器人抢先）&lt;/li&gt;
&lt;li&gt;总收益：2.3 ETH&lt;/li&gt;
&lt;li&gt;平均单次收益：0.018 ETH&lt;/li&gt;
&lt;li&gt;Gas成本：0.8 ETH&lt;/li&gt;
&lt;li&gt;净利润：1.5 ETH&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="mev的影响与争议"&gt;MEV的影响与争议&lt;/h1&gt;
&lt;h2 id="对生态的影响"&gt;对生态的影响&lt;/h2&gt;
&lt;h3 id="负面影响"&gt;负面影响&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;用户损失&lt;/strong&gt;：普通用户成为三明治攻击的受害者，损失滑点&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网络拥堵&lt;/strong&gt;：MEV机器人大量交易导致gas价格上涨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中心化风险&lt;/strong&gt;：专业MEV提取者形成寡头，威胁去中心化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;交易公平性&lt;/strong&gt;：先见之明（看到mempool）创造不公平优势&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="正面影响"&gt;正面影响&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;市场效率&lt;/strong&gt;：套利行为促进价格发现，提高市场效率&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;清算激励&lt;/strong&gt;：为DeFi协议提供及时清算，维持系统健康&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;验证者收益&lt;/strong&gt;：增加验证者收入，提高网络安全性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;协议改进&lt;/strong&gt;：推动更好的协议设计和基础设施&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="应对策略"&gt;应对策略&lt;/h2&gt;
&lt;h3 id="协议层面"&gt;协议层面&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;私有交易池&lt;/strong&gt;：如Flashbots Protect，让用户选择不公开交易&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;订单流拍卖（OFA）&lt;/strong&gt;：让用户分享MEV收益&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MEV重新分配&lt;/strong&gt;：通过协议将MEV返还给用户&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;加密mempool&lt;/strong&gt;：如threshold encryption，延迟交易内容公开&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="用户层面"&gt;用户层面&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;设置合理滑点&lt;/strong&gt;：不要设置过大的滑点容忍度&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用聚合器&lt;/strong&gt;：如1inch、CoW Swap提供MEV保护&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选择私有RPC&lt;/strong&gt;：通过Flashbots Protect发送交易&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;批量交易&lt;/strong&gt;：减少交易次数，降低被攻击概率&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="代码层面"&gt;代码层面&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 在智能合约中添加MEV保护
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kd"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;MEVProtectedSwap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 使用commit-reveal模式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;commitments&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;commitSwap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="n"&gt;commitment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;commitments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;commitment&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;revealAndSwap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;tokenIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;tokenOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="n"&gt;commitment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;keccak256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;encodePacked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tokenIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tokenOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;salt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commitments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;commitment&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Invalid commitment&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;commitments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;commitment&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 执行swap
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="n"&gt;_executeSwap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokenOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="后"&gt;后&lt;/h1&gt;
&lt;p&gt;经过深入学习MEV，我对区块链的理解提升了一个层次。MEV不仅仅是一种套利手段，它揭示了区块链系统中深层次的博弈关系和激励机制。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;MEV的本质是信息不对称和执行权力的货币化。在一个透明的系统中，谁能更好地利用公开信息、谁掌握交易排序权，谁就能提取价值。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;对于开发者而言，理解MEV是构建安全DeFi协议的必修课。对于用户而言，了解MEV可以更好地保护自己的交易不被剥削。对于验证者而言，MEV是除了区块奖励外的重要收入来源。&lt;/p&gt;
&lt;h2 id="进阶学习资源"&gt;进阶学习资源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MEV Wiki&lt;/strong&gt;：https://www.mev.wiki/ （最全面的MEV知识库）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flashbots文档&lt;/strong&gt;：https://docs.flashbots.net/&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flashbots论坛&lt;/strong&gt;：https://collective.flashbots.net/&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MEV研究论文&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Flash Boys 2.0&amp;rdquo; by Daian et al.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Quantifying Blockchain Extractable Value&amp;rdquo; by Qin et al.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实战工具&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;MEV-Inspect: &lt;a href="https://github.com/flashbots/mev-inspect-py"&gt;https://github.com/flashbots/mev-inspect-py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MEV-Share: &lt;a href="https://mevshare.flashbots.net/"&gt;https://mevshare.flashbots.net/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Eigenphi (MEV数据分析): &lt;a href="https://eigenphi.io/"&gt;https://eigenphi.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="下一步探索"&gt;下一步探索&lt;/h2&gt;
&lt;p&gt;我计划在以下方向继续研究：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;跨链MEV&lt;/strong&gt;：研究跨链桥和多链环境中的MEV机会&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;L2 MEV&lt;/strong&gt;：探索Optimistic Rollups和ZK-Rollups中的MEV特性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MEV协议设计&lt;/strong&gt;：研究如何在协议层面最小化MEV负面影响&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隐私与MEV&lt;/strong&gt;：研究加密技术（如ZK-SNARKs）如何影响MEV&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;就这样！希望这篇深度学习笔记能够帮助你理解MEV这个复杂而迷人的领域。如果你也在研究MEV，欢迎交流讨论。&lt;/p&gt;</description></item><item><title>Terraform使用列表来创建资源</title><link>https://blogs.12ms.xyz/posts/2024/11/terraform%E9%80%9A%E8%BF%87%E5%88%97%E8%A1%A8%E7%AE%A1%E7%90%86%E8%B5%84%E6%BA%90/</link><pubDate>Sat, 02 Nov 2024 00:00:00 +0000</pubDate><guid>https://blogs.12ms.xyz/posts/2024/11/terraform%E9%80%9A%E8%BF%87%E5%88%97%E8%A1%A8%E7%AE%A1%E7%90%86%E8%B5%84%E6%BA%90/</guid><description>&lt;h2 id="前"&gt;前&lt;/h2&gt;
&lt;p&gt;在使用 Terraform 在中级的水平之后， 动态管理状态这点将会成为一个很重要以及很常用的特性。比如创建类似的资源的时候，就不在需要one by one 的创建对应的 resource 在配置文件中。&lt;/p&gt;
&lt;p&gt;使用一个列表 或者 一个map 来对资源来进行管理，只需要在配置文件中体验出差分的配置内容即可。&lt;/p&gt;
&lt;p&gt;在这篇文章根据几个实际过程中部署使用的例子来记录下如何使用动态配置。&lt;/p&gt;
&lt;h2 id="通过map来批量批量创建主机"&gt;通过map来批量批量创建主机&lt;/h2&gt;
&lt;p&gt;这段落如何使用 Terraform 定义一个 Map，利用这个 Map 来批量创建具有相同基础属性但个别属性不同的主机资源。通过这种方式，可以配置各个主机的系统盘、操作系统类型、可用区等属性。更重要的是，通过修改 Map 的内容即可动态增减主机数量，而无需修改 Terraform 配置文件本身，从而实现更高效的批量资源管理。&lt;/p&gt;
&lt;h3 id="主机模板以及变量定义"&gt;主机模板以及变量定义&lt;/h3&gt;
&lt;p&gt;此部分记录了一些预定义的配置和初始资源模板的设置。预定义的内容包括子网的选择和动态分配策略，例如可以将一批主机均匀或随机地分配到两个不同的可用区，以实现跨可用区的部署。&lt;/p&gt;
&lt;p&gt;资源模板则定义了所需资源的全部属性，包括标签、系统盘容量、数据盘容量、IAM（身份与访问管理）属性和子网选择等配置。通过该模板，可以标准化资源的配置并确保在创建时符合预设的资源规范。&lt;/p&gt;
&lt;h4 id="子网分配"&gt;子网分配&lt;/h4&gt;
&lt;p&gt;首先，介绍如何实现主机在可用区中的均匀分布配置。由于使用 Map 来定义主机的属性，我们可以利用 &lt;code&gt;index&lt;/code&gt; 参数来获取每个主机的索引值。因为有两个可用区，可以通过将索引值除以 2 来获取可用区列表的索引，从而实现主机在两个可用区中的均匀分布。&lt;/p&gt;
&lt;p&gt;实际上，更好的方法是使用哈希函数等稳定分配的方案，但由于没有找到具体配置，这里只能使用 &lt;code&gt;index&lt;/code&gt;。需要注意的是，Map 的索引值并不稳定，因此在增加或减少主机后，索引可能会发生变化。不过，由于子网并非频繁修改的属性，并且在 AWS 中直接修改子网可能导致主机的销毁，因此我们使用了 &lt;code&gt;lifecycle&lt;/code&gt; 中的 &lt;code&gt;ignore_changes&lt;/code&gt; 属性来忽略子网的变化。这样一来，在调整子网或增减主机时，不会导致其他资源被意外终止。&lt;/p&gt;
&lt;p&gt;所以最终的配置如下所示，这样的话就可以实现一个简单的子网平均分配的方法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;locals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;node_secure_subnets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;aws_subnet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secure_subnet_a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;aws_subnet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secure_subnet_b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aws_instance&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;node_sec_template&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;#...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;subnet_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;node_secure_subnets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;node_sec_instance_config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;lifecycle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ignore_changes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;subnet_id&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="主机模板"&gt;主机模板&lt;/h4&gt;
&lt;p&gt;可以看到这里的 &lt;code&gt;for_each&lt;/code&gt; 会遍历一个映射（map）中的所有内容，然后根据每个元素的值填充到对应的资源字段中。例如，在下面的代码中，我们可以看到 &lt;code&gt;tags&lt;/code&gt; 字段是根据 &lt;code&gt;for_each&lt;/code&gt; 的内容动态生成的。&lt;/p&gt;
&lt;p&gt;如果某个资源包含了另一个需要依赖的资源，比如 &lt;code&gt;EBS_BLOCK_DEVICE&lt;/code&gt;，我们需要在主资源的定义中进行引用。通过这种方式，我们可以基于列表或映射来动态创建多个资源实例。&lt;/p&gt;
&lt;p&gt;总结来说，通过 &lt;code&gt;for_each&lt;/code&gt; 和列表，我们能够高效地生成动态的基础设施资源，比如动态创建多个主机实例，或者挂载 EBS 卷等。这种方式不仅减少了重复的配置代码，还大大提高了灵活性和可维护性。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aws_instance&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;node_sec_template&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# for_each = { for idx, config in var.node_sec_instance_config : idx =&amp;gt; config if length(keys(config)) &amp;gt; 0 }&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;for_each&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;node_config_map&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ami&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ami&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instance_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;instance_type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;org&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aaa&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Node&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;module&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Module&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Monitoring&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;False&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 系统盘配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;root_block_device&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;volume_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root_volume_size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;volume_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;gp3&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;root-${each.value.tags.Name}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数据盘配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dynamic&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ebs_block_device&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;for_each&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data_volume_size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;# 如果 data_volume_size &amp;gt; 0 才创建数据盘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;device_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/dev/sdb&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;volume_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data_volume_size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;volume_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;gp3&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;delete_on_termination&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;data-${each.value.tags.Name}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;iam_instance_profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;role-user&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;key_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;web-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;subnet_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;node_secure_subnets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;node_sec_instance_config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vpc_security_group_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;aws_security_group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allow_outbound_all&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;aws_security_group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compiler_ssh_sg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;lifecycle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ignore_changes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;subnet_id&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="代码解析"&gt;代码解析&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;主机信息映射&lt;/strong&gt;
通过 &lt;code&gt;for_each&lt;/code&gt;，我们将 &lt;code&gt;var.hosts&lt;/code&gt; 转换为一个键值对（map）。每个主机的名称作为键，主机的详细信息作为值。这样可以确保资源的名称是唯一的，同时方便资源之间的引用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态创建 EC2 实例&lt;/strong&gt;
在 &lt;code&gt;aws_instance&lt;/code&gt; 配置中，&lt;code&gt;for_each&lt;/code&gt; 遍历 &lt;code&gt;hosts&lt;/code&gt; 列表，为每一个主机生成一个 EC2 实例，并使用主机对应的 &lt;code&gt;ami&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态挂载 EBS 卷&lt;/strong&gt;
在 &lt;code&gt;aws_ebs_volume_attachment&lt;/code&gt; 配置中，同样使用 &lt;code&gt;for_each&lt;/code&gt; 遍历 &lt;code&gt;hosts&lt;/code&gt; 列表。这里我们引用了实例的 ID，通过 &lt;code&gt;aws_instance.example[each.key].id&lt;/code&gt; 动态关联 EBS 卷到正确的实例。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态引用资源&lt;/strong&gt;
如果某个资源需要依赖另一个动态生成的资源，比如这里的 EBS 卷依赖 EC2 实例，我们可以使用 &lt;code&gt;each.key&lt;/code&gt; 作为索引，精确地引用目标资源。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="通过list来绑定目标组"&gt;通过List来绑定目标组&lt;/h2&gt;
&lt;p&gt;在 Terraform 中，如果我们需要为每个 Target Group 绑定资源，直接为每个 Target Group 手动创建对应的绑定资源会显得非常冗余且繁琐。为了简化这一过程，可以利用列表（list）和 &lt;code&gt;for_each&lt;/code&gt; 来实现批量绑定资源，从而避免重复的配置代码。&lt;/p&gt;
&lt;p&gt;假设我们有一个包含多个 Target Group 的列表，每个 Target Group 都需要绑定到特定的目标主（Target Host）。以下是一个简化的例子：&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;var.tf&lt;/code&gt; 中定义一个列表来存储所有 Target Group 相关的信息，包括需要绑定的 ARN 和目标主的 ID：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;locals {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; target_groups = [
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; target_group_arn = aws_lb_target_group.mine_alph.arn
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; instance_id = aws_instance.node_alph[0].id
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; target_group_arn = aws_lb_target_group.mine_alph.arn
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; instance_id = aws_instance.node_alph[1].id
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通过 for_each 遍历上面定义的列表，为每个 Target Group 动态创建对应的绑定资源&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 定义目标组和实例的映射列表
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 使用for_each合并创建target_group_attachment
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;resource &amp;#34;aws_lb_target_group_attachment&amp;#34; &amp;#34;target_list_attach&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; for_each = { for idx, tg_map in local.target_groups : idx =&amp;gt; tg_map }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; target_group_arn = each.value.target_group_arn
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; target_id = each.value.instance_id
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; port = 3333
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="代码解析-1"&gt;代码解析&lt;/h3&gt;
&lt;h4 id="target_groups-列表"&gt;target_groups 列表&lt;/h4&gt;
&lt;p&gt;列表中的每个元素是一个映射，包含 Target Group 的名称（name）、ARN（arn）以及需要绑定的目标主 ID（target_id）。我们可以根据需求扩展这个结构，比如添加端口号或其他配置项。&lt;/p&gt;
&lt;h4 id="for_each-遍历列表"&gt;for_each 遍历列表&lt;/h4&gt;
&lt;p&gt;在资源 aws_lb_target_group_attachment 中，for_each 会将列表转换成一个映射（map），以 name 作为键，整个元素作为值。这样，每个 Target Group 都会动态生成一个绑定资源实例。&lt;/p&gt;
&lt;h4 id="动态引用"&gt;动态引用&lt;/h4&gt;
&lt;p&gt;在资源配置中，each.value.arn 和 each.value.target_id 分别引用当前遍历元素的 arn 和 target_id。这样就避免了手动为每个 Target Group 写重复的绑定配置。&lt;/p&gt;
&lt;h3 id="优势"&gt;优势&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;简化配置&lt;/strong&gt;
使用列表和 for_each 后，只需要定义一次资源逻辑，所有 Target Group 的绑定操作都可以自动完成。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;灵活性高&lt;/strong&gt;
如果需要新增一个 Target Group，只需要在列表中追加一个元素，而无需手动修改配置代码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;减少冗余&lt;/strong&gt;
避免了为每个 Target Group 手动创建资源的繁琐工作，提升了代码的可读性和维护性。&lt;/p&gt;
&lt;h2 id="后"&gt;后&lt;/h2&gt;
&lt;p&gt;在使用 TF 管理资源时，临配置重复和维护困难的问题，特别是当需要为一组相似的资源进行批量管理时。使用列表与 &lt;code&gt;for_each&lt;/code&gt; 的结合就是最好的方式。这种方法不仅能提升开发效率，还能避免手动操作带来的错误。&lt;/p&gt;
&lt;p&gt;IaC的最佳实践：让配置更具可读性、更易维护。也是从这个角度出发。&lt;/p&gt;</description></item><item><title>记磁盘无法挂载 X.mount is bound to inactive</title><link>https://blogs.12ms.xyz/posts/2024/10/%E8%AE%B0%E4%B8%80%E6%AC%A1data%E6%97%A0%E6%B3%95%E6%8C%82%E8%BD%BD%E6%88%90%E5%8A%9F/</link><pubDate>Tue, 29 Oct 2024 00:00:00 +0000</pubDate><guid>https://blogs.12ms.xyz/posts/2024/10/%E8%AE%B0%E4%B8%80%E6%AC%A1data%E6%97%A0%E6%B3%95%E6%8C%82%E8%BD%BD%E6%88%90%E5%8A%9F/</guid><description>&lt;h2 id="前"&gt;前&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;线上问题记录：Unit X.mount is bound to inactive unit&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在这篇文章中记录一次线上环境中遇到的一个奇怪问题及其解决过程。问题发生在对新创建的磁盘进行挂载时。虽然通过 &lt;code&gt;mount&lt;/code&gt; 命令显示挂载操作已成功，但使用 &lt;code&gt;df -h&lt;/code&gt; 检查时却发现挂载并未生效。&lt;/p&gt;
&lt;p&gt;然而，当尝试在另一个目录（例如 &lt;code&gt;/mnt/D2&lt;/code&gt;）上进行挂载时，操作却可以顺利完成。&lt;/p&gt;
&lt;p&gt;为了解决问题，进一步深入排查。发现问题似乎与 &lt;code&gt;systemd&lt;/code&gt; 相关，因其未被重新更新而导致挂载无法正确生效。所以，写下这篇文章，旨在记录这个问题的发现和分析过程，尝试总结导致该问题的潜在原因。&lt;/p&gt;
&lt;h2 id="定位问题"&gt;定位问题&lt;/h2&gt;
&lt;p&gt;出现挂载问题之后，首先去检查了磁盘的状态，使用 lsblk df fdisk 等命令尝试去发现问题，但是看起来其输出内容都是正常的。排除了磁盘本身的问题。&lt;/p&gt;
&lt;p&gt;熟悉使用 &lt;code&gt;strace&lt;/code&gt; 来跑mount的命令，对比其具体的C调用是否有明显的问题。也没有发现明显异常。排除了系统调用过程中出现的问题。&lt;/p&gt;
&lt;p&gt;尝试创建data2 使用命令挂载到 data2 发现成功挂载，怀疑挂载点问题，使用命令来检查 data 和 data2 的权限，以及特殊标志位的问题，均未发现其他的问题。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -ld /data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsattr -d /data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;stat /data
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;之后开始怀疑可能是系统内核态的问题，所以&lt;code&gt;dmesg | tail -n20 &lt;/code&gt; 查看内核日志。内容如下。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20382.898799] pci 0000:00:1f.0: [1d0f:8061] type 00 class 0x010802
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20382.898912] pci 0000:00:1f.0: reg 0x10: [mem 0x00000000-0x00003fff]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20382.899106] pci 0000:00:1f.0: enabling Extended Tags
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20382.899677] pci 0000:00:1f.0: BAR 0: assigned [mem 0xc0004000-0xc0007fff]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20382.899773] nvme nvme3: pci function 0000:00:1f.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20382.899834] nvme 0000:00:1f.0: enabling device (0000 -&amp;gt; 0002)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20382.915781] nvme nvme3: 2/0/0 default/read/poll queues
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20730.273270] EXT4-fs (nvme2n1): mounting ext3 file system using the ext4 subsystem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20730.450819] EXT4-fs (nvme2n1): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20856.064034] EXT4-fs (nvme2n1): mounting ext3 file system using the ext4 subsystem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20856.241184] EXT4-fs (nvme2n1): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20896.261646] EXT4-fs (nvme2n1): mounting ext3 file system using the ext4 subsystem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[20896.435957] EXT4-fs (nvme2n1): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[21223.746810] EXT4-fs (nvme2n1): mounting ext3 file system using the ext4 subsystem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[21223.921784] EXT4-fs (nvme2n1): mounted filesystem with ordered data mode. Opts: (null).
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但是，从实际上的内容看，mounted 代表着挂载是成功的，还是无法说明挂在失败的原因。继续检查日志查看 syslog&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;syslog&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:22:32 ip-172-18-3-78 multipath: nvme2n1: uid = uuid.53290adb-9273-5530-a714-2ce51145e88e (sysfs)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:23:14 ip-172-18-3-78 kernel: [24724.788270] EXT4-fs (nvme2n1): mounting ext3 file system using the ext4 subsystem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:23:14 ip-172-18-3-78 kernel: [24724.924221] EXT4-fs (nvme2n1): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:23:36 ip-172-18-3-78 systemd[1]: data2.mount: Succeeded.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:23:36 ip-172-18-3-78 systemd[3564]: data2.mount: Succeeded.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:24:01 ip-172-18-3-78 kernel: [24771.875507] EXT4-fs (nvme2n1): mounting ext3 file system using the ext4 subsystem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:24:01 ip-172-18-3-78 systemd[1]: data.mount: Unit is bound to inactive unit dev-disk-by\x2duuid-3ffa8350\x2d323e\x2d4f1d\x2d9ae3\x2df751190774d2.device. Stopping, too.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:24:01 ip-172-18-3-78 kernel: [24772.016299] EXT4-fs (nvme2n1): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:24:01 ip-172-18-3-78 systemd[1]: Unmounting /data...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:24:01 ip-172-18-3-78 systemd[3564]: data.mount: Succeeded.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:24:01 ip-172-18-3-78 systemd[1]: data.mount: Succeeded.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Oct 28 09:24:01 ip-172-18-3-78 systemd[1]: Unmounted /data.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最终发现了异常所在，systemd 主动的把data 给umount 掉了，所以实际上是挂载成功，随即就被systemd 给卸载掉了。看到了 unit 的问题，所以经验上讲可能是 systemd 的mount uuid 状态不对导致，之后尝试&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;daemon&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;reload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;之后重新挂载，挂载成功。并且 syslog 也没有 unmount 的日志出现了。问题解决。&lt;/p&gt;
&lt;h2 id="为什么"&gt;为什么&lt;/h2&gt;
&lt;p&gt;在前面误打误撞的解决了这个挂载“失败”的问题，但是是什么原因导致的？&lt;/p&gt;
&lt;p&gt;于是使用 Unit X.mount is bound to inactive unit 作为搜索关键词得到了下面的结论，又是一个 systemd 的锅，或者是说它多做了一些东西&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Systemd 在启动时&lt;/strong&gt; 会使用其自己的&lt;a href="https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html"&gt;systemd-fstab-generator&lt;/a&gt;读取 /etc/fstab。相当于建立了一个缓存。&lt;/p&gt;
&lt;p&gt;这意味着 Systemd 不会即时的 /etc/fstab 中的更改，因为生成器只运行一次，并且在系统启动后不会再运行，除非手动的进行reload操作。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;systemd-fstab-generator 是一个生成器，它在启动初期以及重新加载系统管理器配置时将 /etc/fstab（有关详细信息，请参阅 fstab(5)）转换为本机 systemd 单元。&lt;/p&gt;
&lt;p&gt;这也意味着只有系统&lt;strong&gt;重启&lt;/strong&gt;或&lt;strong&gt;systemctl daemon-reload&lt;/strong&gt;才会重新启动 systemd-fstab-generator 并重新读取 /etc/fstab。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;在这个场景下，这台主机之前有一个已经挂载的磁盘，我把磁盘卸载之后重新挂载了新的镜像创建的磁盘。但是其fstab 信息对不上，uuid 之类的发生了改变。所以当我们手动挂载到同一个目录的时候，systemd 发现挂载的磁盘的信息与之前不一致，所以就出现了上面的inactibe 的问题。&lt;/p&gt;
&lt;h2 id="参考"&gt;参考&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mamchenkov.net/wordpress/2017/11/09/systemd-strikes-again-unit-var-whatever-mount-is-bound-to-inactive-unit/"&gt;https://mamchenkov.net/wordpress/2017/11/09/systemd-strikes-again-unit-var-whatever-mount-is-bound-to-inactive-unit/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freedesktop.org/software/systemd/man/latest/systemd-fstab-generator.html"&gt;https://www.freedesktop.org/software/systemd/man/latest/systemd-fstab-generator.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.claudiokuenzler.com/blog/1124/linux-mount-not-working-systemd-unit-is-bound-to-inactive"&gt;https://www.claudiokuenzler.com/blog/1124/linux-mount-not-working-systemd-unit-is-bound-to-inactive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Terraform多Region的格式</title><link>https://blogs.12ms.xyz/posts/2024/11/terraform%E5%A4%9Aregoin%E6%A0%BC%E5%BC%8F/</link><pubDate>Sun, 27 Oct 2024 00:00:00 +0000</pubDate><guid>https://blogs.12ms.xyz/posts/2024/11/terraform%E5%A4%9Aregoin%E6%A0%BC%E5%BC%8F/</guid><description>&lt;h2 id="前"&gt;前&lt;/h2&gt;
&lt;p&gt;Terraform 在基础设施的管理是是非常方便的。但是面对一个中型项目，管理文件的复杂度也会大幅提升。&lt;/p&gt;
&lt;p&gt;特别是针对一个多regoin的项目，需要按regoin来进行拆分和管理，来获得更直观的资源展示。&lt;/p&gt;
&lt;p&gt;这篇文章记录一下现在使用的项目结构，以便后续的复用&lt;/p&gt;
&lt;h2 id="项目结构"&gt;项目结构&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;➜&lt;/span&gt; &lt;span class="n"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;eu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;central&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;lbs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;set_env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;terraform&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tfstate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;terraform&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tfstate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;terraform&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tfstate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;east&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;项目结构如上面的目录树，每一个区域都拆分到了单独的文件夹中，对于多region的中小型项目，可以清晰的拆分各个区域的资源。&lt;/p&gt;
&lt;h2 id="配置文件"&gt;配置文件&lt;/h2&gt;
&lt;p&gt;在maintf 中，来设置 provider。通过 module 来引入，对应的模块的文件夹。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# Main.tf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;terraform {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; required_providers {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; aws = {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; source = &amp;#34;hashicorp/aws&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; version = &amp;#34;5.63.1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; backend &amp;#34;local&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; path = &amp;#34;./terraform.tfstate.d/terraform.tfstate&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;module &amp;#34;us_east&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; source = &amp;#34;./us-east-1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;module &amp;#34;eu_central&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; source = &amp;#34;./eu-central-1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在子文件夹中，就可以直接在main 里面设置provider 配置，这里设置的是region区域。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# us-east-1 main.tf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;provider &amp;#34;aws&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; region = &amp;#34;us-east-1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# eu-central-1 main.tf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;provider &amp;#34;aws&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; region = &amp;#34;eu-central-1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通过上面的模块引入之后，就可以使用，标准的方式来预定义一些变量了 。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aws_vpc_id&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;AWS VPC ID&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;vpc-xxxx&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;locals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vpc_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;vpc-0936ab715c6cee712&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sub_private_a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;subnet-xxxx111&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sub_private_b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;subnet-xxxx222&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;public_subnets&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;List of Availability Zones&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;subnet-xxxxcccc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;subnet-xxxxdddd&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="后"&gt;后&lt;/h2&gt;
&lt;p&gt;以上记录一下，对于多region 的场景下如何来设计项目的目录结构来进行合理的划分和隔离。&lt;/p&gt;
&lt;p&gt;这样避免了单个层级，堆叠了多区域/多文件 带来的管理混乱的问题。&lt;/p&gt;</description></item></channel></rss>