DEV Community

Bella Be
Bella Be

Posted on

How to interact with EVM Smart Contracts in Javascript

This tutorial is an introduction to the fundamentals of interacting with EVM compatible Smart Contracts in Javascript. We will demonstrates how to read from or write to Pancakeswap Prediction Smart Contract using web3.js. Pancakeswap Prediction Smart contract allows you to place bets on BNBUSD or CAKEUSD price moves.

Step 1: connect to web3

Pancakeswap runs on BNB Smart Chain. To interact with it we will use web3.js package which contains a collection of libraries that allows interaction with a blockchain node using HTTP, RPC or WebSocket providers. We will use HTTP provider https://bsc-dataseed1.binance.org:443

const Web3 = require("web3");
const provider = "https://bsc-dataseed1.binance.org:443";
const web3 = new Web3(provider);
Enter fullscreen mode Exit fullscreen mode

Step 2: connect to Smart Contract

To connect to Smart Contract we would need its address and ABI. Address of the contract could be found in Pancakeswap docs . Once we know the address, we can retrieve its ABI from BscScan by using its API. To make a network call we will use axios library

const { default: axios } = require("axios");

const contractAddress = "0x18B2A687610328590Bc8F2e5fEdDe3b582A49cdA";

const execute = async() => {
    const response = await axios.get(`https://api.bscscan.com/api?module=contract&action=getabi&address=${contractAddress}&apikey=YOUR_API_KEY`)
    const contract = new web3.eth.Contract(JSON.parse(response.data.result), contractAddress);
}

execute()

Enter fullscreen mode Exit fullscreen mode

Step 3: interact with Smart Contract

In EVM world Smart Contract functions could be of 2 types: read and write. Read functions allow to read Smart Contract data and they do not change Smart Contract state. Write functions instead do alter the state and we would require to pay for it to be executed (calling address should have enough blockchain native currency balance)

const epoch = await contract.methods.currentEpoch().call(); // read function
const roundData = await contract.methods.rounds(epoch).call(); // read function
const gasPrice = await web3.eth.getGasPrice(); // blockchain utility function
const betBullFunctionABI = contract.methods.betBull(epoch).encodeABI(); // prepare write function
const betBearFunctionABI = contract.methods.betBear(epoch).encodeABI(); // prepare write function
const custodialAddress = "your_address";
const custodialAddressKey = "your_address_key";
const account = web3.eth.accounts.privateKeyToAccount(custodialAddressKey); // used to sign transaction
const nonce = await web3.eth.getTransactionCount(custodialAddress); // get your account nonce
const transaction = {
     nonce,
     from: custodialAddress,
     to: contractAddress,
     gasPrice,
     gas: 5000000,
     data: betBullFunctionABI,
     value: "12008140256521106"
} // compose transaction object

const signedTransaction = await account.signTransaction(transaction); // sign transaction
const sentTransaction = await web3.eth.sendSignedTransaction(signedTransaction.rawTransaction); // send transaction to blockchain
console.log(sentTransaction)
const isClaimable = await contract.methods.claimable(epoch, custodialAddress).call(); // read function
if(isClaimable){ // recompose transaction to claim wins
      const claimFunctionABI = contract.methods.claim([epoch]).encodeABI(); // prepare write function
      const nonce = await web3.eth.getTransactionCount(custodialAddress); // get your account nonce
      const claimTransaction = {
            nonce,
            from: custodialAddress,
            to: bnbPredictionContractAddress,
            gasPrice,
            gas: 5000000,
            data: claimFunctionABI,
       }; // compose transaction object
      const signedClaimTransaction = await account.signTransaction(claimTransaction); // sign transaction
      const sentClaimTransaction = await web3.eth.sendSignedTransaction(signedClaimTransaction.rawTransaction); // send transaction to blockchain
      console.log(sentClaimTransaction)
}

Enter fullscreen mode Exit fullscreen mode

Our final code should look like this

const { default: axios } = require("axios");
const Web3 = require("web3");

const provider = "https://bsc-dataseed1.binance.org:443";

const web3 = new Web3(provider);

const contractAddress = "0x18B2A687610328590Bc8F2e5fEdDe3b582A49cdA";

const execute = async() => {
    const response = await axios.get(`https://api.bscscan.com/api?module=contract&action=getabi&address=${contractAddress}&apikey=YOUR_API_KEY`)
    const contract = new web3.eth.Contract(JSON.parse(response.data.result), contractAddress);
    const epoch = await contract.methods.currentEpoch().call(); // read function
    const roundData = await contract.methods.rounds(epoch).call(); // read function
    const gasPrice = await web3.eth.getGasPrice(); // blockchain utility function
    const betBullFunctionABI = contract.methods.betBull(epoch).encodeABI(); // prepare write function
    const betBearFunctionABI = contract.methods.betBear(epoch).encodeABI(); // prepare write function
    const custodialAddress = "your_address";
    const custodialAddressKey = "your_address_key";
    const account = web3.eth.accounts.privateKeyToAccount(custodialAddressKey); // used to sign transaction
    const nonce = await web3.eth.getTransactionCount(custodialAddress); // get your account nonce
    const transaction = {
        nonce,
        from: custodialAddress,
        to: contractAddress,
        gasPrice,
        gas: 5000000,
        data: betBullFunctionABI,
        value: "12008140256521106"
    } // compose transaction object

    const signedTransaction = await account.signTransaction(transaction); // sign transaction
    const sentTransaction = await web3.eth.sendSignedTransaction(signedTransaction.rawTransaction); // send transaction to blockchain
    console.log(sentTransaction)
    const isClaimable = await contract.methods.claimable(epoch, custodialAddress).call(); // read function
    if(isClaimable){ // recompose transaction to claim wins
        const claimFunctionABI = contract.methods.claim([epoch]).encodeABI(); // prepare write function
        const nonce = await web3.eth.getTransactionCount(custodialAddress); // get your account nonce
        const claimTransaction = {
            nonce,
            from: custodialAddress,
            to: bnbPredictionContractAddress,
            gasPrice,
            gas: 5000000,
            data: claimFunctionABI,
          }; // compose transaction object
        const signedClaimTransaction = await account.signTransaction(claimTransaction); // sign transaction
        const sentClaimTransaction = await web3.eth.sendSignedTransaction(signedClaimTransaction.rawTransaction); // send transaction to blockchain
        console.log(sentClaimTransaction)
    }
}

execute()

Enter fullscreen mode Exit fullscreen mode

Link to gist here

P.S Keep in mind that executing the above script might lead to money loss and you would require a good prediction strategy that will help to minimize it.

Top comments (0)