教程区块链区块链技术ch1414.6 多链 DApp 与跨链桥交互

本页目录

2024 年,活跃区块链超过 100 条。用户资产分散在以太坊(主网)、Arbitrum(便宜)、Base(社交)、Solana(高性能)。多链 DApp 不是"可选项",是默认配置。


14.6.1 链切换与链无关设计

用户看到的 vs 前端看到的

graph LR
    subgraph UX["用户视角"]
        U1[使用 DApp]
        U2["需要跨链(如 Arbitrum → Base)]"
        U3[期待"品牌感知"]
    end
    
    subgraph Internal["前端实现"]
        I1[检测当前链]
        I2[调用 wallet_switchEthereumChain]
        I3[重新初始化 provider]
        I4[加载该链合约地址映射]
        I5[查询该链状态]
    end
    
    U1 --> I1
    U2 --> I2 --> I3 --> I4 --> I5
    
    style UX fill:#e8f5e9
    style Internal fill:#e3f2fd

链配置管理

typescript
/**
 * 多链配置管理(TypeScript 骨架)
 */
interface ChainConfig {
  id: number;
  name: string;
  rpcUrl: string;
  currency: { name: string; symbol: string; decimals: number };
  explorer: string;
  contracts: { [name: string]: string }; // 已部署合约地址映射
  isTestnet: boolean;
}

const chains: Record<string, ChainConfig> = {
  mainnet: {
    id: 1,
    name: "Ethereum",
    rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/...",
    currency: { name: "Ether", symbol: "ETH", decimals: 18 },
    explorer: "https://etherscan.io",
    contracts: {
      token: "0x6B1754...", // DAI on mainnet
      aavePool: "0x87870B...",
    },
    isTestnet: false,
  },
  arbitrum: {
    id: 42161,
    name: "Arbitrum One",
    rpcUrl: "https://arb-mainnet.g.alchemy.com/v2/...",
    currency: { name: "Ether", symbol: "ETH", decimals: 18 },
    explorer: "https://arbiscan.io",
    contracts: {
      token: "0xDA1000...", // DAI on Arbitrum
      aavePool: "0x794a61...",
    },
    isTestnet: false,
  },
  base: {
    id: 8453,
    name: "Base",
    rpcUrl: "https://base-mainnet.g.alchemy.com/v2/...",
    currency: { name: "Ether", symbol: "ETH", decimals: 18 },
    explorer: "https://basescan.org",
    contracts: {
      token: "0x50c572...", // DAI on Base
    },
    isTestnet: false,
  },
  sepolia: {
    id: 11155111,
    name: "Sepolia",
    rpcUrl: "https://eth-sepolia.g.alchemy.com/v2/...",
    currency: { name: "SepoliaETH", symbol: "ETH", decimals: 18 },
    explorer: "https://sepolia.etherscan.io",
    contracts: {
      token: "0x123abc...",
    },
    isTestnet: true,
  },
};

// 切换链
async function switchChain(targetChainId: number, wallet: any) {
  try {
    await wallet.request({
      method: "wallet_switchEthereumChain",
      params: [{ chainId: "0x" + targetChainId.toString(16) }], // 0x1, 0xa4b1 (42161)
    });
  } catch (error: any) {
    // 如果链未安装,需要先添加
    if (error.code === 4902) {
      const chain = Object.values(chains).find(c => c.id === targetChainId);
      await wallet.request({
        method: "wallet_addEthereumChain",
        params: [{
          chainId: "0x" + targetChainId.toString(16),
          chainName: chain?.name,
          rpcUrls: [chain?.rpcUrl],
          nativeCurrency: chain?.currency,
          blockExplorerUrls: [chain?.explorer],
        }],
      });
    }
  }
}

console.log("多链配置已定义");

14.6.2 跨链桥的原理

跨链桥不是把 ETH"移动"到另一链——原生资产不能离开其原生链。跨链桥通过锁定 + 铸造机制解决:

sequenceDiagram
    participant User as 用户
    participant Bridge as 跨链桥合约
    participant Oracle as 验证网络 / 预言机
    participant Target as 目标链合约
    
    User ->> Bridge: 锁定 100 ETH (源链)
    Bridge ->> Bridge: 冻结 100 ETH 在合约中
    Bridge -->> Oracle: 证明事件(Merkle proof / 多重签名)
    Oracle -->> Target: 验证 + 签名
    Target ->> Target: 铸造 100 wETH (目标链)
    Target -->> User: 在目标链上使用影子资产
    
    Note over Target: "wETH" 是"包装 ETH",<br/>不是原生 ETH!<br/>赎回时销毁 wETH → 释放锁定的原生 ETH

主要跨链桥方案

技术去中心化程度速度费用
Wormhole多重签名验证者
LayerZero预言机 + 中继器极快
Stargate (LayerZero)统一流动性池极快
Hop Protocol流动性网络较高分钟级
AcrossUMA 乐观验证
官方桥(如 Arbitrum Bridge)欺诈证明 / 有效性证明慢(天级退出)高(L1 gas)

14.6.3 前端跨链交互模式

状态等待 UX

跨链交易需要时间:消息从源链传播到目标链可能是几秒到几十分钟。前端 UX 必须管理这个等待状态。

typescript
/**
 * 跨链交易状态追踪
 */
interface CrossChainTx {
  id: string;
  sourceChain: number;    // 源链 ID
  targetChain: number;    // 目标链 ID
  status: "sending" | "waiting_attestation" | "delivered" | "completed" | "failed";
  sourceTxHash: string;   // 源链交易哈希
  targetTxHash?: string;  // 目标链执行哈希(有延迟)
  estimatedTime: number;  // 秒
  progress: number;       // 0-100%
}

class CrossChainTracker {
  private txs: Map<string, CrossChainTx> = new Map();
  private listeners = new Set<(tx: CrossChainTx) => void>();
  
  // 用户发起桥接
  async initiateBridge(from: number, to: number, amount: bigint, token: string): Promise<string> {
    const txId = crypto.randomUUID(); // 简化 ID
    
    this.txs.set(txId, {
      id: txId,
      sourceChain: from,
      targetChain: to,
      status: "sending",
      sourceTxHash: "",
      estimatedTime: 120, // 2 分钟估计
      progress: 0,
    });
    
    // 简化流程模拟
    setTimeout(() => this.updateStatus(txId, "waiting_attestation", 10), 2000);
    setTimeout(() => this.updateStatus(txId, "delivered", 80), 60000);
    setTimeout(() => this.updateStatus(txId, "completed", 100), 120000);
    
    return txId;
  }
  
  private updateStatus(id: string, status: CrossChainTx["status"], progress: number) {
    const tx = this.txs.get(id);
    if (!tx) return;
    tx.status = status;
    tx.progress = progress;
    for (const cb of this.listeners) cb({ ...tx });
  }
  
  subscribe(txId: string, cb: (tx: CrossChainTx) => void) {
    this.listeners.add(cb);
    return () => this.listeners.delete(cb);
  }
  
  getStatusText(tx: CrossChainTx): string {
    const map: Record<string, string> = {
      sending: "正在发送源链交易...",
      waiting_attestation: "等待目标链验证...",
      delivered: "已到达目标链,确认中...",
      completed: "✅ 完成!",
      failed: "❌ 失败",
    };
    return map[tx.status];
  }
}

// LayerZero SDK 风格的调用层
interface LZSendParam {
  dstEid: number;           // 目标端点 ID (Endpoint ID)
  to: string;               // 目标地址
  amount: bigint;
  minAmount: bigint;        // 防止滑点
  extraOptions: string;     // 额外选项(gas 空投等)
  composeMsg: string;       // 可携带额外消息
  oftCmd: string;           // 命令
}

// 现代跨链桥 SDK 简化高层调用:
// send(srcChain, dstChain, token, amount, recipient)
// 抽象掉 Wormhole VAA / LayerZero 消息包 / 中继器验证 等底层
console.log("跨链架构:锁定-证明-铸造/释放");

14.6.4 桥的风险

跨链桥是历史漏洞重灾区——锁定的巨大 TVL 使其成为攻击首选:

事件损失原因
Wormhole(2022)$320M验证者签名被绕过
Ronin(2022)$622M私钥泄露(社工)
Nomad(2022)$190M初始化错误
Multichain(2023)$126M多签私钥控制问题

启示:跨链桥选择时,验证机制的去中心化程度比"品牌知名度"更重要。


> ← 14.5 去中心化存储 | 前往 → ch14-summary(本章总结) |*

评论

0

评论加载中…

发表评论

0/2000