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

ethers.js调用contract.fund报错invalid decimal value及点击无响应求助

Web3前端应用问题修复方案

问题分析与修复步骤

问题1:控制台出现invalid decimal value错误

该错误因ethers.utils.parseEther()接收到空值或无效ETH金额触发——当输入框为空时,ethAmount是空字符串,直接传给parseEther会引发参数无效错误。

问题2:点击Fund按钮无反应

核心原因是事件绑定错误:你在添加监听时直接执行了函数(connect()、fund()),而非传递函数引用。页面加载时这两个函数就已执行,点击按钮时实际没有绑定回调逻辑。


完整修复后的代码

index.js

import {ethers} from "./ethers-5.2.js"
import {abi, contractAddress} from "./constants.js"

let btn = document.getElementById("connectbutton")
let fundbtn = document.getElementById("fundbutton")

// 修复:去掉函数后的括号,传递函数引用
btn.addEventListener("click", connect)
fundbtn.addEventListener("click", fund)

console.log(ethers)

async function connect() {
    if (typeof window.ethereum !== "undefined") {
        await window.ethereum.request({ method: "eth_requestAccounts" })
        console.log("已连接")
        btn.innerHTML = "已连接"
    } else {
        fundbtn.innerHTML = "请安装MetaMask"
    }
}

async function fund() {
    const ethAmount = document.getElementById("ethAmount").value.trim()
    // 新增:校验输入值有效性
    if (!ethAmount || isNaN(parseFloat(ethAmount)) || parseFloat(ethAmount) <= 0) {
        console.log("请输入有效的ETH金额")
        return
    }
    console.log(`正在转入 ${ethAmount} ETH...`)
    if (typeof window.ethereum !== "undefined") {
      const provider = new ethers.providers.Web3Provider(window.ethereum)
      const signer = provider.getSigner()
      const contract = new ethers.Contract(contractAddress, abi, signer)
      try {
        const transactionResponse = await contract.fund({
          value: ethers.utils.parseEther(ethAmount),
        })
        await listenForTransactionMine(transactionResponse, provider)
        console.log("交易已确认")
      } catch (error) {
        console.error("交易失败:", error)
      }
    } else {
      fundbtn.innerHTML = "请安装MetaMask"
    }
}

// 补充:实现缺失的交易确认监听函数
function listenForTransactionMine(transactionResponse, provider) {
    console.log(`等待交易 ${transactionResponse.hash} 确认...`)
    return new Promise((resolve, reject) => {
        provider.once(transactionResponse.hash, (transactionReceipt) => {
            console.log(`交易已完成,区块号:${transactionReceipt.blockNumber}`)
            resolve()
        })
    })
}

index.html

<button id="connectbutton">连接钱包</button>
<button id="fundbutton">转入资金</button>

<label for="ethAmount">ETH金额</label>
<input type="number" id="ethAmount" placeholder="1" step="0.0001" />

<script src="index.js" type="module"></script>

关键修复点说明

  • 事件绑定修复:将btn.addEventListener("click", connect())改为btn.addEventListener("click", connect),确保点击按钮时才执行对应函数。
  • 输入值校验:在fund函数开头添加校验逻辑,确保输入的ETH金额不为空、是有效数字且大于0,避免parseEther接收无效参数。
  • 补充缺失函数:实现listenForTransactionMine函数,完成交易发送后的区块确认监听逻辑。
  • 输入框优化:添加step="0.0001"属性,支持小数金额输入,匹配ETH的精度要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:50:20