使用useDapp调用Solidity合约payable存款函数无法传入ETH金额求助
问题:useDapp调用payable合约函数无法传入ETH金额
我用Remix编写了DepositWithdraw Solidity合约,其中deposit为payable函数,在Remix中存款操作正常。但前端使用useDapp库的useContractFunction调用该函数时,遇到以下问题:
- 调用
send(value)会提示参数数量错误(deposit函数定义为无参数) - 无参数调用
send()时,MetaMask仅显示Gas费,不显示要存入的ETH金额 - 尝试给
useContractFunction添加选项参数也未解决问题
合约代码
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract DepositWithdraw { mapping(address => uint256) private balances; event Deposit(address indexed depositor, uint256 amount); event Withdrawal(address indexed withdrawer, uint256 amount); function deposit() public payable { balances[msg.sender] += msg.value; emit Deposit(msg.sender, msg.value); } function withdraw(uint256 amount) public { require(balances[msg.sender] >= amount, "Insufficient balance"); balances[msg.sender] -= amount; payable(msg.sender).transfer(amount); emit Withdrawal(msg.sender, amount); } function balanceOf(address account) public view returns (uint256) { return balances[account]; } }
原前端代码
import { Contract } from 'ethers'; import { Interface } from 'ethers/lib/utils'; import { useContractFunction } from '@usedapp/core'; const contractAddress = // 我的合约地址; const ABI = new Interface( //...从Remix复制的合约ABI ); const contract = new Contract(contractAddress, ABI); const { send } = useContractFunction(contract, 'deposit'); // send(value) 会报错,提示deposit函数参数数量不正确(需要0个参数)
解决思路与正确实现
核心原因
useContractFunction返回的send方法,第一个参数是合约函数的业务入参数组,而ETH金额属于交易的value配置项,需要放在第二个参数的配置对象中,不能直接作为第一个参数传入。
正确调用代码
import { Contract } from 'ethers'; import { Interface } from 'ethers/lib/utils'; import { useContractFunction } from '@usedapp/core'; import { utils } from 'ethers'; const contractAddress = "你的合约地址"; const ABI = new Interface( // 从Remix复制的合约ABI ); const contract = new Contract(contractAddress, ABI); const { send } = useContractFunction(contract, 'deposit'); // 处理存款的函数 const handleDeposit = async () => { // 转换金额为wei单位(示例为存入0.1 ETH) const depositAmount = utils.parseEther("0.1"); // send第一个参数是空数组(因为deposit无业务参数),第二个参数是交易配置 await send([], { value: depositAmount }); };
关键注意点
- 必须将ETH金额转换为wei单位:用ethers的
utils.parseEther()或utils.parseUnits()方法,避免因单位错误导致金额异常 - 如果合约函数本身有业务参数(比如
deposit(uint256 tokenId)),则第一个参数传入业务参数数组(如[tokenId]),value仍放在第二个参数的配置中 - 确保useDapp版本在v1.x及以上,该版本开始稳定支持这种交易配置传递方式
内容的提问来源于stack exchange,提问作者Dawid Mazewski
相关产品推荐
相关产品推荐

