You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js DApp连接Rootstock网络调用getBalance报错排查

问题解决:Pinia存储ethers Provider导致的Proxy错误

核心原因

Pinia的ref会对存入的复杂对象(比如ethers的Web3Provider)进行深度响应式代理,但ethers Provider内部包含一些只读、不可配置的内部属性(比如_network),代理后访问这些属性时会触发ES6 Proxy的兼容性问题,导致你遇到的错误。

修复步骤

1. 改用shallowRef存储Provider

将存储provider的ref替换为shallowRef,它只会对对象本身做响应式追踪,不会代理对象内部的属性,避免干扰ethers的内部逻辑:

import { ref, shallowRef } from 'vue'; // 导入shallowRef
import { defineStore } from 'pinia';
import { providers, utils } from 'ethers';

export const useRootstockStore = defineStore('rootstock', () => {
  const balance = ref(0);
  const address = ref('');
  const provider = shallowRef(null); // 替换为shallowRef

  const getBalance = async () => {
    if (!provider.value || !address.value) return;
    // 获取BigNumber格式的余额,转成可读的RBTC格式
    const balanceBigNumber = await provider.value.getBalance(address.value);
    balance.value = utils.formatEther(balanceBigNumber);
  };

  const connect = async () => {
    if (!window.ethereum) throw new Error('请安装MetaMask');
    
    // 请求授权账户
    await window.ethereum.request({ method: 'eth_requestAccounts' });
    // 实例化Provider,指定Rootstock链ID(主网30,测试网31)
    provider.value = new providers.Web3Provider(window.ethereum, 'any');
    
    // 获取当前账户
    const signer = provider.value.getSigner();
    address.value = await signer.getAddress();
    
    // 连接后立即获取余额
    await getBalance();
  };

  // 可选:监听网络/账户变化,自动更新数据
  const setupListeners = () => {
    if (!window.ethereum) return;
    window.ethereum.on('chainChanged', () => window.location.reload());
    window.ethereum.on('accountsChanged', async (accounts) => {
      address.value = accounts[0];
      await getBalance();
    });
  };

  return { balance, address, provider, connect, getBalance, setupListeners };
});

2. 验证Rootstock网络(可选)

在connect函数中添加链ID验证,避免用户连接到其他网络:

const connect = async () => {
  // ... 现有代码
  const network = await provider.value.getNetwork();
  // Rootstock主网ID是30,测试网是31
  if (![30, 31].includes(network.chainId)) {
    throw new Error('请切换到Rootstock网络');
  }
  // ... 后续代码
};

3. 格式化余额显示

ethers的getBalance返回BigNumber类型,直接赋值会显示原始wei数值,需要用utils.formatEther转成人类可读的RBTC单位(1 RBTC = 1e18 wei)。

额外注意事项

  • 调用getBalance前要检查provider和address是否已初始化,避免空值报错
  • 加入MetaMask安装检测,提升用户体验
  • 通过监听chainChanged和accountsChanged事件,确保账户/网络变化时数据同步

内容的提问来源于stack exchange,提问作者Irene Patrikios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:30:54