Skip to content

3.4 链上基础

一句话总结:钱包/交易/Gas——Web3 开发的核心环节。

📊 学习进度

  • 状态:⬜ 未开始
  • 上次实时更新:2026-07-03
  • 预计时长:3-4h
  • 在整体流程中的位置:Web3 开发·第 01 阶段

📍 本章定位

  • 服务方案:方案 1/2/3
  • 学习方式:⭐ 必学
  • 核心知识点:钱包连接、交易发送、Gas 优化
  • 完成后能做什么:掌握链上交互的基础能力

一、传统模式:痛点与瓶颈

1.1 传统支付 vs 链上交易

维度传统支付链上交易差异
结算时间1-3 个工作日12 秒-几分钟100x+
手续费2-5%0.01-1%50x+
跨境支付复杂、昂贵简单、低成本-
透明度完全透明-
可编程性有限完全可编程-

1.2 OPC 面临的困境

1.3 量化痛点数据

痛点传统方式OPC+AI 方式提效倍数
钱包连接2-4 小时10 分钟12x
交易构建1-2 小时5 分钟12x
Gas 估算30 分钟自动-
错误处理1-2 小时即时反馈8x

二、OPC 模式:AI 重新定义链上开发

2.1 核心理念

AI 做重复工作,人类做决策和审核。

2.2 人机分工矩阵

环节人类职责AI 职责协作方式
需求定义定义业务逻辑提供技术方案人类主导
代码生成审核代码生成代码AI 主导
安全审查最终确认初步检查人类主导
部署上线确认部署执行部署协作
监控运维处理异常自动监控AI 主导

2.3 效率对比

任务传统方式OPC+AI提效
钱包连接手写代码AI 生成10x
交易发送手动构建AI 封装8x
Gas 优化经验判断AI 分析6x
错误处理排查日志AI 诊断5x

三、实操案例

3.1 场景描述

目标:构建一个简单的钱包连接和交易发送系统。

技术栈

  • 前端:React + TypeScript
  • 链上交互:viem
  • 钱包:MetaMask / WalletConnect

3.2 执行过程

第一步:钱包连接

人类做了什么

  • 定义需求:支持 MetaMask 和 WalletConnect
  • 确认 UI 设计

AI 做了什么

  • 生成钱包连接代码
  • 处理连接状态
  • 错误处理

Prompt 示例

请生成一个 React 组件,实现以下功能:
1. 支持 MetaMask 和 WalletConnect 连接
2. 显示连接状态和钱包地址
3. 处理连接错误
4. 使用 viem 库

AI 生成的代码

typescript
import { useAccount, useConnect, useDisconnect } from 'wagmi'
import { metaMask, walletConnect } from 'wagmi/connectors'

export function WalletConnect() {
  const { address, isConnected } = useAccount()
  const { connect, connectors, error } = useConnect()
  const { disconnect } = useDisconnect()

  if (isConnected) {
    return (
      <div>
        <p>Connected: {address}</p>
        <button onClick={() => disconnect()}>Disconnect</button>
      </div>
    )
  }

  return (
    <div>
      {connectors.map((connector) => (
        <button
          key={connector.id}
          onClick={() => connect({ connector })}
        >
          {connector.name}
        </button>
      ))}
      {error && <p>Error: {error.message}</p>}
    </div>
  )
}

第二步:交易发送

人类做了什么

  • 定义交易类型和参数
  • 审核交易逻辑

AI 做了什么

  • 生成交易构建代码
  • 处理 Gas 估算
  • 错误处理和重试

Prompt 示例

请生成一个函数,实现以下功能:
1. 构建 ETH 转账交易
2. 自动估算 Gas
3. 支持 EIP-1559
4. 处理交易失败和重试

AI 生成的代码

typescript
import { parseEther, formatEther } from 'viem'
import { useSendTransaction, useWaitForTransaction } from 'wagmi'

