Docs
搜索⌘ K
  • 主页
  • 关于 The Graph
  • 支持的网络
  • 协议合约
  • 子图
    • 子流
      • 代币 API
        • Hypergraph
          • AI Suite
            • 索引
              • 资源
                子图 > 操作指南

                9 分钟

                用嫁接替换合约并保持合约的历史

                在本指南中,您将学习如何通过嫁接现有的子图来构建和部署新的子图。

                什么是嫁接?

                嫁接重用现有子图中的数据,并开始在稍后的区块中对其进行索引。这在开发过程中非常有用,可以快速克服映射中的简单错误,或者在现有子图失败后暂时使其重新工作。此外,当向子图添加特性时可以使用它,因为从头开始索引需要很长时间。

                嫁接子图可以使用一个与基础子图不同的GraphQL 模式,但仅与之兼容。它本身必须是一个有效的子图模式,但是可以通过以下方式偏离基础子图的模式:

                • 添加或删除实体类型
                • 从实体类型中删除属性
                • 将可为空的属性添加到实体类型
                • 将不可为空的属性转换为可空的属性
                • 将值添加到枚举类型中
                • 添加或删除接口
                • 改变了实现接口的实体类型

                有关详情,请参阅:

                • 嫁接

                在本教程中,我们将介绍一个基本用例。我们将用一个相同的合约(用一个新的地址,但相同的代码) 替换现有的合约。然后,将现有的子图嫁接到跟踪新合约的 “基础 “子图上。

                升级到网络时嫁接的重要注意事项

                警告:建议不要对发布到The Graph网络的子图使用嫁接

                为什么这很重要?

                嫁接是一个强大的功能,允许您将一个子图“嫁接”到另一个子图上,有效地将历史数据从现有子图转移到新版本。无法将子图从The Graph网络嫁接回subgraph Studio。

                最佳实践

                初始迁移:当你第一次将子图部署到去中心化网络时,不要进行嫁接。确保子图稳定并按预期运行。

                后续更新:一旦你的子图在去中心化网络上上线并稳定,你可以在未来的版本中使用嫁接,使过渡更平滑,并保留历史数据。

                通过遵守这些准则,您可以将风险降至最低,并确保迁移过程更加顺利。

                构建现有子图

                构建子图是The Graph的重要组成部分,在此文进行更深入的描述。为了能够构建和部署本教程中使用的现有子图,提供了以下库:

                • 子图示例存储库⁠

                注意: 子图中使用的合约取自以下Hackathon Starterkit⁠。

                子图清单定义

                子图诠释了subgraph.yaml标识子图的数据源、感兴趣的触发器以及应该响应这些触发器而运行的函数。下面是您将使用的子图清单示例:

                1specVersion: 1.3.02schema:3  file: ./schema.graphql4dataSources:5  - kind: ethereum6    name: Lock7    network: sepolia8    source:9      address: '0xb3aabe721794b85fe4e72134795c2f93b4eb7e63'10      abi: Lock11      startBlock: 595569012    mapping:13      kind: ethereum/events14      apiVersion: 0.0.915      language: wasm/assemblyscript16      entities:17        - Withdrawal18      abis:19        - name: Lock20          file: ./abis/Lock.json21      eventHandlers:22        - event: Withdrawal(uint256,uint256)23          handler: handleWithdrawal24      file: ./src/lock.ts
                • Lock数据源是我们在编译和部署合约时获得的abi和合约地址。
                • 网络应该对应于一个被查询的索引网络。因为我们运行在Sepolia 测试网上,所以这个网络就是Sepolia。
                • mapping部分定义了感兴趣的触发器以及应该响应这些触发器而运行的函数。在这种情况下,我们正在监听Withdrawl事件,并在发出该事件时调用处理Withdrawal函数。

                嫁接清单定义

                嫁接需要在原始子图清单中添加两个新项:

                1---2features:3  - grafting # feature name4graft:5  base: Qm... # Subgraph ID of base Subgraph6  block: 5956000 # block number
                • features:是所有使用的功能名称的列表。
                • graft:是基础子图和要嫁接到的模块的映射。block是开始索引的区块号。The Graph将把基础子图的数据复制到给定的区块并将其包括在内,然后从该区块开始继续索引新的子图。

                通过部署两个子图可以找到base和block值:一个用于基础索引,一个用于嫁接。

                部署基子图

                1. 转到Subgraph Studio 子图并在Sepolia 测试网上创建一个称为graft-example的子图。
                2. 按照存储库中graft-example文件夹中子图页面的 AUTH& DEPLOY 部分中的说明操作。
                3. 完成后,验证子图是否正确索引。如果在The Graph Playground中运行下列指令。
                1{2  withdrawals(first: 5) {3    id4    amount5    when6  }7}

                它返回的结果是这样的:

                1{2  "data": {3    "withdrawals": [4      {5        "id": "0xe8323d21c4f104607b10b0fff9fc24b9612b9488795dea8196b2d5f980d3dc1d0a000000",6        "amount": "0",7        "when": "1716394824"8      },9      {10        "id": "0xea1cee35036f2cacb72f2a336be3e54ab911f5bebd58f23400ebb8ecc5cfc45203000000",11        "amount": "0",12        "when": "1716394848"13      }14    ]15  }16}

                一旦您验证了子图是正确的索引,您可以快速更新子图与嫁接。

                部署嫁接子图

                嫁接替代Subgraph.yaml将获得一个新的合约地址。这可能发生在更新dapp、重新部署合约等时。

                1. 转到Subgraph Studio 子图并在Sepolia 测试网上创建一个称为graft-replacement的子图。
                2. 创建新清单。 graph-replacement 的subgraph.yaml包含一个不同的合约地址和关于其应该如何嫁接的新信息。这些是旧合约发出的最后一个事件⁠ 的模块,你关心的是旧合约,也是旧子图的基础。基础子图ID是原始graph-example 子图的部署ID。你可以在Subgraph Studio中找到它。
                3. 按照存储库中的graft-replacement文件夹中子图页面上的 AUTH& DEPLOY 部分的说明操作。
                4. 完成后,验证子图是否正确索引。如果在Graph Playground中运行下列指令。
                1{2  withdrawals(first: 5) {3    id4    amount5    when6  }7}

                它返回的结果是这样的:

                1{2  "data": {3    "withdrawals": [4      {5        "id": "0xe8323d21c4f104607b10b0fff9fc24b9612b9488795dea8196b2d5f980d3dc1d0a000000",6        "amount": "0",7        "when": "1716394824"8      },9      {10        "id": "0xea1cee35036f2cacb72f2a336be3e54ab911f5bebd58f23400ebb8ecc5cfc45203000000",11        "amount": "0",12        "when": "1716394848"13      },14      {15        "id": "0x2410475f76a44754bae66d293d14eac34f98ec03a3689cbbb56a716d20b209af06000000",16        "amount": "0",17        "when": "1716429732"18      }19    ]20  }21}

                您可以看到,嫁接替换子图是从旧的graph-example数据和新合约地址的新数据中索引的。原始合约发出了两个撤回事件,事件1⁠和事件2⁠。新合约在事件3⁠之后发出一次撤回。两个先前索引的交易(事件1和2)和新交易(事件3)在graft-replacement子图中合并在一起。

                恭喜! 你成功地将一个子图嫁接到另一个子图上。

                其他资源

                如果你想要更多的嫁接经验,这里有一些流行合约的例子:

                • Curve⁠
                • ERC-721⁠
                • Uniswap⁠,

                要成为更专业的Graph专家,请考虑学习处理底层数据源更改的其他方法。像Data Source Templates 这样的替代方案可以实现类似的结果。

                注意:这篇文章中的很多内容都来自之前发表的Arweave文章。

                ⁠在GitHub上编辑⁠

                在 Arweave 上构建子图安全子图代码生成器
                在此页面上
                • 什么是嫁接?
                • 升级到网络时嫁接的重要注意事项
                • 为什么这很重要?
                • 最佳实践
                • 构建现有子图
                • 子图清单定义
                • 嫁接清单定义
                • 部署基子图
                • 部署嫁接子图
                • 其他资源
                The GraphStatusTestnetBrand AssetsForum安全Privacy PolicyTerms of Service