第7章:Web3.0 前端开发:连接钱包与交互(2025年10月最新版)

第7章:Web3.0 前端开发:连接钱包与交互(2025年10月最新版)


声明:仅供学习参考,不构成投资建议

国外可访问:rainweb3知识库

国内可访问:rainweb3知识库


⚠️ 免责声明:本文档旨在提供教育性、参考性的技术指导,基于当前(2025年)社区广泛认可的最佳实践。它不构成任何形式的投资、法律或专业建议。智能合约开发风险极高,任何部署前都应进行严格的自我审查、自动化扫描和第三方审计。

本章系统讲解现代Web3.0前端开发的核心技术栈 ,涵盖钱包连接、交易发送、事件监听等关键操作。所有内容基于当前(2025年10月)行业最佳实践,采用生产级、无过时信息、可直接部署的技术方案,确保开发者掌握真实可用的技能。


1. Web3.js vs Ethers.js:推荐 Ethers.js

对比项 Ethers.js(推荐) Web3.js
体积与性能 更轻量(~80KB),Tree-shaking 友好 较大(~400KB),包体积大
API 设计 现代、简洁、TypeScript 优先 旧式 API,回调风格遗留
维护状态 活跃维护,v6 是当前稳定版(2023--2025) 维护减缓,社区转向 Ethers
安全性 内置地址校验、ABI 解析更安全 需额外处理边界情况
多链支持 原生支持以太坊及所有 EVM 链(Polygon、Arbitrum 等) 支持但配置复杂

结论(2025年)Ethers.js v6 是当前和未来 Web3 前端开发的事实标准,强烈推荐用于新项目。


2. 钱包连接:使用 window.ethereum 检测 MetaMask

现代 DApp 通过浏览器注入的 window.ethereum 对象与钱包通信(遵循 EIP-1193 标准)。

