Ethers.js Solidity – How to Read Public Variable from Contract

dapp-developmentdappsethers.jssolidity

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

Best Answer

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()
Related Topic