19

I am trying to read public variable from contract on chain using ethers.js.

Calling the methods work but I could not manage to read public property (without getter).

The methods works like this:

const ethers = require('ethers');
const provider = new ethers.providers.JsonRpcProvider('https://bsc-dataseed1.binance.org:443');

const contract = new ethers.Contract(address, [
    'function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256)',
], provider);

let works = await contract.getMultiplier(5, 10);

However, if I try accessing public property, it doesn't work. In fact, I receive error with the ABI.

const contract = new ethers.Contract(address, [
    'uint256 public totalAllocPoint',
    'PoolInfo[] public poolInfo'
], provider);

Error: unsupported fragment (argument="value", value="uint256 public totalAllocPoint", code=INVALID_ARGUMENT, version=abi/5.2.0)

poolInfo is even different because it needs a parameter.

How can I read totalAllocPoint and poolInfo from the contract?


Shouldn't it be like something like this:

let x = await contract.totalAllocPoint;
let y = await contract.poolInfo(2);

In the docs, unfortunately it only shows how to access methods

1 Answer 1

26

actually in solidity docs it's pointing that for each public member variable there will be a getter is defined automatically. In short you'll be able to get basic type public member like this: let x = await contract.totalAllocPoint(); you've been missing parenthesis here.

While you can get array like: let y = await contract.poolInfo(2); if the array length is more than 3 in this case of course.

For mapping types

mapping (address => mapping(uint256 => Order)) public orderByAssetId;
await contract.orderByAssetId(address, id);

To explain it more, if you look into ABI generated from compiling your solidity contract you should be able to see like this:

Defined contract in solidity

contract MasterChef {
...
  uint256 public totalAllocPoint = 0;
...
}

equals to ABI

  {
    "inputs": [],
    "name": "totalAllocPoint",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },

Keep on coding !


With Human-Readable ABI of ethers.js

const contract = new ethers.Contract(contractAddress, [
   'function totalAllocPoint() public view returns (uint256)'
], provider)

await contract.totalAllocPoint()
1
  • what if the public variable is a mapping? Commented Jul 19, 2023 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.