簡體   English   中英

測試松露中的智能合約要求:如果功能不無效,則交易將被還原

[英]Testing Smart contract requires in Truffle: transaction reverted if function isnt void

我正在根據本文嘗試僅通過可靠性來測試智能合約的要求:

http://truffleframework.com/tutorials/testing-for-throws-in-solidity-tests

這是合同,委托代理合同和測試:

/* Testing with solidity tests. */

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/MyContract.sol";

contract TestMyContract {

function testInitialStoredValue() {
    MyContract mycontract = new MyContract();

    uint expected = 24;

    Assert.equal(mycontract.mynumber(), expected, "First number set should be 24.");
}

function testTheThrow() {
    MyContract mycontract = new MyContract(); 

    ThrowProxy throwproxy = new ThrowProxy(address(mycontract)); 
    uint num = 7;
    MyContract(address(throwproxy)).storeNum(num);

    bool r = throwproxy.execute.gas(200000)(); 

    Assert.isFalse(r, "Should be false because is should throw!");

}

function testNoThrow() {
    MyContract mycontract = new MyContract(); 

    ThrowProxy throwproxy = new ThrowProxy(address(mycontract)); 

    MyContract(address(throwproxy)).storeNum(22);

    bool r = throwproxy.execute.gas(200000)(); 

    Assert.isTrue(r, "Should be true because is should throw!");

}

}

// Proxy contract for testing throws
contract ThrowProxy {
  address public target;
  bytes data;

  function ThrowProxy(address _target) {
    target = _target;
  }

  //prime the data using the fallback function.
  function() {
    data = msg.data;
  }

  function execute() returns (bool) {
    return target.call(data);
  }
}

如果我運行測試,則會收到此錯誤:

2

如果我將storeNum函數更改為從

 function storeNum(uint mynum)
        public
        returns (bool)
    {
     require(mynum > 10);
     mynumber = mynum; 
     return true;    
    }

 function storeNum(uint mynum)
        public
    {
     require(mynum > 10);
     mynumber = mynum; 
     return true;    
    }

測試工作..

有任何想法嗎?

我正在使用松露v4.1.11

讓我們看看您的代碼:

function storeNum(uint mynum)
        public
        returns (bool success)
    {
     require(mynum > 10);
     mynumber = mynum; 
     return true;    
    }

通過定義returns (bool success)您對Solidity編譯器說了兩件事:

  • 有一個名為bool類型的success變量(變量定義)。
  • 該變量成功將由函數返回(返回定義)

但是您的變量畢竟不會返回(您的函數以return true結尾,這就是為什么您在測試中收到InvalidResponse錯誤的原因。

對於您的代碼,最有效的代碼是:

function storeNum(uint mynum)
        public
        returns (bool)    // you should define at least the type
    {
     require(mynum > 10);
     mynumber = mynum; 
     return true;    
    }

作為練習,使用變量success的版本:

function storeNum(uint mynum)
        public
        returns (bool success)
    {
     require(mynum > 10);
     mynumber = mynum; 
     success = true;    // don't need to use return
    }

希望能幫助到你。

好吧,我已經向Truffle github提交了一個問題,它仍然是打開的,也許這與最近的更改有關:

https://github.com/trufflesuite/truffle/issues/1001

現在的一種解決方法是將函數包裝到void函數中,並測試執行是否成功:

/*
    Contract wrapper that inherits from MyContract. This contract wraps the calls of non void functions when
    testing for exceptions.

    Why not invoke directly the function?: https://github.com/trufflesuite/truffle/issues/1001
*/

contract MyExposedContract is MyContract() {


    function callStoreNum(uint256 num)  public {
        storeNum(num);
    }

}

然后在測試中使用該包裝器:

function testTheThrow() {
    MyExposedContract mycontract = new MyExposedContract (); 

    ThrowProxy throwproxy = new ThrowProxy(address(mycontract)); 
    uint num = 7;
    MyExposedContract (address(throwproxy)).callStoreNum(num);

    bool r = throwproxy.execute.gas(200000)(); 

    Assert.isFalse(r, "Should be false because it should throw!");

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM