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 即可

相关推荐
wincheshe1 天前
React Native inspector 点击组件跳转编辑器技术详解
react native·react.js·编辑器
墨狂之逸才2 天前
React Native Hooks 快速参考卡
react native
墨狂之逸才2 天前
useRefreshTrigger触发器模式工作流程图解
react native
墨狂之逸才2 天前
react native项目中使用React Hook 高级模式
react native
wayne2142 天前
React Native 状态管理方案全梳理:Redux、Zustand、React Query 如何选
javascript·react native·react.js
Mintopia3 天前
🎙️ React Native(RN)语音输入场景全解析
android·react native·aigc
程序员Agions3 天前
React Native 邪修秘籍:在崩溃边缘疯狂试探的艺术
react native·react.js
Rockbean3 天前
3分钟Solidity: 11.1 重入攻击
web3·智能合约·solidity
Rockbean3 天前
3分钟Solidity: 10.6 时间锁定
web3·智能合约·solidity
电报号dapp1194 天前
DApp开发:从数字工具到自治理社会系统的构建之路
web3·去中心化·区块链·智能合约