动态数据源

SubQuery Team大约 2 分钟

动态数据源

在某些情况下,当项目启动时,您不知道数据源的所有参数。 这方面的一个例子是合约工厂,它将在以后创建新的合同实例。 无法事先知道合约地址是什么。 这就是能够动态创建新数据源的原因。

templates 字段

要使用动态数据源,您需要至少有 0.2.1 的规范版本。 如果您在 0.2.0 上,您需要做的只是更改规范版本。 如果您处于较低版本,那么您应该先使用subql migrate更新到 0.2.0

规范版本 0.2.1 引入了一个新的 templates 字段。 模板与数据源相同,但有几个不同之处。

  • 他们需要 name 来识别模板
  • startBlock 已不再是必要字段。 这将被设置为数据源创建的区块
  • 在自定义数据源的情况下,processor.options字段也可以部分填充,其余选项将在数据源实例化时提供。

示例项目

展示如何使用动态数据源的最佳方法就是展示一个例子。

下面的例子是一个去中心化交易平台,该平台拥有一个工厂合约,在添加新的交易对时部署一个新的合约。 当项目运行时,不可能知道已经创建或将要创建的所有交易对合约的地址。 数据源可以由映射处理程序从模板动态创建,以便为新创建的交易对建立索引。

project.yaml

specVersion: 0.2.1
name: example-project
version: 1.0.0
description: ''
repository: ''
schema:
  file: ./schema.graphql
network:
  genesisHash: '0x91bc6e169807aaa54802737e1c504b2577d4fafedd5a02c10293b1cd60e39527'
  chaintypes:
    file: "./types.yaml"
dataSources:
  - kind: substrate/Moonbeam
    startBlock: 1358833
    processor:
      file: './node_modules/@subql/contract-processors/dist/moonbeam.js'
      options:
        abi: exchangeFactory
        address: '0x0000000000000000000000000000000000000000'
    assets:
      exchangeFactory:
        file: ./src/exchangeFactory.abi.json
    mapping:
      file: ./dist/index.js
      handlers:
        - handler: handleNewTradingPair
          kind: substrate/MoonbeamEvent
          filter:
            topics:
              - newTradingPair(address exchange, address token1, address token2)

templates:
  - name: TradingPair
    kind: substrate/Moonbeam
    processor:
      file: './node_modules/@subql/contract-processors/dist/moonbeam.js'
      options:
        abi: tradingPair
        # we do not know the address at this point, it will be provided when instantiated
    assets:
      tradingPair:
        file: ./src/tradingPair.abi.json
    mapping:
      file: ./dist/index.js
      handlers:
        - handler: handleLiquidityAdded
          kind: substrate/MoonbeamEvent
          filter:
            topics:
              - liquidityAdded(address provider, uint256 amount1, uint256 amount2)
 
Text
Xpath: /pre/code

mappingHandlers.ts

// This function is defined using `subql codegen` cli command
import { createTradingPairDatasource } from '../types';
import {MoonbeamEvent} from '@subql/contract-processors/dist/moonbeam';

async function handleNewTradingPair(event: MoonbeamEvent): Promise<void> {
  const { exchange, token1, token2 } = event.args;

  // Create a new datasource providing the address of the trading pair exchange contract
  await createTradingPairDatasource({ address: exchange });
}

async function handleLiquidityAdded(event: MoonbeamEvent): Promise<void> {
  /* mapping fuction implementation here */
}

查看一个项目动态数据源

动态数据源存储在项目元数据中。 如果您需要看到您可以像以下示例一样查询详细信息:

{
  _metadata {
    dynamicDatasources
  }
}

结果

{
  "data": {
    "_metadata": {
      "dynamicDatasources": "[{\"templateName\":\"TradingPair\",\"args\":{\"address\":\"0x0000000000000000000000000000000000000000\"},\"startBlock\":1358833}]"
    }
  }
}