Q7 · 前端与链交互

Ethers.js 几大核心模块分别做什么?

Ethers.jsProviderSigner有 Demo

⚡ 速记答案(30 秒)

  • Provider:连接区块链节点(RPC),读链上数据
  • Signer / Wallet:持有私钥,可发交易、签名消息
  • Contract:前端与合约交互的封装(读写函数、监听事件)
  • Utils:格式转换、单位转换(parseEther/formatUnits 等)
  • ABI / Interface:解析合约 ABI,编码/解码数据
  • Errors:统一错误类型和错误消息

📖 详细讲解

Ethers.js v6 架构


1. Provider - 只读连接


Provider 用于连接区块链节点,只能读取数据,不能发送交易。


2. Signer - 签名者


Signer 是 Provider 的扩展,持有私钥可以签名交易。常见类型:

Wallet:使用私钥/助记词

JsonRpcSigner:通过 MetaMask 等注入


3. Contract - 合约交互


Contract 是与智能合约交互的抽象层,自动编码/解码调用数据。


面试要点


• Provider 和 Signer 的区别

• v5 到 v6 的 API 变化

• 如何处理大数(BigInt)

💻 代码示例

Provider 使用示例
import { ethers } from 'ethers';

// 1. 创建 Provider(连接到 RPC)
const provider = new ethers.JsonRpcProvider('https://eth.llamarpc.com');

// 2. 读取链上数据
const blockNumber = await provider.getBlockNumber();
const balance = await provider.getBalance('vitalik.eth');
const gasPrice = await provider.getFeeData();

console.log('当前区块:', blockNumber);
console.log('余额:', ethers.formatEther(balance), 'ETH');
Contract 交互示例
import { ethers } from 'ethers';

// ERC20 合约 ABI(仅需用到的方法)
const ERC20_ABI = [
  'function balanceOf(address) view returns (uint256)',
  'function transfer(address to, uint256 amount) returns (bool)',
  'event Transfer(address indexed from, address indexed to, uint256 value)',
];

// 创建合约实例
const usdtAddress = '0xdAC17F958D2ee523a2206206994597C13D831ec7';
const contract = new ethers.Contract(usdtAddress, ERC20_ABI, provider);

// 读取余额(只读操作)
const balance = await contract.balanceOf('0x...');

// 发送交易(需要 Signer)
const contractWithSigner = contract.connect(signer);
const tx = await contractWithSigner.transfer('0x...', 1000000n);
await tx.wait();
💡
面试技巧:回答时先给出核心结论,再展开细节。如果有实际项目经验,一定要结合具体案例说明。