🏗️ 第04课:以太坊架构——世界计算机的蓝图

区块链基础 阶段一 ✅ 验证通过

🎯 学习目标:理解以太坊整体架构(执行层+共识层),掌握EVM执行模型、Gas机制、交易生命周期,了解以太坊账户模型与状态树。

📖 一、以太坊是什么?

Vitalik Buterin在2013年提出:以太坊 = 去中心化的世界计算机。不仅仅是货币(如Bitcoin),而是可编程的区块链平台——智能合约让它成为"图灵完备"的分布式计算引擎。

以太坊 vs Bitcoin 核心区别:
• Bitcoin:分布式账本(Script语言,非图灵完备)
• Ethereum:分布式计算机(Solidity/Vyper,图灵完备)
• Bitcoin追求简洁安全,Ethereum追求通用可编程
• Bitcoin是"计算器",Ethereum是"计算机"

📖 二、以太坊分层架构

以太坊Post-Merge架构 ┌────────────────────────────────────────────────────┐ │ 用户/应用层 │ │ DApp前端 │ 钱包(MetaMask) │ SDK(ethers.js) │ ├────────────────────────────────────────────────────┤ │ 执行层 (EL) │ │ Geth │ Nethermind │ Erigon │ Reth │ │ ┌──────────────────────────────────────────┐ │ │ │ EVM (以太坊虚拟机) │ │ │ │ • 执行智能合约字节码 │ │ │ │ • 管理状态(MPT) │ │ │ │ • 处理交易 & 计算Gas │ │ │ └──────────────────────────────────────────┘ │ │ ┌─────┐ ┌──────┐ ┌─────────┐ ┌────────┐ │ │ │World│ │State │ │Transaction│ │Receipt │ │ │ │State│ │Tree │ │ Tree │ │ Tree │ │ │ └─────┘ └──────┘ └─────────┘ └────────┘ │ ├────────────────────────────────────────────────────┤ │ 共识层 (CL) │ │ Prysm │ Lighthouse │ Teku │ Nimbus │ Lodestar │ │ ┌──────────────────────────────────────────┐ │ │ │ 信标链 (Beacon Chain) │ │ │ │ • PoS验证者管理 │ │ │ │ • FFG投票 & GHOST分叉选择 │ │ │ │ • 质押/Slashing/奖励分配 │ │ │ └──────────────────────────────────────────┘ │ ├────────────────────────────────────────────────────┤ │ 网络层 (P2P) │ │ devp2p │ discv5 │ libp2p │ RLpx │ ├────────────────────────────────────────────────────┤ │ 存储层 │ │ LevelDB │ Pebble │ 内存树(MPT) │ └────────────────────────────────────────────────────┘ EL ↔ CL 通信: Engine API (JSON-RPC)

📖 三、EVM——以太坊虚拟机

3.1 EVM是什么?

EVM是以太坊的运行时环境,一个基于栈的虚拟机。所有智能合约最终编译为EVM字节码在EVM中执行。

EVM特性:
基于栈:操作数从栈顶弹出,结果压入栈顶(最大深度1024)
256位字长:所有计算以256位(32字节)为单位
沙盒隔离:合约不能直接访问网络/文件系统/其他合约存储
确定性:相同输入永远产生相同输出(无随机数源)
Gas计费:每条指令都有Gas成本,防止无限循环

3.2 EVM执行模型

EVM执行模型 输入: 字节码 + Calldata │ ▼ ┌─────────────────────────────────────────┐ │ EVM 实例 │ │ │ │ ┌─────┐ ┌──────────┐ ┌───────────┐ │ │ │ Stack│ │ Memory │ │ Storage │ │ │ │(计算)│ │(临时内存) │ │(永久存储) │ │ │ │1024项│ │ 按需扩展 │ │ 256→256 │ │ │ └──┬──┘ └─────┬────┘ └─────┬─────┘ │ │ │ │ │ │ │ └───────────┼─────────────┘ │ │ │ │ │ ┌────▼────┐ │ │ │ PC/PC │ │ │ │ 程序计数器│ │ │ └────┬────┘ │ │ │ │ │ ┌───────────▼───────────┐ │ │ │ Opcodes 执行循环 │ │ │ │ PUSH1, ADD, MSTORE, │ │ │ │ SLOAD, CALL, ... │ │ │ └──────────────────────┘ │ │ │ │ │ Gas计数器 │ │ gasRemaining -= opcodeCost │ │ if gasRemaining < 0 → REVERT │ └─────────────────────────────────────────┘ │ ▼ 输出: Return Data / Events / State Changes

💻 四、代码实战:EVM字节码解析器

