Metamask移动端确认按钮无响应、代币识别异常,同代码桌面正常求助
问题排查与修复方案
核心问题分析
你的问题主要来自版本兼容性、代币小数位数处理错误、链配置缺失三个方面,结合Metamask移动端新版本的适配特性,以下是具体修复点:
1. 升级依赖版本解决兼容性
当前使用的@walletconnect/web3-provider@1.8.0和web3@1.8.0版本较旧,与Metamask移动端5.9.0+的适配存在已知问题:
- 将
@walletconnect/web3-provider升级至2.x稳定版(1.x已停止维护,对新Metamask版本支持不足) - 将
web3.js升级至1.10.x或4.x版本
2. 修正代币小数位数处理逻辑
你调用w3.utils.toWei()时默认按18位小数计算,但自定义BSC代币的小数位数可能并非18位(比如常见的10、12位)。Metamask移动端会读取合约的decimals()方法识别精度,错误的小数位计算会导致金额显示错乱(比如把1个代币识别成1BNB)。
修复方式:先获取合约的小数位数,再计算正确转账金额:
// 在connect函数中预获取代币小数位数 let tokenDecimals = await contract.methods.decimals().call(); window.tokenDecimals = tokenDecimals; // 在sendtransaction中计算金额 let calcAmount = w3.utils.toBN(vall).mul(w3.utils.toBN(10).pow(w3.utils.toBN(window.tokenDecimals)));
3. 完善WalletConnect Provider链配置
初始化Provider时未指定默认链ID,移动端Metamask可能出现链不匹配的情况,导致确认按钮无响应。同时冗余的givenProvider赋值完全没必要,反而可能干扰provider正常工作。
修复:初始化时添加chainId:56,并移除无用赋值:
var provider = new WalletConnectProvider.default({ infuraId: 'my infura id', chainId: 56, // 明确指定BSC链ID rpc: { 1: "https://mainnet.infura.io/v3/[myinfuraid]", 56: "https://bsc-dataseed.binance.org/" }, })
4. 优化异步流程与错误处理
原代码中connect()直接调用未处理错误,sendtransaction中await和.on()混用会导致异步流程混乱,移动端环境对这类问题更敏感。
优化后的代码示例:
var connect = async () => { try { await provider.enable(); var web3 = new Web3(provider); window.w3 = web3; contract = new w3.eth.Contract(ABI, contractAddress); // 获取代币小数位数 window.tokenDecimals = await contract.methods.decimals().call(); const accounts = await w3.eth.getAccounts(); accountFrom = accounts[0]; } catch (err) { console.error("连接失败:", err); } }; var sendtransaction = async () => { if (!accountFrom) { alert("请先连接钱包"); return; } try { let vall = 100; let calcAmount = w3.utils.toBN(vall).mul(w3.utils.toBN(10).pow(w3.utils.toBN(window.tokenDecimals))); const tx = await contract.methods.transfer(receiver, calcAmount).send({ from: accountFrom }); console.log("交易哈希:", tx.transactionHash); } catch (err) { console.error("转账失败:", err); } };
额外适配建议
- 移除所有
web3.givenProvider相关赋值,Web3.js会自动处理当前provider - 确保合约ABI完整包含
decimals()方法(如果之前ABI遗漏,必须补上) - 测试前确认Metamask移动端已切换至BSC链,避免跨链操作异常
内容的提问来源于stack exchange,提问作者Stef Man
相关产品推荐
相关产品推荐

