The Power of Subgraphs to Access Blockchain Data and How to Build One with Alchemy

Thomas Cosialls

Efficient data access and management have become crucial for developers building decentralized applications (dApps). As the complexity and volume of on-chain data grow, traditional methods of data retrieval are proving to be inadequate. This is where subgraphs come into play, offering a game-changing solution for indexing and querying blockchain data. In this article, we'll explore why subgraphs are essential, how they work, and provide a step-by-step tutorial on building a subgraph using Alchemy Subgraph.

The Limitations of RPC Endpoints

Before diving into subgraphs, it's important to understand why traditional methods of accessing blockchain data, such as RPC (Remote Procedure Call) endpoints, are becoming unsustainable:

  • Scalability Issues: As dApps grow in popularity, the number of requests to RPC endpoints increases dramatically, leading to potential bottlenecks and slow response times.
  • Inefficient Queries: RPC endpoints are not optimized for complex queries or large datasets, making it difficult to retrieve specific information efficiently.
  • High Costs: Frequent RPC calls can be expensive, especially for Ethereum Mainnet, as each call consumes resources and may incur fees.
  • Limited Historical Data: RPC endpoints typically provide access to recent blockchain state, making it challenging to query historical data efficiently.
  • Inconsistent Data Structure: Data retrieved from RPC endpoints like Events often requires additional processing to be usable in applications, adding complexity to the development process.

Enter Subgraphs: A Game-Changer for Web3 Data Access

Subgraphs address these limitations by providing a more efficient and scalable way to index and query blockchain data. Here's why subgraphs are revolutionizing data accessibility in the Web3 ecosystem:

How Subgraphs Work

  • Indexing: Subgraphs continuously scan the blockchain for relevant events and transactions, indexing the data in a structured format.
  • GraphQL API: The indexed data is exposed through a GraphQL API, allowing developers to query exactly the data they need, no more, no less.
  • Real-time Updates: As new blocks are added to the blockchain, subgraphs automatically update their indexes, ensuring data is always current.
  • Customizable: Developers can define their own data schemas, tailoring the subgraph to their specific application needs.

Benefits of Using Subgraphs

  • Faster Queries: By pre-indexing data, subgraphs can return query results much faster than traditional RPC calls.
  • Reduced Load on Nodes: Subgraphs reduce the need for constant RPC calls, decreasing the load on blockchain nodes.
  • Cost-Effective: With optimized queries and reduced infrastructure requirements, subgraphs can significantly lower operational costs for dApps.
  • Enhanced User Experience: Faster data retrieval translates to more responsive dApps, improving overall user experience.
  • Complex Queries Made Simple: GraphQL allows for sophisticated queries that would be difficult or impossible with RPC endpoints alone.

Options for Building a Subgraph

Developers can choose from several options when building and deploying subgraphs, including The Graph Protocol (a decentralized indexing solution), Alchemy Subgraph (a managed platform), or self-hosted solutions. This tutorial focuses on Alchemy Subgraph, which offers a user-friendly and fast approach to subgraph creation and management.

Tutorial: Building a Subgraph with Alchemy Subgraph

Let's walk through the process of creating a subgraph using Alchemy Subgraph. We'll create a simple subgraph that indexes ERC-20 token transfers on the Ethereum mainnet.

