Streamlining Blockchain Access: A Guide to Indexing Rootstock Data with Envio

Pranav KondePranav Konde
13 min read

In the rapidly advancing world of blockchain technology, the need for efficient data management and retrieval has become critical for developers engaged in creating decentralized applications (dApps). As the complexity and volume of blockchain data grow, traditional methods of handling this information often fall short, leading to performance bottlenecks and user experience challenges. Envio emerges as a powerful solution, specifically designed to index blockchain data effectively. This blog will showcase the process of indexing data from the Rootstock blockchain using Envio, highlighting its capabilities and the advantages it offers to developers in optimizing their dApps for better performance and scalability.

Introduction to Rootstock

  • What is Rootstock?

    • Rootstock is a smart contract platform that is merge-mined with Bitcoin, providing a secure and scalable environment for dApps.

    • It aims to bring Ethereum-compatible smart contracts to the Bitcoin ecosystem, allowing developers to leverage the security of Bitcoin while utilizing the flexibility of smart contracts.

    • Rootstock uses a two-way peg with Bitcoin, enabling seamless BTC transfers between the Bitcoin and Rootstock networks, ensuring interoperability.

    • It features a robust ecosystem with tools like RIF (Rootstock Infrastructure Framework), which provides decentralized services such as RIF Wallet, RNS, RIF Relay, and RIF Flyover.

Understanding Indexing and Multi-Chain Indexing

What is Indexing?

  • Definition: Indexing is the process of organizing and structuring blockchain data to make it easily accessible and queryable.

  • Purpose: It transforms raw blockchain data into a structured format, enabling developers to build responsive and scalable applications.

Benefits of Indexing

  • Improved Query Performance: Faster data retrieval compared to scanning the entire blockchain.

  • Enhanced Scalability: Reduces network load by offloading query processing from blockchain nodes.

  • Data Analytics: Facilitates complex queries and data analysis for applications like DeFi and NFTs.

What is Multi-Chain Indexing?

  • Definition: Multi-chain indexing refers to the ability to index and query data across multiple blockchain networks from a single platform.

  • Purpose: It provides a unified view of activities across different blockchain ecosystems, enhancing user experience and enabling cross-chain applications.

Importance of Indexing in Rootstock

  • Efficient Data Access: As Rootstock generates a significant amount of data, indexing is essential for developers to quickly access and utilize this information.

  • Faster Queries: Proper indexing enables rapid data retrieval, allowing dApps to perform efficiently without the need to scan the entire blockchain.

  • Improved Data Management: Effective indexing simplifies the handling of large volumes of blockchain data, allowing developers to focus on building innovative features.

  • Enhanced User Experience: By facilitating quicker queries and more efficient data handling, indexing contributes to a seamless and interactive experience for users of decentralized applications.

Introduction to Envio

Envio is a developer-friendly, speed-optimized blockchain indexing solution designed to address the limitations of traditional blockchain indexing approaches. It helps developers overcome challenges related to latency, reliability, and costs across various sources. Envio serves as the front door for applications needing to access, transform, and save real-time or historical data from any EVM-compatible smart contracts.

Envio offers features like:

  • HyperSync: Ensures fast retrieval of historical on-chain data.

  • Multi-chain Support: Aggregates data across multiple networks into a single database.

  • Flexible Language Support: Allows configuration in JavaScript, TypeScript, or ReScript.

  • Join On-chain and Off-chain Data: Connects indexed blockchain data with off-chain data for richer APIs.

Problems in Blockchain Indexing

Blockchain networks generate vast amounts of data, making it challenging for developers to access and utilize this information effectively. Key problems include:

  • Data Latency: Traditional methods of data retrieval can lead to significant delays, impacting the performance of dApps.

  • Complexity of Data Management: Developers often struggle with the complexities of managing and querying blockchain data.

  • Lack of Multi-Chain Support: Many indexing solutions are limited to single blockchain networks, hindering the development of cross-chain applications.

What Envio is Solving

Envio is a modern, developer-friendly blockchain indexing solution optimized for speed and efficiency. It addresses the limitations of traditional blockchain indexing by providing a seamless experience for accessing, transforming, and saving real-time or historical data from EVM-compatible smart contracts.

