跳到主要内容
区块链Mar 28, 2026

Deep EVM #8:用纯Yul构建Token Swap

OS
Open Soft Team

Engineering Team

为什么用纯Yul构建Token Swap

在前几篇文章中,我们学习了Yul的基础知识。现在我们把所有知识结合起来,构建一个真实的项目:一个完整的Uniswap V2 token swap合约,完全用Yul编写。

这个项目将展示:

  • Calldata解析和函数分发
  • 外部调用构建
  • 返回数据处理
  • 错误处理
  • Gas优化技巧

合约结构

object "TokenSwap" {
    code {
        datacopy(0, dataoffset("runtime"), datasize("runtime"))
        return(0, datasize("runtime"))
    }
    object "runtime" {
        code {
            // 函数分发
            switch selector()
            case 0x12345678 { swap() }
            default { revert(0, 0) }

            function selector() -> s {
                s := shr(224, calldataload(0))
            }

            function swap() {
                // 从calldata解析参数
                let tokenIn := calldataload(0x04)
                let tokenOut := calldataload(0x24)
                let amountIn := calldataload(0x44)
                let pair := calldataload(0x64)

                // 执行swap逻辑...
            }
        }
    }
}

Calldata解析

每个参数从calldata中的固定偏移量读取。前4字节是函数选择器,随后每32字节是一个参数。

外部调用构建

调用ERC-20 transfer需要手动在内存中构建calldata:

// approve(address,uint256)
mstore(0x00, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(0x04, spender)
mstore(0x24, amount)
let success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)

返回数据处理

外部调用后,必须检查成功状态和返回数据。某些代币(如USDT)不返回布尔值。

Gas分析

与Solidity版本相比,纯Yul实现通常节省30-50%的gas,因为消除了ABI编码/解码开销、溢出检查和编译器生成的内存管理。

总结

用纯Yul构建token swap展示了汇编级编程的威力。虽然代码更复杂,但gas节省是实质性的——对于MEV机器人和高频DEX操作来说,这些节省直接转化为利润。