The Graph
The Graph Overview¶
The Graph is a decentralized blockchain data indexing and querying protocol designed to solve the challenge of blockchain data access. It provides developers with an efficient way to index, organize, and query blockchain data, making it simple and efficient to build data-intensive decentralized applications (DApps). The Graph provides data services through GraphQL APIs and has become a vital component of Web3 infrastructure, often referred to as "the Google of blockchains."
Core Concepts¶
1. Subgraphs¶
Subgraphs are the core component of The Graph:
- Data Definition: Defines smart contracts and events to index
- Schema: Uses GraphQL Schema to define data structures
- Mapping: Writes data transformation logic
- Deployment: Deploys to the decentralized network
- Querying: Queries indexed data via GraphQL
2. Graph Node¶
Nodes that run the indexing service:
- Event Listening: Monitors blockchain events
- Data Extraction: Extracts relevant data from the blockchain
- Data Transformation: Executes Mapping to transform data
- Data Storage: Stores data to a database
- Query Service: Responds to GraphQL query requests
3. Decentralized Network¶
Participants in The Graph network:
- Indexers: Run nodes to index data and earn rewards
- Curators: Identify high-quality subgraphs and earn rewards
- Delegators: Delegate GRT to indexers
- Developers: Create subgraphs and pay query fees
- Consumers: Applications and users that use subgraph data
4. GRT Token¶
The Graph's native token:
- Query Fees: Pay data query fees
- Indexing Rewards: Reward indexers and curators
- Governance: Participate in protocol governance
- Staking: Indexers stake GRT to participate in the network
How The Graph Works¶
Data Indexing Flow¶
- Define Subgraph: Developer defines contracts and events to index
- Deploy Subgraph: Deploy the subgraph to The Graph network
- Index Data: Graph Node monitors the blockchain and indexes data
- Data Transformation: Mapping functions transform raw data
- Store Data: Transformed data is stored in a database
- Serve Queries: Query service provided via GraphQL API
GraphQL Queries¶
The Graph uses GraphQL as its query language:
Advantages: - Precise Queries: Request only the fields you need - Single Request: Get multiple resources in one request - Type Safety: Strong type system reduces errors - Live Documentation: Automatically generated API docs - Flexible and Efficient: Avoids over-fetching and under-fetching
Query Example:
{
tokens(first: 10, orderBy: totalSupply, orderDirection: desc) {
id
name
symbol
totalSupply
decimals
}
}
Creating a Subgraph¶
1. Install Graph CLI¶
2. Initialize Subgraph¶
3. Define Schema¶
schema.graphql:
type Token @entity {
id: ID!
name: String!
symbol: String!
decimals: Int!
totalSupply: BigInt!
holders: [Holder!]! @derivedFrom(field: "token")
}
type Holder @entity {
id: ID!
address: Bytes!
balance: BigInt!
token: Token!
}
4. Write Mapping¶
src/mapping.ts:
import { Transfer } from "../generated/Token/Token"
import { Token, Holder } from "../generated/schema"
export function handleTransfer(event: Transfer): void {
let token = Token.load(event.address.toHex())
if (token == null) {
token = new Token(event.address.toHex())
token.name = "Token Name"
token.symbol = "TKN"
token.decimals = 18
token.totalSupply = BigInt.fromI32(0)
}
// Update sender balance
let sender = Holder.load(event.params.from.toHex())
if (sender != null) {
sender.balance = sender.balance.minus(event.params.value)
sender.save()
}
// Update receiver balance
let receiver = Holder.load(event.params.to.toHex())
if (receiver == null) {
receiver = new Holder(event.params.to.toHex())
receiver.address = event.params.to
receiver.balance = BigInt.fromI32(0)
receiver.token = token.id
}
receiver.balance = receiver.balance.plus(event.params.value)
receiver.save()
token.save()
}
5. Configure Subgraph Manifest¶
subgraph.yaml:
specVersion: 0.0.4
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum
name: Token
network: mainnet
source:
address: "0x..."
abi: Token
startBlock: 12000000
mapping:
kind: ethereum/events
apiVersion: 0.0.6
language: wasm/assemblyscript
entities:
- Token
- Holder
abis:
- name: Token
file: ./abis/Token.json
eventHandlers:
- event: Transfer(indexed address,indexed address,uint256)
handler: handleTransfer
file: ./src/mapping.ts
6. Deploy Subgraph¶
# Code generation
graph codegen
# Build
graph build
# Deploy to Hosted Service
graph deploy --product hosted-service username/subgraph-name
# Deploy to decentralized network
graph deploy --node https://api.thegraph.com/deploy/ subgraph-name
Querying Subgraph Data¶
Using GraphQL Playground¶
Access the subgraph URL in a browser:
Integrating in Applications¶
Using Apollo Client:
import { ApolloClient, InMemoryCache, gql } from '@apollo/client'
const client = new ApolloClient({
uri: 'https://api.thegraph.com/subgraphs/name/username/subgraph-name',
cache: new InMemoryCache()
})
const GET_TOKENS = gql`
query GetTokens {
tokens(first: 10, orderBy: totalSupply, orderDirection: desc) {
id
name
symbol
totalSupply
}
}
`
const { data } = await client.query({ query: GET_TOKENS })
Using fetch:
const query = `
{
tokens(first: 10) {
id
name
symbol
}
}
`
const response = await fetch('https://api.thegraph.com/subgraphs/name/username/subgraph-name', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query })
})
const data = await response.json()
The Graph Network¶
Decentralized Network vs Hosted Service¶
| Feature | Decentralized Network | Hosted Service |
|---|---|---|
| Decentralization | Fully decentralized | Centralized service |
| Fees | Requires GRT payment | Free (no new subgraphs) |
| Reliability | Higher | Depends on single point |
| Censorship Resistance | Yes | No |
| Migration | Recommended | Being phased out |
Network Participants¶
Indexers: - Run Graph Node - Stake GRT - Index subgraph data - Earn query fees and indexing rewards
Curators: - Identify quality subgraphs - Stake GRT as signal - Earn query fee share
Delegators: - Delegate GRT to indexers - No need to run nodes - Earn portion of indexing rewards
Supported Blockchains¶
The Graph supports multiple blockchains:
- Ethereum: Mainnet, Goerli, Sepolia
- Polygon: Mainnet, Mumbai
- Arbitrum: One, Nova
- Optimism: Mainnet
- Avalanche: C-Chain
- Celo: Mainnet
- BNB Chain: Mainnet
- Gnosis Chain: Mainnet
Advanced Features¶
1. Entity Relationships¶
Define relationships between entities:
type User @entity {
id: ID!
posts: [Post!]! @derivedFrom(field: "author")
}
type Post @entity {
id: ID!
author: User!
content: String!
}
2. Full-Text Search¶
Add full-text search capabilities:
type Article @entity {
id: ID!
title: String! @fulltext(name: "articleSearch", language: en)
content: String! @fulltext(name: "articleSearch", language: en)
}
Query:
3. Time Travel Queries¶
Query historical state:
4. Subscriptions¶
Real-time data updates:
Best Practices¶
1. Schema Design¶
- Normalization: Avoid data redundancy
- Indexing: Add indexes for frequently queried fields
- Naming: Use clear entity and field names
- Types: Choose appropriate data types
2. Mapping Optimization¶
- Batch Processing: Reduce database operations
- Conditional Checks: Avoid unnecessary operations
- Error Handling: Properly handle exceptions
- Gas Optimization: Optimize on-chain data reads
3. Query Optimization¶
- Pagination: Use first and skip for pagination
- Filtering: Reduce returned data volume
- Sorting: Use orderBy judiciously
- Caching: Leverage client-side caching
Monitoring and Debugging¶
Graph Explorer¶
- Query Statistics: View query counts and fees
- Indexing Status: Monitor indexing progress
- Error Logs: View error messages
- Performance Analysis: Analyze query performance
Local Development¶
Develop locally using Graph Node:
Use Cases¶
- DeFi: Transaction history, liquidity data, price information
- NFT: Ownership tracking, transaction history, rarity analysis
- DAO: Proposals, votes, governance data
- Gaming: Game assets, player data, leaderboards
- Analytics: On-chain data analysis and visualization
Related Concepts and Technologies¶
- GraphQL: The query language used by The Graph
- Ethereum: Primary supported blockchain
- IPFS: Decentralized storage, also supported by The Graph
- Dune Analytics: Another blockchain data analytics platform
Summary¶
The Graph solves the pain points of data access in DApp development by providing efficient blockchain data indexing and query services. Its decentralized architecture, flexible GraphQL queries, and rich ecosystem make it a key component of Web3 infrastructure. Whether for DeFi protocols, NFT marketplaces, or on-chain analytics tools, The Graph provides powerful data support. As more blockchains are integrated and the network continues to improve, The Graph will continue to play an important role in the Web3 data layer.