Envio addresses the above challenges by providing a modern indexing solution that enhances the performance and efficiency of data retrieval from EVM-compatible networks. Envio has extended its support for HyperIndex and HyperSync to the Fuel Network (both mainnet and testnet). Key solutions include:

  • High-Performance Indexing: Envio significantly reduces sync times, allowing developers to deploy and iterate on indexers quickly.

  • Real-Time Data Access: With features like HyperSync, Envio enables real-time data processing, which is essential for applications that require immediate data availability.

  • Multi-Chain Support: Envio allows developers to aggregate data from multiple EVM-compatible blockchains, simplifying the development of cross-chain applications.

How Indexing Works in Envio

Overview of Envio Indexing

  • Purpose: Envio provides a framework for developers to index and aggregate real-time or historical blockchain data, making it easily accessible through GraphQL queries.

  • Components:

    • config.yaml: The config.yaml file automatically includes the Network ID, Start Block, Contract Name, Contract Address, and Event Signature (with requiredEntities), and while users can remove unwanted events, no changes are needed for the indexer to run.

    • schema.graphql: Defines the data model for the application, and By default, the contract import process creates an entity for each event, with fields corresponding to the emitted parameters, and generates an EventsSummary entity that counts and links to the created entities.

    • Event Handlers: Functions that respond to specific blockchain events and Loaders, handlers for each event will be automatically generated, with the loader function loading the EventsSummary entity using a fixed key for updates. The handler will create an instance of the event-specific entity with emitted parameters and update the entity counter in the EventsSummary.

Indexing Process

  1. Data Extraction: The indexer connects to the blockchain network and extracts data from smart contracts.

  2. Data Transformation: The extracted data is transformed into a machine-readable format.

  3. Data Storage: The transformed data is stored in a database for efficient searching and querying.

  4. Search API: Envio provides a GraphQL API for querying the indexed data.

Example of Indexing with Envio

Here’s a simplified example of how to set up an indexer for a smart contract using Envio:

config.yaml

# yaml-language-server: $schema=./node_modules/envio/evm.schema.json
name: envio-indexer
networks:
- id: 30
  start_block: 0
  contracts:
  - name: RIFToken
    address:
    - 0x2AcC95758f8b5F583470ba265EB685a8F45fC9D5
    handler: src/EventHandlers.ts
    events:
    - event: Approval(address indexed owner, address indexed spender, uint256 value)
    - event: OwnershipRenounced(address indexed previousOwner)
    - event: OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
    - event: Transfer(address indexed from, address indexed to, uint256 value, bytes data)
unordered_multichain_mode: true

schema.graphql

type RIFToken_Approval {
  id: ID!
  owner: String!
  spender: String!
  value: BigInt!
}

type RIFToken_OwnershipRenounced {
  id: ID!
  previousOwner: String!
}

type RIFToken_OwnershipTransferred {
  id: ID!
  previousOwner: String!
  newOwner: String!
}

type RIFToken_Transfer {
  id: ID!
  from: String!
  to: String!
  value: BigInt!
  data: String!
}

Event Handler (EventHandlers.ts)

/*
 * Please refer to https://docs.envio.dev for a thorough guide on all Envio indexer features
 */
import {
  RIFToken,
  RIFToken_Approval,
  RIFToken_OwnershipRenounced,
  RIFToken_OwnershipTransferred,
  RIFToken_Transfer,
} from "generated";

RIFToken.Approval.handler(async ({ event, context }) => {
  const entity: RIFToken_Approval = {
    id: `${event.chainId}_${event.block.number}_${event.logIndex}`,
    owner: event.params.owner,
    spender: event.params.spender,
    value: event.params.value,
  };

  context.RIFToken_Approval.set(entity);
});

RIFToken.OwnershipRenounced.handler(async ({ event, context }) => {
  const entity: RIFToken_OwnershipRenounced = {
    id: `${event.chainId}_${event.block.number}_${event.logIndex}`,
    previousOwner: event.params.previousOwner,
  };

  context.RIFToken_OwnershipRenounced.set(entity);
});

