Dynamic Data Source

... 2022-8-5 Less than 1 minute

# Dynamic Data Source

มีหลายกรณีที่คุณไม่ทราบพารามิเตอร์ทั้งหมดของ Data Source เมื่อเริ่มต้นโปรเจกต์ ยกตัวอย่างกรณีนี้ คือ Contact Factory ที่จะมีการสร้าง Contract Instance ใหม่ในภายหลัง เป็นไปไม่ได้เลยที่จะรู้ล่วงหน้าว่าเป็น Contract Address ใด นี่จึงเป็นจุดที่ Dynamic Data Source เข้ามาแก้ปัญหา

# ฟิลด์ templates

ในการใช้ Dynamic Data Source นั้นคุณจะต้องใช้เวอร์ชันขั้นต่ำคือ 0.2.1 หากคุณใช้ 0.2.0 สิ่งที่คุณต้องทำคือเปลี่ยน specVersion หากคุณใช้เวอร์ชันที่ต่ำกว่า คุณควรอัปเดตเป็น 0.2.1 ก่อนด้วยคำสั่ง subql migrate

เวอร์ชัน 0.2.1 นั้นมี templates ใหม่ เทมเพลตจะคล้ายกับ Data Source แต่จะมีความแตกต่างกันเล็กน้อย

  • ระบบต้องการ name เพื่อระบุเทมเพลต
  • startBlock ไม่จำเป็นอีกต่อไป มันจะถูกตั้งไว้เป็นบล็อกที่ Data Source ถูกสร้าง
  • ในกรณีของแหล่งข้อมูลแบบกำหนดเอง processor.options สามารถกรอกข้อมูลได้เพียงบางส่วน สำหรับตัวเลือกที่เหลือจะได้รับเมื่อมีการสร้าง Data Source

# โปรเจกต์ตัวอย่าง

วิธีที่ดีที่สุดที่จะแสดงการใช้งาน Dynamic Data Source คือการยกตัวอย่าง

ตัวอย่างด้านล่าง เป็นการแลกเปลี่ยนแบบไร้ศูนย์กลางที่มี Factory Contract ที่จำใช้งาน Contract ใหม่เมื่อมีการคู่เทรดถูกเพิ่มเข้ามา เมื่อทำการรันโปรเจกต์แล้ว จะไม่สามารถทราบแอดเดรสของคู่เทรดทั้งหมดที่สร้างขึ้นหรือถูกสร้างขึ้นมาได้ Data Source สามารถสร้างได้โดยการใช้ Mapping Handler จากเทมเพลตเพื่อ Index Contract ของคู่เทรดใหม่ที่ถูกสร้างขึ้น

# 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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# mappingHandlers.ts

// ฟังก์ชันนี้ถูกสร้างขึ้นโดยใช้ `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;

  // สร้าง datasource ใหม่โดยใช้แอดเดรสของ Contract ของคู่เทรด
  await createTradingPairDatasource({ address: exchange });
}

async function handleLiquidityAdded(event: MoonbeamEvent): Promise<void> {
  /* mapping fuction implementation here */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# การดู Dynamic Data Source ของโปรเจกต์

Dynamic Data Source จะถูกเก็บไว้ใน Metadata ของโปรเจกต์ หากต้องการดูรายละเอียดคุณสามารถ Query ได้ตามด้านล่าง:

{
  _metadata {
    dynamicDatasources
  }
}
1
2
3
4
5

ผลลัพธ์

{
  "data": {
    "_metadata": {
      "dynamicDatasources": "[{\"templateName\":\"TradingPair\",\"args\":{\"address\":\"0x0000000000000000000000000000000000000000\"},\"startBlock\":1358833}]"
    }
  }
}
1
2
3
4
5
6
7
Last update: August 5, 2022 10:08