Passer au contenu principal

Apprendre les sujets fondamentaux d'Ethereum avec SQL

SQLRequêtesTransactions
Débutant
Paul Apivat
paulapivat.com(opens in a new tab)
11 mai 2021
9 minutes de lecture minute read

De nombreux tutoriels Ethereum ciblent les développeurs, mais il existe un manque de ressources éducatives pour les analystes de données ou pour les personnes qui souhaitent voir des données en chaîne sans faire tourner un client ou un nœud.

Ce tutoriel a pour objectif d'aider les lecteurs à comprendre les concepts fondamentaux d'Ethereum, y compris les transactions, les blocs et la notion de gaz en interrogeant les données en chaîne avec un langage SQL via une interface fournie par Dune Analytics(opens in a new tab).

Les données en chaîne (On-chain) peuvent nous aider à comprendre Ethereum, le réseau, permettre des économies de puissance informatique et devrait servir de base à la compréhension des défis auxquels Ethereum est confronté aujourd'hui (par exemple : la hausse des prix du gaz) et, plus important encore, avoir des discussions sur les solutions évolutives.

Transactions

Le voyage d'un utilisateur sur Ethereum débute par l'initialisation d'un compte utilisateur contrôlé ou d'une entité avec un solde ETH. Il existe deux types de comptes - contrôlé par l'utilisateur ou un contrat intelligent (voir ethereum.org).

N'importe quel compte peut être consulté sur un explorateur de blocs comme Etherscan(opens in a new tab). Les explorateurs de blocs sont votre portail vers les données Ethereum. Ils affichent, en temps réel, des données sur les blocs, les transactions, les mineurs, les comptes et autres activités en chaîne (voir ici).

Cependant, un utilisateur peut vouloir interroger directement les données pour reconsidérer les informations fournies par les explorateurs de blocs externes. Dune Analytics(opens in a new tab) fournit cette capacité à quiconque ayant une certaine connaissance de SQL.

Pour référence, le compte du contrat intelligent de la Fondation Ethereum (EF) peut être consulté sur Etherscan(opens in a new tab).

Une chose à noter est que tous les comptes, y compris ceux de la Fondation Ethereum, disposent d'une adresse publique qui peut être utilisée pour envoyer et recevoir des transactions.

Le solde du compte Etherscan comprend des transactions régulières et des transactions internes. Les transactions internes, malgré le nom, ne sont pas des transactions réelles qui modifient l'état de la chaîne. Ce sont des transferts de valeur initiés par l'exécution d'un contrat (source(opens in a new tab)). Étant donné que les transactions internes n'ont pas de signature, elles ne sont PAS incluses sur la blockchain et ne peuvent pas être interrogées avec Dune Analytics.

Ainsi, ce tutoriel se concentrera sur les transactions dites régulières. Elles peuvent être questionnées ainsi :

1WITH temp_table AS (
2SELECT
3 hash,
4 block_number,
5 block_time,
6 "from",
7 "to",
8 value / 1e18 AS ether,
9 gas_used,
10 gas_price / 1e9 AS gas_price_gwei
11FROM ethereum."transactions"
12WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
13ORDER BY block_time DESC
14)
15SELECT
16 hash,
17 block_number,
18 block_time,
19 "from",
20 "to",
21 ether,
22 (gas_used * gas_price_gwei) / 1e9 AS txn_fee
23FROM temp_table
Afficher tout

Cela donnera les mêmes informations que celles fournies sur la page de transaction Etherscan. À titre de comparaison, voici les deux sources :

Etherscan

La page du contrat de la Fondation Ethereum sur Etherscan.(opens in a new tab)

Dune Analytics

Vous pouvez trouver le tableau de bord ici(opens in a new tab). Cliquez sur la table pour voir la requête (voir aussi ci-dessus).

Décortiquer les transactions

