用嫁接替换合约并保持合约的历史
Reading time: 8 min
在本指南中,您将学习如何通过嫁接现有的子图来构建和部署新的子图。
嫁接重用现有子图中的数据,并开始在稍后的区块中对其进行索引。这在开发过程中非常有用,可以快速克服映射中的简单错误,或者在现有子图失败后暂时使其重新工作。此外,当向子图添加特性时可以使用它,因为从头开始索引需要很长时间。
嫁接子图可以使用一个 GraphQL 模式 schema,该模式与基子图之一不同,但仅与基子图兼容。它本身必须是一个有效的子图模式,但是可以通过以下方式偏离基子图的模式:
- 它添加或删除实体类型
- 它从实体类型中删除属性
- 它将可为空的属性添加到实体类型
- 它将不可为空的属性转换为可空的属性
- 它将值添加到枚举类型中
- 它添加或删除接口
- 它改变了实现接口的实体类型
有关详情,请参阅:
在本教程中,我们将介绍一个基本用例。我们将用一个相同的合约(用一个新的地址,但相同的代码) 替换现有的合约。然后,将现有的子图移植到跟踪新合约的基本子图上。
Caution: if you are upgrading your subgraph from Subgraph Studio or the hosted service to the decentralized network, it is strongly recommended to avoid using grafting during the upgrade process.
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. While this is an effective way to preserve data and save time on indexing, grafting may introduce complexities and potential issues when migrating from a hosted environment to the decentralized network. It is not possible to graft a subgraph from The Graph Network back to the hosted service or 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.
构建子图是Graph的重要组成部分,我们在此文进行更深入的描述。为了能够构建和部署本教程中使用的现有子图,提供了以下存储库:
注意: 子图中使用的合约取自以下Hackathon Starterkit。
子图诠释了subgraph.yaml
标识子图的数据源、感兴趣的触发器以及应该响应这些触发器而运行的函数。下面是您将使用的子图清单示例:
specVersion: 0.0.4schema:file: ./schema.graphqldataSources:- kind: ethereumname: Locknetwork: goerlisource:address: '0x4Ed995e775D3629b0566D2279f058729Ae6EA493'abi: LockstartBlock: 7674603mapping: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和合约地址- 网络应该对应于一个被查询的索引网络。因为我们运行在Goerli testnet上,所以这个网络就是
Goerli
。 mapping
部分定义了感兴趣的触发器以及应该响应这些触发器而运行的函数。在这种情况下,我们正在监听Withdrawl
事件,并在发出该事件时调用处理Withdrawal
函数。
嫁接需要在原始子图清单中添加两个新项:
---features:- grafting # feature namegraft:base: Qm... # subgraph ID of base subgraphblock: 1502122 # block number
features
:是所有使用过的特性名称的列表。graft
:是base
子图和要嫁接到的模块的映射。block
是开始索引的区块号。Graph将把基本子图的数据复制到给定的区块并将其包括在内,然后从该区块开始继续索引新的子图。
通过部署两个子图可以找到base
和block
值:一个用于基索引,一个用于嫁接
- 转到Graph Studio UI并在Goerli 测试网上创建一个称为
嫁接示例
的子图 - 按照存储库中
graft-example
文件夹中子图页面的AUTH& DEPLOY
部分中的说明操作 - 完成后,验证子图是否正确索引。如果在Graph Playground中运行下列指令。
{withdrawals(first: 5) {idamountwhen}}
它返回的结果是这样的:
{"data": {"withdrawals": [{"id": "0x13098b538a61837e9f29b32fb40527bbbe63c9120c250242b02b69bb42c287e5-5","amount": "0","when": "1664367528"},{"id": "0x800c92fcc0edbd26f74e19ad058c62008a47c7789f2064023b987028343dd498-3","amount": "0","when": "1664367648"}]}}
一旦您验证了子图是正确的索引,您可以快速更新子图与嫁接。
嫁接替代Subgraph.yaml将获得一个新的合约地址。这可能发生在更新dapp、重新部署合约等时。
- 到Graph Studio UI并在Goerli testnet上创建一个称为
graft-replacement
的子图 - 创建一个新的清单。
subgraph.yaml
用于graph-replacement
,它包含一个不同的合约地址和关于如何移植的新信息。这些是旧合约发出的最后一个事件的block
和旧子图的base
。base
子图ID是原始graph-example
的Deployment ID
。您可以在Graph Studio UI中找到它。 - 按照存储库中的
graft-replacement
文件夹中子图页面上的AUTH& DEPLOY
部分的说明操作。 - 完成后,验证子图是否正确索引。如果在Graph Playground中运行下列指令。
{withdrawals(first: 5) {idamountwhen}}
它返回的结果是这样的:
{"data": {"withdrawals": [{"id": "0x13098b538a61837e9f29b32fb40527bbbe63c9120c250242b02b69bb42c287e5-5","amount": "0","when": "1664367528"},{"id": "0x800c92fcc0edbd26f74e19ad058c62008a47c7789f2064023b987028343dd498-3","amount": "0","when": "1664367648"},{"id": "0xb4010e4c76f86762beb997a13cf020231778eaf7c64fa3b7794971a5e6b343d3-22","amount": "0","when": "1664371512"}]}}
您可以看到,graft-replacement
子图索引来自旧的graph-example
数据和来自新合约地址的新数据。原始合约发出了两个Withdrawal
事件,即事件1和事件2。新合约在事件3之后发生一次Withdrawal
。先前索引的两个交易(事件1和2)和新的交易(事件3)在graft-replacement
子图中组合在一起。
恭喜! 你成功地将一个子图嫁接到另一个子图上。
如果你想要更多的嫁接经验,这里有一些流行合约的例子:
要成为更专业的Graph专家,请考虑学习处理底层数据源更改的其他方法。像数据源模板这样的替代方案可以实现类似的结果。
注意:这篇文章中的很多内容都来自之前发表的Arweave文章。