iT邦幫忙

2022 iThome 鐵人賽

DAY 25
1
Web 3

Smart Contract Development Breakdown系列 第 25

Day 25 - EVM(Ethereum Virtual Machine) & Memory Pool

  • 分享至 

  • xImage
  •  

EVM(Ethereum Virtual Machine) & Memory Pool

Synchronization Link Tree


Intro.

今天 EVM 的篇幅可能會蠻長的,不過有一部份的內容我已經在 Assembly 和 Optimal Gas Comsumption 的部分提過,大家可以先回去複習這兩篇文章然後回來深入 EVM!

EVM 作為一個處理智能合約編譯之後 Bytecode 的虛擬機,藉由不同的 Opcodes 可以達到圖靈完備性,平常我們在呼叫合約函式時真正去做運算和處理狀態更新的就是 EVM。

From Ledger to State

與比特幣系統最大的不同,以太坊從分散式帳本昇華成分散式狀態機,藉由儲存「狀態」與交易紀錄來讓單純的支付系統變成能夠運行智能合約的圖靈完備網路。而以太坊的 block header 跟比特幣的單純 tx merkle root 不同,以 stateRoot、txRoot 以及 receiptsRoot 組成,詳細可見 EIP-2718: Typed Transaction Envelope 以及 Ethereum Merkle Patricia Trie Explained

以下圖片皆來自於:ETHEREUM VIRTUAL MACHINE (EVM)

由之前的圖我們可以知道 EVM 中主要有三個重點部分:Volatile(Machine State: Stack, Memory, Available Gas)、Global Variables(Storage: BLOCK, MESSAGE, TX)、Persistent(Virtual ROM: Program Code)。其中:

  • Memory 擁有 2^256 個 slot,且每個 word 都是 1 byte 的長度,為 byte addressed linear memory。
  • Stack 中 EVM 使用了 256-bit register stck,stack 部分只能握有 1024 個 256-bit(為了更好的使用 Keccak-256 hashes) 的 items。 EVM 不會把任何值存在 stack 之中,只會在需要的時候把他們從 memory push 到 stack 裡做暫存與使用。
  • Storage 為 key-value 的 mapping,存有這樣一組組的 256 bit-256 bit pairs。

在執行交易的時候,EVM 會:

  1. 調取轉帳數值、交易發起人與對象
  2. 分析合約 bytecode 或交易 object
  3. 計算 Gas 的消耗(手續費)
  4. 確保發出轉賬(發起執行函式者)的地址有足夠的 Gas Fee
  5. 執行合約(執行 bytecode 對應的 opcode)
  6. 實現轉帳到對應的地址或者說執行函式動作與狀態更新

那執行交易有分成三種:單純支付轉帳、創建合約、呼叫合約函式,只有後兩者會讓 EVM 運作,更深入一點來講,當你的 transaction 物件中的 data 有帶東西的時候,才會啟動 EVM 去運算。

From Opcodes to ByteCode

Source: The Ethereum Virtual Machine — How does it work?

這部分我直接取上述的 Source 來作為範例,每一個 opcodes 都會被 encoded 成一個 bytecode(例如 STOP0x00),這個 bytecode 就是我們把一個合約進行編譯之後會產生的一個產物(另外一個則是 ABI)。文中舉的例子為 0x6001600101 這組 bytecode,在執行時 bytecode 會根據其 bytes 長度切開處理(1 byte 等於 2 hexadecimal characters)。

  1. 首先我們可以看見 0x60 這個 bytecode,意思是 PUSH1,也就是將這個 1 byte 長度的 data push 到 stack。
  2. 0x60 之後出現的 0x01 是屬於這個 data 的 value。
  3. 接下來依然是 0x60 也就是 PUSH1 以及他的 value 0x01
  4. 最後一個 bytecode 則為 0x01ADD 這個 opcodes。則會將 stack 中的兩個 item(value 皆為 0x01)拿出來相加並且 push 回 stack。
  5. 最後 stack 中只有一個 item,其值為 0x02

About EVM

Features

Determinism

  • 為了讓成千上萬的使用者都確保每一筆交易跟程式碼運行結果都一樣,EVM 上的運算必須有「確定性」,也就是說執行同一個 input 和同一段程式碼幾次,output 都必須一樣。

Isolated

  • EVM 的其中一個特性便是「獨立」,和其他虛擬機一樣,EVM 也不會影響到任何他架設之於的作業系統,此外 Smart Contract 在進行計算時的 EVM 也不會影響到底層 protocol 與外界,要真正把整個區塊鏈的狀態改變需要等到 EVM 運作完畢打出一筆交易並且被打包。測試時不會占用到主鏈資源,也不受其他區塊鏈或網路的影響。

Terminable

  • EVM 的運算必須是可終止的,為了避免某一個呼叫智能合約的單點錯誤導致整個合約卡住,如果今天超出時間或惡意攻擊發生時,EVM 必須有能力判斷現在需要停下來並終止行為。在 Ethereum 中做這件事的就是「Gas Limit」。

Data Allocations

以太坊中有四種記憶體結構,分別為 calldata, stack, memory 和 storage(由最便宜到最貴):

  • Calldata :external function 中的 reference types 才能使用(例如 array, string),calldata 的參數是唯讀的。
  • Stack : 在 method 中定義的 value types 才能使用。
  • Memory : memory 的變數屬於一種揮發性記憶體,也就是說在 EVM 運算結束時這個變數記憶體就會被刪掉,如果確保只會在 function 使用或者想要暫時宣告一個變數,就可以使用 memory
  • Storage : 會永遠存在鏈上的記憶體配置。

EVM-compatible

EVM 就像是一個程式一樣跑在各種各樣不同的設備上,其中有一個標準化的 Protocol 被稱為 Geth(GO-Ethereum),也有其他不同的語言實作版本。EVM 負責執行所有的 bytecode(轉為 opcodes),只要是 EVM 能夠處理的 bytecode 並在其上運作的鏈便是 EVM-compatible blockchain。

  • EVM Compatible:
    • L1: Binance Smart Chain, Cardano, Tron, Avalanche, Fantom Opera
    • Side Chain: Polygon(Matic), xDAI, Gnosis
    • L2: Optimism, Arbitrum, zkSync2.0
  • non-EVM Compatible:
    • L1: Solana(Rust), Diem(Move), Polkadot
    • L2: Starknet(Cairo), Aztec

舉例來說在 Ethereum 中使用 Solidity 撰寫的程式碼也能夠在其他 EVM-compatible blockchain 使用,這也是為什麼在 L2 開發時於 OP-Rollups 會比 ZK-Rollups 舒適一點(ZK-Rollups 也有 EVM-Compatible 的 Solutions,例如 zkSync)。


Closing

Reference

Opcodes

Data Allocations


最後歡迎大家拍打餵食大學生0x2b83c71A59b926137D3E1f37EF20394d0495d72d


上一篇
Day 24 - Wallet Protocols
下一篇
Day 26 - Contract Vulnerability & Dev. Tool
系列文
Smart Contract Development Breakdown30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言