RIFToken.OwnershipTransferred.handler(async ({ event, context }) => {
  const entity: RIFToken_OwnershipTransferred = {
    id: `${event.chainId}_${event.block.number}_${event.logIndex}`,
    previousOwner: event.params.previousOwner,
    newOwner: event.params.newOwner,
  };

  context.RIFToken_OwnershipTransferred.set(entity);
});

RIFToken.Transfer.handler(async ({ event, context }) => {
  const entity: RIFToken_Transfer = {
    id: `${event.chainId}_${event.block.number}_${event.logIndex}`,
    from: event.params.from,
    to: event.params.to,
    value: event.params.value,
    data: event.params.data,
  };

  context.RIFToken_Transfer.set(entity);
});

How Envio Stands Out

Unique Features and Advantages

  • Speed and Efficiency: Envio's HyperSync technology allows for accelerated data queries, making it 20-100x faster than traditional methods.

  • Developer-Friendly Environment: Automatic code generation and support for multiple programming languages (JavaScript, TypeScript, ReScript) streamline the development process.

  • Customizability: Developers can define their data models and event handlers, allowing for tailored applications.

  • Managed Service Options: Envio offers reliable hosting and expert support, enabling developers to focus on building their applications.

  • You can find more information in the Envio Documentation.

Overview of Envio's Tools

Envio offers a suite of powerful tools designed to enhance blockchain data retrieval and indexing. Below is a brief overview of each tool:

FeatureDescription
HyperSyncA highly specialized data node built in Rust, designed to improve data retrieval speeds significantly.
Serves as a real-time, accelerated data query layer.
Supports multiple programming languages like Python, Rust, NodeJs, and Go.
Can retrieve millions of blocks, logs, transactions, and traces on multiple chains in seconds.
A more efficient alternative to JSON-RPC.
Supports over 50 EVM chains and Fuel.
Ideal for indexers, block explorers, data analysts, and other performance-focused applications.
HyperIndexUses HyperSync as a data source to achieve fast indexing speeds, significantly faster than traditional RPC methods.
Allows for hyper-speed syncing, making it possible to sync a large number of events in a short time.
Default method for syncing in Envio and used for maintaining and populating databases efficiently.
HyperRPCA fast read-only RPC designed for data-intensive tasks, offering a performance boost over traditional nodes.
Optimized for performance in read-only calls.
Supports a limited set of methods like eth_getLogs, eth_getBlockByNumber, and more.
Suitable for heavy data extraction but cannot be used for posting transactions.

These tools are part of Envio's suite to enhance blockchain data retrieval and indexing, each serving different purposes but often working together to provide a comprehensive solution.

Overview of Contract Import in Envio

The Contract Import feature in Envio allows developers to automatically generate the necessary boilerplate code for an indexer project based on one or multiple smart contracts that are already deployed and verified on supported blockchains. This process simplifies the setup and accelerates the development of indexing solutions.

Key Features of Contract Import:

  • Quick Setup: Initialize an indexer in minutes by importing existing contracts.

  • Multi-Chain Support: Import contracts from various EVM-compatible and Fuel blockchains.

  • Automatic Code Generation: Generate configuration files, schemas, and event handlers automatically.

Prerequisites

Before you begin, ensure you have the following installed:

  • Node.js: Recommended to use a version manager like fnm or nvm.

  • pnpm: A fast, disk space-efficient package manager.

  • Contract address: It is needed in Envio to automatically fetch the contract's ABI, enabling accurate indexing of events and transactions specific to that smart contract.

  • Docker Desktop: Required for running the Envio services.

You can install Envio globally using npm:

npm install -g envio

Step-by-Step Guide to Importing Contracts

Step 1: Initialize Your Project

  1. Open your terminal and navigate to the directory where you want to set up your project.

  2. Run the following command to initialize your Envio indexer:

     pnpx envio init
    
  3. You will be prompted to name your indexer:

     ? Name your indexer:
    
  4. Choose the directory for your project (default is the current directory):

     ? Set the directory: (.) .
    
  5. Select the Language you prefer from Javascript, Typescript, and Rescript. In this guide we will be using Typescript.

