用嫁接替换合约并保持合约的历史
Reading time: 7 min
在本指南中,您将学习如何通过嫁接现有的子图来构建和部署新的子图。
嫁接重用现有子图中的数据,并开始在稍后的区块中对其进行索引。这在开发过程中非常有用,可以快速克服映射中的简单错误,或者在现有子图失败后暂时使其重新工作。此外,当向子图添加特性时可以使用它,因为从头开始索引需要很长时间。
嫁接子图可以使用一个 GraphQL 模式 schema,该模式与基子图之一不同,但仅与基子图兼容。它本身必须是一个有效的子图模式,但是可以通过以下方式偏离基子图的模式:
- 它添加或删除实体类型
- 它从实体类型中删除属性
- 它将可为空的属性添加到实体类型
- 它将不可为空的属性转换为可空的属性
- 它将值添加到枚举类型中
- 它添加或删除接口
- 它改变了实现接口的实体类型
有关详情,请参阅:
In this tutorial, we will be covering a basic use case. We will replace an existing contract with an identical contract (with a new address, but the same code). Then, graft the existing subgraph onto the "base" subgraph that tracks the new contract.
Caution: It is recommended to not use grafting for subgraphs published to The Graph Network
Grafting is a powerful feature that allows you to "graft" one subgraph onto another, effectively transferring historical data from the existing subgraph to a new version. It is not possible to graft a subgraph from The Graph Network back to Subgraph Studio.
Initial Migration: when you first deploy your subgraph to the decentralized network, do so without grafting. Ensure that the subgraph is stable and functioning as expected.
Subsequent Updates: once your subgraph is live and stable on the decentralized network, you may use grafting for future versions to make the transition smoother and to preserve historical data.
By adhering to these guidelines, you minimize risks and ensure a smoother migration process.
Building subgraphs is an essential part of The Graph, described more in depth . To be able to build and deploy the existing subgraph used in this tutorial, the following repo is provided:
子图诠释了subgraph.yaml
标识子图的数据源、感兴趣的触发器以及应该响应这些触发器而运行的函数。下面是您将使用的子图清单示例:
specVersion: 0.0.4schema:file: ./schema.graphqldataSources:- kind: ethereumname: Locknetwork: sepoliasource:address: '0xb3aabe721794b85fe4e72134795c2f93b4eb7e63'abi: LockstartBlock: 5955690mapping:kind: ethereum/eventsapiVersion: 0.0.6language: wasm/assemblyscriptentities:- Withdrawalabis:- name: Lockfile: ./abis/Lock.jsoneventHandlers:- event: Withdrawal(uint256,uint256)handler: handleWithdrawalfile: ./src/lock.ts
Lock
数据源是我们在编译和部署合约时获得的abi和合约地址- The network should correspond to an indexed network being queried. Since we're running on Sepolia testnet, the network is
sepolia
mapping
部分定义了感兴趣的触发器以及应该响应这些触发器而运行的函数。在这种情况下,我们正在监听Withdrawl
事件,并在发出该事件时调用处理Withdrawal
函数。
嫁接需要在原始子图清单中添加两个新项:
---features:- grafting # feature namegraft:base: Qm... # subgraph ID of base subgraphblock: 5956000 # block number
features:
is a list of all used .graft
:是base
子图和要嫁接到的模块的映射。block
是开始索引的区块号。Graph将把基本子图的数据复制到给定的区块并将其包括在内,然后从该区块开始继续索引新的子图。
通过部署两个子图可以找到base
和block
值:一个用于基索引,一个用于嫁接
- Go to and create a subgraph on Sepolia testnet called
graft-example
- 按照存储库中
graft-example
文件夹中子图页面的AUTH& DEPLOY
部分中的说明操作 - 完成后,验证子图是否正确索引。如果在Graph Playground中运行下列指令。
{withdrawals(first: 5) {idamountwhen}}
它返回的结果是这样的:
{"data": {"withdrawals": [{"id": "0xe8323d21c4f104607b10b0fff9fc24b9612b9488795dea8196b2d5f980d3dc1d0a000000","amount": "0","when": "1716394824"},{"id": "0xea1cee35036f2cacb72f2a336be3e54ab911f5bebd58f23400ebb8ecc5cfc45203000000","amount": "0","when": "1716394848"}]}}
一旦您验证了子图是正确的索引,您可以快速更新子图与嫁接。
嫁接替代Subgraph.yaml将获得一个新的合约地址。这可能发生在更新dapp、重新部署合约等时。
- Go to and create a subgraph on Sepolia testnet called
graft-replacement
- Create a new manifest. The
subgraph.yaml
forgraph-replacement
contains a different contract address and new information about how it should graft. These are theblock
of the you care about by the old contract and thebase
of the old subgraph. Thebase
subgraph ID is theDeployment ID
of your originalgraph-example
subgraph. You can find this in Subgraph Studio. - 按照存储库中的
graft-replacement
文件夹中子图页面上的AUTH& DEPLOY
部分的说明操作。 - 完成后,验证子图是否正确索引。如果在Graph Playground中运行下列指令。
{withdrawals(first: 5) {idamountwhen}}
它返回的结果是这样的:
{"data": {"withdrawals": [{"id": "0xe8323d21c4f104607b10b0fff9fc24b9612b9488795dea8196b2d5f980d3dc1d0a000000","amount": "0","when": "1716394824"},{"id": "0xea1cee35036f2cacb72f2a336be3e54ab911f5bebd58f23400ebb8ecc5cfc45203000000","amount": "0","when": "1716394848"},{"id": "0x2410475f76a44754bae66d293d14eac34f98ec03a3689cbbb56a716d20b209af06000000","amount": "0","when": "1716429732"}]}}
You can see that the graft-replacement
subgraph is indexing from older graph-example
data and newer data from the new contract address. The original contract emitted two Withdrawal
events, and . The new contract emitted one Withdrawal
after, . The two previously indexed transactions (Event 1 and 2) and the new transaction (Event 3) were combined together in the graft-replacement
subgraph.
Congrats! You have successfully grafted a subgraph onto another subgraph.
If you want more experience with grafting, here are a few examples for popular contracts:
To become even more of a Graph expert, consider learning about other ways to handle changes in underlying datasources. Alternatives like can achieve similar results