Skip to content

필사 모드: 区块链 & Web3 工程师指南 — 从智能合约、DeFi、ZK 证明到 AI+区块链

中文
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

1. 区块链基础:哈希、默克尔树与共识

1.1 哈希函数与不可篡改性

区块链的核心是密码学哈希函数。每个区块都包含前一个区块的哈希,从而形成链条。

import hashlib
import json

def compute_block_hash(index, previous_hash, timestamp, data, nonce):
    block_content = json.dumps({
        "index": index,
        "previous_hash": previous_hash,
        "timestamp": timestamp,
        "data": data,
        "nonce": nonce
    }, sort_keys=True)
    return hashlib.sha256(block_content.encode()).hexdigest()

# SHA-256 的特性:确定性、单向性、雪崩效应
hash1 = hashlib.sha256(b"hello").hexdigest()
hash2 = hashlib.sha256(b"hellO").hexdigest()
# 仅一个字符之差就会产生完全不同的哈希
print(hash1[:16], "vs", hash2[:16])

1.2 默克尔树(Merkle Tree)

默克尔树能以 O(log n) 的证明规模验证大规模数据集的完整性。比特币和以太坊都用它来验证交易。

def build_merkle_tree(leaves):
    if not leaves:
        return None
    layer = [hashlib.sha256(leaf.encode()).hexdigest() for leaf in leaves]
    while len(layer) > 1:
        if len(layer) % 2 != 0:
            layer.append(layer[-1])  # 若为奇数,复制最后一个
        layer = [
            hashlib.sha256((layer[i] + layer[i+1]).encode()).hexdigest()
            for i in range(0, len(layer), 2)
        ]
    return layer[0]  # Merkle Root

txs = ["tx_alice_to_bob", "tx_carol_to_dave", "tx_eve_to_frank", "tx_grace_to_heidi"]
root = build_merkle_tree(txs)
print("Merkle Root:", root)

1.3 共识算法对比

算法能耗吞吐量去中心化程度代表链
PoW非常高~7 TPSBitcoin
PoS~数千 TPSEthereum
DPoS~数万 TPSEOS, TRON
PBFT~数千 TPSHyperledger

PoS 惩罚(Slashing):在以太坊 PoS 中,若验证者双重签名(double voting),其质押 ETH 的一部分会被销毁。这一经济惩罚正是安全性的核心。


2. 以太坊内部机制:EVM、Gas 与状态树

2.1 EVM(以太坊虚拟机)

EVM 是一个 256 位基于栈的虚拟机,是所有以太坊节点上都以相同方式执行的确定性环境。

EVM 栈运算示例(PUSH1ADDMUL):
PUSH1 0x03   → 栈: [3]
PUSH1 0x04   → 栈: [3, 4]
ADD          → 栈: [7]
PUSH1 0x02   → 栈: [7, 2]
MUL          → 栈: [14]

主要的 EVM 存储区域:

  • Stack(栈):最多 1024 个元素,用于临时运算
  • Memory(内存):字节数组,在函数执行期间临时使用
  • Storage(存储):键值型永久存储(成本最高,SSTORE = 20,000 gas)
  • Calldata(调用数据):外部函数调用时传入的数据

2.2 EIP-1559 Gas 机制

在 EIP-1559 之前,Gas 采用竞价方式分配。此后基础费用(base fee)会被销毁,只有小费(priority fee)会转给验证者。

# EIP-1559 交易费用计算
base_fee = 15  # gwei(根据网络状态自动调整)
priority_fee = 2  # gwei(小费)
max_fee = 20  # gwei(允许的最大值)

actual_fee = min(base_fee + priority_fee, max_fee)
gas_used = 21000  # 简单的 ETH 转账
total_cost_gwei = actual_fee * gas_used
total_cost_eth = total_cost_gwei / 1e9
print(f"交易手续费: {total_cost_eth:.6f} ETH")
# base_fee 被销毁 → ETH 通缩效应
burned = base_fee * gas_used / 1e9
print(f"已销毁 ETH: {burned:.6f} ETH")

2.3 The Merge:从 PoW 转向 PoS

2022 年 9 月 15 日,以太坊通过 The Merge 将能耗降低了约 99.95%。

  • 信标链(Beacon Chain):自 2020 年 12 月起并行运行的 PoS 链
  • 执行层:负责既有的 EVM 状态与交易处理
  • 共识层:负责验证者管理、认证(attestation)与最终性(finality)
  • 最低质押量:每个验证者 32 ETH