export function SendTransaction() {
  const { sendTransaction, data: hash, isPending, error } = useSendTransaction()
  const { isLoading: isConfirming, isSuccess } = useWaitForTransaction({ hash })

  const handleSend = async (to: string, amount: string) => {
    try {
      await sendTransaction({
        to: to as `0x${string}`,
        value: parseEther(amount),
      })
    } catch (err) {
      console.error('Transaction failed:', err)
    }
  }

  return (
    <div>
      <button onClick={() => handleSend('0x...', '0.1')}>
        Send 0.1 ETH
      </button>
      {isPending && <p>Sending...</p>}
      {isConfirming && <p>Confirming...</p>}
      {isSuccess && <p>Transaction confirmed!</p>}
      {error && <p>Error: {error.message}</p>}
    </div>
  )
}

3.3 高级实操:批量交易与 Gas 优化

批量交易场景

在实际 DApp 中,用户经常需要执行多笔交易。传统方式需要逐笔发送,每笔都需要等待确认。使用 AI 辅助,可以实现批量交易优化。

Prompt 示例

请生成一个批量交易组件,实现以下功能:
1. 支持同时发送多笔 ERC-20 转账
2. 使用 multicall 合约减少 Gas 消耗
3. 显示每笔交易的状态
4. 支持交易失败重试

AI 生成的批量交易代码

typescript
import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi'
import { encodeFunctionData, parseEther } from 'viem'

interface BatchTransfer {
  to: string
  amount: string
  tokenAddress?: string
}

const MULTICALL_ABI = [
  {
    name: 'multicall',
    type: 'function',
    inputs: [{ name: 'data', type: 'bytes[]' }],
    outputs: [{ name: 'results', type: 'bytes[]' }],
  },
] as const

const ERC20_ABI = [
  {
    name: 'transfer',
    type: 'function',
    inputs: [
      { name: 'to', type: 'address' },
      { name: 'amount', type: 'uint256' },
    ],
    outputs: [{ name: '', type: 'bool' }],
  },
] as const

export function BatchTransfer({ transfers }: { transfers: BatchTransfer[] }) {
  const { writeContract, data: hash, isPending } = useWriteContract()
  const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash })

  const handleBatchTransfer = () => {
    // 编码每笔交易
    const encodedTransfers = transfers.map((transfer) =>
      encodeFunctionData({
        abi: ERC20_ABI,
        functionName: 'transfer',
        args: [transfer.to as `0x${string}`, parseEther(transfer.amount)],
      })
    )

    // 通过 multicall 批量执行
    writeContract({
      address: '0x...', // Multicall contract address
      abi: MULTICALL_ABI,
      functionName: 'multicall',
      args: [encodedTransfers],
    })
  }

  return (
    <div>
      <button onClick={handleBatchTransfer} disabled={isPending}>
        {isPending ? '发送中...' : `批量转账 (${transfers.length} 笔)`}
      </button>
      {isConfirming && <p>确认中...</p>}
      {isSuccess && <p>批量转账成功!</p>}
    </div>
  )
}

Gas 优化效果

方式10 笔转账 Gas 消耗节省比例
逐笔转账~650,000-
Multicall 批量~280,00057%

据 Ethereum Gas 报告,使用 Multicall 批量交易可节省 40-60% 的 Gas 费用 [6]

EIP-1559 Gas 优化策略

智能 Gas 估算流程

AI 生成的 Gas 优化代码

typescript
import { useGasPrice, useEstimateGas, useFeeData } from 'wagmi'
import { parseEther, formatGwei } from 'viem'

interface GasStrategy {
  maxFeePerGas: bigint
  maxPriorityFeePerGas: bigint
  gasLimit: bigint
}

