微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 Mocha 测试智能合约中的 Require 语句?

如何解决如何使用 Mocha 测试智能合约中的 Require 语句?

我是开发智能合约的新手,在测试时遇到了问题。我的目的是确保智能合约不能铸造超过 13 个 ERC721 代币。我的理解是,一个 require 函数可以有第二个字符串参数,如果不满足 require 条件,它会将字符串恢复为错误。这样对吗? 以下是我的智能合约代码

contract TheCondemned_Episode is ERC721Enumerable {

    string[] public episodes;
    

    constructor() ERC721("TheCondemned_e1","TCe1") public {
    }

    function mint(string memory _episode) public {
       
        require(episodes.length <= 13,"Cannot make more than 13 episodes");
        episodes.push(_episode);
        uint _id= episodes.length;
        _mint(msg.sender,_id);
      
    }
}

我正在运行的测试如下:

it('Cannot create more than 13 episodes',async() => {
            
            
            
            for(var i=0; i===13; i++){
                
                var episode= `Episode ${i}`
                await contract.mint(episode)
            }
            
            try {
                await contract.mint('Episode 14');
                assert(true);
            }
            catch (err) {
                return;
            }
            assert(false,"The contract did not throw.");

测试失败并返回“合约没有抛出”。在测试时从失败的要求条件中捕获恢复字符串的最佳实践是什么?

解决方法

我的理解是,require 函数可以有第二个字符串参数,如果不满足 require 条件,该参数会将字符串恢复为错误。这是正确的吗?

没错。下面是一个始终失败的 require() 条件示例,该条件引发异常并显示错误消息。

require(false,'Error message');

但是,您在 Solidity require() 条件以及 JS 测试片段中存在逻辑错误。


首先,让我们揭开 Solidity 代码。为简单起见,我们假设您只允许制作 1 集。

require(episodes.length <= 1,"Cannot make more than 1 episode");
  1. 第一次迭代(预计通过)

    episodes.length 为 0,即 <= 1。条件通过,您铸造第一个令牌,然后推送到 episodes 数组,因此它的 length 在条件之后 变为 1。

  2. 第二次迭代(预计失败)

    episodes.length 是 1,那仍然是 <= 1。所以条件也通过了。

解决方案:<=(小于或等于)替换为 <(小于)。

require(episodes.length < 1,"Cannot make more than 1 episode");
  1. 第一次迭代(预计通过)

    episodes.length 为 0,即 < 1。条件通过,您铸造第一个令牌,然后推送到 episodes 数组,因此它的 length 在条件之后 变为 1。

  2. 第二次迭代(预计失败)

    episodes.length 为 1,如您所料,条件 1 < 1 失败。


我假设您在 JS 代码段中的意图是在循环中调用 mint() 函数 13 次,然后在 try/catch 块中调用 14 次。

然而,循环目前不执行任何迭代。所以实际上,您只执行了一次 mint() 函数(在 try/catch 块中)。

for 循环中的第二个参数是一个条件,说明“只要满足这个条件,这个循环就会一直迭代”。但是由于您在第一个参数中将 i 的值设置为 0,因此不满足循环条件 (i===13),并且循环甚至不会执行第一次迭代。

解决方案:检查 i 是否是“小于 13”而不是“等于 13”。

for(var i = 0; i < 13; i++) {

这样,循环将迭代 13 次。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。