Docs
搜索⌘ K
  • 主页
  • 关于 The Graph
  • 支持的网络
  • 协议合约
  • 子图
    • 子流
      • 代币 API
        • AI Suite
          • 索引
            • 资源
              子图 > 开发 > 创建

              7 分钟

              Writing AssemblyScript Mappings

              概述

              映射将获取的以太坊数据转换为您的模式文件中定义的实体。 映射是用 TypeScript⁠ 的子集编写的,称为 AssemblyScript⁠。 AssemblyScript 可以编译成 WASM (WebAssembly⁠)。 AssemblyScript 比普通的 TypeScript 更严格,但提供了开发者熟悉的语法。

              编写映射

              对于在 mapping.eventHandlers 下的 subgraph.yaml 中定义的每个事件处理程序,都会创建一个同名的导出函数。 每个处理程序必须接受一个名为 event 的参数,其类型对应于正在处理的事件的名称。

              在示例子图中,src/mapping.ts 包含 NewGravatar 和 UpdatedGravatar 事件的处理程序:

              1import { NewGravatar, UpdatedGravatar } from '../generated/Gravity/Gravity'2import { Gravatar } from '../generated/schema'34export function handleNewGravatar(event: NewGravatar): void {5  let gravatar = new Gravatar(event.params.id)6  gravatar.owner = event.params.owner7  gravatar.displayName = event.params.displayName8  gravatar.imageUrl = event.params.imageUrl9  gravatar.save()10}1112export function handleUpdatedGravatar(event: UpdatedGravatar): void {13  let id = event.params.id14  let gravatar = Gravatar.load(id)15  if (gravatar == null) {16    gravatar = new Gravatar(id)17  }18  gravatar.owner = event.params.owner19  gravatar.displayName = event.params.displayName20  gravatar.imageUrl = event.params.imageUrl21  gravatar.save()22}

              第一个处理程序接受 NewGravatar 事件,而且使用 new Gravatar(event.params.id.toHex()) 创建一个新的 Gravatar 实体,使用相应的事件参数填充实体字段。 该实体实例由变量 gravatar 表示,id 值为 event.params.id.toHex()。

              第二个处理程序尝试从 Graph 节点存储加载现有的 Gravatar。 如果尚不存在,则会按需创建。 然后更新实体以匹配新的事件参数,并使用 gravatar.save() 将其保存。

              用于创建新实体的推荐 ID

              强烈建议使用Bytes作为id字段的类型,并且只在确实包含人类可读文本的属性上使用String,例如代币的名称。以下是在创建新实体时需要考虑的一些推荐的id值。

              • transfer.id = event.transaction.hash

              • let id = event.transaction.hash.concatI32(event.logIndex.toI32())

              • 对于存储聚合数据的实体,例如每日交易量,id通常包含天数。在这里,使用Bytes作为id是有益的。确定id的方式可能看起来像这样:

              1let dayID = event.block.timestamp.toI32() / 864002let id = Bytes.fromI32(dayID)
              • 将固定地址转换为Bytes。

              const id = Bytes.fromHexString('0xdead...beef')

              存在一个名为Graph Typescript Library⁠的库,其中包含用于与Graph Node存储交互的工具以及处理智能合约数据和实体的便利功能。它可以从@graphprotocol/graph-ts导入到mapping.ts中。

              处理具有相同ID的entity的策略

              在创建并保存新实体时,如果已存在具有相同ID的实体,则在合并过程中始终优先考虑新实体的属性。这意味着现有的实体将会用新实体的值进行更新。这种方式确保了数据的最新性和一致性,使得每次操作都反映最近的变更和信息。

              如果在具有相同ID的新实体中某个字段故意设置为null值,现有的实体将会被更新为该null值。这种做法允许数据显式地表示无值或已删除的状态,从而在数据处理和存储中提供更大的灵活性和控制。

              如果在具有相同ID的新实体中某个字段没有设置任何值,该字段也将被设为null。这样的处理确保了数据的完整性,防止了意外的旧数据保留,确保了在数据更新时的透明性和一致性。这种做法适用于那些需要明确字段值缺失或未定义情况的应用场景。

              代码生成

              为了使与智能合约、事件和实体的代码编写工作变得简单且类型安全,Graph CLI 可以从子图的 GraphQL 模式和数据源中包含的合约 ABI 生成 AssemblyScript 类型。

              这可以通过以下命令实现:

              1graph codegen [--output-dir <OUTPUT_DIR>] [<MANIFEST>]

              但在大多数情况下,子图已经通过 package.json 进行了预配置,以允许您简单地运行以下命令之一来实现相同的目的:

              1# Yarn2yarn codegen34# NPM5npm run codegen

              这将为 subgrap.yaml 中提到的 ABI 文件中的每个智能合约生成一个 AssemblyScript 类,允许您将这些合约绑定到映射中的特定地址,并针对正在处理的区块调用只读合约方法。它还将为每个合约事件生成一个类,以便于访问事件参数以及事件源自的区块和交易。所有这些类型都写入到<OUTPUT_DIR>/<DATA_SOURCE_NAME>/<ABI_NAME>.ts。在示例子图中,这将成为generated/Gravity/Gravity.ts,允许映射导入这些类型。

              1import {2  // The contract class:3  Gravity,4  // The events classes:5  NewGravatar,6  UpdatedGravatar,7} from '../generated/Gravity/Gravity'

              除此之外,还会为子图的 GraphQL 模式中的每个实体类型生成一个类。 这些类提供类型安全的实体加载、对实体字段的读写访问以及一个 save() 方法来写入要存储的实体。 所有实体类都写入 <OUTPUT_DIR>/schema.ts,允许映射导入它们:

              1import { Gravatar } from '../generated/schema'

              注意: 每次更改 GraphQL 模式文件或清单中包含的 ABI 后,都必须再次执行代码生成。 在构建或部署子图之前,它还必须至少执行一次。

              代码生成不会检查 src/mapping.ts 中的映射代码。 如果您想在尝试将子图部署到 Graph Explorer 之前进行检查,您可以运行 yarn build,并修复 TypeScript 编译器可能发现的任何语法错误。

              ⁠在GitHub上编辑⁠

              GraphQL 模式高级子图功能
              在此页面上
              • 概述
              • 编写映射
              • 用于创建新实体的推荐 ID
              • 处理具有相同ID的entity的策略
              • 代码生成
              The GraphStatusTestnetBrand AssetsForum安全Privacy PolicyTerms of Service