'.balanceOf is not a function - Interact with existing Contract on Blockchain

I want to automate my staking on The Sandbox. For that I need in the first step to interact with the mSand-Matic Pool Contract. It is this one: https://polygonscan.com/address/0x4ab071c42c28c4858c4bac171f06b13586b20f30#code

I have written a little program in a GitHub repository to show what I have done: https://github.com/ChristianErdtmann/mSandMaticStakingAutomation

Or here is the code example from the contract-interact.js

Web3 = require('web3')
const fs = require('fs');

const web3 = new Web3("https://polygon-rpc.com")
const contractAddress = "0x4AB071C42C28c4858C4BAc171F06b13586b20F30"
const contractJson = fs.readFileSync('./abi.json')
const abi = JSON.parse(contractJson)
const mSandMaticContract = new web3.eth.Contract(abi, contractAddress)
mSandMaticContract.balanceOf('0x7e5475290Df8E66234A541483453B5503551C780')

The ABI I have taken from the contract link on the top. But it seems there is a problem.

I tried for testing to read something from the contract. For that I used the function balanceOf(address), how you can see in the code.

But I always get this error:

TypeError: mSandMaticContract.balanceOf is not a function



Solution 1:[1]

I found the solution

  1. web3 needs .methots to get acces to the balanceOf() function
  2. if we want only to read so we need to add .call()
  3. we need to add await before the function is called this needs to be in a asynchonus function

So the final working code is:

Web3 = require('web3')
const fs = require('fs');

const web3 = new Web3("https://polygon-rpc.com")
const contractAddress = "0x4AB071C42C28c4858C4BAc171F06b13586b20F30"
const contractJson = fs.readFileSync('./abi.json')
const abi = JSON.parse(contractJson)
const mSandMaticContract = new web3.eth.Contract(abi, contractAddress)

asyncCall()

async function asyncCall() {
    console.log(await mSandMaticContract.methods.balanceOf('0x7e5475290Df8E66234A541483453B5503551C780').call())
}

If you dont want only to read you need addtional to sign the transaction with:

The solution is, to sign the transaction before sending we can doing this with any method by this code:

encoded = mSandMaticContract.methods.getReward().encodeABI()
var block = await web3.eth.getBlock("latest");
var gasLimit = Math.round(block.gasLimit / block.transactions.length);

var tx = {
    gas: gasLimit,
    to: publicKey,
    data: encoded
}

web3.eth.accounts.signTransaction(tx, privateKey).then(signed => {
    web3.eth.sendSignedTransaction(signed.rawTransaction).on('receipt', console.log)
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1