PolygonScan
HomeTwitterKnowledge Base API PRO
PolygonScan
PolygonScan
  • Introduction
  • ✨Getting Started
    • Creating an Account
    • Getting an API Key
    • Endpoint URLs
  • 🎯API Endpoints
    • Accounts
    • Contracts
    • Transactions
    • Blocks
    • Logs
    • Geth Proxy
    • Tokens
    • Gas Tracker
    • Stats
  • 🏆API PRO
    • PolygonScan API PRO
    • API PRO Endpoints
  • 📖Tutorials
    • Read/Write Smart Contracts
    • Verifying Contracts Programmatically
  • 🔧Misc Tools & Utilities
    • Libraries
    • Plugins
  • 🤝Support
    • FAQ
    • Rate Limits
    • Common Error Messages
    • Getting Help
  • Visit PolygonScan.com
Powered by GitBook
On this page
  • 1. Setting up a Node.js project
  • 2. Obtaining a contract's ABI
  • 3. Connecting to a node
  • 4. Integrating Ethers.js
  • 5. Creating a wallet
  • 6. Reading a contract
  • 7. Writing a contract
  • Beyond the testing grounds
  1. Tutorials

Read/Write Smart Contracts

PreviousAPI PRO EndpointsNextVerifying Contracts Programmatically

Last updated 8 months ago

can be thought of as a restaurant menu , they describe the possible functions that can be called to interact with a smart contract.

By knowing the functions available to a contract, we can programmatically use them — in situations where the project websites are down or when you need to automate certain transactions.

You will need installed, a valid and access to a Polygon node, such as from or .

1. Setting up a Node.js project

In a new folder, initiate a new Node.js project with the command npm init -y to accept all default project parameters.

A package.json file will be created for you, which contains all your packages and project information.

2. Obtaining a contract's ABI

Create a new file named script.js.

https://api-testnet.polygonscan.com/api?module=contract&action=getabi&address=0x50802059B3A299b36bc2c71aBEDBA450032f49AB&apikey=YourApiKeyToken
const fetch = require('node-fetch');

async function main() {

    // make an API call to the ABIs endpoint 
    const response = await fetch('https://api-testnet.polygonscan.com/api?module=contract&action=getabi&address=0x50802059B3A299b36bc2c71aBEDBA450032f49AB&apikey=YourApiKeyToken');
    const data = await response.json();

    // print the JSON response 
    let abi = data.result;
    console.log(abi);
}

main();

3. Connecting to a node

We're using Infura in this case, make sure to set your endpoint to the Mumbai Testnet and copy the WebSockets (WSS) endpoint.

4. Integrating Ethers.js

To do so, run the command npm i ethers from a terminal within this project directory to install it.

Ether.js provides several classes such as a Provider, which represents the state of the Polygon blockchain. We can create a new Provider using the syntax below, and pass in our node URL to initiate a connection to the Polygon network.

const fetch = require('node-fetch');
const ethers = require("ethers");

async function main() {
    const response = await fetch('https://api-testnet.polygonscan.com/api?module=contract&action=getabi&address=0x50802059B3A299b36bc2c71aBEDBA450032f49AB&apikey=YourApiKeyToken');
    const data = await response.json();

    let abi = data.result;
    console.log(abi);

    // creating a new Provider, and passing in our node URL
    const node = "wss://polygon-mumbai.infura.io/ws/v3/733a7efe57364ffd9210b582d7cd0cb3";
    const provider = new ethers.providers.WebSocketProvider(node);
}

main();

5. Creating a wallet

Another class that Ether.js allows us to create is a Wallet, which will allow us to specify a private key and use a Polygon address.

const fetch = require('node-fetch');
const ethers = require("ethers");

async function main() {
    const response = await fetch('https://api-testnet.polygonscan.com/api?module=contract&action=getabi&address=0x50802059B3A299b36bc2c71aBEDBA450032f49AB&apikey=YourApiKeyToken');
    const data = await response.json();

    let abi = data.result;
    console.log(abi);

    const node = "wss://polygon-mumbai.infura.io/ws/v3/733a7efe57364ffd9210b582d7cd0cb3";
    const provider = new ethers.providers.WebSocketProvider(node);

    // initiating a new Wallet, passing in our private key to sign transactions
    let privatekey = "fdfb72ce9754e3cbc1e79e44a8e20804cebd3c4a347605c6a3462a8de05b8784";
    let wallet = new ethers.Wallet(privatekey, provider);

    // print the wallet address
    console.log("Using wallet address " + wallet.address);
}

main();

6. Reading a contract

Finally, to interact with a smart contract we'll need to create a new Contract class.

The Contract class accepts an input of a contract address, an ABI (which we retrieved from the API earlier), and a wallet address to pay gas for any contract interactions.

const fetch = require('node-fetch');
const ethers = require("ethers");

async function main() {
    const response = await fetch('https://api-testnet.polygonscan.com/api?module=contract&action=getabi&address=0x50802059B3A299b36bc2c71aBEDBA450032f49AB&apikey=YourApiKeyToken');
    const data = await response.json();

    let abi = data.result;
    console.log(abi);

    const node = "wss://polygon-mumbai.infura.io/ws/v3/733a7efe57364ffd9210b582d7cd0cb3";
    const provider = new ethers.providers.WebSocketProvider(node);

    let privatekey = "fdfb72ce9754e3cbc1e79e44a8e20804cebd3c4a347605c6a3462a8de05b8784";
    let wallet = new ethers.Wallet(privatekey, provider);

    console.log("Using wallet address " + wallet.address);

    // specifying the deployed contract address 
    let contractaddress = "0x50802059B3A299b36bc2c71aBEDBA450032f49AB";
    
    // initiating a new Contract
    let contract = new ethers.Contract(contractaddress, abi, wallet);
}

main();

Having a closer look at the ABI we retrieved in Step 2, we can see that the contract has a function named retrieve, that doesn't accept an input however does return a uint256 number as an output.

[
   {
      "inputs":[
         // no input required
      ],
      "name":"retrieve", // function name retrieve 
      "outputs":[
         {
            "internalType":"uint256",
            "name":"",
            "type":"uint256" // returns a uint256 output
         }
      ],
      "stateMutability":"view",
      "type":"function"
   },
   {
      "inputs":[
         {
            "internalType":"uint256",
            "name":"num",
            "type":"uint256"
         }
      ],
      "name":"store",
      "outputs":[
         
      ],
      "stateMutability":"nonpayable",
      "type":"function"
   }
]

We can therefore call that function of the contract, read the value stored and print it out.

You may run this code from your console using the command node script.js.

Reading data stored in a contract incurs no gas cost, as it does not change the state of the Polygon blockchain.

const fetch = require('node-fetch');
const ethers = require("ethers");

async function main() {
    const response = await fetch('https://api-testnet.polygonscan.com/api?module=contract&action=getabi&address=0x50802059B3A299b36bc2c71aBEDBA450032f49AB&apikey=YourApiKeyToken');
    const data = await response.json();

    let abi = data.result;
    console.log(abi);

    const node = "wss://polygon-mumbai.infura.io/ws/v3/733a7efe57364ffd9210b582d7cd0cb3";
    const provider = new ethers.providers.WebSocketProvider(node);

    let privatekey = "fdfb72ce9754e3cbc1e79e44a8e20804cebd3c4a347605c6a3462a8de05b8784";
    let wallet = new ethers.Wallet(privatekey, provider);

    console.log("Using wallet address " + wallet.address);

    let contractaddress = "0x50802059B3A299b36bc2c71aBEDBA450032f49AB";
    let contract = new ethers.Contract(contractaddress, abi, wallet);

    // calling the "retrieve" function to read the stored value
    let read = await contract.retrieve();
    console.log("Value stored in contract is " + read.toString());
}

main();

7. Writing a contract

Referring to the ABI once again, we can see that the contract has another method store, which accepts a uint256 number as an input and does not return any output.

[
   {
      "inputs":[
         
      ],
      "name":"retrieve",
      "outputs":[
         {
            "internalType":"uint256",
            "name":"",
            "type":"uint256"
         }
      ],
      "stateMutability":"view",
      "type":"function"
   },
   {
      "inputs":[
         {
            "internalType":"uint256", // requires a uint256 input
            "name":"num",
            "type":"uint256"
         }
      ],
      "name":"store", // function name store
      "outputs":[
         // no output returned
      ],
      "stateMutability":"nonpayable",
      "type":"function"
   }
]

We can call that function and pass in any number as a parameter. To check that its updated, we'll wait for a 2 block confirmation, and read the contract again to confirm that the number has been updated.

You may run this code from your console using the command node script.js.

const fetch = require('node-fetch');
const ethers = require("ethers");

async function main() {
    const response = await fetch('https://api-testnet.polygonscan.com/api?module=contract&action=getabi&address=0x50802059B3A299b36bc2c71aBEDBA450032f49AB&apikey=YourApiKeyToken');
    const data = await response.json();

    let abi = data.result;
    console.log(abi);

    const node = "wss://polygon-mumbai.infura.io/ws/v3/733a7efe57364ffd9210b582d7cd0cb3";
    const provider = new ethers.providers.WebSocketProvider(node);

    let privatekey = "fdfb72ce9754e3cbc1e79e44a8e20804cebd3c4a347605c6a3462a8de05b8784";
    let wallet = new ethers.Wallet(privatekey, provider);

    console.log("Using wallet address " + wallet.address);

    let contractaddress = "0x50802059B3A299b36bc2c71aBEDBA450032f49AB";
    let contract = new ethers.Contract(contractaddress, abi, wallet);

    let read = await contract.retrieve();
    console.log("Value stored in contract is " + read.toString());

    // call the "store" function to update the value to 420
    let write = await contract.store(420);
    
    // wait for 2 blocks of confirmation 
    write.wait(2)
        .then(async () => {  
            // read the contract again, similar to above
            let read = await contract.retrieve();
            console.log("Updated value stored in contract is " + read.toString());
        });
}

main();

Beyond the testing grounds

In JavaScript, we'll be writing our code to make a request to the endpoint "", which you will need to specify your verified contract address.

For this example, we'll be borrowing a default contract available from , which has been deployed on the

To interact with smart contracts, we will need a connection to a Polygon node such as , or even running one of your own.

We'll need to integrate a JavaScript library, known as that will be used to interact with the Polygon blockchain.

Performing write operations will incur gas costs, as such you may get some to pay for transaction fees.

Writing new data to a contract will incur gas costs, as it requires fees to be paid to miners to process your transaction. Make sure your wallet has been funded with some testnet POL

You've now mastered how to programmatically interact with smart contracts , using ABIs retrieved from the Etherscan APIs.

Possible use cases from this include minting NFTs right on the dot , performing trades on Decentralised Exchanges (DEXs) and automating token transfers at certain time intervals .

The full sample code is on , feel free to experiment and use it ( with caution ) on real world contracts out there.

📖
✨
🎯
💰
⏰
Remix
Mumbai Testnet
.
Infura
Alchemy
Ether.js
Github
🍽️
ABIs (Application Binary Interface)
Node.js
Polygonscan API Key
Infura
Alchemy
testnet POL
Get Contract ABI for Verified Contract Source Codes