Search code examples
ethereumsmartcontractsweb3js

How to interact with other smart contracts using web3js?


In the doc of web3.js I can only find use case where interaction with your own smart contracts are described. But how do I interact with other smart contracts on the blockchain?

This is easily possible through blockchain explores like etherscan: Lookup Smart Contract, click "contract", and then click "write contract".

But how to do this in web3.js?


Solution

  • You can also interact with other smart contracts.

    Some implement authorization schemes where only certain sender addresses can execute certain functions. But most smart contract functions are executable by anyone.

    Mind that there are two types of interaction.

    • A transaction needs to be signed by a private key of the sender and costs gas fees. It can change state of the contract.

    • A call only reads data, so it's free but it cannot change any state.

    In order to interact with a contract, your web3js instance needs to be connected to a node provider on the same network as the contract is deployed, and you need to know the contract ABI JSON that's usually provided by the contract author.

    Following example shows interaction with this sample contract.

    Solidity:

    pragma solidity ^0.8;
    
    contract MyContract {
        uint number;
    
        // changes state - requires a transaction
        function setNumber(uint _number) external {
            number = _number;
        }
    
        // a `view` function only reads data - can be called
        function getNumber() external view returns (uint) {
            return number;
        }
    }
    

    web3js:

    const Web3 = require("web3");
    const web3 = new Web3("https://<provider_address>");
    
    async function run() {
        const contract = new web3.eth.Contract(ABI_JSON, ADDRESS);
    
        // calling the `view` function without having to pay for transaction fees
        const number = await contract.methods.getNumber().call();
        console.log(number);
    }
    
    run();