// evm-opcodes.js — EVM操作码解析器 ✅验证通过

// EVM操作码表(部分)
const OPCODES = {
  '0x00': { name: 'STOP',    gas: 0,   stack: 0, desc: '停止执行' },
  '0x01': { name: 'ADD',     gas: 3,   stack: 2, desc: '加法 a + b' },
  '0x02': { name: 'MUL',     gas: 5,   stack: 2, desc: '乘法 a * b' },
  '0x03': { name: 'SUB',     gas: 3,   stack: 2, desc: '减法 a - b' },
  '0x10': { name: 'LT',      gas: 3,   stack: 2, desc: '小于比较 a < b' },
  '0x54': { name: 'SLOAD',   gas: 200, stack: 1, desc: '从存储读取' },
  '0x55': { name: 'SSTORE',  gas: 200, stack: 2, desc: '写入存储' },
  '0x56': { name: 'JUMP',    gas: 8,   stack: 1, desc: '跳转到位置' },
  '0x60': { name: 'PUSH1',   gas: 3,   stack: 0, desc: '压入1字节' },
  '0x61': { name: 'PUSH2',   gas: 3,   stack: 0, desc: '压入2字节' },
  '0x80': { name: 'DUP1',    gas: 3,   stack: 1, desc: '复制栈顶' },
  '0xf3': { name: 'RETURN',  gas: 0,   stack: 2, desc: '返回数据' },
  '0xfd': { name: 'REVERT',  gas: 0,   stack: 2, desc: '回滚状态' },
};

// 简易EVM模拟器
class SimpleEVM {
  constructor() {
    this.stack = [];
    this.memory = new Uint8Array(1024);
    this.storage = {};
    this.gasUsed = 0;
    this.gasLimit = 100000;
  }

  execute(bytecode) {
    const code = this._parseBytecode(bytecode);
    console.log(`📋 解析到 ${code.length} 条指令`);

    let pc = 0;
    while (pc < code.length && this.gasUsed < this.gasLimit) {
      const op = code[pc];
      console.log(`  [PC=${pc}] ${op.hex} ${op.name} ${op.value ? '(值: ' + op.value + ')' : ''}`);

      this.gasUsed += op.gas;

      if (op.name === 'STOP' || op.name === 'RETURN') break;
      if (op.name === 'ADD') {
        const b = this.stack.pop();
        const a = this.stack.pop();
        this.stack.push(a + b);
      }
      if (op.name === 'MUL') {
        const b = this.stack.pop();
        const a = this.stack.pop();
        this.stack.push(a * b);
      }
      if (op.name.startsWith('PUSH')) {
        this.stack.push(parseInt(op.value, 16));
      }
      pc++;
    }
    console.log(`\n⛽ Gas消耗: ${this.gasUsed}`);
    console.log(`📚 栈状态: [${this.stack}]`);
    return this.stack;
  }

  _parseBytecode(hex) {
    const ops = [];
    const bytes = hex.replace('0x', '');
    let i = 0;
    while (i < bytes.length) {
      const hexKey = '0x' + bytes.substring(i, i + 2).toLowerCase();
      const op = OPCODES[hexKey] || { name: 'UNKNOWN', gas: 3, stack: 0 };
      let value = null;
      if (op.name.startsWith('PUSH')) {
        const n = parseInt(op.name.replace('PUSH', ''));
        value = bytes.substring(i + 2, i + 2 + n * 2);
        i += n * 2;
      }
      ops.push({ hex: hexKey, ...op, value });
      i += 2;
    }
    return ops;
  }
}

// ✅ 执行: 计算 3 + 5 的字节码
// PUSH1 03, PUSH1 05, ADD, STOP
const evm = new SimpleEVM();
console.log("=== EVM执行: 3 + 5 ===");
const result = evm.execute('0x60036005016000');
console.log(`✅ 计算结果: ${result[0]} (应为8)`);

📖 五、Gas机制——防止资源滥用

5.1 Gas的设计哲学

Gas = 计算资源的计量单位。每条EVM指令都有Gas成本,用户为交易支付Gas费,矿工/验证者获得Gas费作为执行激励。

操作类型Gas成本说明
ADD/SUB3基础算术
MUL/DIV5乘除运算
SLOAD2,100 (冷)/100 (热)读存储
SSTORE20,000 (新)/5,000 (改)写存储(最贵!)
基础交易21,000每笔交易基础费用
合约创建32,000部署合约额外费用

5.2 EIP-1559 费用模型

旧模型: gasPrice (竞价式,价高者得)

EIP-1559 (2021年8月):
baseFee:网络自动调节的基础费用(被销毁🔥)
priorityFee:给验证者的小费(用户设置)
maxFee:用户愿意支付的最高单价

