SubQuery | Module 1, 2, 4
🔹 У SubQuery есть Academy для Developer.
В этой академии будет 6 модулей:
Module 1 - есть в этом гайде
Module 2 - есть в этом гайде
Module 3 - пропустили задание
Module 4 - Актуально для выполнения. Сдача задания до 24 января (01:00 Киев).
Module 5 - скоро будет
Module 6 - скоро будет
• Чтобы стать SubQuery Spartan нужно выполнить только 1 и 2 модули.
Читайте полную инструкцию как стать Spartan проекта:
teletype.in/@elrmcfteam/SubQuerySpartan
Чтобы выполнить этот модуль нам нужно:
• Акааунт на github.com
• Арендовать сервер, можете прочитать наш гайд как арендовать сервера.
По мощности подойдет любой
я выбрал 1 CPU, 1 GB RAM, 20 GB SSD, Ubuntu-20.04.
Запуск
• У вашего сервера есть IP-адрес сервера - Пользователь - Пароль эти данные мы будем использовать.
- Для Windows скачиваем приложение https://www.putty.org/
- на MacOS/ Linux открываем встроенный "Терминал"
В putty вписываем ваш IP-адрес,в "Терминал" нужно ввести команду ssh root@ваш IP-адрес
root
В открытом терминале MacOS (то что на скрине выше)
ssh root@ваш IP-адрес
Дальше просит вписать пароль, копируем его, но командой Control+V его не вставить, вставка пароля осуществляться правой кнопкой мыши и Enter. Сам пароль при этом не будет отображен, это сделано в целях безопасности.
⚠️ Если после ввода пароля произошел сбой значит нужно: вписать пароль вручную.
Module 1
sudo apt update
• Устанавливаем нужные элементы:
apt install npm
npm install -g yarn
npm install -g @subql/cli
apt install docker-compose
• Обновим ноду до последней версии:
npm install -g n
n latest
• Создаем и входим в директорию:
mkdir SubQl
cd SubQl
subql init --starter subqlHelloWorld
Попунктно будет появлятся каждая строчка, нам нужно заполнить только Authors:
Git repository: Enter
RPC endpoint: Enter
Authors: ваш ник
Description: Enter
Version: [1.0.0]: Enter
License: [Apache-2.0]: Enter
cd subqlHelloWorld
• Устанавливаем зависимости и собираем код:
npm install
npm run-script codegen
npm run-script build
docker-compose pull && docker-compose up
Через несколько минут должный пойти логи, они могут быть с ошибками, это нормально, в целом будет подобная картина:
• Дальше в строке браузера пишем:
• У нас откроется приложение где мы сможем протестировать то что запустили.
{ query{ starterEntities(last:10, orderBy:FIELD1_ASC ){ nodes{ field1 } } } }
Жмем на кнопку по центру и в правой колонке будет отображаться нумерация блока, с каждым нажатием, будет все больше пройденных блоков.
• Если всё окей, в терминале нужно остановить докер чтобы работать дальше нажимаем Control + C и вписываем команду:
docker-compose stop
• Теперь нам нужно сдать задание, для этого нужно загрузить наш проект на https://github.com/ если вы не зарегестрировались в начале гайда делаем это сейчас, не забудьте подтвердить почту.
• Теперь нужно вписать несколько команд
(вписываем переменные не удаляя 👉" 👈):
sudo apt install git
git config --global user.name "ник_гитхаб"
git config --global user.email "ваш_email"
eval ssh-agent -s
ssh-keygen -t rsa -b 4096 -C "ваш_email" -f ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub
Высветился длинный ключ, мы его копируем целиком и переходим в github.com
Вписываем название, я вписал название проекта:
Дальше нужно перейти с настройки:
И добавить ключ который мы скопировали с терминала в поле SSH key:
Вставляем ключ и жмём Add SSH key:
Так же нам нужно создать свой Personal access tokens:
Settings -> Developer Settings -> Personal Access Token -> Generate new token
Даем название своему токену (паролю), выбираем период который он будет действовать, выбираем галочки как на скрине и создаем его.
• Этот access tokens нам скоро понадобится:
(сохраняем его и не теряем, он показывается один раз)
• Возвращаемся в терминал и вписываем несколько команд:
git init
git remote add origin https://github.com/ник_гитхаб/название_репозитория.git
такая строка у вас есть на этом экране
git add .
git commit -m 'create project'
git push origin master
В поле Username for 'https://github.com':
вписываем ник гитхаб.
В поле Password for 'https://ник_гитхаб@github.com':
вписываем access tokens который мы создавали
Если видите эту строку, значит вы всё правильно подключили
* [new branch] master -> master.
• Переходим на сайт https://project.subquery.network/ и логинимся через github.
Создаем новый проект- Create Project.
• Заполняем Project Name и вставляем ссылку на свой репозиторий + Create Project:
• Будут такие два поля, жмем Deploy и внутри еще одна кнопка Deploy update%
Поздравляю, вы выполнили задание.
Module 2
Продолжим ставить всё на том же сервере.
Подключаемся к серверу.
Входим в существующую директорию:
cd SubQl
Дальше очень интересно, можете ознакомиться с официальным гайдом, но спасибо команде nodes.guru они для нас все упростили:
git clone https://github.com/subquery/tutorials-account-balances.git
cd tutorials-account-balances
• Устанавливаем зависимости и собираем код:
npm install
npm run-script codegen
npm run-script build
docker-compose pull && docker-compose up
Стоит подождать несколько минут пока не пойдут подобные логи, могут проскакивать ошибки, это нормально.
• Дальше в строке браузера пишем:
• У нас откроется приложение где мы сможем протестировать то что запустили.
query { accounts(first:15, orderBy:BALANCE_ASC){ nodes{ account balance } } }
Жмем на кнопку по центру и в правой колонке будет так:
• Возвращаемся в терминал, жмем Соntrol+C чтобы остановить все процессы и можно было дальше вводить команды.
Осталось загрузить наш проект на https://github.com/ делаем этого точно так же как выгружали модуль 1
• Нужно вписать несколько команд
(вписываем переменные не удаляя 👉" 👈):
sudo apt install git
git config --global user.name "ник_гитхаб"
git config --global user.email "ваш_email"
eval ssh-agent -s
ssh-keygen -t rsa -b 4096 -C "ваш_email" -f ~/.ssh/id_rsa
• Три раза вписываем чтобы получить длинный ключ:
cat ~/.ssh/id_rsa.pub
• Переходим в github.com, создаем новый репозиторий, все абсолютно так же как с модулем один
(только название самого репозитория меняем).
• Добавляем SSH key
(ключ который мы скопировали с терминала).
• Создать новый access tokens не нужно, используем тот который создали при прохождении первого модуля.
• Возвращаемся в терминал и вписываем несколько команд:
git init
git remote set-url origin https://github.com/ник_гитхаб/название_репозитория
такая строка у вас есть на этом экране, только не добавляем git.
git add .
git commit -m 'create project'
git push origin master
В поле Username for 'https://github.com':
вписываем ник гитхаб.
В поле Password for 'https://ник_гитхаб@github.com':
вписываем access tokens
Если видите эту строку, значит вы всё правильно подключили
* [new branch] master -> master.
• Переходим на сайт https://project.subquery.network/ и логинимся через github.
Создаем новый проект- Create Project.
• Заполняем Project Name и вставляем ссылку на свой репозиторий + Create Project:
• Будут такие два поля, жмем Deploy и внутри еще одна кнопка Deploy update%
Module 4
В этом задании нам нужно будет работать с файловой системой, скачайте программы:
Для Windows - mobaxterm
для MacOS - cyberduck (подключение к серверу через SSH)
Если вы делаете модули в-первые
sudo apt update
• Устанавливаем нужные элементы:
apt install npm
npm install -g yarn
npm install -g @subql/cli
apt install docker-compose
• Обновим ноду до последней версии:
npm install -g n
n latest
Если вы делали предыдущие модули подключайтесь к серверу
• Обновим ноду до последней версии (навсякий случай):
npm install -g n
n latest
Задание 1
subql init
staking-rewards
(Project name [subql-starter]: staking-rewards)
• Заходим в программу которую скачивали и подключаемся к серверу, я буду использовать с cyberduck так как работаю с MacOS.
• В документе schema.graphql меняем содержимое на:
type StakingReward @entity{ id: ID! #blockHeight-eventIdx account: String! balance: BigInt! date: Date! blockHeight: Int! }
• В документе project.yaml заменим некоторые значения, меняем содержимое на:
specVersion: 0.2.0 name: sashabnk version: 1.0.0 description: '' repository: '' schema: file: ./schema.graphql network: genesisHash: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3' endpoint: wss://polkadot.api.onfinality.io/public-ws dataSources: - kind: substrate/Runtime startBlock: 7000000 mapping: file: ./dist/index.js handlers: - handler: handleStakingRewarded kind: substrate/EventHandler filter: module: staking method: Rewarded
• По пути src- mappings- mappingHandlers.ts меняем содержимое на:
import {SubstrateEvent} from "@subql/types"; import {StakingReward} from "../types"; import {Balance} from "@polkadot/types/interfaces"; export async function handleStakingRewarded(event: SubstrateEvent): Promise<void> { const {event: {data: [account, newReward]}} = event; const entity = new StakingReward(`${event.block.block.header.number}-${event.idx.toString()}`); entity.account = account.toString(); entity.balance = (newReward as Balance).toBigInt(); entity.date = event.block.timestamp; entity.blockHeight = event.block.block.header.number.toNumber(); await entity.save(); }
• Так же из-за докера могут быть ошибки, чтобы их избежать заменим в документе docker-compose.yml содержимое на:
version: '3' services: postgres: image: postgres:12-alpine ports: - 5432:5432 volumes: - .data/postgres:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: postgres subquery-node: image: onfinality/subql-node:v0.25.3 depends_on: - "postgres" restart: always environment: DB_USER: postgres DB_PASS: postgres DB_DATABASE: postgres DB_HOST: postgres DB_PORT: 5432 volumes: - ./:/app command: - -f=/app - --local graphql-engine: image: onfinality/subql-query:v0.8.0 ports: - 3000:3000 depends_on: - "postgres" - "subquery-node" restart: always environment: DB_USER: postgres DB_PASS: postgres DB_DATABASE: postgres DB_HOST: postgres DB_PORT: 5432 command: - --name=app - --playground - --indexer=http://subquery-node:3000
cd staking-rewards
yarn install
yarn codegen
yarn build
docker-compose pull && docker-compose up
• Дальше в строке браузера пишем:
• У нас откроется приложение где мы сможем протестировать то что запустили.
query{ stakingRewards(first: 3 orderBy:BLOCK_HEIGHT_ASC){ nodes{ blockHeight account date balance } } }
• Если всё окей, в терминале нужно остановить докер чтобы работать дальше
нажимаем Control + C и вписываем команду:
docker-compose stop
Задание 2
• В документе schema.graphql меняем содержимое на:
type StakingReward @entity{ id: ID! #blockHeight-eventIdx account: String! balance: BigInt! date: Date! blockHeight: Int! } type SumReward @entity{ id: ID! # AccountId totalReward: BigInt! blockheight: Int! }
• В документе project.yaml меняем содержимое на:
specVersion: 0.2.0 name: sashabnk version: 1.0.0 description: '' repository: '' schema: file: ./schema.graphql network: genesisHash: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3' endpoint: wss://polkadot.api.onfinality.io/public-ws dataSources: - kind: substrate/Runtime startBlock: 7000000 mapping: file: ./dist/index.js handlers: - handler: handleSumRewarded kind: substrate/EventHandler filter: module: staking method: Rewarded - handler: handleStakingRewarded kind: substrate/EventHandler filter: module: staking method: Rewarded
• По пути src- mappings- mappingHandlers.ts меняем содержимое на:
import {SubstrateEvent} from "@subql/types"; import {StakingReward, SumReward} from "../types"; import {Balance} from "@polkadot/types/interfaces"; export async function handleStakingRewarded(event: SubstrateEvent): Promise<void> { const {event: {data: [account, newReward]}} = event; const entity = new StakingReward(`${event.block.block.header.number}-${event.idx.toString() }`); entity.account = account.toString(); entity.balance = (newReward as Balance).toBigInt(); entity.date = event.block.timestamp; entity.blockHeight = event.block.block.header.number.toNumber(); await entity.save(); } function createSumReward(accountId: string): SumReward { const entity = new SumReward(accountId); entity.totalReward = BigInt(0); return entity; } export async function handleSumRewarded(event: SubstrateEvent): Promise<void> { const {event: {data: [account, newReward]}} = event; let entity = await SumReward.get(account.toString()); if (entity === undefined){ entity = createSumReward(account.toString()); } entity.totalReward = entity.totalReward + (newReward as Balance).toBigInt(); entity.blockheight = event.block.block.header.number.toNumber(); await entity.save(); }
yarn codegen
yarn build
docker-compose pull && docker-compose up
• Дальше в строке браузера пишем:
• У нас откроется приложение где мы сможем протестировать то что запустили.
query{ sumRewards(first:3 orderBy:BLOCKHEIGHT_ASC){ nodes{ blockheight id totalReward } } }
• Если всё окей, в терминале нужно остановить докер чтобы работать дальше
нажимаем Control + C и вписываем команду:
docker-compose stop
Задание 3
• В документе schema.graphql меняем содержимое на:
type StakingReward @entity{ id: ID! #blockHeight-eventIdx account: SumReward! balance: BigInt! date: Date! blockheight: Int } type SumReward @entity{ id: ID! # AccountId totalReward: BigInt! blockheight: Int! }
• В документе project.yaml меняем содержимое на:
specVersion: 0.2.0 name: sashabnk version: 1.0.0 description: '' repository: '' schema: file: ./schema.graphql network: genesisHash: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3' endpoint: wss://polkadot.api.onfinality.io/public-ws dataSources: - kind: substrate/Runtime startBlock: 7000000 mapping: file: ./dist/index.js handlers: - handler: handleSumRewarded kind: substrate/EventHandler filter: module: staking method: Rewarded - handler: handleStakingRewarded kind: substrate/EventHandler filter: module: staking method: Rewarded
• По пути src- mappings- mappingHandlers.ts меняем содержимое на:
import {SubstrateEvent} from "@subql/types"; import {StakingReward, SumReward} from "../types"; import {Balance} from "@polkadot/types/interfaces"; export async function handleStakingRewarded(event: SubstrateEvent): Promise<void> { const {event: {data: [account, newReward]}} = event; const entity = new StakingReward(`${event.block.block.header.number}-${event.idx.toString() }`); entity.accountId = account.toString(); entity.balance = (newReward as Balance).toBigInt(); entity.date = event.block.timestamp; await entity.save(); } function createSumReward(accountId: string): SumReward { const entity = new SumReward(accountId); entity.totalReward = BigInt(0); return entity; } export async function handleSumRewarded(event: SubstrateEvent): Promise<void> { const {event: {data: [account, newReward]}} = event; let entity = await SumReward.get(account.toString()); if (entity === undefined){ entity = createSumReward(account.toString()); } entity.totalReward = entity.totalReward + (newReward as Balance).toBigInt(); entity.blockheight = event.block.block.header.number.toNumber(); await entity.save(); }
yarn codegen
yarn build
docker-compose pull && docker-compose up
• Дальше в строке браузера пишем:
• У нас откроется приложение где мы сможем протестировать то что запустили.
query{ sumRewards(filter: {id:{equalTo:"16jWQMBXZNxfgXJmVL61gMX4uqtc9WTXV3c8DGx6DUKejm7"}}){ nodes{ blockheight id totalReward stakingRewardsByAccountId{ nodes{ balance } } } } }
Кому интересно:
в результатах должно быть две строки "balance", как в оригинальном документе
Чтобы увидеть обе строки подождите 15 минут с запущенным докером. Так что одна строка с балансом это не проблема.
• Если всё окей, в терминале нужно остановить докер чтобы работать дальше
нажимаем Control + C и вписываем команду:
docker-compose stop
Задание 4
• В документе schema.graphql меняем содержимое на:
type StakingReward @entity{ id: ID! #blockHeight-eventIdx account: SumReward! balance: BigInt! date: Date! blockheight: Int } type SumReward @entity{ id: ID! # AccountId totalReward: BigInt! blockheight: Int }
• В документе project.yaml меняем содержимое на:
specVersion: 0.2.0 name: sashabnk version: 1.0.0 description: '' repository: '' schema: file: ./schema.graphql network: genesisHash: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3' endpoint: wss://polkadot.api.onfinality.io/public-ws dataSources: - kind: substrate/Runtime startBlock: 6000000 mapping: file: ./dist/index.js handlers: - handler: handleSumReward kind: substrate/EventHandler filter: module: staking method: Reward - handler: handleStakingReward kind: substrate/EventHandler filter: module: staking method: Reward
• По пути src- mappings- mappingHandlers.ts меняем содержимое на:
import {SubstrateEvent} from "@subql/types"; import {StakingReward, SumReward} from "../types"; import {Balance} from "@polkadot/types/interfaces"; export async function handleStakingReward(event: SubstrateEvent): Promise<void> { const {event: {data: [account, newReward]}} = event; const entity = new StakingReward(`${event.block.block.header.number}-${event.idx.toString() }`); entity.accountId = account.toString(); entity.balance = (newReward as Balance).toBigInt(); entity.date = event.block.timestamp; await entity.save(); } function createSumReward(accountId: string): SumReward { const entity = new SumReward(accountId); entity.totalReward = BigInt(0); return entity; } export async function handleSumReward(event: SubstrateEvent): Promise<void> { const {event: {data: [account, newReward]}} = event; let entity = await SumReward.get(account.toString()); if (entity === undefined){ entity = createSumReward(account.toString()); } entity.totalReward = entity.totalReward + (newReward as Balance).toBigInt(); entity.blockheight = event.block.block.header.number.toNumber(); await entity.save(); }
yarn codegen
yarn build
docker-compose pull && docker-compose up
• Дальше в строке браузера пишем:
• У нас откроется приложение где мы сможем протестировать то что запустили.
query{ sumRewards(first:3 orderBy:BLOCKHEIGHT_ASC){ nodes{ blockheight id totalReward } } }
• Если всё окей, в терминале нужно остановить докер чтобы работать дальше
нажимаем Control + C и вписываем команду:
docker-compose stop
• Теперь нам нужно сдать задание, для этого нужно загрузить наш проект на https://github.com/ если вы не зарегестрировались в начале гайда делаем это сейчас, не забудьте подтвердить почту.
Как это сделать смотрите с картинками в первом модуле.
В форму для сдачи задания нужно отправлять ссылки на репозиторий в гитхаб.
Полная инструкция по SubQuery Spartan :
teletype.in/@elrmcfteam/SubQuerySpartan
Ссылки проекта:
Discord: https://discord.gg/subquery
Сайт проекта: https://subquery.network/
Канал TG: https://t.me/subquerynetwork
Получить поддержку лучше в: #🇺🇦ukraine или #🇷🇺russian чат Discord.
Наши ссылки:
Чат ELRMCF: https://t.me/joinchat/cXa3BtZytS8wNWU8
| Автор: sasha.bnk Inst