断言和要求之间的区别

Vyg*_*gor 4 blockchain ethereum solidity smartcontracts

您好,我最近刚刚开始从 Udemy 学习 Solidity,尽管在几乎完成课程后我还没有理解 assert 和 require 之间的区别。当不满足要求时,它们不是都会破坏功能吗?在合约内的 Gas 优化方面,两者相比是否有优势?

Yil*_*maz 8

来自文档

\n
\n

断言函数创建 Panic(uint256) 类型的错误

\n

断言只能用于测试内部错误和检查变量。正常运行的代码永远不会产生恐慌,即使外部输入无效。如果发生这种情况,则说明您的合同中存在错误,您应该修复该错误。语言分析工具可以\n评估您的合约,以识别\n会导致恐慌的条件和函数调用。

\n

Require:与断言类似,用于检查条件,如果不满足条件则抛出异常。不同之处在于 require 用于验证输入、返回值或对外部合约的调用。该方法还导致恢复到原始状态。它还可以采用可选参数来提供\n自定义错误消息。

\n
\n

require() 情况:

\n

\xe2\x80\xa2 检查用户输入。例如,如果余额大于 0

\n

\xe2\x80\xa2 检查外部合约的响应,例如 \xe2\x80\x9crequire (external.send\n(amount))\xe2\x80\x9d

\n

\xe2\x80\xa2 在状态更新之前检查条件

\n

\xe2\x80\xa2 尽可能早地使用该函数的 require ,因为如果发生故障,require只会返回未使用的气体。因此,如果您之前实现了一些需要消耗gas的逻辑require,那么如果该require语句失败,您将不会获得之前编写的逻辑所消耗的gasrequire

\n

在以下情况下使用assert():

\n

assert用于验证函数的内部本地状态。当您认为当前状态可能会变得不一致时,应该使用它。这意味着您的代码有错误。您不能传递自定义错误消息来断言,这与require

\n
    \n
  • 检查上溢/下溢。在solidity ^0.8.0之后,编译器会自动检查它。
  • \n
  • 检查不变值
  • \n
  • 修改后检查合同状态
  • \n
  • 避免不可能的情况
  • \n
\n

为了更好地理解使用 的好处assert,您可以阅读以下内容:为什么在此智能合约上使用断言?

\n


小智 7

这两个关键字之间更大的区别是,assert当条件为假时,往往会消耗所有剩余气体并恢复所做的所有更改。相反,require当条件为假时,退还我们愿意支付的所有剩余汽油费,并恢复所有更改。

正是出于最后一个原因,建议使用 require而不是assert。

更多信息请参考此