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 生成的代码:
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 生成的代码:
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 生成的批量交易代码:
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,000 | 57% |
据 Ethereum Gas 报告,使用 Multicall 批量交易可节省 40-60% 的 Gas 费用 [6]。
EIP-1559 Gas 优化策略
智能 Gas 估算流程:
AI 生成的 Gas 优化代码:
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 生成的事件监听代码:
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 生成的多链组件:
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 |
核心方法:
// 连接钱包
connect({ connector: metaMask() })
// 断开连接
disconnect()
// 获取状态
const { address, isConnected, isConnecting } = useAccount()4.2 交易发送 API
| 属性 | 说明 |
|---|---|
| 输入 | 接收地址、金额、Gas 设置 |
| 输出 | 交易哈希、确认状态 |
| 用途 | 发送链上交易 |
| 调用方式 | React Hook |
核心方法:
// 发送交易
sendTransaction({
to: '0x...',
value: parseEther('0.1'),
})
// 等待确认
const { isLoading, isSuccess } = useWaitForTransaction({ hash })4.3 Gas 估算 API
| 属性 | 说明 |
|---|---|
| 输入 | 交易参数 |
| 输出 | Gas 估算值、费用预估 |
| 用途 | 估算交易费用 |
| 调用方式 | Hook |
核心方法:
// 估算 Gas
const { data: gasEstimate } = useEstimateGas({
to: '0x...',
value: parseEther('0.1'),
})
// 获取 Gas 价格
const { data: gasPrice } = useGasPrice()五、趋势预判(2025-2027)
5.1 技术演进方向
| 趋势 | 说明 | 影响 |
|---|---|---|
| 账户抽象 | ERC-4337 | 简化用户体验 |
| Layer 2 | Rollups | 降低 Gas 费用 |
| 跨链互操作 | 多链支持 | 扩大应用范围 |
| 智能钱包 | 多签、社交恢复 | 提升安全性 |
5.2 角色变化趋势
5.3 需要提前准备的能力
- 理解 EVM:以太坊虚拟机原理
- 掌握 viem/ethers.js:链上交互库
- 了解 ERC 标准:ERC-20、ERC-721、ERC-4337
- 学习账户抽象:未来趋势
六、核心洞察
核心洞察
链上基础是 Web3 开发的基石。
- 钱包连接:用户进入 Web3 的入口
- 交易发送:链上交互的核心
- Gas 优化:降低成本的关键
掌握这些基础,才能构建复杂的 DApp。
5.4 常见问题解答
Q1:钱包连接后地址显示不正确?
A:检查以下几点:
- 网络不匹配:确保 DApp 和钱包在同一个网络
- 地址格式:使用
viem的getAddress()函数校验 - 缓存问题:清除浏览器缓存和钱包缓存
import { getAddress } from 'viem'
// 校验地址格式
function validateAddress(address: string): boolean {
try {
getAddress(address) // 会抛出异常如果格式错误
return true
} catch {
return false
}
}Q2:交易一直 Pending 怎么办?
A:交易 Pending 通常是因为 Gas Price 过低。解决方案:
- 加速交易:发送相同 nonce 但更高 Gas Price 的交易
- 取消交易:发送相同 nonce、0 ETH、更高 Gas Price 的交易到自己地址
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 |
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:使用 useEstimateGas 和 useFeeData Hook:
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 配置
八、下一步
完成本阶段后,进入: