[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-5-yul-rumen-solidity-huibian-yuyan":3},{"article":4,"author":58},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":38,"related_articles":39},"d3000000-0000-0000-0000-000000000105","a0000000-0000-0000-0000-000000000032","Deep EVM #5：Yul入门——Solidity的秘密汇编语言","deep-evm-5-yul-rumen-solidity-huibian-yuyan","Yul实践入门：语法、Solidity中的内联汇编、何时使用，以及读取存储、发射事件和绕过Solidity开销的实操示例。","## 什么是Yul以及它为何存在\n\nYul是Solidity团队设计的中间语言，编译为EVM字节码。它介于Solidity和原始操作码之间：你通过可读的、结构化的语法——变量、函数、if\u002Fswitch\u002Ffor构造和作用域块——直接访问每个EVM操作码。\n\nYul的存在是因为Solidity编译器生成保守的字节码。溢出检查、ABI编码、内存管理——对应用合约有用，但对于gas关键代码（如MEV机器人、DEX路由器或链上数学库）来说开销不可接受。\n\n当你在Solidity内写`assembly { ... }`时，你就是在写Yul。\n\n## Yul语法基础\n\nYul的语法极简。没有类型——一切都是256位字。没有数组、没有结构体、没有继承。\n\n### 变量\n```yul\nlet x := 42\nlet y := add(x, 1)    \u002F\u002F y = 43\nlet z := mul(x, y)    \u002F\u002F z = 42 * 43 = 1806\n```\n\n### 函数\n```yul\nfunction safeAdd(a, b) -> result {\n    result := add(a, b)\n    if lt(result, a) {\n        revert(0, 0)  \u002F\u002F 溢出\n    }\n}\n```\n\n### 控制流\n\n**If**（Yul中没有else！）：\n```yul\nif iszero(calldatasize()) {\n    revert(0, 0)\n}\n```\n\n**Switch**（else的等价物）：\n```yul\nswitch selector\ncase 0xa9059cbb { \u002F* 处理transfer *\u002F }\ncase 0x70a08231 { \u002F* 处理balanceOf *\u002F }\ndefault { revert(0, 0) }\n```\n\n## Solidity中的内联汇编\n\n使用Yul最常见的方式是在Solidity的`assembly { }`块内。这绕过了Solidity的映射访问器，节省了ABI编码和边界检查的gas。\n\n## 何时使用Yul（何时不用）\n\n### 使用Yul：\n1. **Gas至关重要** — MEV机器人、DEX聚合路由器\n2. **需要位操作** — 打包\u002F解包数据\n3. **内存布局重要** — 构建外部调用的calldata\n4. **代理合约** — 最小代理（EIP-1167）\n\n### 不使用Yul：\n1. **可读性比gas更重要** — 大多数应用合约\n2. **你对EVM知识不够自信** — Yul没有安全网\n3. **gas节省微不足道** — 不值得审计风险\n\n## Yul vs Huff\n\n| 特性 | Yul | Huff |\n|------|-----|------|\n| 栈管理 | 自动（编译器） | 手动 |\n| 变量名 | 是 | 否（栈位置） |\n| 函数 | 是 | 宏 |\n| 控制流 | if\u002Fswitch\u002Ffor | JUMPI\u002FJUMPDEST |\n| 代码大小控制 | 有限 | 完全 |\n| Gas开销 | 小（变量管理） | 零 |\n\n## 总结\n\nYul是Solidity安全性与EVM原始力量之间的桥梁。它以变量名、函数和结构化控制流给你操作码级别的控制。对MEV开发者来说，掌握Yul是盈利机器人和输给竞争对手之间的差异。","\u003Ch2 id=\"yul\">什么是Yul以及它为何存在\u003C\u002Fh2>\n\u003Cp>Yul是Solidity团队设计的中间语言，编译为EVM字节码。它介于Solidity和原始操作码之间：你通过可读的、结构化的语法——变量、函数、if\u002Fswitch\u002Ffor构造和作用域块——直接访问每个EVM操作码。\u003C\u002Fp>\n\u003Cp>Yul的存在是因为Solidity编译器生成保守的字节码。溢出检查、ABI编码、内存管理——对应用合约有用，但对于gas关键代码（如MEV机器人、DEX路由器或链上数学库）来说开销不可接受。\u003C\u002Fp>\n\u003Cp>当你在Solidity内写\u003Ccode>assembly { ... }\u003C\u002Fcode>时，你就是在写Yul。\u003C\u002Fp>\n\u003Ch2 id=\"yul\">Yul语法基础\u003C\u002Fh2>\n\u003Cp>Yul的语法极简。没有类型——一切都是256位字。没有数组、没有结构体、没有继承。\u003C\u002Fp>\n\u003Ch3>变量\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-yul\">let x := 42\nlet y := add(x, 1)    \u002F\u002F y = 43\nlet z := mul(x, y)    \u002F\u002F z = 42 * 43 = 1806\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>函数\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-yul\">function safeAdd(a, b) -&gt; result {\n    result := add(a, b)\n    if lt(result, a) {\n        revert(0, 0)  \u002F\u002F 溢出\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>控制流\u003C\u002Fh3>\n\u003Cp>\u003Cstrong>If\u003C\u002Fstrong>（Yul中没有else！）：\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-yul\">if iszero(calldatasize()) {\n    revert(0, 0)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Cstrong>Switch\u003C\u002Fstrong>（else的等价物）：\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-yul\">switch selector\ncase 0xa9059cbb { \u002F* 处理transfer *\u002F }\ncase 0x70a08231 { \u002F* 处理balanceOf *\u002F }\ndefault { revert(0, 0) }\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"solidity\">Solidity中的内联汇编\u003C\u002Fh2>\n\u003Cp>使用Yul最常见的方式是在Solidity的\u003Ccode>assembly { }\u003C\u002Fcode>块内。这绕过了Solidity的映射访问器，节省了ABI编码和边界检查的gas。\u003C\u002Fp>\n\u003Ch2 id=\"yul\">何时使用Yul（何时不用）\u003C\u002Fh2>\n\u003Ch3>使用Yul：\u003C\u002Fh3>\n\u003Col>\n\u003Cli>\u003Cstrong>Gas至关重要\u003C\u002Fstrong> — MEV机器人、DEX聚合路由器\u003C\u002Fli>\n\u003Cli>\u003Cstrong>需要位操作\u003C\u002Fstrong> — 打包\u002F解包数据\u003C\u002Fli>\n\u003Cli>\u003Cstrong>内存布局重要\u003C\u002Fstrong> — 构建外部调用的calldata\u003C\u002Fli>\n\u003Cli>\u003Cstrong>代理合约\u003C\u002Fstrong> — 最小代理（EIP-1167）\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch3>不使用Yul：\u003C\u002Fh3>\n\u003Col>\n\u003Cli>\u003Cstrong>可读性比gas更重要\u003C\u002Fstrong> — 大多数应用合约\u003C\u002Fli>\n\u003Cli>\u003Cstrong>你对EVM知识不够自信\u003C\u002Fstrong> — Yul没有安全网\u003C\u002Fli>\n\u003Cli>\u003Cstrong>gas节省微不足道\u003C\u002Fstrong> — 不值得审计风险\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"yul-vs-huff\">Yul vs Huff\u003C\u002Fh2>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>特性\u003C\u002Fth>\u003Cth>Yul\u003C\u002Fth>\u003Cth>Huff\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>栈管理\u003C\u002Ftd>\u003Ctd>自动（编译器）\u003C\u002Ftd>\u003Ctd>手动\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>变量名\u003C\u002Ftd>\u003Ctd>是\u003C\u002Ftd>\u003Ctd>否（栈位置）\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>函数\u003C\u002Ftd>\u003Ctd>是\u003C\u002Ftd>\u003Ctd>宏\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>控制流\u003C\u002Ftd>\u003Ctd>if\u002Fswitch\u002Ffor\u003C\u002Ftd>\u003Ctd>JUMPI\u002FJUMPDEST\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>代码大小控制\u003C\u002Ftd>\u003Ctd>有限\u003C\u002Ftd>\u003Ctd>完全\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Gas开销\u003C\u002Ftd>\u003Ctd>小（变量管理）\u003C\u002Ftd>\u003Ctd>零\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch2 id=\"\">总结\u003C\u002Fh2>\n\u003Cp>Yul是Solidity安全性与EVM原始力量之间的桥梁。它以变量名、函数和结构化控制流给你操作码级别的控制。对MEV开发者来说，掌握Yul是盈利机器人和输给竞争对手之间的差异。\u003C\u002Fp>\n","zh","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:25.877366Z","Yul汇编实践入门：语法、Solidity内联汇编、使用场景以及gas关键智能合约的实操示例。","Yul汇编语言",null,"index, follow",[21,26,30,34],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":31,"name":32,"slug":33,"created_at":25},"c0000000-0000-0000-0000-000000000014","Solidity","solidity",{"id":35,"name":36,"slug":37,"created_at":25},"c0000000-0000-0000-0000-000000000018","Yul","yul","区块链",[40,46,52],{"id":41,"title":42,"slug":43,"excerpt":44,"locale":12,"category_name":38,"published_at":45},"d0000000-0000-0000-0000-000000000599","Ethereum互操作层：55+个L2如何成为一条链","ethereum-hucaozuoceng-55-l2-chengwei-yitiao-lian","Ethereum有55+个Layer 2 rollup，碎片化了流动性和用户体验。Ethereum互操作层 — 结合跨rollup消息传递、共享排序器和based rollup — 旨在将它们统一为一个可组合的网络。","2026-03-28T10:44:44.539584Z",{"id":47,"title":48,"slug":49,"excerpt":50,"locale":12,"category_name":38,"published_at":51},"d0000000-0000-0000-0000-000000000598","ZK证明超越Rollups：Ethereum上的可验证AI推理","zk-zhengming-chaoyue-rollups-ethereum-keyanzheng-ai-tuili","零知识证明不再仅仅是扩容工具。在2026年，zkML实现了链上可验证的AI推理，ZK协处理器将繁重计算移至链下并在链上验证，而SP1和Jolt等新证明系统使其变得实用。","2026-03-28T10:44:44.534954Z",{"id":53,"title":54,"slug":55,"excerpt":56,"locale":12,"category_name":38,"published_at":57},"d0000000-0000-0000-0000-000000000575","EIP-7702实战：Pectra之后构建智能账户流程","eip-7702-shizhan-pectra-zhihou-goujian-zhineng-zhanghu-liucheng","EIP-7702允许任何Ethereum EOA在单笔交易中临时充当智能合约。以下是如何使用新的账户抽象原语实现批量交易、gas赞助和社交恢复。","2026-03-28T10:44:42.997040Z",{"id":13,"name":59,"slug":60,"bio":61,"photo_url":18,"linkedin":18,"role":62,"created_at":63,"updated_at":63},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]