How to interact with an ERC20 token on mainnet

Hello Admin, I know this question might sound silly. How do I interact with erc20 token on the mainnet using infura and openzeppelin in a nodejs project? Any pointers to tutorials would really help…

1 Like

Hi @1baga,

Welcome to the community :wave:

I don’t think there are silly questions. Questions and answers build the knowledge base of the community.

I suggest having a look at the following from Learn guides:

I used them as the basis for the following quick sample. Please ask if you need further explanation:

Setup

$ mkdir mainneterc20
$ cd mainneterc20
$ npm init -y
$ npm i @openzeppelin/contracts @truffle/hdwallet-provider web3 @openzeppelin/contract-loader

Copy the contract artifacts

$ mkdir -p build/contracts/
$ cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/

Create a secrets.json (see the instructions in Connecting to Public Test Networks and create an Infura account if you don’t already have one)
:warning: Do not commit any secrets to a public repository as they can be used by anyone.

index.js

Create a script to interact. I only used read functions but you could also send transactions if you used a mnemonic with funds for gas.

If you are sending transactions, I suggest testing on a public testnet first. You could try with your own token. (See: Create an ERC20 using Truffle, Remix, buidler or OpenZeppelin CLI without writing Solidity)

// src/index.js
const Web3 = require('web3');
const { setupLoader } = require('@openzeppelin/contract-loader');

const { projectId, mnemonic } = require('../secrets.json');
const HDWalletProvider = require('@truffle/hdwallet-provider');

const provider = new HDWalletProvider(mnemonic, `https://mainnet.infura.io/v3/${projectId}`);

async function main() {
  // Set up web3 object
  const web3 = new Web3(provider);

  const loader = setupLoader({ provider: web3 }).web3;

  // Set up a web3 contract, representing a deployed ERC20, using the contract loader
  const address = '0xc00e94cb662c3520282e6f5717214004a7f26888';
  const token = loader.fromArtifact('ERC20', address);

  // Retrieve accounts
  const accounts = await web3.eth.getAccounts();
  
  // Call the deployed token contract
  const name = await token.methods.name().call();
  const symbol = await token.methods.symbol().call();
  const decimals = await token.methods.decimals().call();
  const totalSupply = await token.methods.totalSupply().call();
  console.log(`${name} (${symbol}) - Decimals:${decimals} Total Supply:${totalSupply}`);

  // At termination, `provider.engine.stop()' should be called to finish the process elegantly.
  provider.engine.stop();
}

main();

Set the address to the token that you want to interact with. Please note a token may not implement all the functionality so you may want to use IERC20 rather than ERC20.

For this example I used Compound. Have a look at Etherscan for other tokens to interact with: https://etherscan.io/tokens

Run the script.

$ node ./src/index.js
Compound (COMP) - Decimals:18 Total Supply:10000000000000000000000000

Will give this a try… thank you… but could you give an example of how i could send transactions?

1 Like

Hi @1baga,

To send transactions in a node script, please see the documentation: https://docs.openzeppelin.com/learn/deploying-and-interacting#sending-a-transaction

I recommend testing on a public testnet first and checking the appropriate gas price to use (https://ethgasstation.info) as well as the gas (limit) depending on the function call.

I updated the script to set an allowance on an ERC20 token on Ropsten (note the change in the Infura URL).

// src/index.js
const Web3 = require('web3');
const { setupLoader } = require('@openzeppelin/contract-loader');

const { projectId, mnemonic } = require('../secrets.json');
const HDWalletProvider = require('@truffle/hdwallet-provider');

const provider = new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/${projectId}`);

async function main() {
  // Set up web3 object
  const web3 = new Web3(provider);

  const loader = setupLoader({ provider: web3 }).web3;

  // Set up a web3 contract, representing a deployed ERC20, using the contract loader
  const address = '0xad6d458402f60fd3bd25163575031acdce07538d';
  const token = loader.fromArtifact('ERC20', address);

  // Retrieve accounts
  const accounts = await web3.eth.getAccounts();

  // Call the deployed token contract
  const name = await token.methods.name().call();
  const symbol = await token.methods.symbol().call();
  const decimals = await token.methods.decimals().call();
  const totalSupply = await token.methods.totalSupply().call();
  console.log(`${name} (${symbol}) - Decimals:${decimals} Total Supply:${totalSupply}`);

  console.log('Please wait whilst approve transaction sent')
  const tx = await token.methods.approve(accounts[1], "10000000000000000000")
   .send({ from: accounts[0], gas: 50000, gasPrice: 1e6 });

  console.log(tx);

  const allowance = await token.methods.allowance(accounts[0], accounts[1]).call();
  console.log(`Allowance set by ${accounts[0]} of ${allowance} tokens for ${accounts[1]}`)

  // At termination, `provider.engine.stop()' should be called to finish the process elegantly.
  provider.engine.stop();
}

main();

Hello @ abcoathup,

Is it possible to interact with localhost network, deploy a smart contract and interact with it using an available token from testnet for example or would you have to create/deploy a simple IERC20 token into localhost network e.g. a fake WETH token in order to play with it without forking out any of your own account´s testnet/mainnet tokens?

Thank you very much for your help!

Best,
Sam