Smart Contract Events: A Guide to Automated Ethereum Interactions

The first time I heard about a contract, I was excited. The idea of an agreement made me feel valued, especially as an intern showcasing my skills; that is a work contract. However, I later encountered the term in a completely different context—blockchain—and it took on a whole new meaning.

Introduction

A smart contract is a digital agreement on a blockchain that automatically executes when its terms and conditions (T&C) are met, ensuring transparency and security. Written in languages like Solidity, these contracts are triggered externally, such as by a wallet transaction, and require no intermediaries.

In simple terms, a smart contract is a piece of code that activates when specific conditions are fulfilled through an external trigger.

Understanding Smart Contract Events

Smart contract events are like notifications that a contract sends when certain actions occur, such as updating a value or transferring tokens. They help external applications track these changes efficiently without directly interacting with the contract’s state.

Events are alerts from a smart contract that tell apps when something happens, keeping everything in sync with the blockchain.

You learn well; you can sip water at this moment. Let continue 😊👍🏼

Interacting with Smart Contracts: From Solidity to Web3.js

Smart contracts are written in Solidity, a programming language for Ethereum. Once deployed, you interact with these contracts using Web3.js, a JavaScript library that connects your app to the blockchain.

Web3.js docs on Contract

Understanding ABI

The Application Binary Interface (ABI) allows smart contracts to interact with external applications and other contracts. Unlike traditional APIs, which connect apps to centralized servers, ABIs facilitate communication in a decentralized blockchain environment. They define methods and data types in a JSON format, enabling off-chain and on-chain interactions.

Check my previous videos to connect your web3 to an Ethereum node and get an ABI

I am referencing ABI & Smart Contract Alchemy for more reading updates

Let's Code! Yippee! 💃🏽🕺🏻
If you want to use the ABI I use for this code example: Here

This image shows from smart contract to ABI

import { Web3 } from 'web3';

// Connect to an Ethereum node via Infura
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID'); // Replace with your Infura Project ID

// Define the contract's ABI and address
const contractABI = [ /* ABI array from the compiled contract */ ];
const contractAddress = '0xYourContractAddress'; // Replace with your contract address

// Create a contract instance for interacting with the smart contract
const contract = new web3.eth.Contract(contractABI, contractAddress);

async function fetchData() {
    try {
        // Get the balance of a specific address
        const balance = await contract.methods.balanceOf(address).call(); // Replace 'address' with the token holder's address
        console.log('Balance:', balance);

        // Get the total supply of tokens from the contract
        const totalSupply = await contract.methods.totalSupply().call();
        console.log('Total Supply:', totalSupply);

        // Check if the minting process is finished
        const mintingFinished = await contract.methods.mintingFinished().call();
        console.log('Minting Finished:', mintingFinished);
    } catch (error) {
        console.error('Error fetching contract data:', error);
    }
}

async function fetchPastEvents() {
    try {
        // Get the latest block number as BigInt
        const latestBlock = BigInt(await web3.eth.getBlockNumber());

        // Fetch events from a recent block (e.g., 10 blocks ago) to the latest
        const events = await contract.getPastEvents('allEvents', {
            fromBlock: latestBlock - BigInt(10), // Adjust this number as needed
            toBlock: 'latest'
        });

        console.log('Past Events:', events);
    } catch (error) {
        console.error('Error fetching events:', error);
    }
}

// Execute functions to fetch and display data
fetchData();
fetchPastEvents();

Connecting to an Ethereum Node:

The script connects to the Ethereum network using Infura, which provides reliable access to Ethereum nodes without requiring you to run your own. Infura serves as a gateway to interact with the blockchain.

Contract Interaction:

  • ABI (Application Binary Interface): The ABI defines the contract's methods, including functions, inputs, and outputs, enabling Web3.js to interact with the contract's functions correctly.

  • Contract Instance: A contract instance is created using the ABI and the contract's address, allowing you to call and interact with the deployed contract's methods.

Fetching Data from the Contract:

  • balanceOf: This method retrieves the token balance for a specified address. To find token holders, you can visit Etherscan, search for your contract, and navigate to the "Holders" tab. 0xF977814e90dA44bFA03b6295A0616a897441aceC

  • totalSupply: This method fetches the total number of tokens issued by the contract, representing the total supply in circulation.

  • mintingFinished: Checks if the minting process has concluded, commonly used in token contracts to prevent the creation of additional tokens.

Fetching Past Events:

ThefetchPastEvents function retrieves all past events emitted by the contract within a specified block range, such as from 10 blocks before the latest to the current block. These events can include actions like transfers, approvals, or other state changes logged by the contract.

Web3.js docs on Past Event

This setup allows basic interaction with a smart contract, such as reading balances, checking total supply, verifying minting status, and fetching historical events.

Result of Past Event Log:

Key fields in the array of events:

  • event: Name of the emitted event, like "Transfer" or "Approval".

  • returnValues: Data from the event, such as addresses and values in a "Transfer" (from, to, value).

  • blockNumber: Block number where the event occurred, showing its place in the blockchain.

  • transactionHash: Unique ID of the transaction that triggered the event, useful for tracking on explorers like Etherscan.

  • logIndex: Position of the event within the transaction, relevant if multiple events are emitted.

  • address: Contract address that emitted the event, confirming which contract was involved.

  • removed: Boolean indicating if the event was removed due to a blockchain reorganization.

  • raw: Contains the raw log data of the event, including the original data and topics fields as returned by the Ethereum node, useful for low-level event processing or debugging.

    That's it! You're on your way to becoming a smart DApp developer—great job! 👏

I'll be creating a detailed video on this topic soon, so stay tuned. For more updates and the latest videos, be sure to follow Web3.js on Twitter, subscribe to the Chainsafe YouTube channel, and join our Discord community!

0
Subscribe to my newsletter

Read articles from Adefisayo Adejumo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Adefisayo Adejumo
Adefisayo Adejumo

Software engineer with over two years of experience in delivering clean, readable and maintainable code with an unrelenting appetite for lifelong learning and development. Creative problem solver with a good grasp of object-oriented programming concepts, asynchronous programming, web development, REST APIs, microservices, data structures and algorithms, with outstanding communication, collaborative and team-building skills.