DEV Community

Discussion on: The Complete Guide to Full Stack Ethereum Development

Collapse
horaceshmorace profile image
Horace Nelson

Any idea why getBalance in App.js would throw

Error: call revert exception (method="balanceOf(address)", errorSignature=null, errorArgs=[null], reason=null, code=CALL_EXCEPTION, version=abi/5.1.0)

sendCoins works fine.

Collapse
gautham profile image
Gautham 🌢

Hi Horace, I was getting this same error - my issue was that I had re-deployed my contracts and their addresses had changed, so I had to copy-paste the new addresses to the top of App.js.

Collapse
horaceshmorace profile image
Horace Nelson • Edited on

Here's the deploy output:

Starting: scripts/deploy.js --network localhost
Deploying contracts with the account: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
Deploying a Greeter with greeting: Hello, World!
Greeter deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
Token deployed to: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
Enter fullscreen mode Exit fullscreen mode

And here's my App.js:

import './App.css';
import { useState } from 'react';
import { ethers } from 'ethers'
import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'
import Token from './artifacts/contracts/Token.sol/Token.json'
const greeterAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3"
const tokenAddress = "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512"

function App() {
  const [greeting, setGreetingValue] = useState()
  const [userAccount, setUserAccount] = useState()
  const [amount, setAmount] = useState()

  async function requestAccount() {
    await window.ethereum.request({ method: 'eth_requestAccounts' });
  }

  async function fetchGreeting() {
    if (typeof window.ethereum !== 'undefined') {
      const provider = new ethers.providers.Web3Provider(window.ethereum)
      console.log({ provider })
      const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)
      try {
        const data = await contract.greet()
        console.log('data: ', data)
      } catch (err) {
        console.log("Error: ", err)
      }
    }    
  }

  async function getBalance() {
    if (typeof window.ethereum !== 'undefined') {
      const [account] = await window.ethereum.request({ method: 'eth_requestAccounts' })
      console.log({ account }) // outputs { account: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      const signer = provider.getSigner()
      const contract = new ethers.Contract(tokenAddress, Token.abi, signer)

      // THIS THROWS
      contract.balanceOf(account)
        .then(data => {
          console.log("data: ", data.toString())
        })
    }
  }

  async function setGreeting() {
    if (!greeting) return
    if (typeof window.ethereum !== 'undefined') {
      await requestAccount()
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      console.log({ provider })
      const signer = provider.getSigner()
      const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)
      const transaction = await contract.setGreeting(greeting)
      await transaction.wait()
      fetchGreeting()
    }
  }

  async function sendCoins() {
    if (typeof window.ethereum !== 'undefined') {
      await requestAccount()
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      const signer = provider.getSigner()
      const contract = new ethers.Contract(tokenAddress, Token.abi, signer)
      contract.transfer(userAccount, amount).then(data => console.log({ data }))
    }
  }

  return (
    <div className="App">
      <header className="App-header">
        <button onClick={fetchGreeting}>Fetch Greeting</button>
        <button onClick={setGreeting}>Set Greeting</button>
        <input onChange={e => setGreetingValue(e.target.value)} placeholder="Set greeting" />

        <br />
        <button onClick={getBalance}>Get Balance</button>
        <button onClick={sendCoins}>Send Coins</button>
        <input onChange={e => setUserAccount(e.target.value)} placeholder="Account ID" />
        <input onChange={e => setAmount(e.target.value)} placeholder="Amount" />
      </header>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode
Collapse
smrnjeet222 profile image
Simranjeet Singh


const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner(); // remove this
const contract = new ethers.Contract(tokenAddress, Token.abi, signer); // replace signer with provider

signing is not required here!

Thread Thread
jamiescript profile image
Jamiebones

Signing is required.

Collapse
dabit3 profile image
Nader Dabit Author

Hey, not sure why you would run into that, did you figure it out?

Thread Thread
dominicwong profile image
Dominic Wong

I am running into the same issue

Thread Thread
dominicwong profile image
Dominic Wong

It worked when I called balanceOf inside deploy.js, just not when calling from App.js

Thread Thread
enemycnt profile image
Nikolay

Stuck with the same issue. After some deep dive into hardhat docs finally, I've found the cause.
It looks like instead

npx run scripts/deploy.js --network localhost
Enter fullscreen mode Exit fullscreen mode

should be

npx run hardhat scripts/deploy.js --network localhost
Enter fullscreen mode Exit fullscreen mode

@dabit3 could you please correct it?

Collapse
sprtd profile image
Dav • Edited on

I faced the same issue too and figured it out. First, make sure you've selected the right MetaMask network. If you deployed to a local node, make sure the selected MetaMask network on your browser is Localhost: 8545. If you deployed to ropsten, make sure you've selected Ropsten Test Network. Secondly, each time you successfully deploy your contract, make sure you correctly copy and reference the generated contract address if you intend to interact with the newly deployed contract without errors. Just like @richardmelko advised, make sure that your tokenAddress is pointing the Token contract address you copied after deployment.

Collapse
richardmelko profile image
Richard Melkonian

I had this error after switching to live test nets then back to local host. The error originates from these line of code in your react components.

const greeterAddress = "{address that you copied in from the local node instance}"

const tokenAddress = "{address that you copied in from the local node instance}"

If you're deploying on Ropsten for example, you will need to manually update this line of code, changing the address to the deployed address that hardhat will supply in the terminal after successfully deploying. So when switching from local to test net, this line needs to be changed!

Collapse
niroshans profile image
Niroshan Sooriyakumar • Edited on

Not sure if this will help but I had the same error while working on my own project. I used this blog post as a starting point and my code is slightly different but I was also getting this error on a read-only transaction. The code was working the day before and I was really consued.

After some failed googling, I saw that metamask was still pointing to mainnet (I had switched away from localhost to mainnet later that day). After switching back to localhost things just started working!

Not sure if this will help your particular issue but thought I'd post this here if someone else is also googling this error. Hopes this helps someone out there!