我有一个关于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 内的抛出而花费的。
| 归档时间: |
|
| 查看次数: |
4408 次 |
| 最近记录: |