Przejdź do głównej treści

Poznaj podstawowe zagadnienia Ethereum za pomocą SQL

SQL
zapytania
transakcje
dane i analityka
Początkujący
Paul Apivat
11 maja 2021
8 minut czytania

Wiele samouczków dotyczących Ethereum jest skierowanych do programistów, ale brakuje materiałów edukacyjnych dla analityków danych lub osób, które chcą przeglądać dane onchain bez uruchamiania klienta lub węzła.

Ten samouczek pomaga czytelnikom zrozumieć podstawowe koncepcje Ethereum, w tym transakcje, bloki i gaz, poprzez odpytywanie danych onchain za pomocą języka SQL (Structured Query Language) przez interfejs udostępniany przez Dune Analytics (opens in a new tab).

Dane onchain mogą pomóc nam zrozumieć Ethereum, sieć oraz ekonomię mocy obliczeniowej, a także powinny służyć jako podstawa do zrozumienia wyzwań stojących dziś przed Ethereum (np. rosnące ceny gazu) i, co ważniejsze, dyskusji na temat rozwiązań skalujących.

Transakcje

Podróż użytkownika w Ethereum zaczyna się od zainicjowania konta kontrolowanego przez użytkownika lub podmiotu z saldem ETH. Istnieją dwa typy kont – kontrolowane przez użytkownika lub inteligentny kontrakt (zobacz ethereum.org).

Każde konto można wyświetlić w eksploratorze bloków, takim jak Etherscan (opens in a new tab) lub Blockscout (opens in a new tab). Eksploratory bloków to portal do danych Ethereum. Wyświetlają one w czasie rzeczywistym dane o blokach, transakcjach, górnikach, kontach i innej aktywności onchain (zobacz tutaj).

Użytkownik może jednak chcieć bezpośrednio odpytywać dane, aby zweryfikować informacje dostarczane przez zewnętrzne eksploratory bloków. Dune Analytics (opens in a new tab) zapewnia taką możliwość każdemu, kto posiada pewną wiedzę na temat SQL.

Dla porównania, konto inteligentnego kontraktu Fundacji Ethereum (EF) można zobaczyć w Blockscout (opens in a new tab).

Należy zauważyć, że wszystkie konta, w tym konto EF, mają publiczny adres, który może być używany do wysyłania i odbierania transakcji.

Saldo konta w Etherscan obejmuje zwykłe transakcje i transakcje wewnętrzne. Transakcje wewnętrzne, wbrew nazwie, nie są rzeczywistymi transakcjami, które zmieniają stan łańcucha. Są to transfery wartości inicjowane przez wykonanie kontraktu (źródło (opens in a new tab)). Ponieważ transakcje wewnętrzne nie mają podpisu, nie są one uwzględniane w blockchainie i nie można ich odpytywać za pomocą Dune Analytics.

Dlatego ten samouczek skupi się na zwykłych transakcjach. Można je odpytywać w następujący sposób:

Przyniesie to te same informacje, co na stronie transakcji Etherscan. Dla porównania, oto dwa źródła:

Etherscan

Screenshot of Etherscan transaction explorer view

Strona kontraktu EF w Blockscout. (opens in a new tab)

Dune Analytics

Screenshot of a Dune Analytics query dashboard

Pulpit nawigacyjny można znaleźć tutaj (opens in a new tab). Kliknij tabelę, aby zobaczyć zapytanie (zobacz również powyżej).

Analiza transakcji

Przesłana transakcja zawiera kilka informacji, w tym (źródło):

  • Odbiorca (Recipient): Adres odbierający (odpytywany jako „to”).
  • Podpis (Signature): Chociaż klucze prywatne nadawcy podpisują transakcję, to, co możemy odpytać za pomocą SQL, to publiczny adres nadawcy („from”).
  • Wartość (Value): Jest to ilość przesłanego ETH (zobacz kolumnę ether).
  • Dane (Data): Są to dowolne dane, które zostały zahashowane (zobacz kolumnę data).
  • gasLimit – maksymalna ilość jednostek gazu, która może zostać zużyta przez transakcję. Jednostki gazu reprezentują kroki obliczeniowe.
  • maxPriorityFeePerGas – maksymalna ilość gazu, która ma zostać uwzględniona jako opłata priorytetowa dla górnika.
  • maxFeePerGas – maksymalna ilość gazu, jaką użytkownik jest skłonny zapłacić za transakcję (łącznie z baseFeePerGas i maxPriorityFeePerGas).

Możemy odpytać te konkretne informacje dla transakcji na publiczny adres Fundacji Ethereum:

Bloki

Każda transakcja zmieni stan Wirtualnej Maszyny Ethereum (EVM) (źródło). Transakcje są rozgłaszane w sieci w celu weryfikacji i włączenia do bloku. Każda transakcja jest powiązana z numerem bloku. Aby zobaczyć dane, moglibyśmy odpytać konkretny numer bloku: 12396854 (najnowszy blok wśród transakcji Fundacji Ethereum w momencie pisania tego tekstu, 11.05.2021 r.).

Co więcej, gdy odpytamy dwa kolejne bloki, zobaczymy, że każdy blok zawiera hash poprzedniego bloku (tj. hash rodzica), co ilustruje, w jaki sposób powstaje blockchain.

Każdy blok zawiera odniesienie do swojego bloku nadrzędnego (rodzica). Pokazano to poniżej między kolumnami hash i parent_hash (źródło):

