深入了解 Solidity 错误 #0

  • Tiny熊
  • 更新于 2023-08-02 16:31
  • 阅读 2299

深入了解 Solidity 错误第一篇, EVM 中的错误分类。

img

Zach VesselsUnsplash 上拍摄

今天文章将开启 "深入 Solidity "系列文章中的一个新子系列:”深入了解 Solidity 错误“ ,主要讨论 Solidity 和基于 EVM 的执行环境中的错误。本文是第一篇文章, ”深入了解 Solidity 错误“ 将一共包含 5 篇文章。

备注:这个系列是从 编译器和 EVM 层角度去理解错误,在语言层面如何进行错误处理可以阅读 学习 Solidity -错误处理

在智能合约领域,错误是非常致命的。如果没处理好,会导致错误和漏洞。如果处理错误,则会导致智能合约卡死和无法使用。

在直接进入 Solidity 之前,我们先来了解一下 EVM 在发生糟糕或错误的事情时是如何处理的,以及 EVM 内置了哪些不同类型的错误。

"如果说调试是清除软件错误的过程,那么编程一定是把错误放进去的过程" - Edsger W. Dijkstra

本文将介绍:

  • 程序计数器
  • EVM 错误和停止异常
  • 错误类型(编译时错误与运行时错误)
  • 编译时错误
  • 合约运行时错误
  • EVM 异常停止
    • Gas 耗尽
    • Stack Under/OverFlow
    • Invalid JUMP 目标
    • 错误指令

程序计数器

EVM 运行智能合约字节码时,会使用程序计数器 (PC) 一个接一个地运行每个操作码。

程序计数器(PC)编码了 EVM 下一步应读取(并运行)的指令(存储在合约代码中)。每执行一条指令后,程序计数器(PC)都会递增一个字节("PUSHN "指令和 "JUMP"/"JUMPI "指令除外,在这些指令中,程序计数器(PC)会被修改为字节码中的 "JUMPDEST" 目标)。

把 EVM 想象成路上的司机。当司机遇到一些带有方向、信号和限制的交通标志时,他知道下一步该做什么或不做什么。

只要 PC 遇到有效的操作码,EVM 就会继续在合约的当前执行环境中运行操作码。

但有些操作码可以指示停止执行。当执行停止时,我们称之为 EVM halts(见黄皮书)

但执行可以成功的停止,也可以出错的停止。如果执行成功停止,区块链的状态就会更新。否则,任何状态变化都会被还原,交易也不会在区块链上记录。这是由于以太坊的原子性。交易要么完全完成,要么根本没有做。不存在"部分完成 "的概念。

当程序计数器运行到以下两个操作码之一时,EVM 将停止执行并成功退出:

  • STOP(操作码 0x00 ):成功退出执行。
  • RETURN(操作码 0xf3):成功离开当前上下文+从内存中返回一些数据(=从内存中指定位置偏移开始的特定字节数)。

相反,当程序计数器运行到以下两个操作码之一时,EVM 将停止执行并错误退出:

  • REVERT:还原所有状态变化。一些数据(在内存中指定)和剩余Gas将返回给调用者。
  • INVALID:这是 EVM 指定的无效指令。所有状态变化被还原,所有剩余Gas被消耗。调用者不会得到任何Gas返还。

EVM 错误和异常停止

当 EVM 遇到错误时,运行时停止执行,导致 EVM 回退对状态所做的所有更改。

对于 EVM 来说,如果预期效果没有发生(或发生了意外效果),默认情况下没有安全的方法来继续执行。回退可保持交易的原子性。如 Solidity 文档所述:

最安全的操作是还原所有更改,并使整个交易(或至少调用)没有影响

如上一节所示,当程序计数器遇到操作码 "REVERT" 或 "INVALID"时,就会发生错误。但实际上,这些并不是唯一的情况!在 EVM 执行环境中,其他因素也可能导致错误。

我们将在接下来的章节中看到,根据黄皮书,实际上有两种类型的停止操作:

  • 异常停止错误。
  • 正常停止错误。

在黄皮书中被称为"异常/正常停止状态 "

img

正常与异常停止状态错误(来源:以太坊黄皮书)

错误类型(编译错误与运行时错误)

在 Solidity 中编写智能合约时,会遇到三大类错误。

  • 编译时错误(由 Solidity 编译器生成)
  • 运行时错误(由 EVM 与智能合约字节码交互时产生)
  • 异常停止错误(由 EVM 的堆栈处理器引起)

运行时错误在 Remix 中被定义...

剩余50%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Tiny熊
Tiny熊
0xD682...E8AB
登链社区发起人 通过区块链技术让世界变得更好而尽一份力。