Вивчення базових тем Етеріуму за допомогою SQL
Багато посібників з Етеріуму орієнтовані на розробників, але бракує освітніх ресурсів для аналітиків даних або людей, які хочуть переглядати ончейн-дані без запуску клієнта чи вузла.
Цей посібник допомагає читачам зрозуміти фундаментальні концепції Етеріуму, зокрема транзакції, блоки та газ, шляхом запитів до ончейн-даних за допомогою мови структурованих запитів (SQL) через інтерфейс, який надає Dune Analytics (opens in a new tab).
Ончейн-дані можуть допомогти нам зрозуміти Етеріум, мережу та економіку обчислювальних потужностей, а також мають слугувати основою для розуміння викликів, з якими сьогодні стикається Етеріум (наприклад, зростання цін на газ), і, що важливіше, дискусій навколо рішень для масштабування.
Транзакції
Шлях користувача в Етеріумі починається з ініціалізації контрольованого користувачем акаунта або сутності з балансом ETH. Існує два типи акаунтів: контрольовані користувачем та смарт-контракти (див. ethereum.org).
Будь-який акаунт можна переглянути в оглядачі блоків, наприклад Etherscan (opens in a new tab) або Blockscout (opens in a new tab). Оглядачі блоків — це портал до даних Етеріуму. Вони в режимі реального часу відображають дані про блоки, транзакції, майнерів, акаунти та іншу ончейн-активність (див. тут).
Однак користувач може захотіти зробити запит до даних безпосередньо, щоб звірити інформацію, надану зовнішніми оглядачами блоків. Dune Analytics (opens in a new tab) надає таку можливість будь-кому, хто має певні знання SQL.
Для довідки, акаунт смарт-контракту Фундації Ethereum (EF) можна переглянути на Blockscout (opens in a new tab).
Варто зазначити, що всі акаунти, включно з акаунтом Фундації Ethereum, мають публічну адресу, яку можна використовувати для надсилання та отримання транзакцій.
Баланс акаунта на Etherscan складається зі звичайних та внутрішніх транзакцій. Внутрішні транзакції, незважаючи на назву, не є фактичними транзакціями, які змінюють стан ланцюга. Це перекази цінності, ініційовані виконанням контракту (джерело (opens in a new tab)). Оскільки внутрішні транзакції не мають підпису, вони не включаються до блокчейну, і до них не можна зробити запит за допомогою Dune Analytics.
Тому цей посібник буде зосереджений на звичайних транзакціях. Запит до них можна зробити так:
WITH temp_table AS (
SELECT
hash,
block_number,
block_time,
"from",
"to",
value / 1e18 AS ether,
gas_used,
gas_price / 1e9 AS gas_price_gwei
FROM ethereum."transactions"
WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
ORDER BY block_time DESC
)
SELECT
hash,
block_number,
block_time,
"from",
"to",
ether,
(gas_used * gas_price_gwei) / 1e9 AS txn_fee
FROM temp_table
Це дасть ту саму інформацію, що й на сторінці транзакцій Etherscan. Для порівняння, ось два джерела:
Etherscan
Сторінка контракту Фундації Ethereum на Blockscout. (opens in a new tab)
Dune Analytics
Ви можете знайти інформаційну панель тут (opens in a new tab). Натисніть на таблицю, щоб побачити запит (також див. вище).
Розбір транзакцій
Надіслана транзакція містить кілька елементів інформації, зокрема (джерело):
- Одержувач (Recipient): Адреса отримання (у запиті як «to»)
- Підпис (Signature): Хоча приватні ключі відправника підписують транзакцію, за допомогою SQL ми можемо зробити запит до публічної адреси відправника («from»).
- Значення (Value): Це сума переказаних ETH (див. стовпець
ether). - Дані (Data): Це довільні дані, які були хешовані (див. стовпець
data). - gasLimit — максимальна кількість одиниць газу, яка може бути спожита транзакцією. Одиниці газу представляють обчислювальні кроки.
- maxPriorityFeePerGas — максимальна кількість газу, яка буде включена як пріоритетна комісія майнеру.
- maxFeePerGas — максимальна кількість газу, яку готові заплатити за транзакцію (включно з baseFeePerGas та maxPriorityFeePerGas).
Ми можемо зробити запит на ці конкретні дані для транзакцій на публічну адресу Фундації Ethereum:
SELECT
"to",
"from",
value / 1e18 AS ether,
data,
gas_limit,
gas_price / 1e9 AS gas_price_gwei,
gas_used,
ROUND(((gas_used / gas_limit) * 100),2) AS gas_used_pct
FROM ethereum."transactions"
WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
ORDER BY block_time DESC
Блоки
Кожна транзакція змінюватиме стан віртуальної машини Етеріуму (EVM) (джерело). Транзакції транслюються в мережу для перевірки та включення в блок. Кожна транзакція пов'язана з номером блоку. Щоб побачити дані, ми можемо зробити запит до конкретного номера блоку: 12396854 (останній блок серед транзакцій Фундації Ethereum на момент написання статті, 11.05.2021).
Крім того, коли ми робимо запит до наступних двох блоків, ми бачимо, що кожен блок містить хеш попереднього блоку (тобто батьківський хеш), що ілюструє, як формується блокчейн.
Кожен блок містить посилання на свій батьківський блок. Це показано нижче між стовпцями hash та parent_hash (джерело):
Ось запит (opens in a new tab) на Dune Analytics:
SELECT
time,
number,
hash,
parent_hash,
nonce
FROM ethereum."blocks"
WHERE "number" = 12396854 OR "number" = 12396855 OR "number" = 12396856
LIMIT 10
Ми можемо дослідити блок, зробивши запит на час, номер блоку, складність, хеш, батьківський хеш та нонс.
Єдине, що не охоплює цей запит, — це список транзакцій, який вимагає окремого запиту нижче, та корінь стану (state root). Повний або архівний вузол зберігатиме всі транзакції та переходи станів, дозволяючи клієнтам робити запити щодо стану ланцюга в будь-який час. Оскільки це вимагає великого обсягу пам'яті, ми можемо відокремити дані ланцюга від даних стану:
- Дані ланцюга (список блоків, транзакцій)
- Дані стану (результат переходу стану кожної транзакції)
Корінь стану належить до останніх і є неявними даними (не зберігаються ончейн), тоді як дані ланцюга є явними і зберігаються в самому ланцюзі (джерело (opens in a new tab)).
У цьому посібнику ми зосередимося на ончейн-даних, до яких можна зробити запит за допомогою SQL через Dune Analytics.
Як зазначалося вище, кожен блок містить список транзакцій, ми можемо зробити запит до нього, відфільтрувавши за певним блоком. Спробуємо останній блок, 12396854:
SELECT * FROM ethereum."transactions"
WHERE block_number = 12396854
ORDER BY block_time DESC`
Ось результат SQL на Dune:
Додавання цього єдиного блоку до ланцюга змінює стан віртуальної машини Етеріуму (EVM). Десятки, а іноді й сотні транзакцій перевіряються одночасно. У цьому конкретному випадку було включено 222 транзакції.
Щоб побачити, скільки з них були фактично успішними, ми додамо ще один фільтр для підрахунку успішних транзакцій:
WITH temp_table AS (
SELECT * FROM ethereum."transactions"
WHERE block_number = 12396854 AND success = true
ORDER BY block_time DESC
)
SELECT
COUNT(success) AS num_successful_txn
FROM temp_table
Для блоку 12396854 із 222 загальних транзакцій 204 були успішно перевірені:
Запити на транзакції відбуваються десятки разів на секунду, але блоки фіксуються приблизно раз на 15 секунд (джерело).
Щоб переконатися, що один блок створюється приблизно кожні 15 секунд, ми можемо взяти кількість секунд у добі (86400) і поділити на 15, щоб отримати орієнтовну середню кількість блоків на день (~ 5760).
Графік кількості створених блоків Етеріуму на день (з 2016 року дотепер):
Середня кількість блоків, що створюються щодня за цей період, становить ~5874:
Запити:
# query to visualize number of blocks produced daily since 2016
SELECT
DATE_TRUNC('day', time) AS dt,
COUNT(*) AS block_count
FROM ethereum."blocks"
GROUP BY dt
OFFSET 1
# average number of blocks produced per day
WITH temp_table AS (
SELECT
DATE_TRUNC('day', time) AS dt,
COUNT(*) AS block_count
FROM ethereum."blocks"
GROUP BY dt
OFFSET 1
)
SELECT
AVG(block_count) AS avg_block_count
FROM temp_table
Середня кількість блоків, що створюються на день з 2016 року, трохи перевищує це число і становить 5874. З іншого боку, якщо поділити 86400 секунд на 5874 середніх блоків, вийде 14,7 секунди, або приблизно один блок кожні 15 секунд.
Газ
Блоки обмежені за розміром. Максимальний розмір блоку є динамічним і змінюється залежно від попиту в мережі від 12 500 000 до 25 000 000 одиниць. Ліміти необхідні для того, щоб запобігти створенню довільно великих розмірів блоків, які створюють навантаження на повні вузли з точки зору дискового простору та вимог до швидкості (джерело).
Один із способів концептуалізації ліміту газу блоку — розглядати його як пропозицію доступного простору блоку, в якому можна пакетувати транзакції. Ліміт газу блоку можна запитати та візуалізувати з 2016 року до сьогодні:
SELECT
DATE_TRUNC('day', time) AS dt,
AVG(gas_limit) AS avg_block_gas_limit
FROM ethereum."blocks"
GROUP BY dt
OFFSET 1
Крім того, існує фактичний газ, який щодня використовується для оплати обчислень, що виконуються в ланцюзі Етеріуму (тобто надсилання транзакції, виклик смарт-контракту, карбування NFT). Це попит на доступний простір блоку Етеріуму:
SELECT
DATE_TRUNC('day', time) AS dt,
AVG(gas_used) AS avg_block_gas_used
FROM ethereum."blocks"
GROUP BY dt
OFFSET 1
Ми також можемо зіставити ці два графіки разом, щоб побачити, як співвідносяться попит і пропозиція:
Тому ми можемо розуміти ціни на газ як функцію попиту на простір блоку Етеріуму з огляду на наявну пропозицію.
Нарешті, ми можемо захотіти зробити запит на середні щоденні ціни на газ для ланцюга Етеріуму, однак це призведе до надто тривалого часу виконання запиту, тому ми відфільтруємо наш запит до середньої кількості газу, сплаченої за транзакцію Фундацією Ethereum.
Ми можемо побачити ціни на газ, сплачені за всі транзакції, здійснені на адресу Фундації Ethereum протягом багатьох років. Ось запит:
SELECT
block_time,
gas_price / 1e9 AS gas_price_gwei,
value / 1e18 AS eth_sent
FROM ethereum."transactions"
WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
ORDER BY block_time DESC
Підсумок
Завдяки цьому посібнику ми зрозуміли базові концепції Етеріуму та те, як працює блокчейн Етеріуму, роблячи запити та досліджуючи ончейн-дані.
Інформаційну панель, яка містить весь код, використаний у цьому посібнику, можна знайти тут (opens in a new tab).
Щоб дізнатися більше про використання даних для дослідження Web3, знайдіть мене у Twitter (opens in a new tab).










