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

测试BSC预售dApp时MetaMask仅显示Gas费问题排查

问题排查与解决方案
  • 确认USDT授权流程
    预售合约要扣除用户USDT,必须先获得用户的授权权限。如果前端跳过了授权步骤直接调用购买函数,合约执行会失败,但MetaMask仍会显示Gas费用(因为交易已上链但执行未成功)。需在调用购买函数前,先调用USDT合约的approve方法:

    // 示例:初始化USDT合约实例后发起授权
    const usdtContract = new ethers.Contract(usdtAddress, usdtAbi, signer);
    const approveTx = await usdtContract.approve(presaleContractAddress, ethers.utils.parseUnits("100", 6));
    await approveTx.wait();
    

    注意授权金额需大于等于本次购买所需的USDT数量,且要等待授权交易确认后再执行购买操作。

  • 检查购买函数的参数传递
    确认调用预售合约购买函数时的参数是否匹配合约逻辑:

    • 如果合约要求传入USDT金额(而非KOO数量),需将金额转换为USDT的wei单位(USDT为6位小数,用ethers.utils.parseUnits(amount, 6)处理)。
    • 核对参数顺序、类型是否与合约函数定义一致,避免因参数错误导致合约执行无实质操作。
  • 排查合约函数的payable修饰符
    若预售采用USDT支付,购买函数不能添加payable修饰符(payable用于接收BNB等原生代币)。如果误加该修饰符,MetaMask会默认提示原生币转账,但实际合约逻辑是扣取USDT,就会出现仅显示Gas费的情况。查看Solidity合约代码:

    // 正确的USDT支付购买函数示例
    function buy(uint256 usdtAmount) external {
        IERC20(usdtAddress).transferFrom(msg.sender, address(this), usdtAmount);
        _mint(msg.sender, calculateKooAmount(usdtAmount));
    }
    
  • 添加交易错误捕获
    在前端调用合约函数时加入错误捕获,查看交易是否实际执行失败:

    try {
      const buyTx = await presaleContract.buy(usdtAmountWei);
      const receipt = await buyTx.wait();
      console.log("交易成功", receipt);
    } catch (err) {
      console.error("交易失败详情", err);
    }
    

    控制台的错误信息会直接定位问题,比如ERC20: insufficient allowance表示授权额度不足,ERC20: transfer amount exceeds balance表示用户USDT余额不够。

  • 验证BSC测试网USDT合约地址
    确认使用的BSC测试网USDT地址正确(常用测试网USDT地址:0x337610d27c682E347C9cD60BD4b3b107C9d34dDd),若地址错误,合约调用transferFrom会失败,导致交易无实质资产转移但仍需支付Gas费。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:37:11