The Graph (Indexer)
Introduction
The Graph is a protocol for indexing and querying blockchain. By deploying a "Subgraph", blockchain data is automatically indexed by indexers, and can be easily accessed via GraphQL.
The Graph adopts a decentralized Web3 system based on token economics, but the indexing software is open-source and available for anyone to use as the Graph node.
This document presents instructions on how to run a Graph node on the Verse-Layer and deploy a Subgraph.
Setup the Graph node
Create a docker-compose project
Create the project directory.
$ mkdir /path/to/project
$ cd /path/to/project
Create a .env
.
NETWORK=<set the your verse's name (alphanumeric, hyphens, and underscores only)>
RPC_URL=<set the your verse's rpc (only http(s))>
Create a docker-compose.yml
.
- Ensure the database password is robust.
- Do not publicize the Graph node's Admin API (TCP/8020) and IPFS API (TCP/5001).
version: '3'
services:
graph:
image: graphprotocol/graph-node:v0.31.0
environment:
ethereum: $NETWORK:$RPC_URL
postgres_db: graph_db
postgres_user: graph_user
postgres_pass: graph_pass
postgres_host: postgres
ipfs: http://ipfs:5001/
ports:
- 8000:8000/tcp # GraphQL(http)
- 8001:8001/tcp # GraphQL(websocket)
- 8020:8020/tcp # Admin API
depends_on:
- postgres
- ipfs
postgres:
image: postgres:15.3
environment:
PGDATA: /data
POSTGRES_DB: graph_db
POSTGRES_USER: graph_user
POSTGRES_PASSWORD: graph_pass
POSTGRES_INITDB_ARGS: '--encoding=UTF8 --locale=C --lc-collate=C'
volumes:
- ./data/postgres:/data
ipfs:
image: ipfs/go-ipfs:v0.21.0
environment:
IPFS_PATH: /data
volumes:
- ./assets:/assets:ro
- ./data/ipfs:/data
ports:
- 5001:5001/tcp
Run the Postgres
$ docker-compose up postgres
postgres-1 | 2023-08-01 05:57:59.611 UTC [1] LOG: database system is ready to accept connections
Run the IPFS node
Initialize the IPFS data directory (Only for the first time).
$ docker-compose run --rm --entrypoint ipfs ipfs init
generating ED25519 keypair...done
peer identity: 12D3KooWDqPCG7V9WgwyyFoF8sRy2RT19F7Ze84KxegAEew17zoS
initializing IPFS node at /data
Modify the configuration file(./data/ipfs/config
).
- Prevent connection to other nodes.
# before
"Bootstrap": [
// list of bootstrap nodes
]
# after
"Bootstrap": null - Allow API access from external.
# before
"Addresses": {
"API": "/ip4/127.0.0.1/tcp/5001"
}
# after
"Addresses": {
"API": "/ip4/0.0.0.0/tcp/5001"
}
Run the IPFS.
$ docker-compose up ipfs
ipfs-1 | WebUI: http://0.0.0.0:5001/webui
ipfs-1 | Gateway server listening on /ip4/127.0.0.1/tcp/8080
ipfs-1 | Daemon is ready
Check API access.
$ curl -XPOST 'http://127.0.0.1:5001/api/v0/config?arg=Identity.PeerID'
{"Key":"Identity.PeerID","Value":"12D3KooWA25ixrGxRWsMVReWZc9Dn1qZkDYvuv7LTTgCEsz5M8ef"}
Run the Graph node
$ docker-compose up graph
graph-1 | Aug 01 06:44:11.789 INFO Graph Node version: 0.26.0 (2022-04-22)
~
graph-1 | Aug 01 06:44:45.183 INFO Syncing 1 blocks from Ethereum, code: BlockIngestionStatus, blocks_needed: 1, blocks_behind: 1, latest_block_head: 167721, current_block_head: 167720, provider: verse-rpc-0, component: BlockIngestor
Check API access.
$ curl -H 'Content-Type: application/json' -d '{}' http://127.0.0.1:8020/
{"jsonrpc":"2.0","error":{"code":-32600,"message":"Invalid request"},"id":null}
Deploying Subgraph
Let's try deploying a Subgraph to index the Transfer
events of ERC20.
Install the graph-cli
$ npm install -g @graphprotocol/graph-cli
Create a Subgraph
Set the parameters.
$ CONTRACT_NAME=MyToken
$ CONTRACT_ADDRESS=0x...
$ CONTRACT_ABI=/path/to/contract/abi.json
$ SUBGRAPH_NAME=TestGraph
$ SUBGRAPH_DIR=/path/to/project/dir
Create a Subgraph.
$ graph init $USER/$SUBGRAPH_NAME $SUBGRAPH_DIR \
--node http://127.0.0.1:8020 \
--protocol ethereum \
--network mainnet \
--contract-name $CONTRACT_NAME \
--from-contract $CONTRACT_ADDRESS \
--abi $CONTRACT_ABI \
--index-events
Generate subgraph
Write subgraph to directory
✔ Create subgraph scaffold
✔ Initialize networks config
✔ Initialize subgraph repository
✔ Install dependencies with yarn
✔ Generate ABI and schema types with yarn codegen
Change working directory.
$ cd $SUBGRAPH_DIR
Downgrading Packages
Due to compatibility issues with IPFS in the latest version of The Graph packages, you need to downgrade the version. Please modify the package.json
.
"dependencies": {
"@graphprotocol/graph-cli": "0.45.1",
"@graphprotocol/graph-ts": "0.30.0"
},
"resolutions": {
"ipfs-http-client": "34.0.0",
"concat-stream": "1.6.2"
}
Executing the downgrade.
$ yarn
Modify the Manifest
To index chains not officially supported by The Graph, it is necessary to change the dataSources[].network
in the manifest file(subgraph.yaml
) to the same string as the $NETWORK
variable in the .env
file.
# before
network: mainnet
# after
network: '<Set the $NETWORK value in the .env>'
Deploy
Register the Subgraph with the indexer. (Only for the first time)
$ npm run create-local
> create-local
> graph create --node http://localhost:8020/ username/TestGraph
Created subgraph: username/TestGraph
Deploy it. You will be asked for a version name, so please specify as appropriate.
$ npm run deploy-local
> deploy-local
> graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 username/TestGraph
Which version label to use? (e.g. "v0.0.1"): v0.0.1
~
Build completed: QmbZC8ENbFWV7WNHqGuFPGzH4mSDtKRc9rXkst99eShT7i
Deployed to http://localhost:8000/subgraphs/name/username/TestGraph/graphql
Subgraph endpoints:
Queries (HTTP): http://localhost:8000/subgraphs/name/username/TestGraph
Querying
Let's try querying. First, transact a mint or transfer method on the ERC20 contract specified at $CONTRACT_ADDRESS
to generate a Transfer event.
Then, open the development query editor (GraphiQL) and run your query. The editor URL is displayed as Queries (HTTP)
when deploying.
(Example: http://localhost:8000/subgraphs/name/{username}/{subgraph_name}
)
{
transfers {
id
from
to
value
}
}
If the setup is successful, you should be able to retrieve the indexed Transfer events.