区块链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操作来说,这些节省直接转化为利润。