WalletConnect调用USDT ERC20转账时钱包金额显示异常问题
WalletConnect对接Rainbow/Trust Wallet时USDT转账金额显示异常
我在DApp中通过WalletConnect二维码实现了移动端钱包(Omni、Rainbow、Trust Wallet)的连接,现在尝试发起USDT-ERC20转账,代码如下:
async function TransferUSDT() { let provider = new WalletConnectProvider({ rpc: { 1: "https://cloudflare-eth.com/" } }); await provider.enable(); const web3 = new Web3(provider); const contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7"; const contract = new web3.eth.Contract(abi, contractAddress, { gasLimit: "46085", gasPrice: "16747612334" }); contract.methods .transfer(destinationAdrs, "1000000") .send({ from: activeAccount }) .then(function (receipt: any) { console.log(receipt); }); }
发起1 USDT转账请求时,仅Omni钱包能正确显示1 USDT金额,Rainbow钱包显示为1 ETH,Trust Wallet显示为0 ETH。请问这是什么原因?该如何修复?
原因分析
- ABI信息不完整:你使用的
abi可能仅包含transfer方法,缺少USDT合约的核心元数据方法(name()、symbol()、decimals())。Omni钱包可能内置了主流代币的合约信息,能自动识别USDT,但Rainbow和Trust Wallet需要通过ABI解析代币属性,才能正确转换并显示金额。 - Provider实例重复初始化:每次调用转账函数都新建
WalletConnectProvider,导致会话无法持续,钱包无法缓存合约相关信息,增加了解析错误的概率。 - 硬编码Gas参数:固定的
gasLimit和gasPrice可能不符合钱包的预期格式,干扰了交易信息的正常解析。
修复方案
1. 使用完整的USDT合约ABI
确保ABI包含name、symbol、decimals等视图方法,示例片段如下:
[ { "constant": true, "inputs": [], "name": "name", "outputs": [{"name": "", "type": "string"}], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [{"name": "", "type": "string"}], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [{"name": "", "type": "uint8"}], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ {"name": "_to", "type": "address"}, {"name": "_value", "type": "uint256"} ], "name": "transfer", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "nonpayable", "type": "function" } ]
2. 复用WalletConnectProvider实例
将Provider初始化移到函数外部,避免重复建立连接:
// 全局初始化Provider let provider = new WalletConnectProvider({ rpc: { 1: "https://cloudflare-eth.com/" } }); let web3; async function initWalletConnect() { await provider.enable(); web3 = new Web3(provider); } // 转账函数复用已初始化的web3和provider async function TransferUSDT() { if (!web3) { await initWalletConnect(); } const contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7"; const contract = new web3.eth.Contract(completeAbi, contractAddress); // 估算Gas参数,替代硬编码 const gasLimit = await contract.methods.transfer(destinationAdrs, "1000000").estimateGas({ from: activeAccount }); const gasPrice = await web3.eth.getGasPrice(); contract.methods .transfer(destinationAdrs, "1000000") .send({ from: activeAccount, gasLimit: gasLimit, gasPrice: gasPrice }) .then(function (receipt) { console.log(receipt); }); }
3. 动态估算Gas参数
使用estimateGas和getGasPrice获取实时Gas参数,避免硬编码导致的兼容性问题,同时让钱包更易识别交易的合法性。
内容的提问来源于stack exchange,提问作者Abhilash Reddy
相关产品推荐
相关产品推荐

