Deploying a Subgraph to Multiple Networks
Reading time: 6 min
This page explains how to deploy a subgraph to multiple networks. To deploy a subgraph you need to first install the . If you have not created a subgraph already, see .
在某些情况下,您需要将相同的子图部署到多个网络,而不复制其所有代码。随之而来的主要挑战是这些网络上的合约地址不同。
Both graph build
(since v0.29.0
) and graph deploy
(since v0.32.0
) accept two new options:
Options:...--network <name> Network configuration to use from the networks config file--network-file <path> Networks config file path (default: "./networks.json")
You can use the --network
option to specify a network configuration from a json
standard file (defaults to networks.json
) to easily update your subgraph during development.
Note: The init
command will now auto-generate a networks.json
based on the provided information. You will then be able to update existing or add additional networks.
If you don't have a networks.json
file, you'll need to manually create one with the following structure:
{"network1": { // the network name"dataSource1": { // the dataSource name"address": "0xabc...", // the contract address (optional)"startBlock": 123456 // the startBlock (optional)},"dataSource2": {"address": "0x123...","startBlock": 123444}},"network2": {"dataSource1": {"address": "0x987...","startBlock": 123},"dataSource2": {"address": "0xxyz..","startBlock": 456}},...}
Note: You don't have to specify any of the templates
(if you have any) in the config file, only the dataSources
. If there are any templates
declared in the subgraph.yaml
file, their network will be automatically updated to the one specified with the --network
option.
Now, let's assume you want to be able to deploy your subgraph to the mainnet
and sepolia
networks, and this is your subgraph.yaml
:
# ...dataSources:- kind: ethereum/contractname: Gravitynetwork: mainnetsource:address: '0x123...'abi: Gravitymapping:kind: ethereum/events
您的网络配置文件应该是这样的:
{"mainnet": {"Gravity": {"address": "0x123..."}},"sepolia": {"Gravity": {"address": "0xabc..."}}}
现在我们可以运行以下命令之一:
# Using default networks.json fileyarn build --network sepolia# Using custom named fileyarn build --network sepolia --network-file path/to/config
The build
command will update your subgraph.yaml
with the sepolia
configuration and then re-compile the subgraph. Your subgraph.yaml
file now should look like this:
# ...dataSources:- kind: ethereum/contractname: Gravitynetwork: sepoliasource:address: '0xabc...'abi: Gravitymapping:kind: ethereum/events
Now you are ready to yarn deploy
.
Note: As mentioned earlier, since graph-cli 0.32.0
you can directly run yarn deploy
with the --network
option:
# Using default networks.json fileyarn deploy --network sepolia# Using custom named fileyarn deploy --network sepolia --network-file path/to/config
One way to parameterize aspects like contract addresses using older graph-cli
versions is to generate parts of it with a templating system like or .
To illustrate this approach, let's assume a subgraph should be deployed to mainnet and Sepolia using different contract addresses. You could then define two config files providing the addresses for each network:
{"network": "mainnet","address": "0x123..."}
和
{"network": "sepolia","address": "0xabc..."}
Along with that, you would substitute the network name and addresses in the manifest with variable placeholders {{network}}
and {{address}}
and rename the manifest to e.g. subgraph.template.yaml
:
# ...dataSources:- kind: ethereum/contractname: Gravitynetwork: mainnetnetwork: {{network}}source:address: '0x2E645469f354BB4F5c8a05B3b30A929361cf77eC'address: '{{address}}'abi: Gravitymapping:kind: ethereum/events
In order to generate a manifest to either network, you could add two additional commands to package.json
along with a dependency on mustache
:
{..."scripts": {..."prepare:mainnet": "mustache config/mainnet.json subgraph.template.yaml > subgraph.yaml","prepare:sepolia": "mustache config/sepolia.json subgraph.template.yaml > subgraph.yaml"},"devDependencies": {..."mustache": "^3.1.0"}}
To deploy this subgraph for mainnet or Sepolia you would now simply run one of the two following commands:
# Mainnet:yarn prepare:mainnet && yarn deploy# Sepolia:yarn prepare:sepolia && yarn deploy
A working example of this can be found .
Note: This approach can also be applied to more complex situations, where it is necessary to substitute more than contract addresses and network names or where generating mappings or ABIs from templates as well.
This will give you the chainHeadBlock
which you can compare with the latestBlock
on your subgraph to check if it is running behind. synced
informs if the subgraph has ever caught up to the chain. health
can currently take the values of healthy
if no errors occurred, or failed
if there was an error which halted the progress of the subgraph. In this case, you can check the fatalError
field for details on this error.
A subgraph version in Studio is archived if and only if it meets the following criteria:
- The version is not published to the network (or pending publish)
- The version was created 45 or more days ago
- The subgraph hasn't been queried in 30 days
In addition, when a new version is deployed, if the subgraph has not been published, then the N-2 version of the subgraph is archived.
受此策略影响的每个子图都有一个选项,可以回复有问题的版本。
如果子图成功同步,这是一个好信号,表明它将永远运行良好。然而,网络上的新触发器可能会导致子图遇到未经测试的错误条件,或者由于性能问题或节点操作符的问题,子图开始落后。
Graph Node exposes a GraphQL endpoint which you can query to check the status of your subgraph. On the hosted service, it is available at https://api.thegraph.com/index-node/graphql
. On a local node, it is available on port 8030/graphql
by default. The full schema for this endpoint can be found . Here is an example query that checks the status of the current version of a subgraph:
{indexingStatusForCurrentVersion(subgraphName: "org/subgraph") {syncedhealthfatalError {messageblock {numberhash}handler}chains {chainHeadBlock {number}latestBlock {number}}}}
This will give you the chainHeadBlock
which you can compare with the latestBlock
on your subgraph to check if it is running behind. synced
informs if the subgraph has ever caught up to the chain. health
can currently take the values of healthy
if no errors occurred, or failed
if there was an error which halted the progress of the subgraph. In this case, you can check the fatalError
field for details on this error.