【问题标题】:Solidity Time-Travel Test FailingSolidity 时间旅行测试失败
【发布时间】:2021-12-27 05:54:30
【问题描述】:

我正在关注 CryptoZombies 教程,但无法通过其中一项测试。测试如下:

it("zombies should be able to attack another zombie", async () => {
        let result;
        result = await contractInstance.createRandomZombie(zombieNames[0], {from: alice});
        const firstZombieId = result.logs[0].args.zombieId.toNumber();
        result = await contractInstance.createRandomZombie(zombieNames[1], {from: bob});
        const secondZombieId = result.logs[0].args.zombieId.toNumber();
        await time.increase(time.duration.days(1));
        await contractInstance.attack(firstZombieId, secondZombieId, {from: alice});
        expect(result.receipt.status).to.equal(true);
    })

本质上,创建zombie1,创建zombie2,快进一天,让zombie1攻击zombie2(因为从zombie创建到允许附加之间有一个冷却时间),最后断言智能合约能够执行.

测试失败,出现这个无用的错误消息:

  1) Contract: CryptoZombies
       zombies should be able to attack another zombie:
     Uncaught TypeError: callback is not a function
      at /home/deepsports/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/provider/wrapper.js:107:1
      at XMLHttpRequest.request.onreadystatechange (/home/deepsports/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-providers-http/lib/index.js:98:1)
      at XMLHttpRequestEventTarget.dispatchEvent (/home/deepsports/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:1)
      at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._setReadyState (/home/deepsports/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:208:1)
      at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._onHttpResponseEnd (/home/deepsports/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:318:1)
      at IncomingMessage.<anonymous> (/home/deepsports/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:289:47)
      at endReadableNT (internal/streams/readable.js:1334:12)
      at processTicksAndRejections (internal/process/task_queues.js:82:21)

对于背景,我正在使用:

  • 松露 v5.4.17
  • 坚固度 0.4.25
  • Node v14.18.0(如果有帮助?)

堆栈跟踪有点难以解析,因为在我引用的实际代码中没有任何行。通过排除过程,能够确认是这行代码导致了失败: await time.increase(time.duration.days(1));

调用此代码(作为教程的一部分创建):

async function increase(duration) {

    //first, let's increase time
    await web3.currentProvider.send({
        jsonrpc: "2.0",
        method: "evm_increaseTime",
        params: [duration], // there are 86400 seconds in a day
        id: new Date().getTime()
    });

    //next, let's mine a new block
    web3.currentProvider.send({
        jsonrpc: '2.0',
        method: 'evm_mine',
        params: [],
        id: new Date().getTime()
    })

}

【问题讨论】:

    标签: ethereum solidity smartcontracts web3 truffle


    【解决方案1】:

    似乎 CryptoZombies 正在模拟已弃用的 web3 版本(我猜他们也使用了 sendAsync - 这是在 CZ tutorial 中,而不是在您的代码中),这本来可以奏效的。

    但是,正如 GitHub issue 中所述,web3.currentProvider.send() 现在需要一个回调参数,并且无法使用 await 解决。

    // no callback, fails
    await web3.currentProvider.send({
        jsonrpc: "2.0",
        method: "evm_increaseTime",
        params: [duration],
        id: new Date().getTime()
    });
    

    工作解决方案:

    async function increase(duration) {
        return new Promise((resolve, reject) => {
            web3.currentProvider.send({
                jsonrpc: "2.0",
                method: "evm_increaseTime",
                params: [duration],
                id: new Date().getTime()
            }, (err, result) => {
                // second call within the callback
                web3.currentProvider.send({
                    jsonrpc: '2.0',
                    method: 'evm_mine',
                    params: [],
                    id: new Date().getTime()
                }, (err, result) => {
                    // need to resolve the Promise in the second callback
                    resolve();
                });
            });
        });
    }
    

    注意:不要将此与其他 web3 send() 方法混淆,例如 contract.methods.foo().send(),可以使用 await 解决。

    【讨论】:

    • 我遇到了同样的问题。你的解决方案也为我解决了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 2022-06-28
    • 1970-01-01
    • 2018-11-04
    相关资源
    最近更新 更多