Categories
erc20 Getting started javascript

Calling a smart contract from JavaScript

In this tutorial we’ll see how to call a smart contract function from JavaScript. First is reading the state of a smart contract (for eg the balance of an ERC20 holder), then we’ll modify the state of the blockchain by making a token transfer. You should be already be familiar with setting up JS environement to interact with the blockchain.

For this examples we’ll play with the DAI token, for testing purpose we’ll fork the blockchain using ganache-cli and unlock an address that already has a lot of DAI:

ganache-cli -f https://mainnet.infura.io/v3/[YOUR INFURA KEY] -d -i 66 1 --unlock 0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81

To interact with a smart contract we’ll need its address and ABI:

const ERC20TransferABI = [
    {
        "constant": false,
        "inputs": [
            {
                "name": "_to",
                "type": "address"
            },
            {
                "name": "_value",
                "type": "uint256"
            }
        ],
        "name": "transfer",
        "outputs": [
            {
                "name": "",
                "type": "bool"
            }
        ],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [
            {
                "name": "_owner",
                "type": "address"
            }
        ],
        "name": "balanceOf",
        "outputs": [
            {
                "name": "balance",
                "type": "uint256"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
]

const DAIADDRESS = "0x6b175474e89094c44da98b954eedeac495271d0f"

For this project we stripped the complete ERC20 ABI to just keep the balanceOf and transfer function but you can find the full ERC20 ABI here.

We then need to instanciate our smart contract:

Join the newsletter

Get a weekly summary of what is happening in the Ethereum developer space for free

const web3 = new Web3('http://localhost:8545'); 

const daiToken = new web3.eth.Contract(ERC20TransferABI, DAIADDRESS);

We’ll also etup two address, the one who will receive the transfer and the one we already unlocked that will send it:

const senderAddress = "0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81"
const receiverAddress = "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE"

In the next part we’ll call the balanceOf function to retrieve the current amount of tokens both addresses holds.

Call: Reading value from a smart contract

The first example will call a “constant” method and execute its smart contract method in the EVM without sending any transaction. For this we’ll read the ERC20 balance of an address. If you did not read our article abour ERC20 tokens you should read it.

You can access an instanciated smart contract methods that you provided the ABI for as follow: yourContract.methods.methodname. By using the call function you’ll receive the result of executing the function.

daiToken.methods.balanceOf(senderAddress).call(function(err, res) {
    if (err) {
        console.log("An error occured", err);
        return
    }
    console.log("The balance is: ",res)
})

Remember that DAI ERC20 has 18 decimals which means you need to remove 18 zeros to get the correct amount. uint256 are returned as strings as Javascript does not handle big numeric values. If you’re not sure how to deal with big numbers in JS check our tutorial about bignumber.js.

Send: Sending a transaction to a smart contract function

For the second example we’ll call the transfer function of the DAI smart contract to send 10 DAI to our second address. The transfer function accepts two parameters: the recipient address and the amount of token to transfers:

daiToken.methods.transfer(receiverAddress, "100000000000000000000").send({from: senderAddress}, function(err, res) {
    if (err) {
        console.log("An error occured", err);
        return
    }
    console.log("Hash of the transaction: " + res)
})

The call function returns the hash of the transaction that will be mined into the blockchain. On Ethereum, transaction hash are predictable that’s how we can get the hash of the transaction before it is executed (learn how hash are calculated here).

As the function only submits the transaction to the blockchain, we can’t see the result until we now when it is mined and included in the blockchain. In the next tutorial we’ll learn how to wait for a transaction to be executed on the blockchain by knowing it’s hash.

Leave a Reply