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
相关产品推荐
相关产品推荐

