前言
本文主要用 Ethers.js v5 在一篇文章里讲透「钱包全链路」:连接 → 授权 → 转账 → 检测 → 交易记录 → 账号列表。所有代码片段可直接拷进项目跑通。补充:使用ganache作为测试账号,通过创建自定义网络的导入账号;以web端为主
准备工作
- 注册个Ganache账号用来测试,安装ganache-cli运行节点或者下载个客户端
arduino
启动终端指令 cmd
ganache//返回链id rpc链接 和10个账号的公钥和私钥 助记词等
-
ganache返回值汇总
字段 值 网络名称 Ganache Local RPC URL http://127.0.0.1:8545 链 ID 1337 货币符号 ETH 区块浏览器 URL (可不填) -
安装个metamask浏览器插件,用来导入测试账号和dapp交互使用
bash
# 插件安装完毕,已经注册了metamask账号
# 点击设置选择网络
# 点击 添加自定义网络
# 弹出面板,分别填写 网络名称、RPCURL、链ID、货币符号、区块浏览器url(可填、可部填),这些信息获取可以通过ganache返回值中获取 .
项目配置
- 安装 ethers + RN 适配包
perl
# 包安装
npx expo install ethers
npx expo install @ethersproject/shims
npx expo install react-native-get-random-values
- 在项目入口文件(
_layout.tsx
)顶部 第一行 引入 shims
arduino
import '@ethersproject/shims';
import 'react-native-get-random-values';
- 组件中使用
ethers
javascript
import { ethers } from 'ethers';
链接、断开钱包
javascript
# 链接钱包
const onConnectWalletFunction=async ()=>{
// 1. 判断 MetaMask
if (!window.ethereum) {
alert('请先安装 MetaMask');
return null;
}
// 2. 创建 Provider
const provider = new ethers.providers.Web3Provider(window.ethereum);
// 3. 唤起授权
await provider.send('eth_requestAccounts', []);
let addressList=await provider.listAccounts()
console.log(addressList);
// 4. 获取签名器 & 地址
const signer = await provider.getSigner();
const address = await signer.getAddress();
// 5. 查余额(wei → ETH)
const balanceWei = await provider.getBalance(address);
const balanceEth = ethers.utils.formatEther(balanceWei);
//使用zustand 存储钱包的信息:例如 地址 余额交易信息等等
setAddress(address);//zustand 定义的方法
setBalance(balanceEth);//zustand 定义的方法
setAddressBookList([...addressList]);//联系人 钱包列表
}
# 断开钱包
# 断开钱包需要手动断开,组件知识清除存储的信息
const disconnectFn=()=>{
setBalance("")
setWellatAddress("")
useWallet.persist.clearStorage();//zustand清空数据
}
获取指定账号的交易记录
说明 :主要自定义网络
只能通过扫描log日志来实现交易记录整理,(不是最优解
),如果是测试链(mainnet)可以通过(new ethers.providers.EtherscanProvider
)来实现更加优雅
- 以太主网交易记录
ini
const provider = new ethers.providers.EtherscanProvider('mainnet', YOUR_KEY);
const history = await provider.getHistory(address, 0, 'latest');
console.log(history.slice(-100));
- 自定义网络交易记录
typescript
# 说明通过扫描日志log来获取信息,整理交易信息
const hostlistFn= async ()=>{
const TARGET_ADDR = address.toLowerCase();
const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545');//ganache rpcurl
const latest = await provider.getBlockNumber();//获取区块
const list: any[] = [];
console.log(`开始扫描 0 → ${latest} 区块...`);
for (let i = 0; i <= latest; i++) {
const block = await provider.getBlockWithTransactions(i);
console.log(block)
for (const tx of block.transactions) {
if (
tx.from.toLowerCase() === TARGET_ADDR ||
(tx.to && tx.to.toLowerCase() === TARGET_ADDR)
) {
list.push({
hash: tx.hash,
from: tx.from,
to: tx.to,
value: ethers.utils.formatEther(tx.value),
block: tx.blockNumber,
timestamp: new Date(block.timestamp * 1000).toLocaleString(),
});
}
}
}
return list;
}
hostlistFn()
.then(txs => {
console.log(`共 ${txs.length} 笔转账`);
console.table(txs);
})
.catch(console.error);
监听钱包事件
csharp
# 核心代码
window.ethereum.on('accountsChanged',async (accounts: string[]) => {
if (accounts.length === 0) {
// 用户断开所有账户
setAddress(null);
} else {
//可以进行后续的操作
}
})
转账
javascript
const onSend=async()=>{
// 1. 拿到浏览器注入的 provider
const provider = new ethers.providers.Web3Provider(window.ethereum);
// 2. 让用户授权并拿到 signer
await provider.send("eth_requestAccounts", []);
const signer = await provider.getSigner();
// 3. 构造交易
const tx = await signer.sendTransaction({
to: Recipient, // 接收地址
value: ethers.utils.parseEther(Amount), // 0.01 ETH → wei
// gasLimit、maxFeePerGas 可省略,MetaMask 会自动估算
});
// 4. 等待确认
const receipt = await tx.wait();
console.log("交易已确认,哈希:", receipt); // 成功
if(receipt.status==1){
//成功后进行后续操作
}else{
alert("交易失败");
}
}
获取账号列表
ini
# 创建 Provider
const provider = new ethers.providers.Web3Provider(window.ethereum);
# 授权
await provider.send('eth_requestAccounts', []);
# 获取账号列表
let addressList=await provider.listAccounts()
效果图
总结
至此,「钱包全链路」完整闭环:
连接 → 授权 → 转账 → 余额 → 交易记录 → 账号列表 → 监听 → 断开。
所有代码可直接落地项目;如需支持移动端 React-Native,把 window.ethereum
换成 WalletConnect 即可