Hardhat – Calling a Method from Local Hardhat Deployment

ethers.jsjavascriptsolidityweb3js

I'm trying to interact with contracts that are deployed in the local hardhat env through web3

I'm unable to get back the data from the contract, here's the info

I have:

var list = await contract.methods.getList();
console.log("list ", list );

which gets me

list {arguments: Array(0), call: ƒ, send: ƒ, encodeABI: ƒ, estimateGas: ƒ, …}

When I do

var list = await contract.methods.getList().call();
console.log("list ", list );

I get this error in the browser:

Returned values aren't valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node which is not fully synced.

I do:

Setup in console:

npx hardhat node
>Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/
>Accounts
>========
>...
npx hardhat compile
> Nothing to compile
npx hardhat run scripts/deploy.js --network hardhat    

Note: In the deploy.js file, I do a

const list = await contract.getList();
console.log("list", list ); // correctly outputs ["string", "string"]

The method:

mapping(uint256 => address) internal list;
uint256 internal listCount;

function getList() public override view returns (address[] memory) {
    address[] memory assets = new address[](listCount);

    for (uint256 i = 0; i < listCount; i++) {
      assets[i] = list[i];
    }
    return assets;
}

In react App.js:

import Contract_from './data/abi/Contract_.json'; // Contract_ is a placer

var contract = new web3.eth.Contract(Contract_, address_given_on_deploy);
var contractAddress = await contract .options.address; // correctly outputs


var list= await contract.methods.getList().call();
console.log("list", list);

As you see, this doesn't return the values from the method. What am I doing wrong here?

For any reason and may be likely the issue, here's my config:

require("@nomiclabs/hardhat-waffle");

// openzeppelin adds
require("@nomiclabs/hardhat-ethers");
require('@openzeppelin/hardhat-upgrades');

//abi
require('hardhat-abi-exporter');



// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async () => {
  const accounts = await ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  networks: {
    hardhat: {
      gas: 12000000,
      blockGasLimit: 0x1fffffffffffff,
      allowUnlimitedContractSize: true,
      timeout: 1800000,
      chainId: 1337
    }
  },
  solidity: {
    compilers: [
      {
        version: "0.8.0",
        settings: {
          optimizer: {
            enabled: true,
            runs: 1000
          }
        }
      },
      {
        version: "0.8.2",
        settings: {
          optimizer: {
            enabled: true,
            runs: 1000
          }
        }
      },
    ],
  },
  abiExporter: {
    path: './frontend/src/data/abi',
    clear: true,
    flat: true,
    only: [],
    spacing: 2
  }
}

__

I thought maybe i would try ethers.js since that is what i do my testing in but same issue.

For whatever reason, I can "get" the contracts, print the methods that belong to them, but I can't actually call the methods.

Here's my ethers.js brevity:

provider = new ethers.providers.Web3Provider(window.ethereum);
if(provider != null){
    const _contract = new ethers.Contract(address, _Contract, provider);
    var list= await _contract.getList().call();
    console.log("list", list);
}

The error i get from this is:

Error: call revert exception (method="getList()", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.4.0)

I've tried numerous contracts in the protocol and same thing for each

Best Answer

There are two things here. First, the error you get call revert exception when:

  • Method reverts during its execution.
  • Method is not present in your contract.
  • Contract not deployed on the network you're connected to (or address put is incorrect).

Probably you're facing the 3rd issue.

Second, ethers.js has a different API for .call() and .send().

If your method is view or pure, _contract.getList() will make a eth_call, similar to web3's .call(). If not then it will proceed with building a transaction and sending it, similar to web3's .send().

const list = await _contract.getList()