第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 状态的推荐模式。
相关推荐
SimonKing7 小时前
SpringBoot集成:5分钟实现HTML转PDF功能
java·后端·程序员
OpenBuild.xyz1 天前
区块链分层学:新的开始
区块链
leijiwen1 天前
S11e Network 商业模型:AI × Web3 × RWA 驱动的实体经济新范式
人工智能·web3·区块链
app出海创收老李1 天前
海外独立创收日记(5)-上个月收入回顾与本月计划
前端·后端·程序员
大模型教程1 天前
AI Agent竞争的下半场:决胜关键不在模型,而在系统架构
程序员·llm·agent
app出海创收老李1 天前
海外独立创收日记(4)-第一笔汇款
前端·后端·程序员
大模型教程1 天前
基于DeepSeek-R1手搓AI Agent智能体(手把手,个人电脑也能玩)
程序员·llm·agent
AI大模型1 天前
基于Qwen千问实现自然语言数据分析AI Agent智能体(手把手,个人电脑也能玩哦)
程序员·llm·agent
radient1 天前
初识Agent、Prompt、Function Coding、MCP
后端·程序员·架构