简体   繁体   中英

Can't seem to call a smart contract function in the UI

I'm working on this little project where the smart contract has a deposit function and a withdraw function, and the balance gets updated whenever I interact with it. 在此处输入图像描述

The deposit function works as expected, but whenever I try to withdraw nothing happens. I'm using ethers.js, react.js, bootstrap, and hardhat.

Front end:

import React, { useState, useEffect } from "react";
import { ethers } from "ethers";

function App() {
  const [balance, setBalance] = useState()
  const [depositValue, setDepositValue] = useState('')
  const [withdrawValue, setWithdrawValue] = useState('')

  const provider = new ethers.providers.Web3Provider(window.ethereum)
  const signer = provider.getSigner()
  const contractAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3"

  const ABI = [
    {
      "inputs": [],
      "name": "deposit",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        }
      ],
      "name": "returnBalance",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "withdraw",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ]

  const contract = new ethers.Contract(contractAddress, ABI, signer);

  useEffect(() => {
    const connectWallet = async () => {
      await provider.send("eth_requestAccounts", []);
    }

    const getBalance = async () => {
      const balance = await provider.getBalance(contractAddress)
      const balanceFormatted = ethers.utils.formatEther(balance)
      setBalance(balanceFormatted);
    }

    connectWallet()
      .catch(console.error);

    getBalance()
      .catch(console.error);
  })

  const handleDepositChange = (e) => {
    setDepositValue(e.target.value);
  }

  const handleWithdrawChange = (e) => {
    setWithdrawValue(e.target.value);
  }

  const handleDepositSubmit = async (e) => {
    e.preventDefault()
    console.log(depositValue)
    const ethValue = ethers.utils.parseEther(depositValue)
    const depositEth = await contract.deposit({ value: ethValue })
    await depositEth.wait()
    const balance = await provider.getBalance(contractAddress)
    const balanceFormatted = ethers.utils.formatEther(balance)
    setBalance(balanceFormatted);
  }

  const handleWithdrawSubmit = async (e) => {
    //I suspect the problem is here
    e.preventDefault()
    console.log(withdrawValue)
    const ethValue = ethers.utils.parseEther(withdrawValue)
    const withdrawEth = await contract.withdraw({ value: ethValue })
    await withdrawEth.wait()
    const balance = await provider.getBalance(contractAddress)
    const balanceFormatted = ethers.utils.formatEther(balance)
    setBalance(balanceFormatted);
  }

  return (
    <div className="container">
      <div className="container">
        <div className="row mt-5">
          <div className="col-sm">
            <h3>Welcome</h3>
            <p>Your Balance: {balance} ETH</p>
          </div>
          <div className="col-sm">
            <form onSubmit={handleDepositSubmit}>
              <div className="form-group">
                <input type="number" className="form-control" placeholder="0" value={depositValue} onChange={handleDepositChange} />
              </div>
              <button type="submit" className="btn btn-success mt-3">Deposit</button>
            </form>
            <form className="mt-5" onSubmit={handleWithdrawSubmit}>
              <div className="form-group">
                <input type="number" className="form-control" placeholder="0" value={withdrawValue} onChange={handleWithdrawChange} />
              </div>
              <button type="submit" className="btn btn-dark mt-3">Withdraw</button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;

Smart contract:

pragma solidity 0.8.4;

contract bank {
    mapping(address => uint256) private balances;

    function returnBalance(address account) public view returns (uint256) {
        return balances[account];
    }

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }

    function withdraw(uint256 amount) public {
        require(returnBalance(msg.sender) >= amount);
        balances[msg.sender] -= amount;
        payable(msg.sender).transfer(amount);
    }
}

Your withdraw function accepts amount as a parameter in wei format. Update your handleWithdrawSubmit function like following.

const handleWithdrawSubmit = async (e) => {
    //I suspect the problem is here
    e.preventDefault()
    console.log(withdrawValue)
    let amount = ethers.utils.parseEther(withdrawValue)
    amount = amount.toString();
    const withdrawEth = await contract.withdraw(amount)
    await withdrawEth.wait()
    const balance = await provider.getBalance(contractAddress)
    console.log('balance', balance)
    const balanceFormatted = ethers.utils.formatEther(balance)
    setBalance(balanceFormatted);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM