Subgraph
Example locally hosted subgraph in Acala EVM+.
The Subgraph that we will establish in this example demonstrates how to establish your own Subgraph for projects running in the Acala EVM+.
NOTE: As this example focuses on Subgraph, we won't be analysing the smart contract used. If you wish to learn more about building smart contracts within Acala EVM+, please refer to our tutorials.

Setup

In order to be able to run the example, we need to run the local network first and then spin up the graph-node stack.

Spin up the local development network

You can read up on how to spin up the local development network in the documentation. For those that just want to get started with the Subgraph part, you need to use the following commands:
1
git clone --recurse-submodules [email protected]:AcalaNetwork/bodhi.js.git
2
cd bodhi.js/evm-subql
3
yarn
4
yarn build
5
docker compose up
Copied!
Once the network converges (you should start seeing the evm-subql-mandala-node-1 start reporting that it's ready), open up another terminal and run the RPC adapter:
1
LOCAL_MODE=1 SUBQL_URL=http://localhost:3001 npx @acala-network/[email protected]^2.4.12
Copied!
Once you get the following output, your local development network and RPC adapter are ready:
1
-------------------------------
2
πŸ”¨ local development mode is ON
3
❌ don't use it for production!
4
-------------------------------
5
​
6
2022-06-09 12:20:05 API/INIT: RPC methods not decorated: evm_blockLimits
7
​
8
--------------------------------------------
9
πŸš€ SERVER STARTED πŸš€
10
--------------------------------------------
11
version : bodhi.js/eth-rpc-adapter/2.4.12
12
endpoint url : ws://0.0.0.0::9944
13
subquery url : http://localhost:3001
14
listening to : http 8545 | ws 3331
15
max cacheSize : 200
16
max batchSize : 50
17
max storageSize: 5000
18
safe mode : false
19
local mode : true
20
--------------------------------------------
Copied!

Clone the example repository

Cloning this repository gives access to the Gravity smart contract as well as the migrations needed to deploy it. The truffle.js contains the required network configuration and the configuration files for a local subgraph node are included as well.
The example repository is available here: https://github.com/AcalaNetwork/subgraph-example​
1
git clone [email protected]:AcalaNetwork/subgraph-example.git
Copied!
To install the required dependencies simply use:
1
yarn
Copied!
This will install all of the dependencies needed to deploy the smart contract to Acala EVM+ and the dependencies required to spin up the subgraph.
The package.json contains scripts that allow for compilation and deployment of the smart contracts in the "scripts" section:
1
"build-contract": "truffle compile",
2
"deploy-contract": "truffle migrate --network mandala --reset"
Copied!

Subgraph

The definition of the subgraph lives within subgraph.yaml and doesn't differ from other subgraph definitions. You can learn more about subgraph definitions in the documentation.
The Gravatar is defined in the schema.graphql and doesn't differ from any schema designed for another environment. If you wish to learn more about building schemas, you can do so here.
The subgraph will live in the docker along with docker-hosted IPFS and Postgres. You can check out how the all of them connect to each other and to the already-running local development network in the docker-compose.yml.

Usage

In order to use the locally hosted subgraph, we need to spin up our Docker containers by using:
1
docker compose up
Copied!
Once the containers are running, you should see the following output:
1
subgraph-example-graph-node-1 | Jun 14 21:44:32.410 INFO Starting block ingestors with 1 chains [acala]
2
subgraph-example-graph-node-1 | Jun 14 21:44:32.410 INFO Starting block ingestor for network, network_name: acala
3
subgraph-example-graph-node-1 | Jun 14 21:44:32.411 INFO Starting firehose block ingestors with 0 chains []
4
subgraph-example-graph-node-1 | Jun 14 21:44:32.411 INFO Starting firehose block ingestors with 0 chains []
5
subgraph-example-graph-node-1 | Jun 14 21:44:32.412 INFO Starting job runner with 4 jobs, component: JobRunner
6
subgraph-example-graph-node-1 | Jun 14 21:44:32.452 INFO Starting JSON-RPC admin server at: http://localhost:8020, component: JsonRpcServer
7
subgraph-example-graph-node-1 | Jun 14 21:44:32.468 INFO Starting GraphQL HTTP server at: http://localhost:8000, component: GraphQLServer
8
subgraph-example-graph-node-1 | Jun 14 21:44:32.471 INFO Starting index node server at: http://localhost:8030, component: IndexNodeServer
9
subgraph-example-graph-node-1 | Jun 14 21:44:32.475 INFO Starting metrics server at: http://localhost:8040, component: MetricsServer
10
subgraph-example-graph-node-1 | Jun 14 21:44:32.476 INFO Starting GraphQL WebSocket server at: ws://localhost:8001, component: SubscriptionServer
11
subgraph-example-graph-node-1 | Jun 14 21:44:32.524 INFO Started all assigned subgraphs, node_id: default, count: 1, component: SubgraphRegistrar
12
subgraph-example-graph-node-1 | Jun 14 21:44:32.695 INFO Resolve subgraph files using IPFS, sgd: 1, subgraph_id: QmWbRi1CvZGy2sKbdp549dH99KDbALZKy3133WyK1CgaHm, component: SubgraphInstanceManager
13
subgraph-example-graph-node-1 | Jun 14 21:44:32.702 INFO Resolve schema, link: /ipfs/QmbSFRGGvHM7Cn8YSjDL41diDMxN4LQUDEMqaa5VVc5sC4, sgd: 1, subgraph_id: QmWbRi1CvZGy2sKbdp549dH99KDbALZKy3133WyK1CgaHm, component: SubgraphInstanceManager
14
subgraph-example-graph-node-1 | Jun 14 21:44:32.703 INFO Resolve data source, source_start_block: 0, source_address: Some(0xf80a32a835f79d7787e8a8ee5721d0feafd78108), name: Gravity, sgd: 1, subgraph_id: QmWbRi1CvZGy2sKbdp549dH99KDbALZKy3133WyK1CgaHm, component: SubgraphInstanceManager
15
subgraph-example-graph-node-1 | Jun 14 21:44:32.704 INFO Resolve mapping, link: /ipfs/Qmf1LHCv7pcM4sVykN4uTocLPSwHN5o9JzWcuLU9pqHgXF, sgd: 1, subgraph_id: QmWbRi1CvZGy2sKbdp549dH99KDbALZKy3133WyK1CgaHm, component: SubgraphInstanceManager
16
subgraph-example-graph-node-1 | Jun 14 21:44:32.704 INFO Resolve ABI, link: /ipfs/QmajZTadknSpgsCWRz9fG6bXFHdpVXPMWpx9yMipz3VtMQ, name: Gravity, sgd: 1, subgraph_id: QmWbRi1CvZGy2sKbdp549dH99KDbALZKy3133WyK1CgaHm, component: SubgraphInstanceManager
17
subgraph-example-graph-node-1 | Jun 14 21:44:32.728 INFO Successfully resolved subgraph files using IPFS, sgd: 1, subgraph_id: QmWbRi1CvZGy2sKbdp549dH99KDbALZKy3133WyK1CgaHm, component: SubgraphInstanceManager
18
subgraph-example-graph-node-1 | Jun 14 21:44:32.728 INFO Data source count at start: 1, sgd: 1, subgraph_id: QmWbRi1CvZGy2sKbdp549dH99KDbALZKy3133WyK1CgaHm, component: SubgraphInstanceManager
19
subgraph-example-graph-node-1 | Jun 14 21:44:33.076 ERRO registering metric [deployment_eth_rpc_request_duration] because it was already registered, component: MetricsRegistry
20
subgraph-example-graph-node-1 | Jun 14 21:44:33.077 ERRO registering metric [deployment_eth_rpc_errors] because it was already registered, component: MetricsRegistry
Copied!
We are now ready to deploy the local subgraph. The steps to deploy it can be separated into two distinct groups:
  1. 1.
    Build and deploy the Gravitar smart contract to Acala EVM+
  2. 2.
    Create and deploy the subgraph

Build and deploy the Gravitar smart contract to Acala EVM+

We can optionally reset the project by using the clean script:
1
"clean": "rm -rf data/ generated/ build/ temp/ lib/ network.json"
Copied!
To be able to easily build the smart contract as well as deploy it, build-contract and deploy-contract scripts have to be added to package.json:
1
"build-contract": "truffle compile",
2
"deploy-contract": "truffle migrate --network mandala --reset"
Copied!
Running these scripts should succecssfully deploy the smart contract and populate the gravatars:
1
yarn clean #optional
2
yarn build-contract
3
yarn deploy-contract
Copied!
Now that the smart contract has been successfully deployed, we can move on to deploying the subgraph.

Create and deploy the subgraph

Scripts to generate the Graph code, build it, create and deploy it need to be added to the package.json:
1
"build-graph": "graph build",
2
"create-local": "graph create acala/examplesubgraph --node http://127.0.0.1:8020",
3
"remove-local": "graph remove acala/examplesubgraph --node http://127.0.0.1:8020",
4
"deploy-local": "graph deploy acala/examplesubgraph --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020"
Copied!
Running them should deploy the subgraph:
1
yarn codegen
2
yarn build-graph
3
yarn create-local
4
yarn deploy-local
Copied!
When running the deploy-local script, you can decide to specify the version of the subgraph, but for the example purposes accepting the default value should suffice:
1
yarn deploy-local
2
yarn run v1.22.19
3
$ graph deploy acala/examplesubgraph --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020
4
βœ” Version Label (e.g. v0.0.1) Β·
5
Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
6
Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
7
Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
8
Skip migration: Bump mapping apiVersion from 0.0.4 to 0.0.5
9
Skip migration: Bump mapping specVersion from 0.0.1 to 0.0.2
10
βœ” Apply migrations
11
βœ” Load subgraph from subgraph.yaml
12
Compile data source: Gravity => build/Gravity/Gravity.wasm
13
βœ” Compile subgraph
14
Copy schema file build/schema.graphql
15
Write subgraph file build/Gravity/abis/Gravity.json
16
Write subgraph manifest build/subgraph.yaml
17
βœ” Write compiled subgraph to build/
18
Add file to IPFS build/schema.graphql
19
.. QmbSFRGGvHM7Cn8YSjDL41diDMxN4LQUDEMqaa5VVc5sC4
20
Add file to IPFS build/Gravity/abis/Gravity.json
21
.. QmajZTadknSpgsCWRz9fG6bXFHdpVXPMWpx9yMipz3VtMQ
22
Add file to IPFS build/Gravity/Gravity.wasm
23
.. Qmf1LHCv7pcM4sVykN4uTocLPSwHN5o9JzWcuLU9pqHgXF
24
βœ” Upload subgraph to IPFS
25
​
26
Build completed: QmWbRi1CvZGy2sKbdp549dH99KDbALZKy3133WyK1CgaHm
27
​
28
Deployed to http://127.0.0.1:8000/subgraphs/name/acala/examplesubgraph/graphql
29
​
30
Subgraph endpoints:
31
Queries (HTTP): http://127.0.0.1:8000/subgraphs/name/acala/examplesubgraph
32
Subscriptions (WS): http://127.0.0.1:8001/subgraphs/name/acala/examplesubgraph
33
​
34
✨ Done in 6.19s.
Copied!
As you can see, we can now interact with the locally deployed subgraph.

Quick build script

As an additionally supported script, we have added the run-all script to the package.json, which can be used to quickly deploy the smart contract as well as the locally hosted subgraph:
1
yarn run-all
2
yarn run v1.22.19
3
$ yarn build-all && yarn deploy-all
4
$ yarn clean && yarn build-contract && yarn codegen && yarn build-graph
5
$ rm -rf data/ generated/ build/ temp/ lib/ network.json
6
$ truffle compile
7
​
8
Compiling your contracts...
9
===========================
10
> Compiling ./contracts/Gravity.sol
11
> Compiling ./contracts/Migrations.sol
12
> Artifacts written to /Users/jan/Acala/subgraph-example/build/contracts
13
> Compiled successfully using:
14
- solc: 0.4.25+commit.59dbf8f1.Emscripten.clang
15
$ graph codegen
16
Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
17
Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
18
Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
19
Skip migration: Bump mapping apiVersion from 0.0.4 to 0.0.5
20
Skip migration: Bump mapping specVersion from 0.0.1 to 0.0.2
21
βœ” Apply migrations
22
βœ” Load subgraph from subgraph.yaml
23
Load contract ABI from abis/Gravity.json
24
βœ” Load contract ABIs
25
Generate types for contract ABI: Gravity (abis/Gravity.json)
26
Write types to generated/Gravity/Gravity.ts
27
βœ” Generate types for contract ABIs
28
βœ” Generate types for data source templates
29
βœ” Load data source template ABIs
30
βœ” Generate types for data source template ABIs
31
βœ” Load GraphQL schema from schema.graphql
32
Write types to generated/schema.ts
33
βœ” Generate types for GraphQL schema
34
​
35
Types generated successfully
36
​
37
$ graph build
38
Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
39
Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
40
Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
41
Skip migration: Bump mapping apiVersion from 0.0.4 to 0.0.5
42
Skip migration: Bump mapping specVersion from 0.0.1 to 0.0.2
43
βœ” Apply migrations
44
βœ” Load subgraph from subgraph.yaml
45
Compile data source: Gravity => build/Gravity/Gravity.wasm
46
βœ” Compile subgraph
47
Copy schema file build/schema.graphql
48
Write subgraph file build/Gravity/abis/Gravity.json
49
Write subgraph manifest build/subgraph.yaml
50
βœ” Write compiled subgraph to build/
51
​
52
Build completed: /Users/jan/Acala/subgraph-example/build/subgraph.yaml
53
​
54
$ yarn deploy-contract && yarn create-local && yarn deploy-local
55
$ truffle migrate --network mandala --reset
56
​
57
Compiling your contracts...
58
===========================
59
> Everything is up to date, there is nothing to compile.
60
​
61
​
62
Starting migrations...
63
======================
64
> Network name: 'mandala'
65
> Network id: 595
66
> Block gas limit: 15000000 (0xe4e1c0)
67
​
68
​
69
1_initial_migration.js
70
======================
71
​
72
Deploying 'Migrations'
73
----------------------
74
> transaction hash: 0xa4c6295639c832781b5a08d0e1caf7f048de2e11cc486532c3aa5202d78226ad
75
> Blocks: 0 Seconds: 0
76
> contract address: 0x1a906E71FF9e28d8E01460639EB8CF0a6f0e2486
77
> block number: 17
78
> block timestamp: 1655246466
79
> account: 0x75E480dB528101a381Ce68544611C169Ad7EB342
80
> balance: 10000990.675883098224
81
> gas used: 239894 (0x3a916)
82
> gas price: 11251.291893661 gwei
83
> value sent: 0 ETH
84
> total cost: 2.699117417537911934 ETH
85
​
86
> Saving migration to chain.
87
> Saving artifacts
88
-------------------------------------
89
> Total cost: 2.699117417537911934 ETH
90
​
91
​
92
2_deploy_contract.js
93
====================
94
​
95
Deploying 'GravatarRegistry'
96
----------------------------
97
> transaction hash: 0x0539850eaa0f34b8583fa38af76436876f1e2edd8db584437f82346be1b98417
98
> Blocks: 0 Seconds: 0
99
> contract address: 0x78b1F763857C8645E46eAdD9540882905ff32Db7
100
> block number: 19
101
> block timestamp: 1655246478
102
> account: 0x75E480dB528101a381Ce68544611C169Ad7EB342
103
> balance: 10000988.456154170068
104
> gas used: 1214156 (0x1286cc)
105
> gas price: 2974.008289142 gwei
106
> value sent: 0 ETH
107
> total cost: 3.610910008311494152 ETH
108
​
109
> Saving migration to chain.
110
> Saving artifacts
111
-------------------------------------
112
> Total cost: 3.610910008311494152 ETH
113
​
114
​
115
3_create_gravatars.js
116
=====================
117
Account address: 0x78b1F763857C8645E46eAdD9540882905ff32Db7
118
> Saving migration to chain.
119
-------------------------------------
120
> Total cost: 0 ETH
121
​
122
Summary
123
=======
124
> Total deployments: 2
125
> Final cost: 6.310027425849406086 ETH
126
​
127
​
128
$ graph create acala/examplesubgraph --node http://127.0.0.1:8020
129
Created subgraph: acala/examplesubgraph
130
$ graph deploy acala/examplesubgraph --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020
131
βœ” Version Label (e.g. v0.0.1) Β·
132
Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
133
Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
134
Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
135
Skip migration: Bump mapping apiVersion from 0.0.4 to 0.0.5
136
Skip migration: Bump mapping specVersion from 0.0.1 to 0.0.2
137
βœ” Apply migrations
138
βœ” Load subgraph from subgraph.yaml
139
Compile data source: Gravity => build/Gravity/Gravity.wasm
140
βœ” Compile subgraph
141
Copy schema file build/schema.graphql
142
Write subgraph file build/Gravity/abis/Gravity.json
143
Write subgraph manifest build/subgraph.yaml
144
βœ” Write compiled subgraph to build/
145
Add file to IPFS build/schema.graphql
146
.. QmbSFRGGvHM7Cn8YSjDL41diDMxN4LQUDEMqaa5VVc5sC4
147
Add file to IPFS build/Gravity/abis/Gravity.json
148
.. QmajZTadknSpgsCWRz9fG6bXFHdpVXPMWpx9yMipz3VtMQ
149
Add file to IPFS build/Gravity/Gravity.wasm
150
.. Qmf1LHCv7pcM4sVykN4uTocLPSwHN5o9JzWcuLU9pqHgXF
151
βœ” Upload subgraph to IPFS
152
​
153
Build completed: QmWbRi1CvZGy2sKbdp549dH99KDbALZKy3133WyK1CgaHm
154
​
155
Deployed to http://127.0.0.1:8000/subgraphs/name/acala/examplesubgraph/graphql
156
​
157
Subgraph endpoints:
158
Queries (HTTP): http://127.0.0.1:8000/subgraphs/name/acala/examplesubgraph
159
Subscriptions (WS): http://127.0.0.1:8001/subgraphs/name/acala/examplesubgraph
160
​
161
✨ Done in 24.44s.
Copied!

Subgraph interaction

The playground is reachable at http://127.0.0.1:8000/subgraphs/name/acala/examplesubgraph/graphql. You can query the gravatars from the Gravity smart contract using the following query:
1
query {
2
gravatars {
3
id,
4
displayName,
5
imageUrl,
6
owner
7
}
8
}
Copied!
The result should give information about three gravatars:
1
{
2
"data": {
3
"gravatars": [
4
{
5
"id": "0x0",
6
"displayName": "AAAAA",
7
"imageUrl": "https://example/AAAAA.png",
8
"owner": "0x75e480db528101a381ce68544611c169ad7eb342"
9
},
10
{
11
"id": "0x1",
12
"displayName": "BBBBB",
13
"imageUrl": "https://example/BBBBB.jpg",
14
"owner": "0x0085560b24769dac4ed057f1b2ae40746aa9aab6"
15
},
16
{
17
"id": "0x2",
18
"displayName": "CCCCC",
19
"imageUrl": "https://example/CCCCC.jpg",
20
"owner": "0x0294350d7cf2c145446358b6461c1610927b3a87"
21
}
22
]
23
}
24
}
Copied!
Querying the local subgraph
This concludes out locally hosted subgraph example in Acala EVM+.