React Native DApp 开发全栈实战·从 0 到 1 系列(钱包全链路)

前言

本文主要用 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 即可

相关推荐
LING2 小时前
RN容器启动优化实践
android·react native
Live000003 天前
在鸿蒙中使用 Repeat 渲染嵌套列表,修改内层列表的一个元素,页面不会更新
前端·javascript·react native
木西4 天前
揭秘 Web3 隐私社交标杆:CocoCat 的核心架构与智能合约实现
web3·智能合约·solidity
木西5 天前
深度拆解 Grass 模式:基于 EIP-712 与 DePIN 架构的奖励分发系统实现
web3·智能合约·solidity
Black_mario7 天前
Web3 时代的“伯克希尔”时刻:解析 Jason Hitchcock 与 Greenlane 的 Berachain 主权财库之路
web3
lbb 小魔仙7 天前
鸿蒙跨平台项目实战篇03:React Native Bundle增量更新详解
react native·react.js·harmonyos
China_Yanhy7 天前
入职 Web3 运维日记 · 第 14 日:铸造无形钥匙 —— OIDC 与 CI/CD 施工实录
运维·web3
2301_796512527 天前
【精通篇】打造React Native鸿蒙跨平台开发高级复合组件库开发系列:点击组件(跳转快应用)
javascript·react native·react.js·ecmascript·harmonyos
2301_796512527 天前
【精通篇】打造React Native鸿蒙跨平台开发高级复合组件库开发系列:Sidebar 侧边导航(绑定当前选中项的索引)
javascript·react native·react.js·ecmascript·harmonyos
lbb 小魔仙7 天前
鸿蒙跨平台项目实战篇01:React Native Bundle版本管理详解
react native·react.js·harmonyos