3. 智能合约:Solidity 模式与安全

3.1 带 ReentrancyGuard 的 ERC-20 代币

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract SecureToken is ERC20, ReentrancyGuard, Ownable {
    uint256 public constant MAX_SUPPLY = 1_000_000 * 10**18;
    mapping(address => uint256) public lockTime;

    event TokensLocked(address indexed user, uint256 amount, uint256 unlockTime);
    event TokensUnlocked(address indexed user, uint256 amount);

    constructor() ERC20("SecureToken", "STKN") Ownable(msg.sender) {
        _mint(msg.sender, 100_000 * 10**18);
    }

    // 应用 Checks-Effects-Interactions 模式
    function lockAndRelease(uint256 amount, uint256 duration)
        external
        nonReentrant  // 防重入
    {
        // 1. Checks: 校验条件
        require(amount > 0, "Amount must be positive");
        require(balanceOf(msg.sender) >= amount, "Insufficient balance");
        require(duration >= 1 days && duration <= 365 days, "Invalid duration");

        // 2. Effects: 状态变更(在外部调用之前)
        lockTime[msg.sender] = block.timestamp + duration;
        _transfer(msg.sender, address(this), amount);

        // 3. Interactions: 外部调用(在状态变更之后)
        emit TokensLocked(msg.sender, amount, lockTime[msg.sender]);
    }

    function unlock() external nonReentrant {
        // Checks
        require(block.timestamp >= lockTime[msg.sender], "Still locked");
        uint256 contractBalance = balanceOf(address(this));
        require(contractBalance > 0, "Nothing to unlock");

        // Effects
        lockTime[msg.sender] = 0;

        // Interactions
        _transfer(address(this), msg.sender, contractBalance);
        emit TokensUnlocked(msg.sender, contractBalance);
    }

    function mint(address to, uint256 amount) external onlyOwner {
        require(totalSupply() + amount <= MAX_SUPPLY, "Exceeds max supply");
        _mint(to, amount);
    }
}

3.2 重入攻击原理

这一模式正是 The DAO 事件(2016 年,被盗 360 万 ETH)中被利用的攻击手法。

// 存在漏洞的合约(切勿使用)
contract VulnerableBank {
    mapping(address => uint256) public balances;

    function withdraw() external {
        uint256 amount = balances[msg.sender];
        // 状态变更前先发起外部调用 → 可能被重入!
        (bool success,) = msg.sender.call{value: amount}("");
        require(success, "Transfer failed");
        balances[msg.sender] = 0;  // 太晚了
    }
}

// 攻击合约
contract Attacker {
    VulnerableBank public target;

    receive() external payable {
        if (address(target).balance >= 1 ether) {
            target.withdraw();  // 递归调用反复提款
        }
    }
}

3.3 Hardhat 测试

const { expect } = require('chai')
const { ethers } = require('hardhat')

describe('SecureToken', function () {
  let token, owner, alice, bob

  beforeEach(async function () {
    ;[owner, alice, bob] = await ethers.getSigners()
    const SecureToken = await ethers.getContractFactory('SecureToken')
    token = await SecureToken.deploy()
    await token.waitForDeployment()
  })

  it('재진입 공격을 방어해야 한다', async function () {
    // 向 alice 转账代币
    await token.transfer(alice.address, ethers.parseEther('1000'))
    expect(await token.balanceOf(alice.address)).to.equal(ethers.parseEther('1000'))
  })

  it('잠금 기간 전에는 언락 불가', async function () {
    await token.transfer(alice.address, ethers.parseEther('100'))
    await token.connect(alice).lockAndRelease(
      ethers.parseEther('100'),
      86400 // 1 天
    )
    await expect(token.connect(alice).unlock()).to.be.revertedWith('Still locked')
  })

  it('Foundry 스타일 퍼즈 테스트 시뮬레이션', async function () {
    const amounts = [1, 100, 1000].map((n) => ethers.parseEther(n.toString()))
    for (const amount of amounts) {
      await token.mint(alice.address, amount)
    }
    const total = amounts.reduce((a, b) => a + b, 0n)
    expect(await token.balanceOf(alice.address)).to.equal(total)
  })
})

3.4 Foundry forge 测试

// test/SecureToken.t.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "forge-std/Test.sol";
import "../src/SecureToken.sol";

