You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity中如此使用revert是否正确?参数验证与Gas返还咨询

问题:Solidity中modifier里同时使用require和revert是否正确?

我编写了一个抽象合约,需要对参数进行验证,若参数无效则返回错误并返还Gas费用。我创建了名为checkNumber的modifier,在其中验证_number参数,同时使用了require和revert语句,相关代码如下:

//SPDX-License-Identifier: UNLICENSED

// Solidity files have to start with this pragma.
// It will be used by the Solidity compiler to validate its version.
pragma solidity >=0.7.0 <0.9.0;

struct Information {
    uint number;
    string avatar;
}

abstract contract AbstractCandidate {
    uint[6] private _numbers = [1, 2, 3, 4, 5, 6];
    string[6] private _avatars = [
        "https://raw.githubusercontent.com/thiagosaud/dApp-superior-electoral-court/main/temp/imgs/candidate-1.png",
        "https://raw.githubusercontent.com/thiagosaud/dApp-superior-electoral-court/main/temp/imgs/candidate-2.png",
        "https://raw.githubusercontent.com/thiagosaud/dApp-superior-electoral-court/main/temp/imgs/candidate-3.png",
        "https://raw.githubusercontent.com/thiagosaud/dApp-superior-electoral-court/main/temp/imgs/candidate-4.png",
        "https://raw.githubusercontent.com/thiagosaud/dApp-superior-electoral-court/main/temp/imgs/candidate-5.png",
        "https://raw.githubusercontent.com/thiagosaud/dApp-superior-electoral-court/main/temp/imgs/candidate-6.png"
    ];

    modifier checkNumber(uint _number) {
        string memory _errorMessage = "Candidate number is incorret!";

        require(_number < 1 || _number > _numbers.length, _errorMessage);

        if (_number < 1 || _number > _numbers.length) {
            revert(_errorMessage);
        }

        _;
    }

    function getInformation(uint _number) external view checkNumber(_number) returns(Information memory) {
        return Information({ avatar: _avatars[_number], number: _numbers[_number] });
    }
}

请问这样使用revert是否正确?


回答

你的用法不正确,核心问题有以下几点:

  1. require条件逻辑完全写反
    require的执行逻辑是:当条件为true时继续执行代码,条件为false时触发回滚并返回错误信息。你当前的require(_number < 1 || _number > _numbers.length, _errorMessage);意思是「只有参数无效时才允许继续执行」,这和你的验证需求完全相反。正确的条件应该是验证参数有效:
require(_number >= 1 && _number <= _numbers.length, _errorMessage);
  1. 重复验证完全多余
    在require已经触发回滚的前提下,后面的if判断和revert语句永远不会被执行——因为如果参数无效,require已经终止了代码执行并回滚。所以同时使用require和revert做相同验证是毫无意义的,选其中一个即可(实际开发中更常用require做参数校验)。

  2. 存在数组索引越界风险
    你的_numbers和_avatars是长度为6的数组,索引从0到5,但候选编号是1到6。当你用_avatars[_number]时,比如_number=6,会访问数组索引6,直接触发越界报错。正确的写法应该是用_number - 1来匹配数组索引:

return Information({ avatar: _avatars[_number - 1], number: _numbers[_number - 1] });

另外注意你的错误信息里拼写错误:incorret应该改为incorrect。

修正后的核心代码

modifier checkNumber(uint _number) {
    string memory _errorMessage = "Candidate number is incorrect!";
    require(_number >= 1 && _number <= _numbers.length, _errorMessage);
    _;
}

function getInformation(uint _number) external view checkNumber(_number) returns(Information memory) {
    return Information({ avatar: _avatars[_number - 1], number: _numbers[_number - 1] });
}

总结:

  • require和revert的作用一致,都是触发回滚并返还未消耗的Gas,无需同时使用
  • 编写校验条件时一定要注意逻辑正确性,避免反向判断
  • 访问数组时要确保索引在合法范围内,防止越界报错

内容的提问来源于stack exchange,提问作者THIAGO DE BONIS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 19:05:21