Skip to content
Leonardo Yvens edited this page Jul 7, 2019 · 28 revisions

Supported Features

Does The Graph support ERC20 tokens?

It depends. Right now, indexing Ethereum contracts is done by handling Ethereum events. If your ERC20 token contract emits Transfer events and others, it is possible to write a subgraph for it.

Supporting any ERC20 token—such as those listed on decentralized exchanges—is planned.

Does the GraphQL API support aggregates?

Examples would be the number of entities returned or the average value of a field across many entities. This is planned but currently not supported.

Can a subgraph index multiple versions of smart contracts?

Yes, it is as simple as adding them both to the subgraph manifest as separate data sources. See the 0x subgraph for an example.

Can a subgraph index smart contracts that are created dynamically?

Not right now, but we are working on it.

Does The Graph support Vyper Contracts?

Yes! See the Uniswap Subgraph for an implementation.

Graph CLI

When do I need to run yarn codegen / graph codegen?

It's a good idea to re-run this every time you make a change to the GraphQL schema or the ABIs of your subgraph. This is because graph codegen generates AssemblyScript types for all entity types in the schema and all smart contracts and events in the subgraph ABIs.

Graph Typescript API (graph-ts)

Is JSON parsing supported?

Yes! Please check out the Origin subgraph for an implementation of it.

How can I read IPFS data?

You will need the IPFS content hash of the file you are looking for. These start with Qm. Then you can use ipfs.cat(hash) to read the file. See the Origin subgraph for an example.

GraphQL Schemas

How do I represent Ethereum addresses in the GraphQL schema?

For this, the built-in Bytes type can be used. In the GraphQL API for the subgraph, values of type Bytes will be represented as hexadecimal strings.

type YourType @entity {
  owner: Bytes! # Note: not Address or String
}

What does the ! in the GraphQL schema mean?

It means that the value of a field may never be null. If you are certain the field can never be null, use !, as it is a useful hint for clients.

Mappings

How do I use a BigInt or Address as an entity ID?

Entity IDs need to be strings, so it may not obvious that

let entity = new YourType(event.params.id)

does not work right away if event.params.id is a BigInt or Address. To convert them to a hexadecimal string that can be used as an entity ID, do

let entity = new YourType(event.params.id.toHex())

How do I load an existing entity?

If you are 100% certain that the entity already exists—maybe it is guaranteed that another event that creates it will be called first—, you can do the following:

let entity = YourType.load(entityId) as YourType

If your goal is to create entities lazily, you can do this:

let entity = YourType.load(entityId)
if (entity == null) {
  entity = new YourType(entityId)
}

How do I modify an entity?

After creating or loading an entity, you can read and write its properties as if they were regular JavaScript object fields. You can then save the entity back to the store with .save():

// Read
entity.bigNumber + BigInt.fromI32(10)
entity.address

// Write
entity.bigNumber = entity.bigNumber + BigInt.from(5)
entity.address = event.params.address

// Save
entity.save()

How do I update array properties of an entity?

Arrays are defined in the schema as e.g.

type YourType @entity {
  numbers: [BigInt!]!
}

In mappings, you can then access this property via entity.numbers to read it. Unfortunately, pushing values to this array isn't as easy as

// This will not work
entity.numbers.push(BigInt.fromI32(100))

This is because entity.numbers creates a new array with values converted to types that are easy to work with in AssemblyScript. As a result, you have to explicitly set the property to a new value:

// This will work
let numbers = entity.numbers
numbers.push(BigInt.fromI32(100))
entity.numbers = numbers

When should I store Ethereum blocks and transactions in entities?

You can access block data with event.block and transaction data with event.transaction. These are both valuable to record in your entities. It is up to you where and when you want to use this data, but adding block and transaction hashes, for instance, can be useful when filtering GraphQL queries.

Should I query the public getters for data, or just use the data emitted from events?

This is up to you. But keep in mind, the mappings will run much slower if you use the public getters. This is because the Graph Node will have to ping the Ethereum Node (i.e. Infura), and wait for the response. This adds a lot of time for syncing over 7 million blocks. If you can, avoid using the public getters if you can get all the data from events. But if the data isn't available in an event, then by all means, use the getters!

Should I delete my Entities if they are deleted on the smart contract storage?

This is up to you. If you want you subgraph to have the exact same storage as the smart contract, then delete the entity with store.remove(entity: string, id: string). But if you also want to keep historical data, then you don't need to delete it.

Can I Use a switch case statement?

No! Sadly we found that there are some weird errors that happen in the AssemblyScript compiler. It is best to just use some chained if else statements. Hopefully this is supported in AssemblyScript in the near future.

Debugging a subgraph

Why do I have to sync from block 0 everytime I redeploy? The iteration cycle takes forever!

We are working on this, follow the issue on it here.

What is the best way to test my subgraph?

If you have your own smart contracts, and they are not on mainnet or testnet, use ganache, and submit your own transactions and watch the subgraph update live! If you are creating a subgraph for contracts that exist on mainnet or testnet, it is useful to test them on mainnet. If you want to interact with the subgraph, then get some testnet Ether, and submit transactions to see it in action.

How long will my subgraph take to sync?

Syncing largely depends on how many transactions the contracts have done. We have seen subgraphs finish in under 5 minutes. And we have seen them take between 10-20 hours. If you are creating a subgraph for an ERC20 token with hundreds of thousands of transactions, such as DAI, it could take a few days. There are a lot of factors that affect this, such as your Ethereum node you have chosen to connect to, and how complex the mappings are.

Explorer

I can't see my organization even though I granted access to The Graph on signup.

If you don't see the organization in the list of accounts on your Dashboard, it might be that it has the "Access Restricted" policy. In order to let The Graph view your organization, you need to request the organization approval for our OAuth app. Please follow the steps here.