8 分钟
将子图部署到多个网络
本页介绍如何将子图部署到多个网络。要部署子图,需要首先安装Graph CLI。如果尚未创建子图,请参见创建子图。
将子图部署到多个网络
在某些情况下,您需要将相同的子图部署到多个网络,而不复制其所有代码。随之而来的主要挑战是这些网络上的合约地址不同。
使用graph-cli
graph build(从v0.29.0版本开始)和graph deploy(从v0.32.0版本开始)都接受两个新选项:
1Options:23 ...4 --network <name> Network configuration to use from the networks config file5 --network-file <path> Networks config file path (default: "./networks.json")您可以使用—network选项从json标准文件(默认为networks.json`)中指定网络配置,以便在开发期间轻松更新子图。
注意: init命令现在将根据提供的信息自动生成 networks.json。然后,您就可以更新现有的或添加其他网络。
如果您没有 networks.json 文件,您则需要手动创建一个具有以下结构的文件:
1{2 "network1": { // the network name3 "dataSource1": { // the dataSource name4 "address": "0xabc...", // the contract address (optional)5 "startBlock": 123456 // the startBlock (optional)6 },7 "dataSource2": {8 "address": "0x123...",9 "startBlock": 12344410 }11 },12 "network2": {13 "dataSource1": {14 "address": "0x987...",15 "startBlock": 12316 },17 "dataSource2": {18 "address": "0xxyz..",19 "startBlock": 45620 }21 },22 ...23}注意:您不必在配置文件中指定任何模板(如果有),只需指定dataSources。如果subgraph.yaml文件中声明了任何模板,则其网络将自动更新为--network选项指定的模板。
现在,让我们假设您希望能够将子图部署到mainnet 和 sepolia网络中,这是您的subgraph.yaml:
1# ...2dataSources:3 - kind: ethereum/contract4 name: Gravity5 network: mainnet6 source:7 address: '0x123...'8 abi: Gravity9 mapping:10 kind: ethereum/events您的网络配置文件应该是这样的:
1{2 "mainnet": {3 "Gravity": {4 "address": "0x123..."5 }6 },7 "sepolia": {8 "Gravity": {9 "address": "0xabc..."10 }11 }12}现在我们可以运行以下命令之一:
1# Using default networks.json file2yarn build --network sepolia34# Using custom named file5yarn build --network sepolia --network-file path/to/configBuild 命令将使用 sepolia 配置更新 subgrap.yaml,然后重新编译子图。你的subgraph.yaml现在应该是这样的:
1# ...2dataSources:3 - kind: ethereum/contract4 name: Gravity5 network: sepolia6 source:7 address: '0xabc...'8 abi: Gravity9 mapping:10 kind: ethereum/events现在你准备好了 yarn 部署。
注意: 如前所述,由于是 graph-cli 0.32.0,所以您可以使用 --network选项直接运行yarn deploy:
1# Using default networks.json file2yarn deploy --network sepolia34# Using custom named file5yarn deploy --network sepolia --network-file path/to/config使用 subgraph.yaml 模板
使用较旧的graph-cli版本对合约地址等方面进行参数化的一种方法是使用Mustache或Handlebars等模板系统生成部分内容。
为了说明这种方法,我们假设应该使用不同的合约地址将子图部署到 mainnet 和 Sepolia。然后,您可以定义两个配置文件,提供每个网络的地址:
1{2 "network": "mainnet",3 "address": "0x123..."4}和
1{2 "network": "sepolia",3 "address": "0xabc..."4}除此之外,您还可以使用可变占位符{{network}} 和 {{address}}替换清单中的网络名称和地址,并将清单重命名为,例如 subgraph.template.yaml:
1# ...2dataSources:3 - kind: ethereum/contract4 name: Gravity5 network: mainnet6 network: {{network}}7 source:8 address: '0x2E645469f354BB4F5c8a05B3b30A929361cf77eC'9 address: '{{address}}'10 abi: Gravity11 mapping:12 kind: ethereum/events为了向任何一个网络生成一个清单,您可以向package.json 添加两个额外的命令以及对mustache的依赖:
1{2 ...3 "scripts": {4 ...5 "prepare:mainnet": "mustache config/mainnet.json subgraph.template.yaml > subgraph.yaml",6 "prepare:sepolia": "mustache config/sepolia.json subgraph.template.yaml > subgraph.yaml"7 },8 "devDependencies": {9 ...10 "mustache": "^3.1.0"11 }12}要为 mainnet 或 Sepolia 部署这个子图,现在只需运行以下两个命令之一:
1# Mainnet:2yarn prepare:mainnet && yarn deploy34# Sepolia:5yarn prepare:sepolia && yarn deploy[这里]可以找到一个工作示例。(https://github.com/graphprotocol/example-subgraph/tree/371232cf68e6d814facf5e5413ad0fef65144759)。
注意: 这种方法也可以应用于更复杂的情况,在这种情况下,需要替换的不仅仅是合约地址和网络名称,或者也需要从模板生成映射或 ABI。
这将为您提供chainHeadBlock,您可以将其与子图上的latestBlock进行比较,以检查它是否落后。同步通知子图是否已经赶上链。如果没有发生错误,health当前可以取healthy的值,如果有错误导致子图的进度停止,则可以取failed的值。在这种情况下,您可以查看fatalError字段以了解此错误的详细信息。
子图工作室子图封存策略
Studio中的子图版本只有在满足以下条件时才会存档:
- 该版本未发布到网络(或等待发布)
- 该版本创建于45天或更早之前
- 该子图已有30天未被查询
此外,当部署新版本时,如果子图尚未发布,则子图的N-2版本将被存档。
受此策略影响的每个子图都有一个选项,可以回复有问题的版本。
检查子图状态
如果子图成功同步,这是一个好信号,表明它将永远运行良好。然而,网络上的新触发器可能会导致子图遇到未经测试的错误条件,或者由于性能问题或节点操作符的问题,子图开始落后。
Graph Node公开了一个GraphQL端点,您可以查询该端点以检查子图的状态。在托管服务上,可以在https://api.thegraph.com/index-node/graphql使用。在本地节点的默认情况下,在8030/graphql端口上可用。此端点的完整架构可以在此处找到。以下是一个检查子图当前版本状态的示例查询:
1{2 indexingStatusForCurrentVersion(subgraphName: "org/subgraph") {3 synced4 health5 fatalError {6 message7 block {8 number9 hash10 }11 handler12 }13 chains {14 chainHeadBlock {15 number16 }17 latestBlock {18 number19 }20 }21 }22}这将为您提供chainHeadBlock,您可以将其与子图上的latestBlock进行比较,以检查它是否落后。同步通知子图是否已经赶上链。如果没有发生错误,health当前可以取healthy的值,如果有错误导致子图的进度停止,则可以取failed的值。在这种情况下,您可以查看fatalError字段以了解此错误的详细信息。