Dynamic Data Source
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)
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 */
}
การดู Dynamic Data Source ของโปรเจกต์
Dynamic Data Source จะถูกเก็บไว้ใน Metadata ของโปรเจกต์ หากต้องการดูรายละเอียดคุณสามารถ Query ได้ตามด้านล่าง:
{
_metadata {
dynamicDatasources
}
}
ผลลัพธ์
{
"data": {
"_metadata": {
"dynamicDatasources": "[{\"templateName\":\"TradingPair\",\"args\":{\"address\":\"0x0000000000000000000000000000000000000000\"},\"startBlock\":1358833}]"
}
}
}