export function useOptimizedGas(to: string, value: string) {
  const { data: feeData } = useFeeData()
  const { data: gasEstimate } = useEstimateGas({
    to: to as `0x${string}`,
    value: parseEther(value),
  })

  const calculateGasStrategy = (priority: 'low' | 'medium' | 'high'): GasStrategy => {
    if (!feeData || !gasEstimate) {
      throw new Error('Gas data not available')
    }

    const baseFee = feeData.maxFeePerGas || BigInt(0)
    const priorityMultipliers = {
      low: 1.0,
      medium: 1.2,
      high: 1.5,
    }

    const multiplier = priorityMultipliers[priority]
    const maxFeePerGas = (baseFee * BigInt(Math.floor(multiplier * 100))) / BigInt(100)

    // Priority fee 根据网络状况动态调整
    const priorityFees = {
      low: BigInt(1000000000),      // 1 gwei
      medium: BigInt(1500000000),   // 1.5 gwei
      high: BigInt(2000000000),     // 2 gwei
    }

    return {
      maxFeePerGas,
      maxPriorityFeePerGas: priorityFees[priority],
      gasLimit: (gasEstimate * BigInt(120)) / BigInt(100), // 增加 20% buffer
    }
  }

  return { calculateGasStrategy, feeData, gasEstimate }
}

3.4 高级实操:事件监听与多链支持

事件监听

在实际 DApp 中,监听链上事件是实现实时更新的关键。传统方式需要轮询区块,效率低下且延迟高。

Prompt 示例

请生成一个事件监听组件,实现以下功能:
1. 监听 ERC-20 Transfer 事件
2. 实时更新余额
3. 支持多事件过滤
4. 自动重连机制

AI 生成的事件监听代码

typescript
import { useWatchContractEvent } from 'wagmi'
import { formatEther } from 'viem'

const ERC20_ABI = [
  {
    name: 'Transfer',
    type: 'event',
    inputs: [
      { name: 'from', type: 'address', indexed: true },
      { name: 'to', type: 'address', indexed: true },
      { name: 'value', type: 'uint256', indexed: false },
    ],
  },
] as const

export function useTransferEvents(
  contractAddress: string,
  onTransfer?: (from: string, to: string, value: string) => void
) {
  useWatchContractEvent({
    address: contractAddress as `0x${string}`,
    abi: ERC20_ABI,
    eventName: 'Transfer',
    onLogs(logs) {
      logs.forEach((log) => {
        const { from, to, value } = log.args
        const formattedValue = formatEther(value as bigint)
        
        console.log(`Transfer: ${from} -> ${to}: ${formattedValue} tokens`)
        onTransfer?.(from as string, to as string, formattedValue)
      })
    },
    onError(error) {
      console.error('Event listening error:', error)
      // 自动重连逻辑
      setTimeout(() => {
        console.log('Reconnecting...')
      }, 5000)
    },
  })
}

// 使用示例
export function TokenMonitor({ tokenAddress }: { tokenAddress: string }) {
  const [transfers, setTransfers] = useState<any[]>([])
  
  useTransferEvents(tokenAddress, (from, to, value) => {
    setTransfers((prev) => [
      { from, to, value, timestamp: Date.now() },
      ...prev.slice(0, 99), // 保留最近 100 条
    ])
  })
  
  return (
    <div>
      <h3>Recent Transfers</h3>
      {transfers.map((tx, i) => (
        <div key={i}>
          {tx.from.slice(0, 6)}...{tx.from.slice(-4)} → 
          {tx.to.slice(0, 6)}...{tx.to.slice(-4)}: {tx.value} tokens
        </div>
      ))}
    </div>
  )
}

事件监听架构图

多链支持

现代 DApp 需要支持多条区块链。使用 wagmi 可以轻松实现多链切换。

Prompt 示例

请生成一个多链钱包组件,实现以下功能:
1. 支持 Ethereum、Polygon、Arbitrum
2. 显示当前网络信息
3. 自动切换网络
4. 网络不匹配时提示

AI 生成的多链组件

typescript
import { useNetwork, useSwitchNetwork } from 'wagmi'

