Defining a Subgraph Project

Hasnat Sajid
5 min readOct 27, 2020

Define a Subgraph

A subgraph defines which data The Graph will index from Ethereum, and how it will store it. Once deployed, it will form a part of a global graph of blockchain data.

The subgraph definition consists of a few files:

  • subgraph.yaml: a YAML file containing the subgraph manifest
  • schema.graphql: a GraphQL schema that defines what data is stored for your subgraph, and how to query it via GraphQL
  • AssemblyScript Mappings: AssemblyScript code that translates from the event data in Ethereum to the entities defined in your schema (e.g. mapping.ts in this tutorial)

Before you go into detail about the contents of the manifest file, you need to install the Graph CLI which you will need to build and deploy a subgraph.

Installation

We are not going to install Graph Node from the source code directly because XXX. Instead, we are going to use the official Docker image and a CLI that allows us to deploy our subgraph easily.

Before we begin, we strongly recommend reading the Quick Start guide from The Graph. It provides a wide overview of how Graph Node works and how to deploy a subgraph.

Once you have Docker running, you need a Docker Hub user account to run the Graph Node Docker image. If you don’t have an account, create one on Docker’s website.

Creating the subgraph

Now that we have a Graph Node running locally, we create our subgraph. We use TwitterHumanityApplicant and HumanityGovernance, both deployed on mainnet. Pay attention to the contract address and to the Contract tab.

In this subgraph, we need a way to access:

  • The addresses of all proposers
  • The proposals initiated for each address
  • Basic information about the proposal, such as the Twitter account, can votes, status, etc
  • Proposals counters like approved, rejected and pending

The simplest way to create a subgraph is by using the graph command from graph-cli. After running graph init it will ask you questions to generate the initial code for a subgraph. After that, a sample subgraph, based on the given contract, is ready to run.

The graph init the command can be used to set up a new subgraph project, either from an existing contract on any of the public Ethereum networks or from an example subgraph.

The following command creates a subgraph that indexes all events of an existing contract. It attempts to fetch the contract ABI from Etherscan and falls back to requesting a local file path. If any of the optional arguments are missing, it takes you through an interactive form.

graph init \
--from-contract <CONTRACT_ADDRESS> \
[--network <ETHEREUM_NETWORK>] \
[--abi <FILE>] \
<GITHUB_USER>/<SUBGRAPH_NAME> [<DIRECTORY>]

The <GITHUB_USER> is your GitHub user or organization name, <SUBGRAPH_NAME> is the name for your subgraph, and <DIRECTORY> is the optional name of the directory where graph init will put the example subgraph manifest.

The <CONTRACT_ADDRESS> is the address of your existing contract. <ETHEREUM_NETWORK> is the name of the Ethereum network that the contract lives on. <FILE> is a local path to a contract ABI file. Both --network and --abi are optional.

Supported networks on the Hosted Service are:

  • mainnet
  • kovan
  • rinkeby
  • ropsten
  • goerli
  • poa-core
  • xdai
  • poa-sokol

Install the Graph CLI

The Graph CLI is written in JavaScript, and you will need to install either yarn or npm to use it; it is assumed that you have yarn in what follows. Detailed instructions for installing yarn can be found in the graph-CLI repo

Once you have yarn, install the Graph CLI by running

yarn global add @graphprotocol/graph-cli

The Subgraph Manifest

If you already have a smart contract deployed to Ethereum mainnet or one of the tenets, bootstrapping a new subgraph from this contract can be a good way to get started.

The subgraph manifest subgraph.yaml defines the smart contracts your subgraph indexes, which events from these contracts to pay attention to, and how to map event data to entities that Graph Node stores and allows to query. The full specification for subgraph manifests can be found here.

The example subgraph:

specVersion: 0.0.1
description: Gravatar for Ethereum
repository: https://github.com/graphprotocol/example-subgraph
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum/contract
name: Gravity
network: mainnet
source:
address: '0x2E645469f354BB4F5c8a05B3b30A929361cf77eC'
abi: Gravity
startBlock: 6175244
mapping:
kind: ethereum/events
apiVersion: 0.0.1
language: wasm/assemblyscript
entities:
- Gravatar
abis:
- name: Gravity
file: ./abis/Gravity.json
eventHandlers:
- event: NewGravatar(uint256,address,string,string)
handler: handleNewGravatar
- event: UpdatedGravatar(uint256,address,string,string)
handler: handleUpdatedGravatar
callHandlers:
- function: createGravatar(string,string)
handler: handleCreateGravatar
blockHandlers:
- function: handleBlock
- function: handleBlockWithCall
filter:
kind: call
file: ./src/mapping.ts
  1. source: what address to listen for defined events + ABI.
  2. entities: what are the created entities we could query upon.
  3. eventHandlers: name of an event and the related handler.

The important entries to update for the manifest are:

  • dataSources.source: the address of the smart contract the subgraph sources, and the abi of the smart contract to use. The address is optional; omitting it allows to index matching events from all contracts.
  • dataSources.mapping.entities: the entities that the data source writes to the store. The schema for each entity is defined in the the schema.graphql file.
  • dataSources.mapping.callHandlers: lists the smart contract functions this subgraph reacts to and handlers in the mapping that transform the inputs and outputs to function calls into entities in the store.
  • A single subgraph can index data from multiple smart contracts. Add an entry for each contract from which data needs to be indexed to the dataSources array.

--

--