Solidity 中的错误处理

2025年6月2日 | 阅读 5 分钟

在任何编程语言中,错误都是不可避免的;可能存在编译时错误和运行时错误。 编译时错误很容易捕获,因为每次编译代码时都会进行语法检查,指出错误,以便程序员可以更正它。 相比之下,运行时错误很难捕获;一些常见的运行时错误是 out-of-gas 错误、数据类型溢出错误、数组索引越界错误等。

Solidity 的 4.10 版本之前,程序中使用单个 throw 语句来处理编译时或运行时错误。 因此,为了处理错误,用户必须实现多个 if…else 语句来检查输入值,并且最终必须使用 throw 语句来捕获消耗更多 gas 的错误。 为了防止这种情况,solidity 开发人员引入了不同的方法来处理运行时错误。

从 0.4.10 版本开始,Solidity 提供了以下方法来处理运行时错误

  1. Require()
  2. Assert()
  3. Revert()

让我们简要讨论一下它们中的每一个,以及它们的语法和示例。

错误处理:Require()

Require 函数保证了编程条件的逻辑,这些条件在评估之前可能不会被注意到。 它验证输入、状态变量和对外部合约的调用。

Require() 语句只接受一个参数,并在执行后返回一个布尔值。 它还允许用户添加自定义字符串消息。 如果返回布尔值 False,则会引发异常并终止程序执行。 未使用的 gas 将返回给用户,程序状态将恢复到其原始状态。

以下是 require 类型异常的一些情况

  • require() 仅在参数返回 False 作为结果时触发。
  • 当消息调用的函数未成功完成时。
  • 如果使用 new 关键字创建 solidity 合约未成功完成,则调用 require()。
  • 当无代码合约尝试与外部函数交互时,会调用 require()。
  • 当使用公共 getter 方法将 ethers 发送到合约时,会触发 require()。

语法

示例 1:在下面的程序中,合约 requireStatementExample 显示了“require 语句”的示例。

输出

Error Handling in Solidity

示例 2:在下面的程序中,合约 requireStatementExample 显示了“require 语句”的示例。

输出

Error Handling in Solidity

错误处理:Assert()

assert() 方法用于程序中,以验证合约中的内部错误。 当条件未满足时,assert() 方法会消耗 gas 来恢复合约的状态。

此函数在执行条件后返回一个布尔值。 如果条件匹配,则返回布尔值 True,程序将执行而不会抛出任何错误。 如果条件不满足,则返回布尔值 False,并且会抛出异常。 此函数的缺点是它会占用整个 gas 供应,然后将状态恢复到原始状态。

以下是触发 require 类型异常的一些情况

  • assert() 仅在参数返回 False 作为结果时触发。
  • 如果启动零初始化的变量函数,则调用 assert() 语句。
  • 当将大值或负值转换为枚举时,会调用 assert() 语句。
  • 如果在 solidity 程序中,用户尝试将值除以或取模为零,则调用 assert() 语句。
  • 当在索引中访问数组太大或为负数时,会调用 assert() 语句。

语法

示例:在下面的程序中,合约 assertStatementExample 显示了“assert 语句”的示例。

输出 Error Handling in Solidity

说明

在上面的程序中,我们在 num1 和 num2 中传递了两个值 345、23,总共得到 368。如果总和大于 255,则会触发 assert() 语句。 由于程序返回 False,因此将打印消息“Value within 255, Overflow exists”。

错误处理:Revert()

Revert() 语句用于 solidity 中以抛出异常、显示错误消息,返回未使用的 gas,并最终将状态恢复到原始状态。 它不消耗任何 gas。 Revert 函数的工作方式与 require 语句相同,但逻辑稍微复杂一些。

语法

示例:在下面的程序中,合约 revertStatementExample 显示了“revert 语句”的示例。

输出

Error Handling in Solidity

说明

在上面的程序中,我们在 num1 和 num2 中传递了两个值 430、23,总共得到 453。如果总和大于 255,则会触发 revert() 语句。 由于程序返回 False,因此将打印消息“Overflow detected in the program,”。