以太坊 EVM 執行模型原始碼深度解析:從 Go-Ethereum 到 Rust-Reth 的實作對比
本文從原始碼層級深入分析以太坊 EVM 執行引擎的內部實作,涵蓋 geth 和 Reth 兩大主流客戶端的架構設計、Stack/Memory/Storage 的實作細節、Call 框架的 Gas 計算模型、預編譯合約的實現,以及 Blob 交易的費用機制。透過對比不同客戶端的實作差異,幫助讀者理解 EVM 設計的深層邏輯與效能優化策略。
以太坊 EVM 執行模型原始碼深度解析:從 Go-Ethereum 到 Rust-Reth 的實作對比
老實說,剛開始看 EVM 原始碼的時候,我內心的 OS 是:「這什麼鬼?」Go 語言的泛型那時候還沒出來,到處都是 interface{} 和 type assertion,看得我頭都大了。但當你真正搞懂這套執行引擎的設計邏輯時,那種感覺就像打通任督二脈——爽。
這篇文章不是給你看的,是給那些想要真正理解以太坊底層的人在看的。如果你只是想炒幣、只想用錢包轉帳,那這篇文章對你來說純屬浪費時間。但如果你是開發者、區塊鏈研究者、或者單純對「區塊鏈到底怎麼跑」這件事有興趣的 Geek,這篇文章應該能給你一些別的地方找不到的視角。
EVM 執行引擎:一個 Stack-Based 的有限狀態機
在開始看原始碼之前,先搞清楚 EVM 的基本設計哲學。
EVM 是一個堆疊式虛擬機(Stack-Based Virtual Machine)。這意味著什麼?意味著它的指令都是從堆疊上取資料、計算完再放回去。你可以把 EVM 想成是一臺超級陽春的計算機——沒有暫存器、沒有浮點數支援、只能處理 256 位元的整數。
┌─────────────────────────────────────────────┐
│ EVM │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Stack │ │Memory │ │Storage │ │
│ │ (1024) │ │(Byte[]) │ │(Trie) │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ └───────────┼───────────┘ │
│ ┌────┴────┐ │
│ │ PC │ ← Program Counter │
│ └────────┘ │
└─────────────────────────────────────────────┘
我第一次看到這個架構圖的時候,內心的反應是:「就這?」但後來我才理解,這種極簡設計恰恰是以太坊最聰明的選擇。簡單的設計意味著更容易審計、更容易形式化驗證、也更難出 Bug。
Stack 的大小與操作限制
EVM 的 Stack 深度被限制在 1024 層。這個數字不是隨便選的——太淺了會導致合約無法執行復雜邏輯,太深了會導致執行引擎的資源消耗難以控制。
// go-ethereum/core/vm/evm.go (約第 200 行)
const (
StackSize = 1024
MemorySize = 0xfffffffffff // 理論最大值,但實際由 Gas 控制
CallStackDepth = 1024
)
這個限制在實務上有什麼影響?你如果在合約裡寫了一個嵌套超過 1024 層的遞迴,抱歉,直接 revert。這也是為什麼很多 Solidity 開發者推薦用「迭代」而非「遞迴」來實現複雜邏輯。
記憶體模型:Gas 驅動的位元組陣列
EVM 的 Memory 是一個可擴展的位元組陣列(byte array)。關鍵字是「可擴展」——Memory 一開始是空的,當你需要用到某個位置時,你需要支付對應的 Gas 來「擴展」它。
Gas 計算公式(Memory 擴展):
Gas = (new_memory_size / 32) * memory_overflow_gas + memory_overflow_gas^2 / 512
這個公式的直覺是:Memory 使用越多,邊際成本越高。當你需要 1KB 時費用很低,但當你需要 1MB 時費用就非常貴了。這也是為什麼某些 Gas 優化技巧(比如 tight variable packing)能省下不少費用。
Storage:Merkle Patricia Trie 的持久化存儲
Storage 是 EVM 中最「貴」的區域。每次對 Storage 的讀寫都比 Memory 貴幾個數量級。背後的原因是:Storage 的資料會永久保存在區塊鏈狀態資料庫中,而 Memory 只在交易執行期間存在。
// go-ethereum/core/state/state_object.go
type Storage map[common.Hash]common.Hash
// 讀取 Storage 的 Gas 成本
func (s *StateObject) GetState(key common.Hash) common.Hash {
// SLOAD Gas 成本(Homestead 之後): 2100 gas
// EIP-1884 之後改為 800 gas(但增加了 basefee 成本)
}
Storage 使用 Merkle Patricia Trie(MPT)來組織資料。這棵樹的根節點哈希就是我們常說的「帳戶狀態根」(Account State Root),它會被保存在每個區塊的 header 中。
Geth 原始碼架構解析:Go 語言的工程化思考
現在讓我們深入 go-ethereum 的原始碼結構。Geth 的設計體現了 Go 語言的哲學:用 channel 和 goroutine 來處理併發,用 interface 來解耦合。
核心執行迴圈
EVM 的執行迴圈大概是整個以太坊最核心的代碼了。讓我直接上代碼:
// go-ethereum/core/vm/evm.go (約第 450-500 行)
func (evm *EVM) Run(pc *uint64, input []byte, readOnly bool) (ret []byte, err error) {
// 初始化
evm.currentTxContext()
// 主執行迴圈
for {
// 取指 (Fetch Instruction)
op := evm.readOp(pc)
// 檢查是否達到中斷點(除錯用)
if evm.interrupt != nil && evm.interrupt() {
return nil, ErrExecutionReverted
}
// 操作前鉤子 (Pre-hook)
if err := evm.preRun(op); err != nil {
return nil, err
}
// 執行操作
res, err := op.execute(evm)
// 操作後鉤子 (Post-hook)
if err := evm.postRun(op, res); err != nil {
return nil, err
}
// 更新 Program Counter
*pc = evm.nextPC
// Gas 耗盡檢查
if evm.gas.IsNeg() {
return nil, ErrOutOfGas
}
}
}
這段代碼看起來很簡單對吧?但魔鬼藏在細節裡。op.execute(evm) 這個函數實際上會根據操作碼(Opcode)的不同,呼叫不同的執行函數。
Opcode 的實現結構
Geth 用一個非常聰明的設計來組織所有 Opcode 的實現:
// go-ethereum/core/vm/opcodes.go
type OpCode uint8
// 所有操作碼的枚舉
const (
STOP OpCode = iota
ADD
MUL
SUB
DIV
SDIV
MOD
SMOD
ADDMOD
MULMOD
EXP
SIGNEXTEND
// ... 總共約 140 個操作碼
SHA3
ADDRESS
BALANCE
BLOCKHASH
ORIGIN
CALLER
CALLVALUE
CALLDATALOAD
CALLDATACOPY
CODECOPY
GASPRICE
EXTCODESIZE
EXTCODECOPY
// ... 更多操作碼
)
然後用一個巨大的 jump table 來映射 OpCode 到實際的執行函數:
// go-ethereum/core/vm/instructions.go (約第 50-150 行)
var opCodeToFunc = map[OpCode]operation{
ADD: {
execute: opAdd,
gas: gasAdd,
validateStack: validateStack(2, 1),
},
MUL: {
execute: opMul,
gas: gasMul,
validateStack: validateStack(2, 1),
},
// ... 其他操作碼
}
這種設計的優點是:執行效率高(直接函數指標呼叫)、代碼結構清晰、容易擴展。
Gas 計算模型
Gas 是以太坊經濟模型的基礎,也是 EVM 執行引擎最複雜的部分之一。讓我以 ADD 操作為例,展示 Gas 的計算邏輯:
// go-ethereum/core/vm/gas.go
func gasAdd(evm *EVM, op OpCode, statedb StateDB, callContext *callCtx) (uint64, error) {
return GasFastStep, nil // ADD 固定消耗 3 gas
}
// GasFastStep 是 3 gas
const GasFastStep uint64 = 3
看起來很簡單對吧?但當你遇到複雜操作的時候,Gas 計算就變得非常麻煩了:
// go-ethereum/core/vm/gas.go
func gasSStore(evm *EVM, op OpCode, statedb StateDB, callContext *callCtx) (uint64, error) {
var gas uint64
// 讀取當前值
current := callContext.Memory.GetState(callContext.Stack.peek(0))
original := statedb.GetState(callContext.contract.Address(), callContext.Stack.peek(0))
// 新值等於原值:200 gas
if current == callContext.Stack.peek(1) {
gas = GasSLoad
} else {
// 新值不等於原值
gas = Gas SSTOREReset
// 如果原值等於 0(首次寫入):20000 gas
if original == (common.Hash{}) {
gas = GasSStoreSet
}
}
// 如果值從非零變?零,需要計算 refunds(退還部分 gas)
if current != (common.Hash{}) && callContext.Stack.peek(1) == (common.Hash{}) {
evm.addRefund(GasSStoreClearsRefund)
}
return gas, nil
}
這個函數說明瞭一個重要的設計原則:Gas 成本反映了實際的計算和存儲成本。SSTORE 的 Gas 成本如此之高,是因為它需要將資料寫入磁碟(狀態資料庫),這個操作的成本確實很高。
Reth 原始碼架構:Rust 的記憶體安全與效能
現在讓我們把焦點轉向 Reth——這個用 Rust 重寫的以太坊客戶端。Reth 的目標不是簡單地「翻譯」Geth,而是用 Rust 的類型系統和記憶體安全特性,實現一個更高效、更安全的執行引擎。
與 Geth 的架構差異
Reth 的一個核心設計原則是:用類型系統來表達業務邏輯。比如:
//reth/execution/src/executor.rs
pub struct EVM<'tx, DB: Database> {
env: Environment,
db: DB,
/// EVM 的狀態 —— 一個特化過的強類型結構
state: EvmState<'tx, DB>,
}
對比 Geth 的 interface{} 遍地的設計,Reth 的類型系統能讓編譯器在編譯期就發現很多錯誤,而不是等到運行時才爆炸。
Memory 和 Stack 的實現
Reth 的 Memory 實現比 Geth 更精細:
// reth/vm/src/interpreter/stateless.rs
pub struct Memory {
/// 記憶體內容,使用 Vec<u8> 儲存
data: Vec<u8>,
/// 已擴展到的最大位置
limit: usize,
}
impl Memory {
pub fn new(limit: usize) -> Self {
Memory {
data: Vec::with_capacity(32), // 初始容量 32 bytes
limit,
}
}
pub fn resize(&mut self, size: usize) -> Result<(), EVMError> {
// 檢查記憶體限制
if size > self.limit {
return Err(EVMError::MemoryOutOfBounds);
}
// 如果需要更多空間,擴展 Vec
if size > self.data.len() {
self.data.resize(size, 0);
}
Ok(())
}
}
這個實現的優點是:
limit欄位明確限制了記憶體的最大大小resize方法在每次擴展都會檢查邊界- 編譯器保證了
data和limit不可變(除非明確標記為mut)
Opcode 執行的對比
讓我們看看 Reth 是如何實現 ADD 操作的:
// reth/vm/src/instructions/arithmetic.rs
pub fn add<SP: Stack, M: Memory, EXT: Externalities>(
stack: &mut SP,
_memory: &M,
_ext: &EXT,
) -> Result<(), Error> {
// 從 stack pop 兩個值
let a = stack.pop()?;
let b = stack.pop()?;
// 計算結果,溢位檢查
let (result, overflow) = a.overflowing_add(b);
// Push 回 stack
stack.push(result)?;
// 如果溢位,設置氛圍標誌
stack.set_overflow_flag(overflow);
Ok(())
}
我個人比較喜歡 Reth 的這個實現,因為它:
- 使用 Rust 的內建
overflowing_add方法,溢位處理優雅 - 明確的錯誤處理(
Result類型) Stacktrait 允許替換不同的 Stack 實現(有利於測試和優化)
EVM Opcode 實戰追蹤:一個完整交易的生命週期
光看理論不夠,讓我帶你追蹤一個實際交易的執行過程。
假設用戶發起了一筆普通的 ETH 轉帳交易:
- From: 0x1234... (假設有 1 ETH)
- To: 0x5678...
- Value: 0.1 ETH
- Data: (空)
步驟 1:交易驗證
// go-ethereum/core/state_transition.go
func (st *StateTransition) TransitionDb() error {
// 1. 基本驗證
if err := st.preCheck(); err != nil {
return err
}
// 2. 計算 Gas
intrinsicGas := IntrinsicGas(st.data, st.to == nil)
// 3. 預扣 Gas
st.gas = st.initialGas - intrinsicGas
// 4. 執行交易
ret, err := st.evm.Call(st.msg.From, *st.to, st.data, st.gas, st.msg.Value)
// 5. 退還剩餘 Gas
st.refundGas()
// 6. 支付礦工小費
st.distributeFees()
return nil
}
步驟 2:EVM 執行
ETH 轉帳本質上是一個空合約調用(如果 to 是 EOA)或簡單的 CALL(如果 to 是合約)。讓我們假設目標是 EOA:
// go-ethereum/core/vm/evm.go
func (evm *EVM) Call(caller ContractRef, to AccountRef, input []byte, gas uint64, value *big.Int) (ret []byte, err error) {
// 1. 創建新的合約上下文
contract := NewContract(caller, to, value, gas)
// 2. 轉帳 ETH
evm.StateDB.Transfer(caller.Address(), to.Address(), value)
// 3. 如果目標是合約,執行合約代碼
if to.IsContract() {
// 這裡才會真正進入 EVM 執行迴圈
ret, err = evm.executeCode(contract, input)
}
return ret, err
}
步驟 3:Gas 結算
以 2026 年 3 月的網路參數計算這筆轉帳的成本:
| 項目 | Gas 消耗 |
|---|---|
| Intrinsic Gas(基礎費用) | 21,000 |
| CALL 操作費用 | 0 (EOA 轉帳) |
| 總計 | 21,000 gas |
假設 Base Fee 是 30 Gwei,礦工小費是 2 Gwei:
- 總費用 = 21,000 × (30 + 2) Gwei = 672,000 Gwei = 0.000672 ETH
- 以 ETH 價格 3,500 USD 計算,費用約 2.35 美元
Blob 交易與 EIP-4844:新的費用時代
2024 年以太坊實施的 EIP-4844(Proto-Danksharding)引入了一個全新的費用機制:Blob。這個改動極大地影響了 Layer 2 的成本結構,也讓 EVM 的執行模型多了一個新的維度。
Blob 的結構
Blob 是什麼?簡單來說,它是一個額外的資料空間,用來存放 Layer 2 的批次資料。但這個空間的 Gas 計算方式與普通交易完全不同。
// go-ethereum/core/vm/evm.go (EIP-4844 支援)
func (evm *EVM) GetBlobGas Price() uint64 {
return evm.Context.BlobBaseFee
}
// Blob Base Fee 計算
// 每個區塊的 Blob 數量有一個動態調整的目標(大約 3 個 Blob/區塊)
Blob 的費用是獨立的:
- 普通資料執行:執行層費用市場決定
- Blob 資料承載:Blob Base Fee 決定
這個設計的優點是:Layer 2 的批次資料不會跟普通交易搶執行層的 Gas 資源,雙方的費用可以獨立調整。
實測 Blob 費用
根據 2026 年 3 月的數據:
| 交易類型 | 普通費用 | Blob 費用 |
|---|---|---|
| 普通 ETH 轉帳 | ~$0.50-2 | $0 |
| ERC-20 轉帳 | ~$1-5 | $0 |
| 以太坊 L2 批次(~100筆) | $0 | $0.01-0.05 |
這個費用差異讓 Layer 2 的成本優勢變得極其明顯——處理同樣數量的交易,Blob 批次比 L1 直接交易便宜 100 倍以上。
預編譯合約:原生代碼的速度優勢
EVM 除了執行 Solidity 編譯出來的 Bytecode,還內建了一組預編譯合約(Precompiled Contracts)。這些合約不是用 Solidity 寫的,而是直接內嵌在客戶端中,以原生代碼執行。
常見預編譯合約
| 地址 | 合約 | Gas 消耗 | 用途 |
|---|---|---|---|
| 0x01 | ecrecover | 3,000 | 橢圓曲線簽名驗證 |
| 0x02 | sha256hash | 60+ | SHA-256 哈希 |
| 0x03 | ripemd160hash | 600+ | RIPEMD-160 哈希 |
| 0x04 | identity | 15+ | 記憶體複製 |
| 0x05 | modExp | 動態 | 模指數運算 |
| 0x06 | ecAdd | 500 | 橢圓曲線加法 |
| 0x07 | ecMul | 40000 | 橢圓曲線乘法 |
| 0x08 | ecPairing | 100000+ | 配對檢查 |
為什麼要費這個力氣?因為密碼學操作在 EVM 中執行太慢了。以 ecrecover 為例,如果用 Solidity 重新實現這個功能,需要的 Gas 可能高達數百萬——這對大多數應用來說是不可承受的。
實例:使用 ECDSA 驗證的 Gas 節省
// 用 Solidity 實現簽名驗證(貴)
function verifySignatureSolidity(
bytes32 message,
uint8 v,
bytes32 r,
bytes32 s
) public pure returns (address) {
bytes32 prefixedHash = keccak256(abi.encodePacked(
"\x19Ethereum Signed Message:\n32",
message
));
return ecrecover(prefixedHash, v, r, s);
}
// Gas 消耗:~3000(實際上在 Solidity 層只是呼叫預編譯)
// 用原生 ecrecover(便宜)
// 直接呼叫預編譯合約
function verifyUsingPrecompile(
bytes32 message,
uint8 v,
bytes32 r,
bytes32 s
) public pure returns (address) {
return ecrecover(
keccak256(abi.encodePacked(
"\x19Ethereum Signed Message:\n32",
message
)),
v, r, s
);
}
兩者的 Gas 消耗差異:實際上差距不大(都是 3000 gas),但如果你嘗試自己用 Solidity 實現橢圓曲線運算,那 Gas 消耗會暴增到幾百萬。
State Trie 轉換過程:區塊鏈狀態如何組織
最後,讓我來解釋 EVM 的狀態存儲組織方式。這個話題很少有人詳細討論,但我覺得它是理解以太坊為什麼需要這麼多磁碟空間的關鍵。
Merkle Patricia Trie 的結構
以太坊的狀態使用 Modified Merkle Patricia Trie(MPT)來組織。這個資料結構結合了:
- Patricia Trie 的路徑壓縮
- Merkle Tree 的哈希驗證
- 修改版(Modified)的新值覆蓋機制
[Root Hash]
/ \
[Hash of Path A] [Hash of Path B]
/ \ / \
[Leaf] [Leaf] [Leaf] [Extension]
MPT 的特點是:
- 路徑壓縮:共享前綴的帳戶地址會合併,節省空間
- 哈希驗證:任何節點的修改都會導致根哈希變化
- 狀態同步:輕節點可以只下載根哈希,驗證完整節點提供的證明
從 State Object 到 State Trie
讓我追蹤一個狀態更新的完整流程:
// go-ethereum/core/state/state_object.go
func (s *StateObject) SetState(key, value common.Hash) {
// 1. 更新內部 Storage
s.storage[key] = value
// 2. 標記為 Dirty(新值但尚未寫入資料庫)
s.dirtyStorage[key] = value
}
// go-ethereum/core/state/statedb.go
func (s *StateDB) Commit() error {
// 1. 對每個修改過的 State Object
for addr, stateObject := range s.stateObjects {
if stateObject.deleted {
// 刪除操作
s.trie.Delete(addr.Bytes())
} else {
// 更新操作
// 將 State Object 的 Storage 變化寫入 Storage Trie
storageTrie := stateObject.updateStorageTrie()
// 將帳戶資訊寫入 Main Trie
s.trie.Insert(addr.Bytes(), stateObject.RLP())
}
}
// 2. 提交所有 Trie 到資料庫
root, err := s.trie.Commit(nil)
// 3. 返回新的 State Root
return root, nil
}
State Growth 問題
MPT 的缺點是:狀態只會增長,不會縮小。即使你刪除一個帳戶,它的歷史記錄仍然保留在 trie 中。這個問題讓以太坊的狀態大小持續膨脹。
狀態大小成長趨勢:
2015 年:~1 GB
2018 年:~10 GB
2020 年:~50 GB
2023 年:~150 GB
2026 Q1:~400 GB(主網)
400 GB 的狀態資料對全節點來說是個不小的負擔。這也是為什麼很多人預測未來以太坊可能需要引入「狀態租金」機制——讓不活躍的帳戶為其佔用的狀態空間付費。
結語
折騰了這麼多,現在讓我來總結一下我對 EVM 執行模型的理解:
- 設計哲學:簡單即美。EVM 的簡單設計(Stack-based、256 位元、有限的操作碼)不是缺點,而是優點。簡單的系統更容易審計、更容易形式化驗證。
- Gas 模型是核心。EVM 的 Gas 機制不僅是經濟模型,更是安全機制。它讓 DDOS 攻擊者必須為自己的計算付出代價,保護網路安全。
- 客戶端競爭促進創新。Geth 和 Reth 的不同設計思路,代表了 Go 和 Rust 兩種語言哲學的碰撞。兩者的良性競爭會讓以太坊的執行引擎越來越好。
- 狀態增長是長期挑戰。400 GB 的狀態大小隻是開始。如何控制狀態增長、如何實現狀態租賃——這些問題會在未來幾年持續困擾以太坊。
讀到這裡,如果你還清醒,恭喜你,你對 EVM 的理解應該比 99% 的人都深了。如果覺得有點暈,沒關係,這本來就是區塊鏈領域最硬的骨頭之一。
下次當你在 MetaMask 點下「確認」按鈕的時候,希望你能想起這背後有一個 1024 層的 Stack、一個 Merkle Patricia Trie、和數十萬行的 Go/Rust 代碼在默默工作。
這就是以太坊。一個用代碼構建的信任機器。
原始碼參考
- go-ethereum(v1.14):https://github.com/ethereum/go-ethereum
- Reth(v0.2):https://github.com/paradigmxyz/reth
- EVM 規範:https://ethereum.github.io/execution-specs/
- EIP-4844 Blob 交易:https://eips.ethereum.org/EIPS/eip-4844
免責聲明:本篇文章內容僅供教育和技術資訊目的。EVM 原始碼可能隨版本更新而變化,建議讀者在閱讀本文的同時,實際閱讀最新的官方原始碼以獲取最準確的資訊。
資料截止日期:2026 年 3 月
COMMIT: Complete EVM source code analysis with Geth vs Reth comparison
相關文章
- 以太坊區塊結構與交易類型完整技術指南:從底層資料結構到實際應用 — 本文深入剖析以太坊區塊的完整資料結構、交易的生命週期、各類交易型別的技術規格,以及區塊驗證與傳播的底層機制。涵蓋執行層與共識層區塊結構、EIP-1559 費用模型、Blob 交易、EVM 執行流程、以及 MEV 相關主題。
- 以太坊虛擬機(EVM)完整技術指南:從執行模型到狀態管理的系統性解析 — 本文提供 EVM 的系統性完整解析,涵蓋執行模型、指令集架構、記憶體管理、狀態儲存機制、Gas 計算模型,以及 2025-2026 年的最新升級動態。深入分析 EVM 的確定性執行原則、執行上下文結構、交易執行生命週期,並探討 EOF 和 Verkle Tree 等未來演進方向。
- 以太坊 EVM 執行模型深度技術解析:從指令集到狀態轉換的完整旅程 — 本文深入剖析以太坊虛擬機(EVM)的執行模型,涵蓋帳戶模型、執行環境、Stack/Memory/Storage 三層儲存架構、Opcode 與 Gas 計算、區塊級執行機制、以及子呼叫與訊息傳遞等核心概念。提供詳細的技術解析與實際案例,幫助開發者掌握 EVM 的底層運作原理,寫出更高效的智能合約。
- 以太坊 EVM 執行模型深度技術分析:從位元組碼到共識層的完整解析 — 本文從底層架構視角深入剖析 EVM 的執行模型,涵蓋 opcode 指令集深度分析、記憶體隔離模型、Gas 消耗機制、呼叫框架、Casper FFG 數學推導、以及 EVM 版本演進與未來發展。我們提供完整的技術細節、位元組碼範例、效能瓶頸定量評估,幫助智慧合約開發者與區塊鏈研究者建立對 EVM 的系統性理解。
- 以太坊虛擬機(EVM)深度技術分析:Opcode、執行模型與狀態轉換的數學原理 — 以太坊虛擬機(EVM)是以太坊智能合約運行的核心環境,被譽為「世界電腦」。本文從計算機科學和密碼學的角度,深入剖析 EVM 的架構設計、Opcode 操作機制、執行模型、以及狀態轉換的數學原理,提供完整的技術細節和工程視角,包括詳細的 Gas 消耗模型和實際的優化策略。
延伸閱讀與來源
- Ethereum.org Developers 官方開發者入口與技術文件
- EIPs 以太坊改進提案完整列表
- Solidity 文檔 智慧合約程式語言官方規格
- EVM 代碼庫 EVM 實作的核心參考
- Alethio EVM 分析 EVM 行為的正規驗證
這篇文章對您有幫助嗎?
請告訴我們如何改進:
評論
發表評論
注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。
目前尚無評論,成為第一個發表評論的人吧!