GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — WTF-EVM-Opcodes/17_RevertOp at main · WTFAcademy/WTF-EVM-Opcodes

Expand file tree

/

17_RevertOp

/
Copy path

Directory actions

More options

More options

Directory actions

More options

More options

Latest commit

 

History

History
History
/

17_RevertOp

/
Copy path

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
RevertOp.ipynb
RevertOp.ipynb
 
 
readme.md
readme.md
 
 

readme.md

Outline

WTF Opcodes极简入门: 17. Revert指令

我最近在重新学以太坊opcodes,也写一个“WTF EVM Opcodes极简入门”,供小白们使用。

推特:@0xAA_Science

社区:Discord|微信群|官网 wtf.academy

所有代码和教程开源在github: github.com/WTFAcademy/WTF-Opcodes


这一讲,我们将介绍EVM中与异常处理相关的2个指令: REVERT 和 INVALID。当它们被触发时,交易会回滚。

交易状态

我们需要在咱们的极简evm中跟踪交易的状态success,默认为True,当交易失败回滚时变为False,只有当success为True时继续执行opcodes,否则结束交易:

class EVM:
    def __init__(self):
        # ... 其他属性 ...
        self.success = True

    def run(self):
        while self.pc < len(self.code) and self.success:
            op = self.next_instruction()
        # ... 指令操作 ...

REVERT

当合约运行出错,或者达到了某种条件需要终止执行并返回错误信息时,可以使用REVERT指令。REVERT指令会终止交易的执行,返回一个错误消息,并且所有状态更改(例如资金转移、存储值的更改等)都不会生效。它会从堆栈中弹出两个参数:内存中错误消息的起始位置mem_offset和错误消息的长度length。它的操作码为0xFD,gas消耗为内存扩展消耗。

def revert(self):
    if len(self.stack) < 2:
        raise Exception('Stack underflow')
    mem_offset = self.stack.pop()
    length = self.stack.pop()

    # 拓展内存
    if len(self.memory) < mem_offset + length:
        self.memory.extend([0] * (mem_offset + length - len(self.memory)))

    self.returnData = self.memory[mem_offset:mem_offset+length]
    self.success = False

INVALID

INVALID是EVM中用来表示无效操作的指令。当EVM遇到无法识别的操作码时,或者在故意触发异常的情境下,它会执行INVALID指令,导致所有状态更改都不会生效,并且消耗掉所有的gas。它确保了当合约试图执行未定义的操作时,不会无所作为或产生不可预测的行为,而是会安全地停止执行,对EVM的安全至关重要。它的操作码为0xFE,gas消耗为所有剩余的gas。

def invalid(self):
    self.success = False

测试

  1. REVERT: 我们运行一个包含REVERT指令的字节码:60aa6000526001601ffd(PUSH1 aa PUSH1 0 MSTORE PUSH1 1 PUSH1 1f REVERT)。这个字节码将aa存在内存中,然后使用REVERT指令将交易回滚,并将aa复制到returnData中。

    # REVERT
    code = b"\x60\xa2\x60\x00\x52\x60\x01\x60\x1f\xfd"
    evm = EVM(code)
    evm.run()
    print(evm.returnData.hex())
    # output: a2

总结

这一讲,我们学习了EVM中与异常处理相关的2个指令:REVERT和INVALID,并通过代码示例为极简EVM添加了对这些指令的支持。异常处理是任何程序或合约执行的重要部分,而这两个指令是Solidity中的require,error和assert关键字的基础。目前,我们已经学习了144个操作码中的136个(94%)!

You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.