Une transaction soumise comprend plusieurs informations dont (source ) :

  • Recipient : (destinataire) l'adresse de réception (requête « to »)
  • Signature : Alors que la clé privée d'un expéditeur signe une transaction, ce que nous pouvons demander avec SQL est l'adresse publique de l'expéditeur (« from »).
  • Value : (valeur) Il s'agit du montant d'ETH transféré (voir colonne ether).
  • Data : (données) il s'agit de données arbitraires qui ont été hachées (voir colonne data).
  • gasLimit : Quantité maximum d’unités de gaz pouvant être consommée par la transaction. Les unités de gaz représentent les étapes de calcul.
  • maxPriorityFeePerGas : la quantité maximale de gaz à inclure comme un pourboire pour le mineur.
  • maxFeePerGas - le montant maximum de gaz prêt à être payé pour la transaction (incluant baseFeePerGas et maxPriorityFeePerGas)

Nous pouvons interroger ces informations spécifiques pour les transactions à l'adresse publique de la Fondation Ethereum :

1SELECT
2 "to",
3 "from",
4 value / 1e18 AS ether,
5 data,
6 gas_limit,
7 gas_price / 1e9 AS gas_price_gwei,
8 gas_used,
9 ROUND(((gas_used / gas_limit) * 100),2) AS gas_used_pct
10FROM ethereum."transactions"
11WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
12ORDER BY block_time DESC
Afficher tout

Les blocs

Chaque transaction va changer l'état de la machine virtuelle Ethereum (EVM) (source). Les transactions sont diffusées sur le réseau pour être vérifiées et incluses dans un bloc. Chaque transaction est associée à un numéro de bloc. Pour consulter les données, nous pourrions interroger un numéro de bloc spécifique : 12396854 (le bloc le plus récent parmi les transactions de la Fondation Ethereum à ce jour, 11/05/21).

De plus, lorsque nous interrogeons les deux blocs suivants, nous pouvons constater que chaque bloc contient le hachage du bloc précédent (c.-à-d. parent hash), illustrant la façon dont la blockchain est formée.

Chaque bloc contient une référence vers le bloc parent. Ceci est affiché ci-dessous entre les colonnes hash et parent_hash (source ) :

parent_hash

Voici la requête(opens in a new tab) sur Dune Analytics :

1SELECT
2 time,
3 number,
4 hash,
5 parent_hash,
6 nonce
7FROM ethereum."blocks"
8WHERE "number" = 12396854 OR "number" = 12396855 OR "number" = 12396856
9LIMIT 10
Afficher tout

Nous pouvons examiner un bloc en interrogeant le temps, le numéro de bloc, la difficulté, l'empreinte numérique, le hachage parent et le nonce.

La seule chose que cette requête ne couvre pas est la liste de transactions qui nécessite une requête séparée ci-dessous et la racine d'état. Un nœud complet ou archivé stockera toutes les transactions et transitions d'état, permettant aux clients d'interroger l'état de la chaîne à tout moment. Parce que cela nécessite un grand espace de stockage, nous pouvons séparer les données de la chaîne des données d'état :

  • Données de chaîne (liste des blocs, transactions)
  • Données d'état (résultat de la transition d'état pour chaque transaction)

La racine d'état tombe dans cette dernière et sont des données implicites (non stockées sur la chaîne), alors que les données en chaîne sont explicites et stockées sur la chaîne elle-même (source(opens in a new tab)).

Pour ce tutoriel, nous nous concentrerons sur les données en chaîne que l'on peut interroger avec SQL via Dune Analytics.

Comme indiqué ci-dessus, chaque bloc contient une liste de transactions, nous pouvons les consulter en filtrant un bloc spécifique. Nous allons essayer le bloc le plus récent, 12396854 :

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

Voici la sortie SQL sur Dune :

Cet unique bloc étant ajouté à la chaîne change l'état de la Machine Virtuelle Ethereum (EVM). Des dizaines de fois, des centaines de transactions sont vérifiées en même temps. Dans ce cas précis, 222 transactions ont été incluses.

Pour voir combien de transactions ont réellement réussi, nous ajoutons un autre filtre pour compter les transactions réussies :