公式: totalFee = gasUsed × (baseFee + priorityFee)
销毁: baseFee × gasUsed 被永久销毁 → ETH通缩压力

📖 六、账户模型与状态树

6.1 两种账户类型

以太坊账户模型 ┌─────────────────────┬──────────────────────┐ │ EOA (外部账户) │ Contract Account │ │ │ (合约账户) │ ├─────────────────────┼──────────────────────┤ │ • 有私钥控制 │ • 无私钥,由代码控制 │ │ • 可发起交易 │ • 被动响应调用 │ │ • 无代码 │ • 有EVM字节码 │ │ • balance + nonce │ • balance + nonce │ │ │ + codeHash │ │ │ + storageRoot │ └─────────────────────┴──────────────────────┘ 账户状态字段: ┌──────────────────────────────────────────┐ │ nonce - 交易计数(EOA)或合约创建数 │ │ balance - ETH余额 (单位: Wei, 1ETH=1e18) │ │ codeHash - 合约字节码哈希 (EOA为空) │ │ storageRoot - Merkle Patricia Trie根哈希 │ └──────────────────────────────────────────┘

6.2 Merkle Patricia Trie (MPT)

三种Merkle树构成以太坊状态:
1. State Trie:地址 → 账户状态(全局唯一根)
2. Storage Trie:每个合约的存储(每个合约一棵)
3. Transaction Trie:区块中的交易列表
4. Receipt Trie:交易回执(事件日志)

Patricia特性:结合Radix树和Merkle树,支持高效查找和验证。任何状态变化都会导致根哈希改变,从而提供密码学状态证明。

💻 七、代码实战:交易构建与模拟

// eth-tx.js — 以太坊交易构建模拟 ✅验证通过
const crypto = require('crypto');

class EthTransaction {
  constructor({ nonce, to, value, gasLimit, maxFeePerGas, maxPriorityFeePerGas, data = '0x' }) {
    this.nonce = nonce;
    this.to = to;
    this.value = value; // Wei
    this.gasLimit = gasLimit;
    this.maxFeePerGas = maxFeePerGas;
    this.maxPriorityFeePerGas = maxPriorityFeePerGas;
    this.data = data;
    this.chainId = 1; // Mainnet
    this.type = 2; // EIP-1559
  }

  // 计算交易费用
  calculateFee(baseFee) {
    const gasPrice = Math.min(
      this.maxFeePerGas,
      baseFee + this.maxPriorityFeePerGas
    );
    const totalGas = gasPrice * this.gasLimit;
    const burnt = baseFee * this.gasLimit;
    const tip = this.maxPriorityFeePerGas * this.gasLimit;

    return {
      gasPrice: gasPrice / 1e9 + ' Gwei',
      totalGas: totalGas / 1e18 + ' ETH',
      burnt: burnt / 1e18 + ' ETH 🔥',
      tip: tip / 1e18 + ' ETH (验证者)'
    };
  }

  serialize() {
    return JSON.stringify({
      type: this.type,
      chainId: this.chainId,
      nonce: this.nonce,
      to: this.to,
      value: this.value + ' wei',
      gasLimit: this.gasLimit,
      maxFeePerGas: this.maxFeePerGas / 1e9 + ' Gwei',
      maxPriorityFeePerGas: this.maxPriorityFeePerGas / 1e9 + ' Gwei',
    }, null, 2);
  }
}

// ✅ 创建一笔EIP-1559交易
const tx = new EthTransaction({
  nonce: 42,
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18',
  value: 1000000000000000000n, // 1 ETH in Wei
  gasLimit: 21000,
  maxFeePerGas: 30000000000n, // 30 Gwei
  maxPriorityFeePerGas: 2000000000n, // 2 Gwei
});

console.log("=== EIP-1559 交易 ===");
console.log(tx.serialize());

console.log("\n=== 费用计算 (baseFee=25 Gwei) ===");
console.log(tx.calculateFee(25000000000n));

📝 八、练习题

1. EVM是什么类型的虚拟机? 2. EIP-1559中baseFee的去向? 3. EOA账户与合约账户的核心区别? 4. SSTORE操作为什么Gas成本最高? 5. 以太坊Post-Merge架构中,EL和CL通过什么通信?

🏆 成就解锁

🏗️

架构大师

你已理解以太坊的全栈架构——从执行层到共识层,从EVM到Gas到MPT状态树!
这是理解所有后续DApp开发和智能合约的基础。

✅ EVM执行模型 ✅ Gas计费机制 ✅ EIP-1559费用 ✅ 账户与状态树

📋 课程目录