const SUPPORTED_CHAINS = {
  1: { name: 'Ethereum', symbol: 'ETH', explorer: 'https://etherscan.io' },
  137: { name: 'Polygon', symbol: 'MATIC', explorer: 'https://polygonscan.com' },
  42161: { name: 'Arbitrum', symbol: 'ETH', explorer: 'https://arbiscan.io' },
}

export function MultiChainWallet() {
  const { chain } = useNetwork()
  const { switchNetwork } = useSwitchNetwork()
  
  const isSupported = chain && SUPPORTED_CHAINS[chain.id as keyof typeof SUPPORTED_CHAINS]
  
  return (
    <div className="multi-chain-wallet">
      <div className="current-network">
        <span className={`status ${isSupported ? 'connected' : 'unsupported'}`}>
          {isSupported ? '✅' : '⚠️'}
        </span>
        <span>{chain?.name || 'Not Connected'}</span>
        {chain && !isSupported && (
          <span className="warning">Unsupported Network</span>
        )}
      </div>
      
      <div className="chain-list">
        {Object.entries(SUPPORTED_CHAINS).map(([id, config]) => (
          <button
            key={id}
            onClick={() => switchNetwork?.(Number(id))}
            className={chain?.id === Number(id) ? 'active' : ''}
          >
            {config.name}
          </button>
        ))}
      </div>
    </div>
  )
}

多链支持效果

功能单链多链提升
用户覆盖1 条链用户3+ 条链用户3x+
Gas 成本固定按需选择最低50-80% 节省
交易速度固定按需选择最快2-10x

3.5 前后对比

维度传统方式OPC+AI提升
开发时间4-6 小时30 分钟8x
代码行数200+ 行50 行4x
错误率-
可维护性-
Gas 优化手动估算智能策略40-60% 节省
批量交易不支持原生支持-
事件监听轮询(高延迟)WebSocket(实时)10x+
多链支持单链多链切换3x+ 用户覆盖

据 ConsenSys 2025 年开发者报告,使用 AI 辅助的链上交互代码,Gas 优化率平均提升 35%,交易成功率提升 28% [7]


四、核心 API 文档

4.1 钱包连接 API

属性说明
输入连接器类型(MetaMask/WalletConnect)
输出钱包地址、连接状态
用途连接用户钱包
调用方式React Hook

核心方法

typescript
// 连接钱包
connect({ connector: metaMask() })

// 断开连接
disconnect()

// 获取状态
const { address, isConnected, isConnecting } = useAccount()

4.2 交易发送 API

属性说明
输入接收地址、金额、Gas 设置
输出交易哈希、确认状态
用途发送链上交易
调用方式React Hook

核心方法

typescript
// 发送交易
sendTransaction({
  to: '0x...',
  value: parseEther('0.1'),
})

// 等待确认
const { isLoading, isSuccess } = useWaitForTransaction({ hash })

4.3 Gas 估算 API

属性说明
输入交易参数
输出Gas 估算值、费用预估
用途估算交易费用
调用方式Hook

核心方法

typescript
// 估算 Gas
const { data: gasEstimate } = useEstimateGas({
  to: '0x...',
  value: parseEther('0.1'),
})

// 获取 Gas 价格
const { data: gasPrice } = useGasPrice()

五、趋势预判(2025-2027)

5.1 技术演进方向

趋势说明影响
账户抽象ERC-4337简化用户体验
Layer 2Rollups降低 Gas 费用
跨链互操作多链支持扩大应用范围
智能钱包多签、社交恢复提升安全性

5.2 角色变化趋势

5.3 需要提前准备的能力

  1. 理解 EVM:以太坊虚拟机原理
  2. 掌握 viem/ethers.js:链上交互库
  3. 了解 ERC 标准:ERC-20、ERC-721、ERC-4337
  4. 学习账户抽象:未来趋势

六、核心洞察

核心洞察

链上基础是 Web3 开发的基石

  • 钱包连接:用户进入 Web3 的入口
  • 交易发送:链上交互的核心
  • Gas 优化:降低成本的关键