(1)检测钱包存在
ts 复制代码
function detectWallet() {
  if (typeof window.ethereum !== 'undefined') {
    console.log('MetaMask is installed!');
    return true;
  } else {
    alert('Please install MetaMask to use this DApp.');
    return false;
  }
}
(2)请求用户授权(eth_requestAccounts
ts 复制代码
async function connectWallet() {
  if (!detectWallet()) return;

  try {
    // 请求用户授权连接
    const accounts = await window.ethereum.request({
      method: 'eth_requestAccounts',
    });

    const account = accounts[0];
    console.log('Connected account:', account);
    return account;
  } catch (error) {
    console.error('User rejected request or error:', error);
    throw error;
  }
}

🔐 安全提示

  • eth_requestAccounts 是标准方法,不会自动连接。
  • 用户必须主动点击"连接"按钮才能触发。

3. 获取用户地址、余额、网络

(1)获取用户地址
ts 复制代码
const account = await provider.getSigner().getAddress();
(2)获取余额
ts 复制代码
async function getBalance(account: string, provider: ethers.Provider) {
  const balanceWei = await provider.getBalance(account);
  const balanceEth = ethers.formatEther(balanceWei); // 转换为 ETH
  console.log(`Balance: ${balanceEth} ETH`);
  return balanceEth;
}
(3)获取当前网络
ts 复制代码
async function getNetwork(provider: ethers.Provider) {
  const network = await provider.getNetwork();
  console.log(`Chain ID: ${network.chainId}, Name: ${network.name}`);
  return network;
}

🌐 常见 Chain ID(2025年)

  • Ethereum Mainnet: 1
  • Polygon PoS: 137
  • Arbitrum One: 42161
  • Optimism: 10
  • Base: 8453

4. 发送交易:调用合约方法

以调用 NFT 合约的 mint 方法为例。

(1)初始化合约实例
ts 复制代码
const contractAddress = "0xYourContractAddress";
const contractABI = [ /* 从 artifacts 复制 ABI */ ];

// 使用 signer(有权限发送交易)
const signer = await provider.getSigner();
const contract = new ethers.Contract(contractAddress, contractABI, signer);
(2)发送 Mint 交易
ts 复制代码
async function mintNFT(amount: number) {
  if (!contract) throw new Error("Contract not initialized");

  try {
    const tx = await contract.publicMint(amount, {
      value: ethers.parseEther("0.01"), // 发送 0.01 ETH
      gasLimit: 300000, // 可选:设置 Gas 上限
    });

    console.log("Transaction sent:", tx.hash);

    // 等待交易确认
    const receipt = await tx.wait();
    console.log("Transaction confirmed in block:", receipt?.blockNumber);
    return receipt;
  } catch (error: any) {
    console.error("Transaction failed:", error.message);
    throw error;
  }
}

💡 关键参数说明

  • value: 发送 ETH(单位为 Wei,使用 ethers.parseEther() 转换)。
  • gasLimit: 手动设置 Gas 上限,避免意外消耗过多。
  • tx.wait(): 返回交易回执(Receipt),包含状态、日志、区块号等。

5. 事件监听:监听合约事件

监听 Transfer 事件,实时更新前端 UI。

(1)监听单个事件
ts 复制代码
contract.on("Minted", (minter, tokenId) => {
  console.log(`New NFT minted! Owner: ${minter}, Token ID: ${tokenId.toString()}`);
  // 更新前端状态,如刷新 NFT 列表
});
(2)监听所有事件(调试用)
ts 复制代码
contract.on("Transfer", (from, to, tokenId) => {
  console.log(`NFT #${tokenId} transferred from ${from} to ${to}`);
});
(3)移除监听器
ts 复制代码
// 避免内存泄漏
contract.off("Minted", listenerFunction);

⚠️ 生产建议

  • 在 React 中使用 useEffect 清理监听器。
  • 对于高频事件,考虑使用 The Graph 或后端索引服务。

6. 前端框架集成:React + Ethers.js(推荐模式)

React + TypeScript + Vite 为例,展示最佳实践结构。

(1)安装依赖
bash 复制代码
npm create vite@latest my-dapp -- --template react-ts
cd my-dapp
npm install ethers@6
(2)创建 Web3 上下文(Web3Context.tsx
tsx 复制代码
import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { ethers } from 'ethers';

interface Web3ContextType {
  account: string | null;
  balance: string;
  chainId: number | null;
  provider: ethers.Provider | null;
  connectWallet: () => Promise<void>;
}

const Web3Context = createContext<Web3ContextType | undefined>(undefined);

export function Web3Provider({ children }: { children: ReactNode }) {
  const [account, setAccount] = useState<string | null>(null);
  const [balance, setBalance] = useState("0");
  const [chainId, setChainId] = useState<number | null>(null);
  const [provider, setProvider] = useState<ethers.Provider | null>(null);

  useEffect(() => {
    if (typeof window.ethereum !== 'undefined') {
      const prov = new ethers.BrowserProvider(window.ethereum);
      setProvider(prov);
    }
  }, []);

  const connectWallet = async () => {
    if (!provider) return;

    try {
      const accounts = await provider.send("eth_requestAccounts", []);
      const acc = accounts[0];
      setAccount(acc);

      const bal = await provider.getBalance(acc);
      setBalance(ethers.formatEther(bal));

      const network = await provider.getNetwork();
      setChainId(network.chainId);
    } catch (err) {
      console.error("Failed to connect wallet", err);
    }
  };

  return (
    <Web3Context.Provider value={{ account, balance, chainId, provider, connectWallet }}>
      {children}
    </Web3Context.Provider>
  );
}

export const useWeb3 = () => {
  const context = useContext(Web3Context);
  if (!context) throw new Error("useWeb3 must be used within Web3Provider");
  return context;
};
(3)在组件中使用
tsx 复制代码
import { useWeb3 } from './Web3Context';

function App() {
  const { account, balance, connectWallet } = useWeb3();

  return (
    <div>
      <h1>My DApp</h1>
      {!account ? (
        <button onClick={connectWallet}>Connect Wallet</button>
      ) : (
        <div>
          <p>Account: {account}</p>
          <p>Balance: {balance} ETH</p>
        </div>
      )}
    </div>
  );
}

本章小结

截至2025年10月,Web3.0前端开发已形成清晰的技术路径:

  • 首选 Ethers.js v6,因其轻量、安全、现代化。
  • 钱包连接 基于 window.ethereumeth_requestAccounts
  • 交易发送 需正确处理 signergasvalue 和交易回执。
  • 事件监听实现响应式UI更新。
  • React + Context API 是管理 Web3 状态的推荐模式。
相关推荐
财迅通Ai14 小时前
南华期货半年净利预期高增,稀缺自主清算壁垒驱动跨境业务规模放量
大数据·人工智能·区块链·南华期货
没有了遇见15 小时前
AI Agent 是什么?—— 一文理解 LLM、Memory、Skills、Tools、MCP、Workflow,Context
android·前端·程序员
北冥you鱼19 小时前
区块链智能合约升级中的数据存储兼容性挑战与解决方案
区块链·智能合约
双缝观察者1 天前
虚假承兑商链上资产流向追踪与线下身份锁定技术
区块链
DogDaoDao1 天前
【GitHub】 LLVM Project 深度解析:现代编译器基础设施的基石
java·c++·python·程序员·github·编译器·llvm
SamDeepThinking2 天前
为什么我会主动给一个年轻程序员加薪、晋升?
java·后端·程序员
AI小码2 天前
WAIC 2026前瞻:AI产业进入拼落地的下半场
人工智能·算法·ai·程序员·大模型·编程·智能体
zzzll11112 天前
LangChain实战-RAG问答机器人
学习·计算机·程序员·大模型
Coffeeee2 天前
22道AI Agent 工程师必会的面试题,别啥都不会就出去找工作
程序员·agent·ai编程
AskHarries2 天前
用 OpenClaw 做网页调研:搜索、打开网页、提取信息和生成报告
程序员