Step 2: Choose Initialization Option

  1. When setting up a smart contract, you can choose between Contract Import and Template options.

    Contract Import

    Selecting Contract Import allows you to bring in an existing smart contract, offering flexibility for customization without starting from scratch.

    Template

    Choosing the Template option presents two choices:

    • Greeter Template: A simple contract that lets users write a greeting message on the blockchain. It’s ideal for demonstrating event indexing with Envio, allowing you to listen for events like NewGreeting and update your database accordingly.

    • ERC20 Template: Designed for indexing events from ERC20 token contracts, this template tracks token transfers, approvals, and other standard events. It’s essential for applications that need to monitor token movements and balances.

    ? Choose an initialization option
      Template
    > ContractImport

Step 3: Select Import Method

  1. You will be prompted to choose between importing from a block explorer or a local ABI:

    • Block Explorer: Requires the contract address and chain.

    • Local ABI: Requires a JSON file containing the smart contract ABI.

    ? Would you like to import from a block explorer or a local abi?
    > Block Explorer
      Local ABI

Step 4: Specify Blockchain and Contract Address

  1. Choose the blockchain from which you want to import the contract:

     ? Which blockchain would you like to import a contract from?
     > arbitrum-one
     > rsk 
     > All EVM Blockchain Supported by ENVIO List
    

    Until now, it should look alike:

  2. Enter the contract address:
    If you don’t have one, refer this guide

     ? What is the address of the contract?
    

    Note: If using a proxy contract, provide the proxy address.

    Here, I indexed the RIF contract on Rootstock.

Step 5: Configure Events to Index

  1. You will be prompted to select which events you would like to index:

    • Use the spacebar to select or deselect events.

Step 6: Finalize Contract Import

After selecting the events, you can choose to add more contracts or finish the import process:

? Would you like to add another contract?
> I'm finished
  Add a new address for same contract on same network
  Add a new network for same contract
  Add a new contract (with a different ABI)

Step 7: Generate the Token

API Tokens are essential for authenticating and authorizing access to Envio's services, including HyperSync. To create a token, visit Envio's API Tokens page and follow the instructions.

Configuration Files Generated

Upon completion of the import process, Envio will generate several key files, and the folder structure will look alike:

Step 8: Stop the local environment

The command envio stop is used to stop the local environment, delete the database, and stop all processes (including Docker) for the current directory. Here's how you can use it:

pnpx envio stop

Step 9: Running Your Indexer

  1. To start your indexer, run the following command:

     pnpm envio dev
    
  2. Ensure Docker is running, as it is required for the Envio services.

Finally, it will navigate to the http://localhost:8080

For more details on CLI commands, you can check the Envio CLI Commands documentation.

Step 10: Start interacting

Enter the password as testing

In this section, you can create custom queries based on the events from the provided contract, effectively serving as a playground for exploring and interacting with the data. This feature allows you to experiment with various query configurations and gain insights from the underlying data structure.

In the data section, we can view the events presented as database schemas, allowing for easy tracking and management of the data. This structured representation facilitates a clearer understanding of the events and their relationships within the database.

Similarly,

Actions are custom queries or mutations that are resolved via HTTP handlers. Actions can be used to carry out complex data validations, data enrichment from external sources or execute just about any custom business logic.

Remote schemas are external GraphQL services that can be merged with Hasura to provide a unified GraphQL API. Think of it like automated schema stitching. All you need to do is build a GraphQL service and then provide its HTTP endpoint to Hasura. Your GraphQL service can be written in any language or framework.

Event triggers automatically capture events (insert, update, delete) on a specified table and then reliably calls an HTTP webhook to run some custom business logic.

Conclusion

Indexing Rootstock data using Envio provides developers with a powerful toolset to enhance their dApps performance and efficiency. By leveraging Envio's capabilities, developers can create responsive, scalable, and innovative applications that meet the demands of the blockchain landscape. With its high-performance indexing, real-time data access, and multi-chain support, Envio stands out as an ideal solution for managing Rootstock data effectively. As the blockchain ecosystem continues to grow, utilizing advanced indexing solutions like Envio will be crucial for developers aiming to build robust and efficient decentralized applications.

If facing any errors, join Rootstock discord and ask under the respective channel.

Until then, dive deeper into Rootstock by exploring its official documentation. Keep experimenting, and happy coding!

For more information, you can visit the Envio documentation or join their community on Discord

0
Subscribe to my newsletter

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

Written by

Pranav Konde
Pranav Konde