Перейти к основному контенту

Изучение базовых тем Эфириума с помощью SQL

SQL
запросы
транзакции
данные и аналитика
Для начинающих
Пол Апиват
11 мая 2021 г.
8 минут на чтение

Многие руководства по Эфириуму ориентированы на разработчиков, но не хватает образовательных ресурсов для аналитиков данных или для людей, которые хотят просматривать ончейн-данные без запуска клиента или узла.

Это руководство поможет читателям понять фундаментальные концепции Эфириума, включая транзакции, блоки и газ, путем запроса ончейн-данных с помощью языка структурированных запросов (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).

Следует отметить, что все аккаунты, включая аккаунт EF, имеют публичный адрес, который можно использовать для отправки и получения транзакций.

Баланс аккаунта на Etherscan состоит из обычных и внутренних транзакций. Внутренние транзакции, несмотря на название, не являются фактическими транзакциями, которые изменяют состояние цепи. Это переводы средств, инициированные выполнением контракта (источник (opens in a new tab)). Поскольку внутренние транзакции не имеют подписи, они не включаются в блокчейн и не могут быть запрошены с помощью Dune Analytics.

Поэтому в данном руководстве основное внимание будет уделено обычным транзакциям. Их можно запросить следующим образом:

Это даст ту же информацию, что и на странице транзакций Etherscan. Для сравнения, вот два источника:

Etherscan

Screenshot of Etherscan transaction explorer view

Страница контракта EF на Blockscout. (opens in a new tab)

Dune Analytics

Screenshot of a Dune Analytics query dashboard

Вы можете найти дашборд здесь (opens in a new tab). Нажмите на таблицу, чтобы увидеть запрос (также см. выше).

Разбор транзакций

Отправленная транзакция включает в себя несколько элементов информации, в том числе (источник):

  • Получатель (Recipient): Адрес получения (запрашивается как «to»).
  • Подпись (Signature): Хотя транзакция подписывается закрытыми ключами отправителя, с помощью SQL мы можем запросить публичный адрес отправителя («from»).
  • Сумма (Value): Это количество переведенных ETH (см. столбец ether).
  • Данные (Data): Это произвольные данные, которые были хешированы (см. столбец data).
  • Лимит газа (gasLimit) — максимальное количество единиц газа, которое может быть потреблено транзакцией. Единицы газа представляют собой вычислительные шаги.
  • maxPriorityFeePerGas — максимальное количество газа, которое будет включено в качестве чаевых майнеру.
  • maxFeePerGas — максимальное количество газа, которое отправитель готов заплатить за транзакцию (включая baseFeePerGas и maxPriorityFeePerGas).

Мы можем запросить эти конкретные данные для транзакций на публичный адрес Фонда Ethereum:

Блоки

Каждая транзакция изменяет состояние виртуальной машины Эфириума (EVM) (источник). Транзакции транслируются в сеть для проверки и включения в блок. Каждая транзакция связана с номером блока. Чтобы увидеть данные, мы можем запросить конкретный номер блока: 12396854 (самый последний блок среди транзакций Фонда Ethereum на момент написания статьи, 11.05.2021).

Более того, когда мы запрашиваем следующие два блока, мы видим, что каждый блок содержит хеш предыдущего блока (т. е. родительский хеш), что иллюстрирует, как формируется блокчейн.

Каждый блок содержит ссылку на свой родительский блок. Это показано ниже между столбцами hash и parent_hash (источник):

parent_hash

Вот запрос (opens in a new tab) в Dune Analytics:

Мы можем изучить блок, запросив время, номер блока, сложность, хеш, родительский хеш и нонс.

Единственное, что не охватывает этот запрос, — это список транзакций, для которого требуется отдельный запрос ниже, и корень состояния (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:

Screenshot of a list of Ethereum transactions

Добавление этого единственного блока в цепь изменяет состояние виртуальной машины Эфириума (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 были успешно проверены:

Screenshot of a successful Ethereum transaction

Запросы на транзакции происходят десятки раз в секунду, но блоки фиксируются примерно раз в 15 секунд (источник).

Чтобы убедиться, что один блок создается примерно каждые 15 секунд, мы можем разделить количество секунд в сутках (86400) на 15, чтобы получить расчетное среднее количество блоков в день (~ 5760).

График количества создаваемых блоков Эфириума в день (с 2016 года по настоящее время) выглядит так:

Chart showing daily Ethereum block production

Среднее количество блоков, создаваемых ежедневно за этот период времени, составляет ~5874:

Chart showing daily Ethereum block production

Запросы:

Среднее количество блоков, создаваемых в день с 2016 года, немного превышает это число и составляет 5874. В качестве альтернативы, разделив 86400 секунд на 5874 средних блока, мы получим 14,7 секунды, или примерно один блок каждые 15 секунд.

Газ

Блоки ограничены в размере. Максимальный размер блока динамичен и варьируется в зависимости от спроса в сети от 12 500 000 до 25 000 000 единиц. Лимиты необходимы для предотвращения создания произвольно больших блоков, создающих нагрузку на полные узлы с точки зрения дискового пространства и требований к скорости (источник).

Один из способов концептуализации лимита газа в блоке — рассматривать его как предложение доступного пространства блока, в котором можно пакетировать транзакции. Лимит газа в блоке можно запросить и визуализировать с 2016 года по сегодняшний день:

Chart showing average Ethereum gas limit over time

SELECT
    DATE_TRUNC('day', time) AS dt,
    AVG(gas_limit) AS avg_block_gas_limit
FROM ethereum."blocks"
GROUP BY dt
OFFSET 1

Кроме того, существует фактический газ, ежедневно используемый для оплаты вычислений, выполняемых в цепи Эфириума (т. е. отправка транзакции, вызов смарт-контракта, чеканка NFT). Это спрос на доступное пространство блоков Эфириума:

Chart showing daily Ethereum gas used

SELECT
    DATE_TRUNC('day', time) AS dt,
    AVG(gas_used) AS avg_block_gas_used
FROM ethereum."blocks"
GROUP BY dt
OFFSET 1

Мы также можем сопоставить эти два графика вместе, чтобы увидеть, как соотносятся спрос и предложение:

gas_demand_supply

Таким образом, мы можем понимать цены на газ как функцию спроса на пространство блоков Эфириума при наличии доступного предложения.

Наконец, мы можем захотеть запросить средние ежедневные цены на газ для цепи Эфириума, однако это приведет к особенно долгому времени выполнения запроса, поэтому мы отфильтруем наш запрос по среднему количеству газа, уплаченному за транзакцию Фондом Ethereum.

Chart showing Ethereum Foundation daily gas usage

Мы можем увидеть цены на газ, уплаченные за все транзакции, совершенные на адрес Фонда 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, найдите меня в Твиттере (opens in a new tab).