contract SecureTokenTest is Test {
    SecureToken public token;
    address public alice = makeAddr("alice");

    function setUp() public {
        token = new SecureToken();
        token.transfer(alice, 1000 ether);
    }

    function testLockRequiresDuration() public {
        vm.startPrank(alice);
        vm.expectRevert("Invalid duration");
        token.lockAndRelease(100 ether, 12 hours);  // 不足 1 天
        vm.stopPrank();
    }

    // 模糊测试:用任意金额反复验证
    function testFuzz_LockAmount(uint256 amount) public {
        amount = bound(amount, 1 ether, 1000 ether);
        vm.startPrank(alice);
        token.lockAndRelease(amount, 1 days);
        assertEq(token.balanceOf(address(token)), amount);
        vm.stopPrank();
    }
}

4. DeFi 协议:AMM、借贷与 MEV

4.1 Uniswap v3 集中流动性

v2 的 x*y=k 公式将流动性均匀分散在整个价格区间。v3 允许 LP 将流动性集中到特定价格区间,把资本效率最多提升 4000 倍。

import math

# Uniswap v3 价格计算(基于 tick)
# tick = log(sqrt(price)) / log(sqrt(1.0001))

def tick_to_price(tick):
    return 1.0001 ** tick

def price_to_tick(price):
    return math.floor(math.log(price) / math.log(1.0001))

def calculate_liquidity_v3(amount0, amount1, price_current, price_lower, price_upper):
    """计算集中流动性头寸的 L(流动性)"""
    sqrt_p = math.sqrt(price_current)
    sqrt_pa = math.sqrt(price_lower)
    sqrt_pb = math.sqrt(price_upper)

    if price_current <= price_lower:
        # 全部为 token0
        L = amount0 * (sqrt_pa * sqrt_pb) / (sqrt_pb - sqrt_pa)
    elif price_current >= price_upper:
        # 全部为 token1
        L = amount1 / (sqrt_pb - sqrt_pa)
    else:
        # 混合
        L0 = amount0 * (sqrt_p * sqrt_pb) / (sqrt_pb - sqrt_p)
        L1 = amount1 / (sqrt_p - sqrt_pa)
        L = min(L0, L1)
    return L

# ETH/USDC 池示例
# 当前价格: 3000 USDC/ETH,区间: 2500 ~ 3500
L = calculate_liquidity_v3(
    amount0=1.0,       # 1 ETH
    amount1=3000.0,    # 3000 USDC
    price_current=3000,
    price_lower=2500,
    price_upper=3500
)
print(f"流动性 L: {L:.4f}")

4.2 MEV(可提取的最大价值)

MEV 是区块生产者通过操纵交易顺序所能提取的最大价值。

主要 MEV 类型

  • 三明治攻击(Sandwich Attack):在大额兑换前后分别买入/卖出,从滑点中获利
  • 套利(Arbitrage):捕捉去中心化交易所之间的价格差
  • 清算(Liquidation):通过清算抵押不足的仓位获得奖励

Flashbots:为 MEV 民主化而生的基础设施

  • mev-boost:连接以太坊验证者与区块构建者(block builder)
  • 通过公开竞价提升 MEV 分配的透明度
  • 缓解暗网(dark forest,即内存池攻击)问题

5. ZK 证明:zk-SNARK、PLONK、ZK Rollup

5.1 zk-SNARK 原理

zk-SNARK(Zero-Knowledge Succinct Non-interactive ARguments of Knowledge)让证明者能在不公开秘密信息(witness)的情况下,向验证者证明某个命题为真。

核心性质:

  • 完备性(Completeness):真命题总能被证明
  • 可靠性(Soundness):假命题无法被证明
  • 零知识性(Zero-knowledge):证明过程中不泄露秘密
// 使用 snarkjs 的简单 ZK 证明示例
// 电路: a * b = c(在不公开 a、b 的情况下证明乘法关系)

const snarkjs = require('snarkjs')
const fs = require('fs')

async function generateAndVerifyProof() {
  // 1. 计算 witness(非公开输入)
  const input = {
    a: 3, // 秘密
    b: 11, // 秘密
    c: 33, // 公开: a * b = c
  }

  // 2. 生成证明(需要 proving key)
  const { proof, publicSignals } = await snarkjs.groth16.fullProve(
    input,
    'multiply.wasm',
    'multiply_final.zkey'
  )

  console.log('公开信号:', publicSignals) // [33]
  console.log('证明大小:', JSON.stringify(proof).length, 'bytes')

  // 3. 验证(只需要 verification key)
  const vKey = JSON.parse(fs.readFileSync('verification_key.json'))
  const isValid = await snarkjs.groth16.verify(vKey, publicSignals, proof)
  console.log('证明是否有效:', isValid) // true
  // 若没有证明,a=3、b=11 这一事实无法被推知
}

