Запросы к этому посту можно найти здесь — https://dune.xyz/queries/153902
Проведя некоторое время в стране NFT, я жажду узнать что-то новое.
Горячей темой в последнее время был выпуск протоколов Ethereum Layer 2, и я нашел очень хорошую панель инструментов, которая кажется идеальной для погружения.
Панель инструментов называется Optimistic-Ethereum, а ее автор — «@Marcov».
Прежде чем углубиться, я хотел немного объяснить, как я обучаюсь и почему я пишу здесь. После просмотра запросов из примера панели инструментов я пишу их с нуля самостоятельно. Я хочу убедиться, что могу заставить запрос выполняться так же, как автор, и это дает мне возможность попрактиковаться и работать над ошибками. Публикация объяснений на Medium еще больше укореняет мое понимание, а также имеет для меня смысл, если помогает хотя бы одному человеку. Я всегда буду поощрять написание запросов вместо того, чтобы читать о них и предполагать, что вы понимаете.
Хорошо, давайте погрузимся.
Всего транзакций в день. По аналогии с таблицей «транзакций» Эфириума существует соответствующая таблица под названием «оптимизм» «транзакции». Очень удобно. Как только вы найдете эту таблицу, расчеты количества транзакций будут довольно простыми SQL.
select date_trunc(‘day’,”block_time”) as “day” , count(*) from optimism.”transactions” group by date_trunc(‘day’,”block_time”) order by “day” asc
Уникальных пользователей в день. В этом разделе используется та же таблица, что и в запросе транзакций выше, но вместо подсчета строк в таблице транзакций мы будем подсчитывать отдельный (уникальный) адрес в столбце «от». Чтобы убедиться, что мы не дважды погружаем пользователей в несколько дней (следовательно, уникальных пользователей), мы сначала выбираем группировку min(block_time) по «от», чтобы получить только первый день, когда новый адрес использовался Optimism. Затем мы можем суммировать пользователей за каждый день и, наконец, использовать предложение over, чтобы сделать эту сумму кумулятивной.
with first_tx as ( select min(“block_time”) as “min_block_time” , “from” from optimism.”transactions” group by “from”), users as (select date_trunc(‘day’,”min_block_time”) as “day” , count(*) as users from first_tx group by date_trunc(‘day’,”min_block_time”)) select sum(users) over (order by “day”) as “cum_users” , “day” from users
Средняя стоимость транзакции. Снова та же таблица, что и для транзакций, и похожа на количество транзакций и уникальных пользователей, но на этот раз рассчитывается количество газа ETH по формуле (gas_limit*gas_cost)/10¹⁸. Автор также включил среднюю стоимость транзакции Uniswap, которая представляет собой тот же запрос, но с добавлением WHERE «to» = адрес контракта Uniswap.
select avg((“gas_limit”*”gas_price”)/10¹⁸) as eth_gas_price , date_trunc(‘day’,”block_time”) as “day” from optimism.”transactions” group by date_trunc(‘day’,”block_time”)
Я немного удивился, почему автор не включил конверсию в доллары США, поэтому я решил попробовать. Таблица Prices.usd пока недоступна в базе данных Optimism, поэтому мне пришлось искать альтернативу. Я нашел таблицу dune_user_generated.»uniswap_prices», которая казалась многообещающей, и на самом деле она работала. Я создал подвыбор ниже и присоединился к нему на основе дня, чтобы рассчитать цену газа в долларах США.
SELECT max(price) as price , “day” from dune_user_generated.”uniswap_prices” where “symbol”=’ETH’ group by “day”
ETH об оптимизме. Теперь все становится немного интереснее. В этом запросе мы используем таблицу с именем optimism.logs. Автор использует поле «block_time», данные, тему и адрес контракта.
Поле data представляет стоимость транзакции и делится на 10¹⁸, чтобы получить значение ETH. Поле данных также преобразуется в тип «byte2numeric», который необходим для выполнения вычисления деления, поскольку вы не можете разделить поле «bytea».
В полях topic автор проводит различие между сжиганием ETH и выпуском ETH. Мое понимание функции L2 заключается в том, что когда вы соединяете свои активы, активы временно сжигаются в цепочке L1 и чеканятся в цепочке L2, а когда вы выходите, происходит обратное. Когда «topic3» = адрес записи, ETH записывается на L2. Затем «topic2» = адрес записи, после чего ETH чеканится на L2. Поле «данные» отрицательное (-) для ожогов и положительное (+) для монетных дворов.
Адрес контракта в предложении where представляет адрес контракта ETH на Optimism. Чтобы подтвердить это, я использовал версию Etherscan для оптимизма (весело!) https://optimistic.etherscan.io.
Когда вы объединяете чеканку и сжигание транзакций, вы получаете оставшийся ETH на Optimism.
with mints as ( select bytea2numeric(“data”)/1e18 as “eth” , date_trunc(‘day’,”block_time”) as “day” from optimism.”logs” where “contract_address”= ‘\x4200000000000000000000000000000000000006’ — ETH and “topic2”= ‘\x0000000000000000000000000000000000000000000000000000000000000000’ ) , burns as ( select -1 * bytea2numeric(“data”)/1e18 as “eth” , date_trunc(‘day’,”block_time”) as “day” from optimism.”logs” where “contract_address”= ‘\x4200000000000000000000000000000000000006’ — ETH and “topic3”= ‘\x0000000000000000000000000000000000000000000000000000000000000000’
Total Elements. Для меня это была новая концепция. Мы не уверены, что такое «элемент».
Из краткого изучения используемых таблиц видно, что каждая «пакетная» транзакция содержит переменное количество «элементов». Я не совсем уверен, правильно ли это, но я предполагаю, что каждый элемент представляет собой одну транзакцию, которая объединяется в пакеты и отправляется в цепочку L1 в виде сверток.
Таблица, используемая в этих объектах, уникальна тем, что не отображается при поиске в проводнике. А еще у него ужасно длинное имя.
OVM_CanonicalTransactionChain_evt_TransactionBatchAppended — в этой таблице есть каждый отдельный пакет с соответствующим количеством элементов. Существует столбец под названием _prevTotalElements, который представляет собой промежуточную сумму элементов в каждом пакете.
Чтобы показать Total Elements, вы просто выбираете первую строку в таблице, упорядоченную по evt_block_time.
select “_prevTotalElements” from optimism.”OVM_CanonicalTransactionChain_evt_TransactionBatchAppended” order by evt_block_time desc limit 1
Чтобы показать кумулятивную сумму элементов, вы можете агрегировать максимальное значение за каждый день без необходимости суммировать () по (), потому что, как я уже упоминал, столбец уже является кумулятивным.
select max(“_prevTotalElements”) as “cum_elements” , date_trunc(‘day’,”evt_block_time”) as “day” from optimism.”OVM_CanonicalTransactionChain_evt_TransactionBatchAppended” group by date_trunc(‘day’,”evt_block_time”) order by date_trunc(‘day’,”evt_block_time”) asc
Размер пакета. Это измерение также берется из таблицы OVM_Canonical и измеряется в столбце «_batchSize». Это не кумулятивный столбец, и на основе данных, которые в настоящее время находятся в этом поле, максимальное значение равно 251. Я считаю, что это представляет собой общий размер транзакций («элементов»), которые могут быть включены в каждую партию, которая должна увеличиваться в течение время, когда Оптимизм выходит за рамки своей бета-фазы.
Время между пакетами. Опять же, мы используем каноническую таблицу. В этом расчете используется «новая для меня» функция под названием «задержка», которая позволяет вам динамически выбирать из предыдущей строки данных (довольно круто). Автор вычитает evt_block_time-lag(evt_block_time) из (в порядке возрастания evt_block_time), чтобы получить время между каждым пакетом. Затем автор включает «день» транзакций, а затем суммирует и усредняет «batch_time» для каждого дня.
with batches as (select date_trunc(‘day’,”evt_block_time”) as “day” , “evt_block_time” — lag(“evt_block_time”) over (order by “evt_block_time” asc) as “batch_time” from optimism.”OVM_CanonicalTransactionChain_evt_TransactionBatchAppended”) select “day” , avg(“batch_time”) as “avg_batch_time” from batches group by “day” order by “day” asc
Вот и все. Моя философия всегда заключалась в том, что вы действительно не узнаете, пока не попробуете. Попадая туда и выполняя запросы, я получаю самые ценные уроки.
Примечание. При использовании функции «Выполнить по выбору» я продолжал получать сообщение об ошибке, показанной ниже. Не уверен, что это уникально для схемы Optimism или даже для таблицы OVM. Когда я скопировал запросы в «Новый запрос» и запустил весь блок, они работали нормально. Не знаю, почему это происходило. Ошибка: связь "optimism.OVM_CanonicalTransactionChain_evt_TransactionBatchAppended" не существует в строке 3, позиция