You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity汇编代码出现execution reverted错误,寻求问题排查

问题分析与修复

你的汇编代码触发execution reverted主要是因为内存布局错误导致路由器合约无法识别函数调用,以下是具体问题和修复方案:

  • 函数选择器存储位置错误
    构造合约调用数据时,函数选择器必须放在内存起始位置(0x00),你将其存在0x7c,导致路由器无法匹配目标函数,直接触发回滚。
    修正:把函数选择器写入0x00:

    mstore(0x00, SWAP_ETH_FOR_TOKEN)
    
  • 参数内存布局完全错误
    Uniswap V2的swapExactETHForTokens(对应你用的SWAP_ETH_FOR_TOKEN选择器)参数的内存布局有严格要求:

    1. 函数选择器(4字节,0x00-0x03)
    2. amountOutMin(uint256,32字节,0x04-0x23)
    3. path数组的偏移量(uint256,0x24-0x43)—— 动态数组需指定其在内存中的起始位置
    4. to地址(uint256,0x44-0x63)
    5. deadline(uint256,0x64-0x83)
      此外,你直接存储path的calldata指针是错误的,必须将数组内容复制到内存:
    // 把calldata中的address[2]数组复制到内存(0x84起始)
    calldatacopy(0x84, path.offset, mul(2, 32))
    // 设置path数组在call data中的偏移量
    mstore(0x24, 0x84)
    
  • call指令的输入范围错误
    你当前call的起始位置是0x7c、长度0x100,完全指向错误的内存区域。修正后,call的起始应为0x00,长度需覆盖函数选择器+所有参数+数组内容的总长度(示例中为0xC4)。

  • to参数逻辑错误(可选优化)
    address()获取的是当前合约地址,若要让代币转到调用者账户,应使用caller()(对应Solidity的msg.sender):

    mstore(0x44, caller())
    
  • revert指令无效
    revert(3,3)的长度为0,无法传递错误信息,建议改为回滚时返回路由器的错误数据:

    if iszero(success) {
        returndatacopy(0x00, 0x00, returndatasize())
        revert(0x00, returndatasize())
    }
    

修正后的完整代码

function swapEthForToken(
    address router,
    uint256 minAmount,
    address[2] calldata path
) public payable {
    assembly {
        let deadline := add(timestamp(), 300)
        // 确保SWAP_ETH_FOR_TOKEN是swapExactETHForTokens的正确选择器(0x7ff36ab5)
        let swapSelector := SWAP_ETH_FOR_TOKEN

        // 构造call data内存布局
        mstore(0x00, swapSelector) // 函数选择器
        mstore(0x04, minAmount)    // amountOutMin
        mstore(0x24, 0x84)         // path数组的偏移量
        mstore(0x44, caller())     // 接收代币的地址(msg.sender)
        mstore(0x64, deadline)     // deadline

        // 复制path数组到内存
        calldatacopy(0x84, path.offset, mul(2, 32))

        // 调用路由器合约
        let success := call(gas(), router, callvalue(), 0x00, 0xC4, 0x00, 0x00)

        // 处理调用失败
        if iszero(success) {
            returndatacopy(0x00, 0x00, returndatasize())
            revert(0x00, returndatasize())
        }
    }
}

内容的提问来源于stack exchange,提问作者Mehul Singh Rathore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 23:15:33