Error send ERC20 smart contract method [SOLVED]

Hi there,
I just started with Moralis and I’m following your video tutorial on youtube. I created a simple token in solidity and I’m trying to call its function from the browser console in js, but I get an error.

Here an image of the console:

I’m using ganache and metamask is connected to my website.
This is the function I want to call that are inside my smart contract:

function stake(uint256 _amount) public {
      // Make sure staker actually is good for it
      require(_amount < balanceOf(msg.sender), "Cannot stake more than you own");

        _stake(_amount);
         // Burn the amount of tokens on the sender
        _burn(msg.sender, _amount);
    }
function hasStake(address _staker) public view returns(StakingSummary memory){
        // totalStakeAmount is used to count total staked amount of the address
        uint256 totalStakeAmount; 
        // Keep a summary in memory since we need to calculate this
        StakingSummary memory summary = StakingSummary(0, stakeholders[stakes[_staker]].address_stakes);
        // Itterate all stakes and grab amount of stakes
        for (uint256 s = 0; s < summary.stakes.length; s += 1){
           uint256 availableReward = calculateStakeReward(summary.stakes[s]);
           summary.stakes[s].claimable = availableReward;
           totalStakeAmount = totalStakeAmount+summary.stakes[s].amount;
        }
       // Assign calculate amount to summary
       summary.total_amount = totalStakeAmount;
       return summary;
    }

Also, I have another 2 questions:

  • When should I use .call({from: }) rather then .send({from: })?
  • How can I read the return value of my “hasStake()” function after I called it?

Thank you in advance for your help!

Hi @xXNicolaXx

Have you approved tokens before spending?

For first question: you should use .call when you use functions that only read data from the smart contract and use .send when you want to interact with the smart contract in order to change the internal state of the smart contract (like you are trying to do stake here). .send will pop up MetaMask in order to sign a transaction and to send it to the blockchain in order to be mined.
For second question: you can try to call the function to see what it returns.

1 Like

Thanks for your answers @Yomoo and @cryptokid.

@Yomoo do you mean in metamask? I deploy the contract with remix to my local chain (ganache), so it’s not deployed on the mainnet net or the test net. When I try to interact with the contract, metamask pop up only when I use the send({from:}). Or do you mean that I should approve it by code?

@cryptokid thanks for the explaination. So I changed the .call() to .send() when I want to use the stake function, but when mematask popup it says there is an exception thrown by the contract, before I click “confirm”. How can I see this exception? Maybe is the one in the previous screenshot (?).

Also, now if I call hasStake() like this await contract.methods.hasStake(userAddress).call({from: userAddress}); it returns the value correctly (maybe before I didn’t use the .call({from})

I don’t understand what you mean with maybe before I didn’t use the .call({from}.

Related to your exception, you’ll have to debug the smart contract yourself, try to remove some code from it, to see if it works will less code until you get it work.

Ok I think I solved the problem. I have 2 contract in my .sol file, one is Stakeable and the other one is my token contract which inherit from Stakeable. I deployed Stakeable instead of the Token contract which contains the stake function. Now it works. Thanks for your help guys!

2 Likes

Great job @xXNicolaXx

Happy BUIDLing :man_mechanic: