Uncaught (in promise) Error: call revert exception when trying to call a read only function

I just tried using Moralis in calling functions in the deployed contract in Ganache.

I successfully did one transaction, but if I call a simple view function, I got this error:

moralis.js:42616 Uncaught (in promise) Error: call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method=“getCredslength()”, errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.6.0)

This is the view function:

function getCredslength()
    public
    view
    returns(uint total){
      total = allCreds.length;
      return(total);
    }

and this is the function I used in calling the method:

async function getIssuedCreds(){
    const credlength = {
        contractAddress: "0x0566200D13627204e7AE3D7cf3976B13A1E5e6d4",
        functionName: "getCredslength",
        abi: CredentialsArtifact.abi,
    }

    const l = await Moralis.executeFunction(credlength);
    console.log(l);
}

I’m not sure why I’m getting this error. It says in CALL_EXCEPTION that it might be because:

  • the code does not exist on-chain
  • wrong code is being accessed
  • wrong ABI is being used
  • I’m connected to a different network than the contract deployed

On the code does not exist on-chain, wrong code is being accessed, :

I was able to successfully make a transaction and mine a block using the same contract. It’s also in the Ganache UI

On wrong ABI is being used:
I’m importing the JSON file of the deployed contract and stored it in a variable and got the ABI from there.

So I think I’m left with this, I'm connected to a different network than the contract deployed.

Does this mean if metamask is connected to the ganache? or the project is connected to ganache?

You have to connect MetaMask to ganache. After you connect MetaMask to ganache you should be able to make a transfer for eth directly in MetaMask from one address to another address.

1 Like

Metamask is already connected to ganache. I also tried transferring eth directly in Metamask and it reflected in the Ganache UI.

Then, you could try to make a send instead of a call to see if it gets executed in ganache. You can remove that view in abi (the equivalent of that view).

I tried sending and it works fine. The transaction is also in ganache.

what did you try sending? you used Moralis.executeFunction with a write function?

1 Like

Yes I used executeFunction with write function. Here’s how I called it:

    const transaction = {
        contractAddress: "0x0566200D13627204e7AE3D7cf3976B13A1E5e6d4",
        functionName: "issueDoc",
        abi: CredentialsArtifact.abi,
        params: {
            _recipient: recipient,
            _docAddress: fileURL,
            _dateIssued: dateIssued,
        }
    }

    await Moralis.executeFunction(transaction);

and this is the write function:

function issueDoc(address _recipient, string memory _docAddress,
     string memory _dateIssued
    )
    public
    {
      emit DocAdded(msg.sender);

      allDocs.push(
        Doc({
          issuer: msg.sender, 
          recipient: _recipient,
          docAddress: _docAddress,
          dateIssued: _dateIssued,
        })
      );

ok, then you should not have problems with that read only function, unless the function generates that exception on execution

I tried using it on a pure function just to check if it will successfully return a static data but I still got the same error. I’m not sure why this is not working.

maybe you can try with a simpler function, that just returns a number

1 Like

I did that. I tried returning just a uint 1 but I got the same error

strange, can you try directly with ethers or web3 to call that function?

Hi! I tried doing it directly with web3. It’s also working with the write functions but with the view functions I’m getting this error:

Uncaught (in promise) Error: 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.

strange, it should work without problems, what is the code that you use with web3?

I followed Truffle’s documentation.

I first initialized Web3 and the contract with this functions

var CredentialsArtifact;

async function initWeb3(){
    if (window.ethereum) {
        web3Provider = window.ethereum;
        try {
          // Request account access
          await window.ethereum.request({ method: "eth_requestAccounts" });;
        } catch (error) {
          // User denied account access...
          console.error("User denied account access")
        }
      }
      // Legacy dapp browsers...
      else if (window.web3) {
        web3Provider = window.web3.currentProvider;
      }
      // If no injected web3 instance is detected, fall back to Ganache
      else {
        web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
      }
        web3 = new Web3(web3Provider);
        return initContract();
}

function initContract() {
    var contract = require('@truffle/contract');
    $.getJSON('../build/contracts/Credentials.json', function(data) {
        // Get the necessary contract artifact file and instantiate it with @truffle/contract
        CredentialsArtifact = data;
        contracts.Credentials = TruffleContract(CredentialsArtifact);
        
        // Set the provider for our contract
        contracts.Credentials.setProvider(web3Provider);
    });
}

then used this function to call the method:

async function getLength(){
    await web3.eth.getAccounts(function(error, accounts){
        if(error){
            console.log(error);
        }
        var account = accounts[0];

        contracts.Credentials.deployed().then(function(instance){
          let x = instance.getCredslength.call();
          console.log(x);
        });

    });
}

if instead of let x = instance.getCredslength.call(); you write let x = instance.getCredslength.send(); then it works?

I tried doing that just now, and it throwed this error:

TypeError: instance.getCredslength.send is not a function

I think because getCredslength is a view function in the contract.

I’ve been stuck with this for almost a day now. I can’t figure out what’s wrong. Just in case this will be useful, here’s my truffle-config file:

module.exports = {
  networks: {
    development: {
     host: "127.0.0.1",     // Localhost (default: none)
     port: 7545,            // Standard Ethereum port (default: none)
     network_id: "*",       // Any network (default: none)
    },
  },

  // Set default mocha options here, use special reporters etc.
  mocha: {
    // timeout: 100000
  },

  // Configure your compilers
  compilers: {
    solc: {
      version: "0.8.13",      // Fetch exact version from solc-bin (default: truffle's version)
    }
  },
};

can you try to deploy the contract in remix to see if it works as expected there?

Yes, all functions are working.

you can try to deploy it from remix, to local ganache, to see if it works that way