generateAndVerifyProof()

5.2 ZK Rollup 架构

ZK Rollup 在 L2 上处理数千笔交易,只将有效性证明(validity proof)发布到 L1。

L2 交易批处理:
[tx1, tx2, ..., tx1000]
        ↓ 证明者(prover)
ZK Proof(数百字节)
L1 验证者
以太坊主网(节省 99%+ Gas)

zkSync Era vs StarkNet

  • zkSync Era:兼容 EVM(Boojum 证明系统,基于 PLONK)
  • StarkNet:使用 Cairo 语言,STARK 证明(抗量子计算)
  • Polygon zkEVM:Type 2 EVM 等价性

6. AI + 区块链

6.1 去中心化 AI 计算

Gensyn:让分布式 GPU 集群上的 AI 模型训练变得可验证的协议。

  • 将训练任务拆分为更小的子任务
  • 为每个子任务生成可验证的证明
  • 家用 GPU 也能参与网络

Bittensor(TAO):AI 模型之间的去中心化市场

  • 按子网划分的专用 AI 任务
  • 由验证者(validator)评估矿工(miner)的输出
  • 按贡献度发放 TAO 代币奖励

6.2 链上 AI 验证

# FHE(全同态加密)概念示例
# 在加密状态下执行运算

# 实际实现: Microsoft SEAL、OpenFHE
# 概念示例:
def fhe_inference_concept(encrypted_input, model_weights):
    """
    使用 FHE,可以在不解密输入数据的情况下
    以加密状态执行 AI 推理
    - 医疗数据: 在不暴露患者信息的情况下完成诊断
    - 金融数据: 在保护隐私的同时进行信用评估
    """
    # 同态运算(加法、乘法均可在加密状态下进行)
    encrypted_result = homomorphic_matrix_multiply(
        encrypted_input,
        model_weights  # 模型是公开的,只有输入被加密
    )
    return encrypted_result

7. 开发工具

7.1 用 web3.py 与合约交互

from web3 import Web3
import json

# Alchemy/Infura RPC 连接
w3 = Web3(Web3.HTTPProvider("https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"))
print("连接状态:", w3.is_connected())
print("最新区块:", w3.eth.block_number)

# ERC-20 余额查询
ERC20_ABI = [
    {"inputs": [{"name": "account", "type": "address"}],
     "name": "balanceOf",
     "outputs": [{"name": "", "type": "uint256"}],
     "type": "function"},
    {"inputs": [],
     "name": "symbol",
     "outputs": [{"name": "", "type": "string"}],
     "type": "function"}
]

USDC_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
usdc = w3.eth.contract(
    address=Web3.to_checksum_address(USDC_ADDRESS),
    abi=ERC20_ABI
)

address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"  # vitalik.eth
balance = usdc.functions.balanceOf(address).call()
symbol = usdc.functions.symbol().call()
print(f"{symbol} 余额: {balance / 10**6:.2f}")

# 发送交易(含签名)
def send_erc20(private_key, to_address, amount_wei):
    account = w3.eth.account.from_key(private_key)
    nonce = w3.eth.get_transaction_count(account.address)
    tx = usdc.functions.transfer(to_address, amount_wei).build_transaction({
        "from": account.address,
        "nonce": nonce,
        "gas": 100000,
        "maxFeePerGas": w3.to_wei(20, "gwei"),
        "maxPriorityFeePerGas": w3.to_wei(2, "gwei"),
    })
    signed = w3.eth.account.sign_transaction(tx, private_key)
    tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
    return tx_hash.hex()

7.2 ethers.js v6

import { ethers } from 'ethers'

// 配置 provider
const provider = new ethers.JsonRpcProvider('https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY')

// 解析 ENS 名称
const address = await provider.resolveName('vitalik.eth')
console.log('vitalik.eth →', address)

// 订阅事件(实时监听 Transfer)
const ERC20_FILTER_ABI = ['event Transfer(address indexed from, address indexed to, uint256 value)']
const usdc = new ethers.Contract(
  '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  ERC20_FILTER_ABI,
  provider
)

