Using The Graph on REI Network
To use Graph on REI, you should run a local Graph Node against REI testnet and point your Subgraph to it. From the link below you can get information on how to run a nodeThe Bank Contract
For this example, a simple Bank contract will be used. You can find the Solidity file in the
The contract contains a bank where users can deposit rei for themselves, or transfer their rei in bank to others. They can also withdraw their rei from bank.
The main functions of the contract are the following:
- deposit() — function to send rei to the contract, then you can get your own proof of deposit in the bank
- transfer(address to, uint256 amount) — transfer your rei in bank to others
- whithdraw(unit256 amount) — redeem your money based on certificates of deposit
The Graph uses the events emitted by the contract to index data. The bank contract emits three events:
- Deposit(address indexed from, uint256 indexed amount) — in the deposit function. It provides information related to deposit entry, including account address and deposit rei amount
- Transfer(address indexed from, address indexed to, uint256 indexed amount) — in the transfer function. It provides information on transaction between accounts in the bank, including accounts address and rei amount
- Withdraw(address indexed from, uint256 indexed amount) — in the withdraw function. It provides information related to withdraw entry, including account address and withdraw rei amount
This section goes through the process of creating a Subgraph. For the Bank Subgraph, a GitHub repository was prepared with everything you need to help you get started. The repository also includes the Bank contract, as well as a Hardhat configuration file and deployment script. If you are not familiar with it, you can check our Hardhat integration guide to learn about the configuration file and how to deploy a contract using Hardhat.
To get started, first clone the repository and install the dependencies
git clone https://github.com/bijianing97/REIBank-subgraph && cd REIBank-subgraph
npm i
Now, you can create the TypeScript types for the Graph by running
npm run codegen
The types will in the src/types/
Creating the types requires you to have the ABI files specified in the
subgraph.yaml
file. This sample repository has the file already, but this is usually obtained after compiling the contract.You also can use following command to specify the generated directory
npx graph codegen --output-dir xxxx
For this example, the contract was deployed to
0x1Ec9238A1c0adca222251e1f607a77237E8686a3
. The README.md
file in the project has the steps necessary to compile and deploy the contract if required.In general terms, Subgraphs define the data that The Graph will index from the blockchain and the way it is stored. The subgraph definition consists of a few files:
- 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 to the entities defined in your schema (e.g.
bank.ts
in this tutorial)
The schema for your subgraph is in the file
schema.graphql
. GraphQL schemas are defined using the GraphQL interface definition language. If you've never written a GraphQL schema, it is recommended that you check out this primer on the GraphQL type system. Reference documentation for GraphQL schemas can be found in the GraphQL API section.For this example, here one entry is defined for bank:- Account — Record the users in bank, about their account address and balance
So the
schema.graphql
should look like the following snippet:type Account @entity {
id: ID!
balance: BigInt!
operateTime: BigInt!
}
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.For the example subgraph,
subgraph.yaml
is:Some of the most important parameters in the
subgraph.yaml
file are:- repository — Github repository of the subgraph
- schema/file — location of the
schema.graphql
file - dataSources/name — the name of the Subgraph
- network — refers to the network name. This value must be set to the local graph node name which you setted
- dataSources/source/address — the address of the contract
- dataSources/source/abi — refers to where the interface of the contract is stored inside the
types
folder created with thecodegen
command - dataSources/source/startBlock — refers to the start block from which the indexing will start
- dataSources/mapping/file — refers to the location of the mapping file, eg
bank.ts
- dataSources/mapping/entities — definitions of the entities in the
schema.graphql
file - dataSources/abis/name — where the interface of the contract is stored inside the
types/dataSources/name
- dataSources/abis/file — refers to the location where the
.json
file with the contract's ABI is stored - dataSources/eventHandlers — no value needs to be defined here, but this section refers to all the events that The Graph will index
- dataSources/eventHandlers/event — refers to the structure of an event to be tracked inside the contract. You need to provide the event name and its type of variables
- dataSources/eventHandlers/handler — refers to the name of the function inside the
mapping.ts
file which handles the event data
In short, the
subgraph.yaml
should look like the following snippet:specVersion: 0.0.2
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum
name: Bank
network: reidev
source:
address: "0x1Ec9238A1c0adca222251e1f607a77237E8686a3"
abi: Bank
mapping:
kind: ethereum/events
apiVersion: 0.0.6
language: wasm/assemblyscript
entities:
- Account
abis:
- name: Bank
file: ./abis/Bank.json
eventHandlers:
- event: Deposit(indexed address,indexed uint256)
handler: handleDeposit
- event: Transfer(indexed address,indexed address,indexed uint256)
handler: handleTransfer
- event: Withdraw(indexed address,indexed uint256)
handler: handleWithdraw
file: ./src/Bank.ts
The mappings transform the Ethereum data your mappings are sourcing into entities defined in your schema. Mappings are written in a subset of TypeScript called AssemblyScript which can be compiled to WASM (WebAssembly). AssemblyScript is stricter than normal TypeScript, yet provides a familiar syntax.
The mapping file used for the Bank example can be found in the project:
export function handleDeposit(event: Deposit): void {
const address = event.params.from
const amount = event.params.amount
const id = `${address.toHex()}`
let instance = Account.load(id)
if (!instance) {
instance = new Account(id)
instance.balance = amount
instance.operateTime = BigInt.fromU32(1)
} else {
instance.balance = instance.balance.plus(amount)
instance.operateTime = instance.operateTime.plus(BigInt.fromU32(1))
}
instance.save()
}
With your local Graph Node, you can create your Subgraph executing the following code:
npx graph create <username>/<subgraph-name> --node <graph-node>
Where:
- username — refers to the username related to the Subgraph being created
- subgraph-name — the Subgraph name
- graph-node — refers to the URL of the hosted service to use. Typically, for a local Graph Node is
http://127.0.0.1:8020
Once created, you can deploy your Subgraph by running the following command with the same parameters as before:
npx graph deploy <username>/<subgraph-name> \
--ipfs <ipfs-url> \
--node <graph-node> \
Where:
- username — refers to the username used when creating the Subgraph
- subraph-name — refers to the Subgraph name defined when creating the Subgraph
- ipfs-url — refers to the URL for IPFS. For your local Graph Node, the default value is
http://localhost:5001
- graph-node — refers to the URL of the hosted service to use. For your local Graph Node, the default value is
http://localhost:8020
The logs for the sucessful deployed should look like:

DApps can now use the Subgraph endpoints to fetch the data indexed by The Graph protocol.
If there has existed call record for contract, you can call the Graph node to get the data, just like this:
curl -X POST -d '{ "query": "{accounts{id,balance,operateTime}}"}' http://localhost:8000/subgraphs/name/bank| json_pp
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 366 100 318 100 48 26500 4000 --:--:-- --:--:-- --:--:-- 33272
{
"data" : {
"accounts" : [
{
"balance" : "199999999999999922243",
"id" : "0x809fae291f79c9953577ee9007342cff84014b1c",
"operateTime" : "3"
},
{
"balance" : "15000000000000000000",
"id" : "0x898b84b6a6430eed36a6cfc14a1cb7da326c91c4",
"operateTime" : "1"
},
{
"balance" : "77777",
"id" : "0x8dd89ed567ac41866babddeb8931af2a695106af",
"operateTime" : "0"
}
]
}
}
Last modified 1yr ago