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…
Hi @1baga,
Welcome to the community
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)
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?
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