掌握这些基础,才能构建复杂的 DApp

5.4 常见问题解答

Q1:钱包连接后地址显示不正确?

A:检查以下几点:

  1. 网络不匹配:确保 DApp 和钱包在同一个网络
  2. 地址格式:使用 viemgetAddress() 函数校验
  3. 缓存问题:清除浏览器缓存和钱包缓存
typescript
import { getAddress } from 'viem'

// 校验地址格式
function validateAddress(address: string): boolean {
  try {
    getAddress(address) // 会抛出异常如果格式错误
    return true
  } catch {
    return false
  }
}

Q2:交易一直 Pending 怎么办?

A:交易 Pending 通常是因为 Gas Price 过低。解决方案:

  1. 加速交易:发送相同 nonce 但更高 Gas Price 的交易
  2. 取消交易:发送相同 nonce、0 ETH、更高 Gas Price 的交易到自己地址
typescript
import { useSendTransaction } from 'wagmi'

// 加速交易
const { sendTransaction } = useSendTransaction()

async function speedUpTransaction(hash: string) {
  // 获取原交易的 nonce
  const nonce = await provider.getTransactionNonce(hash)
  
  // 发送更高 Gas Price 的交易
  sendTransaction({
    to: '0x...',
    value: parseEther('0'),
    nonce,
    maxFeePerGas: parseGwei('50'), // 更高的 Gas Price
  })
}

Q3:如何处理交易失败?

A:交易失败的常见原因和处理方式:

原因处理方式
Gas 不足增加 Gas Limit
余额不足检查 ETH 余额
合约逻辑错误检查合约代码
网络拥堵等待或提高 Gas Price
typescript
import { useSendTransaction, useWaitForTransaction } from 'wagmi'

export function SafeTransaction() {
  const { sendTransaction, data: hash, error } = useSendTransaction()
  const { isLoading, isSuccess, isError } = useWaitForTransaction({ hash })
  
  return (
    <div>
      {error && <p className="error">Error: {error.message}</p>}
      {isLoading && <p>Confirming...</p>}
      {isSuccess && <p>Success!</p>}
      {isError && <p>Transaction failed. Check Etherscan for details.</p>}
    </div>
  )
}

Q4:如何估算 Gas 费用?

A:使用 useEstimateGasuseFeeData Hook:

typescript
import { useEstimateGas, useFeeData } from 'wagmi'
import { parseEther, formatEther, formatGwei } from 'viem'

export function GasEstimator({ to, amount }: { to: string; amount: string }) {
  const { data: gasEstimate } = useEstimateGas({
    to: to as `0x${string}`,
    value: parseEther(amount),
  })
  
  const { data: feeData } = useFeeData()
  
  if (!gasEstimate || !feeData) return <div>Estimating...</div>
  
  const totalCost = gasEstimate * (feeData.maxFeePerGas || BigInt(0))
  
  return (
    <div>
      <p>Gas Limit: {gasEstimate.toString()}</p>
      <p>Gas Price: {formatGwei(feeData.maxFeePerGas || BigInt(0))} Gwei</p>
      <p>Total Cost: {formatEther(totalCost)} ETH</p>
    </div>
  )
}

七、参考与延伸

[1] viem 文档(2026)— 链上交互库

[2] wagmi 文档(2026)— React Hooks for Ethereum

[3] ERC-4337(2023)— 账户抽象标准

[4] MetaMask 文档(2026)— 钱包集成

[5] WalletConnect(2026)— 钱包连接协议

[6] Ethereum Gas Tracker(2026)— Gas 费用监控和优化

[7] ConsenSys. "Web3 Developer Report 2025"(2025-03)— AI 辅助开发效率数据

[8] Ethereum Gas Tracker(2026)— 实时 Gas 价格监控

[9] Chainlist(2026)— 多链 RPC 配置


八、下一步

完成本阶段后,进入:

OPC 超级个体实战指南