Переклад українською виконав cryptoaxel#2921
Підграф визначає, які дані The Graph буде індексувати з Ethereum і як він буде їх зберігати.
Матеріал для перекладу взято з статті - https://thegraph.com/docs/define-a-subgraph.
Три ключові компоненти підграфа для кращого розуміння на високому рівні:
- Маніфест
- Схема GraphQL
- mappings
Підкатегорія маніфесту
Маніфест підграфа subgraph.yaml
визначає смарт-контракти, на які індексуються ваші підграфи, на які події з цих контрактів слід звертати увагу і як зіставляти дані подій з сутностями, які вузол The Graph зберігає і дозволяє запитувати. Повну специфікацію для маніфестів подграфов можна знайти тут .
Для прикладу підграф, subgraph.yaml
є:
specVersion: 0.0.1
опис: Gravatar для
сховища Ethereum : https://github.com/graphprotocol/example-subgraph
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum /
назва контракту : Gravity
network: mainnet
source:
адреса: '0x2E645469f354BB4F5c8a05B3b30A929361cf77eC'
abi: Гравітація
startBlock: 6175244
відображення:
вид: ethereum / події
apiVersion: 0.0.1
мова: wasm / Assemblyscript
сутності:
- Gravatar
abis:
- ім'я
/ GravbisonG файл:
GravisonG.
- подія: NewGravatar (uint256, адреса, рядок, рядок)
обробник: handleNewGravatar
- подія: UpdatedGravatar (uint256, адреса, рядок, рядок)
обробник: handleUpdatedGravatar
callHandlers:
- function: createGravatar (string, string)
handler: handleCreateGravatar
blockHandlers:
- function : handleBlock
- функція: handleBlockWithCall
фільтр:
kind:
файл виклику : ./src/mapping.ts
Важливими записами маніфесту є:
description
: читаємо опис того, що це за підграф. Опис відображається в Graph Explorer, коли підграф розгортається в розміщеній службі .repository
: URL-адресу сховища, в якому можна знайти маніфест підграфа. Це також відображається в Graph Explorer.dataSources.source
:address
Смарт-контракту, джерела підграфа іabi
смарт-контракту для використання.address
не є обов'язковим; його відсутність дозволяє індексувати збігаються події з усіх контрактів.dataSources.source.startBlock
: Необов'язковий номер блоку, з якого джерело даних починає індексацію. У більшості випадків ми пропонуємо використовувати блок, в якому був створений контракт.dataSources.mapping.entities
: Сутність, які джерело даних записує в сховище. Схема для кожної сутності визначається у файліschema.graphql
.dataSources.mapping.abis
: Один або кілька іменованих файлів ABI для вихідного контракту, а також будь-яких інших смарт-контрактів, з якими ви взаємодієте з зіставлень.dataSources.mapping.eventHandlers
: Перераховує події смарт-контрактів, на які реагує цей підграф, і обробники в файлі mapping-./src/mapping.ts
в прикладі, які перетворять ці події в entities in the store.dataSources.mapping.callHandlers
: Перераховує функції смарт-контракту, на які реагує цей підграф, і обробники в зіставленні, які перетворять вхідні і вихідні дані в виклики функцій в entities in the store.dataSources.mapping.blockHandlers
: Перераховує блоки, на які цей підграф реагує, і обробники в зіставленні, які запускаються при додаванні блоку в ланцюжок. Без фільтра обробник блоку буде запускатися кожен блок. Необов'язковий фільтр може бути наступних видів:call
. Фільтрcall
запустить обробник, якщо блок містить хоча б один виклик контракту джерела даних.
Один підграф может т індексувати дані з декількох смарт-контрактів. Додайте запис для кожного контракту, з якого необхідно індексувати дані, в масив dataSources
.
Тригери для джерела даних в блоці упорядковуються з використанням наступного процесу:
- Тригери подій і викликів спочатку впорядковуються за індексом транзакції в блоці.
- Тригери подій і викликів, що містяться в одній транзакції, упорядковуються за угодою: спочатку тригери подій, потім тригери виклику, причому кожен тип відповідає порядку, який вони визначені в маніфесті.
- Блокові тригери запускаються після подій та тригерів виклику в тому порядку, в якому вони визначені в маніфесті.
Ці правила можуть бути змінені.
отримання ABIs
Файл (и) ABI повинен відповідати вашому контрактом (ам). Є кілька способів отримати файли ABI:
- Якщо ви створюєте свій власний проект, у вас, ймовірно, буде доступ до ваших найостаннішим ABI.
- Якщо ви створюєте підграф для загальнодоступного проекту, ви можете завантажити цей проект на свій комп’ютер і отримати ABI за допомогою
truffle compile
або використанняsolc
для компіляції. - Ви також можете знайти ABI на Etherscan , але це не завжди надійно, оскільки завантажений туди ABI може бути застарілим. Переконайтеся, що у вас правильний ABI, інакше виконання вашого подграфа не вдасться.
Схема GraphQL
Схема для вашого подграфа знаходиться в файлі schema.graphql
. Схеми GraphQL визначаються з використанням мови визначення інтерфейсу GraphQL. Якщо ви ніколи не писали схему GraphQL, рекомендується ознайомитися з цим підручником по системі типів GraphQL. Довідкову документацію по схемам GraphQL можна знайти в розділі GraphQL API .
визначення сутностей
Перед визначенням сутностей важливо зробити крок назад і подумати про те, як ваші дані структуровані і пов’язані. Всі запити будуть виконуватися проти моделі даних, визначеної в схемі подграфа, і сутностей, проіндексованих подграфом. Через це добре визначити схему подграфа таким чином, щоб вона відповідала потребам вашого dApp. Може бути корисно уявити суті як «об’єкти, що містять дані», а не як події або функції.
За допомогою The Graph ви просто визначаєте типи сутностей в schema.graphql, а Graph Node буде генерувати поля верхнього рівня для запиту окремих екземплярів і колекцій цього типу сутності.
Приклад
Сутність Gravatar
нижче структурована навколо об'єкта Gravatar і є хорошим прикладом того, як можна визначити сутність.
введіть Gravatar @entity {
id: ID!
власник: Байти
displayName: Рядок
imageUrl: Рядок
прийнято: Boolean
}
поганий приклад
введіть GravatarAccepted @entity {
id: ID!
власник: Байти
displayName: Рядок
imageUrl: String
} тип GravatarDeclined @entity {
id: ID!
власник: байти
displayName: рядок
imageUrl: рядок
}
Написання Mappings
Mappings перетворять дані Ethereum, які ваші mappings отримують, по суті, певні у вашій схемі. Mappings записуються в підмножині TypeScript , званому AssemblyScrip t, який може бути скомпільовано в WASM ( WebAssembly ). AssemblyScript суворіше звичайного TypeScript, але забезпечує знайомий синтаксис.
Для кожного обробника подій, певного в subgraph.yaml
в розділі mapping.eventHandlers
, створіть експортовану функцію з тим же ім'ям. Кожен обробник повинен приймати один параметр з ім'ям event
з типом, відповідним імені оброблюваного події.
У прикладі подграфа src/mapping.ts
містить обробники подій NewGravatar
і UpdatedGravatar
:
import {NewGravatar, UpdatedGravatar} from '../generated/Gravity/Gravity'
import {Gravatar} from '../generated/schema' export function handleNewGravatar (event: NewGravatar): void {
let gravatar = new Gravatar (event.params .id.toHex ())
gravatar.owner = event.params.owner
gravatar.displayName = event.params.displayName
gravatar.imageUrl = event.params.imageUrl
gravatar.save ()
} функція експорту handleUpdatedGravatar (event: UpdatedGravatar): void {
let id = event.params.id.toHex ()
let gravatar = Gravatar.load (id)
if (gravatar == null) {
gravatar = new Gravatar (id)
}
gravatar.owner = event.params.owner
gravatar.displayName = event.params.displayName
gravatar.imageUrl = event.params.imageUrl
gravatar.save ()
}
Перший обробник приймає подія NewGravatar
і створює нову сутність Gravatar-new Gravatar(event.params.id.toHex())
, заповнюючи поля суті з використанням відповідних параметрів події. Цей екземпляр сутності представлений змінною gravatar
зі значенням id
event.params.id.toHex()
.
Другий обробник намагається завантажити існуючий Gravatar
зі сховища Graph Node. Якщо його ще немає, він створюється за запитом. Потім об'єкт оновлюється відповідно до нових параметрів події, перш ніж він буде збережений назад в сховище за допомогою gravatar.save()
.
Рекомендовані ідентифікатори для створення нових об’єктів
У кожної сутності повинен бути id
, унікальний серед усіх сутностей одного типу. Значення id
об'єкта встановлюється при створенні об'єкта. Нижче наведені деякі рекомендовані значення id
, які слід враховувати при створенні нових сутностей. ПРИМІТКА. Значення id
має бути string
.
event.params.id.toHex()
event.transaction.from.toHex()
event.transaction.hash.toHex() + "-" + event.logIndex.toString()
Ми надаємо бібліотеку Graph Typescript Library , яка містить утиліти для взаємодії зі сховищем Graph Node і зручності для роботи з даними і об’єктами смарт-контрактів. Ви можете використовувати цю бібліотеку в своїх порівняннях, імпортувавши @graphprotocol/graph-ts
в mapping.ts
.
Про проект The Graph
Це протокол індексації для організації та ефективного доступу до даних блокчейнов і мереж зберігання. З січня 2019 року The Graph використовує розміщений сервіс з більш ніж 2300 підграфів, розгорнутими для додатків Web3 і DeFi, побудованих на Ethereum і IPFS, таких як Synthetix, Uniswap, Aave, Balancer, Gnosis, Aragon та інших.