iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
Web 3

以 Python 進入以太坊虛擬機 (EVM) 的幻想境界系列 第 16

虛擬境界 16:完整 EVM 實現

  • 分享至 

  • xImage
  •  

在 Ethereum 虛擬機 (EVM) 中,我們已經介紹了各種操作碼 (opcodes)。這些操作碼是智能合約執行的基礎。在這一章中,我們將把這些操作碼組合起來,實現一個完整的 EVM。

EVM 架構

EVM 類是整個虛擬機的核心,它負責執行智能合約的代碼。以下是其主要功能:

  • 初始化:當創建一個新的 EVM 實例時,它會初始化代碼、程序計數器、堆疊和內存。
  • 程序計數器next 函數負責返回當前的操作碼並將程序計數器加一。
  • 執行execute 函數是 EVM 的主要循環,它會持續執行代碼直到達到終止條件。

操作碼執行

execute 函數中,EVM 會根據當前的操作碼調用相應的操作模組。

utils 中列出所有 opcode 和對應數字。

而這些 class 都在前面幾章有實現過,我後續會更新上更完整的 code 上來,目前還在調整和除 bug 中,嘿嘿~

主函數

main 函數中,我們創建了一個新的 EVM 實例,並執行了一段代碼。這段代碼只包含一個操作碼 0x40,該操作碼對應於 BLOCKHASH 操作。執行後,我們可以打印堆疊的內容來查看結果。

EVM Class

import utils.opcodes as opcodes
from vm import ( 
    stack, 
    arith, 
    comparison, 
    sha3env, 
    block,
    storage, 
    flow, 
    log,
    system 
)

class EVM:
    def __init__(self, code) -> None:
        self.code = code
        self.pc = 0
        self.stack = []
        self.memory = bytearray()
        self.storage = {}
    
    # Program Counter Return Execute Opcodes
    def next(self):
        opCode = self.code[self.pc]
        self.pc += 1
        return opCode

    # Run EVM until code end
    def execute(self):
        while self.pc < len(self.code):
            opCode = self.next()
            # stack operations (50, 5F-7F, 80-8F, 90-9F)
            if opcodes.PUSH0 <= opCode and opcodes.PUSH32 or \
                opcodes.POP == opCode or \
                opcodes.DUP1 <= opCode and opcodes.DUP16 or \
                opcodes.SWAP1 <= opCode and opcodes.SWAP16:
                stack.Stack(self, opCode)
            
            # stop operations (00)
            elif opcodes.STOP == opCode:
                break

            # arithmetic operations (01-0B)
            elif opcodes.ADD <= opCode and opCode <= opcodes.SIGNEXTEND:
                arith.Arithmetic(self, opCode)

            # comparison & bitwise logic operations (10-1D)
            elif opcodes.LT <= opCode and opCode <= opcodes.SAR:
                comparison.Comparison(self, opCode)

            # sha3 & enviroment operations (20, 30-3F)
            elif opcodes.SHA3 <= opCode and opCode <= opcodes.EXTCODECOPY:
                sha3env.Sha3Env(self, opCode)
            
            # block operations (40-48)
            elif opcodes.BLOCKHASH <= opCode and opCode <= opcodes.BASEFEE:
                block.Block(self, opCode)
            
            # memory & stack operations (51-55)
            elif opcodes.MLOAD <= opCode and opCode <= opcodes.SSTORE:
                storage.Storage(self, opCode)

            # flow operations (56-5B)
            elif opcodes.JUMP <= opCode and opCode <= opcodes.JUMPDEST:
                flow.Flow(self, opCode)
            
            # log operations (A0-A4)
            elif opcodes.LOG0 <= opCode and opCode <= opcodes.LOG4:
                log.Log(self, opCode)

            # system operations (F0-FF)
            elif opcodes.CREATE <= opCode and opCode <= opcodes.SELFBALANCE:
                system.System(self, opCode)
             
            else:
                raise("Invalid Opcodes")
# main
if __name__ == '__main__':
    code =  b"\x40"
    evm = EVM(code)
    evm.execute()
    print(evm.stack)

這就是目前 EVM 虛擬機完整實現,我們接下來要用 python 實現個 proof system 來證明該 EVM 行為的一致。

等鐵人賽 30 天,我會將完整 EVM monorepo 開源,便可使用該系統來 run 一部分的 solidity code 並觀看stack 狀態,接下來剩下一半的賽程會教大家如何將這些指令用 zk 來 proof 該行為是正確的,會比較偏理論一點,也會帶 code 來證明。


上一篇
虛擬境界 15:系統指令合約呼叫及回傳
下一篇
虛擬境界17:EVM to ZKRollup
系列文
以 Python 進入以太坊虛擬機 (EVM) 的幻想境界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言