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

Solidity时间旅行测试失败:CryptoZombies攻击用例Truffle测试报错

问题原因
  • 报错核心是你使用的Truffle v5.4.17对应的web3版本中,web3.currentProvider.send()是回调风格API,不支持直接用await调用,必须传入回调函数作为第二个参数,原实现未传回调就触发了callback is not a function错误。
  • 原increase方法中evm_mine的调用未加await,即使修复第一个调用的报错,也会出现时间调整未即时生效的问题,导致攻击冷却校验不通过。
  • 你的测试用例存在隐藏缺陷:调用attack方法时没有将返回值赋值给result,后续断言用的result还是第二次创建僵尸的返回结果,就算时间问题解决,断言也不符合预期。
解决方案

方案1:修改自定义increase实现

将回调风格的send调用封装为Promise适配await,修改后的代码如下:

async function increase(duration) {
    // 封装RPC调用为Promise格式兼容await
    const sendRPC = (payload) => {
        return new Promise((resolve, reject) => {
            web3.currentProvider.send(payload, (error, response) => {
                if (error) return reject(error)
                resolve(response)
            })
        })
    }

    // 调整EVM时间
    await sendRPC({
        jsonrpc: "2.0",
        method: "evm_increaseTime",
        params: [duration],
        id: new Date().getTime()
    });

    // 挖矿出块使时间调整生效
    await sendRPC({
        jsonrpc: '2.0',
        method: 'evm_mine',
        params: [],
        id: new Date().getTime()
    })
}

方案2:使用Truffle官方测试工具(更稳定)

Truffle官方提供了封装好的时间操作工具@truffle/test-helpers,无需自己实现RPC调用,安装后直接导入即可使用和原调用逻辑完全一致的time.increase方法,兼容性更好。

修复测试用例隐藏缺陷

将测试用例中调用attack的行修改为:

result = await contractInstance.attack(firstZombieId, secondZombieId, {from: alice});

确保后续断言的是攻击交易的执行状态。

内容的提问来源于stack exchange,提问作者DeepSports

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:45:04