1WITH temp_table AS (
2 SELECT * FROM ethereum."transactions"
3 WHERE block_number = 12396854 AND success = true
4 ORDER BY block_time DESC
5)
6SELECT
7 COUNT(success) AS num_successful_txn
8FROM temp_table

Pour le bloc 12396854, sur un total de 222 transactions, 204 ont été vérifiées avec succès :

Les requêtes de transactions se produisent des dizaines de fois par seconde, mais les blocs sont produits environ une fois toutes les 15 secondes (source).

Pour voir qu'un bloc est produit environ toutes les 15 secondes, nous pourrions prendre le nombre de secondes dans un jour (86400) divisé par 15 pour obtenir une estimation moyenne de blocs par jour (~ 5760).

Le graphique des blocs Ethereum produits par jour (en 2016) est :

Le nombre moyen de blocs produits quotidiennement au cours de cette période est de ~5 874 :

Les requêtes sont :

1# query to visualize number of blocks produced daily since 2016
2
3SELECT
4 DATE_TRUNC('day', time) AS dt,
5 COUNT(*) AS block_count
6FROM ethereum."blocks"
7GROUP BY dt
8OFFSET 1
9
10# average number of blocks produced per day
11
12WITH temp_table AS (
13SELECT
14 DATE_TRUNC('day', time) AS dt,
15 COUNT(*) AS block_count
16FROM ethereum."blocks"
17GROUP BY dt
18OFFSET 1
19)
20SELECT
21 AVG(block_count) AS avg_block_count
22FROM temp_table
Afficher tout

Le nombre moyen de blocs produits par jour depuis 2016 est légèrement supérieur à ce nombrede 5 874. Alternativement, diviser 86 400 secondes par 5 874 blocs en moyenne donne 14,7 secondes, soit environ un bloc toutes les 15 secondes.

Gaz

Les blocs sont limités en taille. La taille maximale de bloc est dynamique et varie en fonction de la demande sur le réseau, entre 12 500 000 et 25 000 000 d'unités. Des limites sont requises pour éviter que des blocs de taille arbitraire puissent déformer des nœuds complets en termes d'espace disque et de vitesse requise (source).

Une façon de conceptualiser la limite de gaz par bloc est de la considérer comme l'approvisionnement de l'espace disponible d'un bloc dans lequel réaliser les transactions par lots. La limite de gaz du bloc peut être consultée et visualisée de 2016 à nos jours :

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

Ensuite, il existe le gaz réellement utilisé quotidiennement pour payer les calculs effectués sur la chaîne Ethereum (par exemple en envoyant une transaction, en appelant un contrat intelligent, en frappant un NFT). Ceci est la demande pour l'espace disponible de bloc Ethereum :

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

Nous pouvons également juxtaposer ces deux graphiques pour voir comment la ligne demand and supply se présente :

gas_demand_supply

Par conséquent, nous pouvons comprendre les prix du gaz en fonction de la demande en blocs Ethereum, au regard de l'offre disponible.

Enfin, nous pourrions vouloir interroger les prix quotidiens moyens du gaz sur la chaîne Ethereum. Cela entraînera un temps de requête particulièrement long. Nous filtrerons donc notre requête sur le montant moyen de gaz payé par la Fondation Ethereum.

Nous pouvons voir les prix de gaz payés au fil des années pour les transactions à l'adresse de la Fondation Ethereum. Voici la requête :

1SELECT
2 block_time,
3 gas_price / 1e9 AS gas_price_gwei,
4 value / 1e18 AS eth_sent
5FROM ethereum."transactions"
6WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
7ORDER BY block_time DESC

Résumé

Avec ce tutoriel, nous comprenons les concepts fondateurs d'Ethereum et comment fonctionne la blockchain d'Ethereum en interrogeant et en se donnant une idée des données en chaîne.

Le tableau de bord qui contient tout le code utilisé dans ce tutoriel peut être trouvé ici(opens in a new tab).

Pour une plus grande utilisation des données à des fins d'analyse de web3 vous pouvez me retrouver sur Twitter(opens in a new tab).

Dernière modification: @MATsxm(opens in a new tab), 15 août 2023

Ce tutoriel vous a été utile ?