Prerequisites

  • Node.js and npm installed on your system
  • An Alchemy account (sign up at https://alchemy.com)
  • Basic knowledge of GraphQL and Solidity

Step 1: Set Up Your Environment

First, install the Alchemy Subgraph CLI:

npm install -g @graphprotocol/graph-cli

Step 2: Initialize Your Subgraph Project

Create a new directory for your project and initialize it:

mkdir erc20-transfers-subgraph cd erc20-transfers-subgraph graph init --product hosted-service

Follow the prompts to set up your project. Choose a name for your subgraph, select the network (Ethereum mainnet in this case) and the contract address you want to monitor. Make sure you are putting the proxy contract address if you have implemented upgradeability.

graph init alchemy subgraph
Follow the subgraph initializer to quickly get started

Step 3: Define Your Schema

Edit the schema.graphql file to define the entities you want to track. For our ERC-20 transfer subgraph, we'll use the following schema:

schema.graphql
type Transfer @entity {
  id: ID!
  from: Bytes!
  to: Bytes!
  value: BigInt!
  token: Token!
  timestamp: BigInt!
}

type Token @entity {
  id: ID!
  symbol: String!
  name: String!
  totalSupply: BigInt!
}

Step 4: Update the Subgraph Manifest

Edit the subgraph.yaml file to specify the contract address, events to track, and mapping functions:

subgraph.yaml
specVersion: 0.0.4
schema:
  file: ./schema.graphql
dataSources:
  - kind: ethereum
    name: ERC20
    network: mainnet
    source:
      address: "0x6B175474E89094C44Da98b954EedeAC495271d0F"  # DAI token address
      abi: ERC20
    mapping:
      kind: ethereum/events
      apiVersion: 0.0.6
      language: wasm/assemblyscript
      entities:
        - Transfer
        - Token
      abis:
        - name: ERC20
          file: ./abis/ERC20.json
      eventHandlers:
        - event: Transfer(indexed address,indexed address,uint256)
          handler: handleTransfer
      file: ./src/mapping.ts

Step 5: Implement the Mapping Functions

Create a file src/mapping.ts and implement the handleTransfer function:

src/mapping.ts
import { Transfer as TransferEvent } from "../generated/ERC20/ERC20"
import { Transfer, Token } from "../generated/schema"
import { BigInt } from "@graphprotocol/graph-ts"

export function handleTransfer(event: TransferEvent): void {
  let token = Token.load(event.address.toHexString())
  if (token === null) {
    token = new Token(event.address.toHexString())
    token.symbol = "DAI"
    token.name = "Dai Stablecoin"
    token.totalSupply = BigInt.fromI32(0)
    token.save()
  }

  let transfer = new Transfer(event.transaction.hash.toHex() + "-" + event.logIndex.toString())
  transfer.from = event.params.from
  transfer.to = event.params.to
  transfer.value = event.params.value
  transfer.token = token.id
  transfer.timestamp = event.block.timestamp
  transfer.save()
}

Step 6: Generate Types

Generate TypeScript types based on your schema:

graph codegen

Step 7: Build the Subgraph

Compile your subgraph:

graph build

Step 8: Deploy to Alchemy Subgraph

Deploy your subgraph to Alchemy:

graph deploy {YOUR_PROJECT_NAME} \ --version-label v0.0.1-new-version \ --node https://subgraphs.alchemy.com/api/subgraphs/deploy \ --deploy-key {API_KEY} \ --ipfs https://ipfs.satsuma.xyz

Replace {YOUR_PROJECT_NAME} with your project name and {YOUR_ALCHEMY_API_KEY} with your actual Alchemy API key.

Step 9: Query Your Subgraph

Once deployed, you can query your subgraph using the GraphQL endpoint provided by Alchemy. Here's an example query to get recent transfers:

{ transfers(first: 5, orderBy: timestamp, orderDirection: desc) { id from to value token { symbol } timestamp } }

You can use the playground site generated by Alchemy to directly build GraphQL requests. Here is the playground generated for Kleek, our blockchain based event platform built during WalletConnect's hackathon.

Conclusion

Subgraphs have become an indispensable tool in the Web3 developer's arsenal, offering a more efficient and scalable way to access and query blockchain data. By leveraging the power of subgraphs, developers can create faster, more responsive, and cost-effective decentralized applications.

Alchemy Subgraph provides a user-friendly platform for building and deploying subgraphs, making it easier than ever to harness the power of indexed blockchain data. As the Web3 ecosystem continues to grow, subgraphs will play an increasingly crucial role in unlocking the full potential of blockchain technology.

By following this tutorial, you've taken your first steps into the world of subgraphs. Continue exploring and experimenting with different data models and queries to discover how subgraphs can enhance your Web3 projects.

Ready to take your project to the next level?

Contact us today to discuss how we can help you achieve your goals in the blockchain space.