Interacting with Smart Contracts – Using Web3.js or Ethers.js

This lesson focuses on bridging the gap between your front-end and the smart contracts you've deployed on the blockchain. You'll learn how to use JavaScript libraries like Web3.js or Ethers.js to connect your web application to a blockchain, allowing you to read data from and interact with your smart contracts directly from the browser.

Learning Objectives

  • Understand the role of Web3.js or Ethers.js in interacting with smart contracts.
  • Learn how to connect a front-end application to a specific blockchain network (e.g., Ganache, Goerli).
  • Be able to read data (e.g., variables, balances) from a deployed smart contract.
  • Comprehend the basic process of calling a smart contract function from a front-end.

Lesson Content

Introduction: Front-End to Blockchain Connection

Your front-end (HTML, CSS, and JavaScript) is the user interface. But it needs a way to communicate with the blockchain. Web3.js and Ethers.js are JavaScript libraries that act as bridges, allowing your front-end code to send requests to and receive responses from a blockchain network. They handle the complex communication protocols, allowing you to focus on the application logic. Think of them as translators, converting your JavaScript code into blockchain-understandable instructions (like calling a function or retrieving data).

Quick Check: What is the primary function of Web3.js or Ethers.js in web3 development?

Choosing Your Library: Web3.js vs. Ethers.js

Both Web3.js and Ethers.js are excellent choices, offering similar functionalities but with different design philosophies.

Web3.js: The original and more widely used library. It offers a comprehensive set of features and is well-documented.

Ethers.js: Generally considered more user-friendly and feature-rich for advanced developers, with improved features such as modularity and gas-estimation. It prioritizes developer experience and offers features for more secure transactions.

For this beginner lesson, we'll focus on Web3.js. You can easily adapt the concepts to Ethers.js with minor adjustments in syntax. The choice often comes down to personal preference and project needs.

Key Point: You only need one of these libraries to interact with a smart contract.

Quick Check: Which method is used to read data from a smart contract function?

Setting Up Your Development Environment

Before you begin, you'll need the following:

  1. A Web3-enabled Browser (MetaMask): MetaMask is a browser extension that allows you to interact with the Ethereum blockchain and manage your accounts. Install it from the official MetaMask website.
  2. A Development Blockchain (Ganache): Ganache is a personal blockchain for development that you can run locally. Download and install Ganache. When you start Ganache, it will provide you with several test accounts and their private keys.
  3. A Simple Smart Contract: Deploy a simple smart contract (e.g., a contract that stores a number) to your development blockchain (Ganache). Make sure you have the contract's ABI (Application Binary Interface) and contract address. The ABI describes the functions and data structures of your contract in a machine-readable format; the contract address is where it lives on the blockchain. Remember to compile and deploy your contract with a tool like Remix IDE or Hardhat.

  4. A basic HTML file: Create an index.html file with a basic structure. Import the Web3.js library to your HTML file using a CDN link, such as <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>.

<!DOCTYPE html>
<html>
<head>
  <title>Smart Contract Interaction</title>
</head>
<body>
  <h1>My Smart Contract</h1>
  <p id="data">Loading...</p>
  <button id="getDataButton">Get Data</button>
  <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
  <script src="script.js"></script>
</body>
</html>
  1. A basic Javascript file: Create a script.js file where you will write your Javascript code. This file will interact with the blockchain.

Quick Check: Which of these is NOT required to interact with a smart contract in the browser?

Connecting to the Blockchain with Web3.js

In your script.js file, you'll start by connecting to the blockchain. Web3.js needs to know which blockchain you want to use. If you're using MetaMask, it automatically injects a provider (window.ethereum) into your web page. If not using metamask (or a similar injected provider), you can specify a provider, such as Ganache, with the following code:

// Check if MetaMask is available
if (window.ethereum) {
    web3 = new Web3(window.ethereum); // Use injected provider (MetaMask)
    // Request account access if needed
    window.ethereum.enable().then(function() {
        console.log("MetaMask enabled");
    }).catch(function(err) {
        console.log("User denied account access");
    });
} else {
    // If no injected web3, fall back to a local RPC endpoint (e.g., Ganache)
    web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:7545')); // Or your Ganache endpoint
    console.log('No web3 provider detected.  Falling back to local node.');
}

This code checks if MetaMask (or another provider) is installed. If so, it uses it. Otherwise, it connects to a local blockchain (replace the URL with your Ganache or other development blockchain endpoint if needed). This is usually http://localhost:7545 when using ganache.

Quick Check: What is the purpose of the ABI?

Interacting with Your Smart Contract: Reading Data

Now, let's read data from your smart contract. First, you'll need the ABI and contract address of your deployed contract. The ABI is a JSON array that defines the contract's interface. You can find this in your Remix IDE deployment details.

// Assuming you have the ABI and contract address
const contractABI = [ /* Your Contract ABI Here */ ];
const contractAddress = '0xYourContractAddressHere';

const contract = new web3.eth.Contract(contractABI, contractAddress);

// Example: Reading a 'getData()' function
contract.methods.getData().call()
    .then(result => {
        document.getElementById('data').innerText = 'Data: ' + result;
    })
    .catch(error => {
        console.error(error);
        document.getElementById('data').innerText = 'Error fetching data.';
    });

Explanation:

  1. contractABI: Replace /* Your Contract ABI Here */ with your contract's ABI (a JSON array).
  2. contractAddress: Replace '0xYourContractAddressHere' with the actual address of your deployed smart contract.
  3. new web3.eth.Contract(contractABI, contractAddress): Creates a contract instance, using the ABI to understand the contract's functions and data.
  4. contract.methods.getData().call(): Calls the getData() function of your contract. The .call() method is used for read-only functions. The data returned by getData() is provided within a then callback and displayed on the webpage.
  5. contract.methods.getData().send(): The .send() function is used for state-changing functions. It requires the user to approve a transaction in their MetaMask wallet (or other injected provider).

Quick Check: When calling a function that changes the blockchain state, which method is typically used?

Interacting with Your Smart Contract: Calling Functions

To call a function that modifies the blockchain's state (e.g., setting a value), you'll use the .send() method.

// Assuming you have a 'setData()' function that takes a number as input
const setDataButton = document.getElementById('setDataButton');

setDataButton.addEventListener('click', () => {
    const newValue = parseInt(document.getElementById('newValue').value);
    contract.methods.setData(newValue).send({
        from: account // User's Ethereum address, from MetaMask
    })
    .then(receipt => {
        console.log('Transaction receipt:', receipt);
        alert('Data set successfully!');
    })
    .catch(error => {
        console.error(error);
        alert('Error setting data.');
    });
});

Explanation:

  1. setDataButton: References to a button defined in your HTML.
  2. addEventListener('click', ...): Attaches a click listener to the button.
  3. parseInt(document.getElementById('newValue').value): Gets the input value, which is then converted into an integer.
  4. contract.methods.setData(newValue).send({from: account}): Calls the setData() function. The send() function initiates a transaction that modifies the blockchain's state, and it requires from: account which specifies the address to pay for the transaction. The account is usually supplied through MetaMask.
  5. then(receipt => ...): The receipt is the response containing transaction details (e.g., transaction hash).
  6. catch(error => ...): Handles errors, such as a rejected transaction in MetaMask or contract errors.
Progress
0%