在测试中处理Solidity合同的模式是什么?

Int*_*ion 7 ethereum truffle

我有一个关于Solidity合约的函数.例如.

   function do(x,y)  {
        if ( msg.sender != owner )
            throw;
        // ...
   }
Run Code Online (Sandbox Code Playgroud)

在Truffle环境中,我有一个测试js,如:

//.... part of a promise chain
       .then(
            function (_bool0) {
                assert.isTrue(_bool0,"whoops - should be true");
                return contract.do( "okdoke" , {from: accounts[1]} );
            }).then(
            function (tx_id) {
                //..
                done();
            }
    // ...
Run Code Online (Sandbox Code Playgroud)

return contract.do()会导致导致throw的条件.在此测试的松露测试输出中产生以下内容:

Error: VM Exception while executing transaction: invalid JUMP
Run Code Online (Sandbox Code Playgroud)

在像这样的测试中处理合同函数抛出的习惯用法是什么?抛出是正确的行为.

小智 3

对于这个问题,我能想到的“最正确”的解决方案是检查所有发送的气体是否已用完,这就是抛出时发生的情况,但是还有一个额外的问题要使该解决方案在两个 TestRPC 上都有效(考虑到抛出的实际错误,我猜你正在使用它)和 Geth。当 Geth 中发生抛出时,仍然会创建一个交易,消耗所有的 Gas,但不会发生状态变化。TestRPC 实际上会抛出错误,这对于调试目的很有用。

   //Somewhere where global functions can be defined
   function checkAllGasSpent(gasAmount, gasPrice, account, prevBalance){
       var newBalance = web3.eth.getBalance(account);
       assert.equal(prevBalance.minus(newBalance).toNumber(), gasAmount*gasPrice, 'Incorrect amount of gas used');
   }

   function ifUsingTestRPC(){
       return;
   }

   //Some default values for gas
   var gasAmount = 3000000;
   var gasPrice = 20000000000;

   ....

   //Back in your actual test
   it('should fail ', function (done) {
       var prevBalance;

   ....

   .then(function (_bool0) {
        assert.isTrue(_bool0,"whoops - should be true");
        prevBalance = web3.eth.getBalance(accounts[1]);
        return contract.do( "okdoke" , {from: accounts[1], gasPrice:gasPrice, gas:gasAmount } );
        })
    .catch(ifUsingTestRPC)
    .then(function(){
         checkAllGasSpent(gasAmount, gasPrice, accounts[1], prevBalance);
    })
    .then(done)
    .catch(done);
Run Code Online (Sandbox Code Playgroud)

不过,如果出现另一个解决方案,我会很乐意实施一个更直接的解决方案。

注意:如果您在一笔意外有效的交易中花费了所有的 Gas,则不会发现这一点 - 它会假设 Gas 是由于 VM 内的抛出而花费的。