usdc.on('Transfer', (from, to, value, event) => {
  const amount = ethers.formatUnits(value, 6)
  if (parseFloat(amount) > 100000) {
    console.log(`大额 USDC 转账: ${amount} USDC`)
    console.log(`from: ${from} → to: ${to}`)
    console.log(`tx: ${event.log.transactionHash}`)
  }
})

小测验

Q1. 以太坊 PoS 相比 PoW 更节能、同时又能维持安全性,靠的是什么经济机制?

答案:通过惩罚机制(Slashing)实现的经济性处罚

解释:PoW 依靠消耗物理能源(电力)来构筑攻击成本,而 PoS 则要求验证者锁定 32 ETH 作为担保。一旦出现双重签名、环绕投票(surround voting)等恶意行为,其质押 ETH 的一部分(至少 1/32)会被自动销毁。若全网超过三分之一的验证者合谋发起攻击,最高会触发 100% 惩罚,让攻击者蒙受巨大损失。它无需消耗能源,就实现了与 PoW 相同的威慑力——只是用经济损失取代了能源消耗。

Q2. 重入攻击在智能合约中发生的模式,以及防御方法是什么?

答案:Checks-Effects-Interactions 模式 + ReentrancyGuard

解释:重入攻击是指外部合约通过回调(receive/fallback)反复调用原始函数的攻击方式。存在漏洞的模式会在把余额清零之前就发送 ETH。防御方法有三种:(1) Checks-Effects-Interactions——在任何外部调用之前完成所有状态变更;(2) OpenZeppelin 的 ReentrancyGuard——用 nonReentrant 修饰符阻止对同一函数的重入;(3) Pull Payment 模式——不是由合约主动推送资金,而是由用户自行提取。

Q3. Uniswap v3 的集中流动性为什么比 v2 的资本效率更高?

答案:LP 将流动性集中到特定价格区间,从而最大化活跃资本的占比

解释:v2 的 x*y=k 公式会把流动性从 0 到无穷大均匀分布在整个价格区间上。而实际交易大多发生在狭窄的价格区间内,导致大部分资本处于闲置状态。在 v3 中,LP 只需将资本部署在预期的价格区间内(例如 2500~3500 USDC/ETH)。用同样的资本,在该区间内可以提供最多 4000 倍更深的流动性,手续费收入也因此更集中。缺点是一旦价格超出该区间,就不再产生手续费收入。

Q4. zk-SNARK 中,证明者是如何在不暴露知识本身的情况下说服验证者的?

答案:多项式约定(Polynomial Commitment)与基于配对(pairing)的密码学

解释:zk-SNARK 把计算转换为多项式方程(R1CS → QAP)。证明者不会直接公开秘密 witness,而是提交编码在椭圆曲线上的点(Elliptic Curve Point)形式的多项式求值结果。验证者通过双线性配对(bilinear pairing)运算来确认多项式关系是否成立。由于离散对数问题的难解性,无法从中反推出真正的 witness。证明大小只有数百字节,验证耗时以毫秒计。

Q5. MEV 对区块链生态系统有哪些影响?Flashbots 又扮演了什么角色?

答案:MEV 具有两面性,Flashbots 通过透明竞价缓解其负面效应

解释:MEV 的积极一面在于通过套利实现价格效率,以及通过及时清算维持 DeFi 的稳定性。消极一面则包括三明治攻击给普通用户带来的损失、内存池拥堵与 Gas 大战、以及诱发链重组(reorg)的激励问题。Flashbots 通过 mev-boost 将区块构建者与验证者分离,建立起透明的公开竞价市场。用户可以通过打包交易(bundle transaction)来防止抢先交易(front-running),MEV 收益也能更公平地分配给验证者。


结语

区块链工程是密码学、分布式系统与经济学交叉融合的复杂领域。以太坊生态正随着 EVM 优化、ZK 技术的成熟、以及与 AI 的融合而快速演进。智能合约安全与代码编写本身同等重要——Hardhat/Foundry 测试与正式审计都是不可或缺的环节。ZK Rollup 与 AI+区块链的结合,将定义 Web3 的下一个阶段。

현재 단락 (1/348)

区块链的核心是**密码学哈希函数**。每个区块都包含前一个区块的哈希,从而形成链条。

작성 글자: 0원문 글자: 12,206작성 단락: 0/348