parent_hash

Oto zapytanie (opens in a new tab) w Dune Analytics:

Możemy zbadać blok, odpytując czas, numer bloku, trudność, hash, hash rodzica i nonce.

Jedyną rzeczą, której to zapytanie nie obejmuje, jest lista transakcji, która wymaga osobnego zapytania poniżej, oraz korzeń stanu (state root). Pełny lub archiwalny węzeł będzie przechowywał wszystkie transakcje i przejścia stanów, umożliwiając klientom odpytywanie stanu łańcucha w dowolnym momencie. Ponieważ wymaga to dużej przestrzeni dyskowej, możemy oddzielić dane łańcucha od danych stanu:

  • Dane łańcucha (lista bloków, transakcje)
  • Dane stanu (wynik przejścia stanu każdej transakcji)

Korzeń stanu należy do tej drugiej kategorii i jest daną niejawną (nieprzechowywaną onchain), podczas gdy dane łańcucha są jawne i przechowywane w samym łańcuchu (źródło (opens in a new tab)).

W tym samouczku skupimy się na danych onchain, które mogą być odpytywane za pomocą SQL przez Dune Analytics.

Jak wspomniano powyżej, każdy blok zawiera listę transakcji, którą możemy odpytać, filtrując pod kątem konkretnego bloku. Wypróbujemy najnowszy blok, 12396854:

SELECT * FROM ethereum."transactions"
WHERE block_number = 12396854
ORDER BY block_time DESC`

Oto wynik SQL w Dune:

Screenshot of a list of Ethereum transactions

Ten pojedynczy blok dodany do łańcucha zmienia stan Wirtualnej Maszyny Ethereum (EVM). Dziesiątki, a czasem setki transakcji są weryfikowane jednocześnie. W tym konkretnym przypadku uwzględniono 222 transakcje.

Aby zobaczyć, ile z nich faktycznie zakończyło się sukcesem, dodalibyśmy kolejny filtr do zliczania udanych transakcji:

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

Dla bloku 12396854, z 222 wszystkich transakcji, 204 zostały pomyślnie zweryfikowane:

Screenshot of a successful Ethereum transaction

Żądania transakcji występują dziesiątki razy na sekundę, ale bloki są zatwierdzane mniej więcej raz na 15 sekund (źródło).

Aby zobaczyć, że jeden blok jest produkowany mniej więcej co 15 sekund, moglibyśmy wziąć liczbę sekund w dniu (86400) i podzielić przez 15, aby uzyskać szacunkową średnią liczbę bloków dziennie (~ 5760).

Wykres bloków Ethereum produkowanych dziennie (od 2016 r. do chwili obecnej) to:

Chart showing daily Ethereum block production

Średnia liczba bloków produkowanych dziennie w tym okresie wynosi ~5874:

Chart showing daily Ethereum block production

Zapytania to:

Średnia liczba bloków produkowanych dziennie od 2016 roku jest nieco wyższa i wynosi 5874. Alternatywnie, podzielenie 86400 sekund przez średnio 5874 bloki daje 14,7 sekundy, czyli w przybliżeniu jeden blok co 15 sekund.

Gaz

Bloki mają ograniczony rozmiar. Maksymalny rozmiar bloku jest dynamiczny i zmienia się w zależności od zapotrzebowania sieci od 12 500 000 do 25 000 000 jednostek. Limity są wymagane, aby zapobiec obciążaniu pełnych węzłów przez arbitralnie duże rozmiary bloków pod względem wymagań dotyczących przestrzeni dyskowej i szybkości (źródło).

Jednym ze sposobów na konceptualizację limitu gazu w bloku jest myślenie o nim jako o podaży dostępnej przestrzeni bloku, w której można grupować transakcje. Limit gazu w bloku można odpytywać i wizualizować od 2016 roku do dnia dzisiejszego:

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

Następnie mamy rzeczywisty gaz zużywany codziennie do opłacania obliczeń wykonywanych w łańcuchu Ethereum (tj. wysyłanie transakcji, wywoływanie inteligentnego kontraktu, wybijanie NFT). Jest to popyt na dostępną przestrzeń bloków Ethereum:

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

Możemy również zestawić te dwa wykresy razem, aby zobaczyć, jak kształtują się popyt i podaż:

gas_demand_supply

Dlatego możemy rozumieć ceny gazu jako funkcję popytu na przestrzeń bloków Ethereum przy danej dostępnej podaży.

Na koniec możemy chcieć odpytać średnie dzienne ceny gazu dla łańcucha Ethereum, jednak zrobienie tego spowoduje wyjątkowo długi czas zapytania, więc przefiltrujemy nasze zapytanie do średniej ilości gazu płaconej za transakcję przez Fundację Ethereum.

Chart showing Ethereum Foundation daily gas usage

Możemy zobaczyć ceny gazu płacone za wszystkie transakcje dokonane na adres Fundacji Ethereum na przestrzeni lat. Oto zapytanie:

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

Podsumowanie

Dzięki temu samouczkowi rozumiemy podstawowe koncepcje Ethereum i sposób działania blockchaina Ethereum poprzez odpytywanie i zapoznanie się z danymi onchain.

Pulpit nawigacyjny zawierający cały kod użyty w tym samouczku można znaleźć tutaj (opens in a new tab).

Aby dowiedzieć się więcej o wykorzystaniu danych do eksploracji Web3, znajdź mnie na Twitterze (opens in a new tab).