Si vous avez déjà effectué une transaction sur Ethereum (ou sur n'importe quelle blockchain activée par des contrats intelligents), alors vous avez probablement cherché des informations sur un explorateur de blocs comme etherscan.io et vu cette masse d'informations :
Onglet Aperçu des Transactions
Et si vous avez essayé de regarder les journaux ou les traces (transactions internes), vous avez peut-être vu ces pages confuses :
Onglet Journaux (vous êtes chanceux s'ils sont bien décodés comme ça)
Onglet Traces (oui, cela ressemble à un tas de non-sens)
Apprendre à lire les détails d'une transaction sur les explorateurs de blocs sera la base de toutes vos analyses de données et connaissances sur Ethereum, alors couvrons toutes les parties et comment travailler avec elles en SQL.
Je ne vais expliquer que les concepts de manière générale; si vous voulez apprendre à décoder manuellement, vous devrez vous familiariser avec la manière dont ils sont structurés.les données sont encodées(c'est la même chose pour les transactions/les traces/les journaux) et comment les utiliserLes fonctions bytearray/hex de Dunealler entre différents types.
À la fin de ce guide, vous serez capable de comprendre et de naviguer dans les tables de données pour tout contrat en utilisant cette requête de recherche de table de transaction :
Lien de requête(Insérez n'importe quelle transaction, chaîne et numéro de bloc)
Une fois que vous aurez appris les concepts de ce guide, vous devriez également apprendre à utiliser monTableau de bord de démarrage rapide EVMpour commencer toute analyse de contrat.
·
30 décembre 2022
Les transactions ne sont que la partie visible de l'iceberg des données, toutes les traces et journaux sont invoqués APRÈS que les données d'entrée initiales déclenchent la fonction de niveau supérieur. Commençons d'abord par étiqueter tous les champs que vous verrez sur la page de transaction de l'explorateur de blocs :
Ce sont les mêmes champs que vous verrez lorsque vous interrogez "ethereum.transactions" sur Dune. L'élément clé à apprendre à identifier ici est si le "to" est un contrat ou non. Normalement, les contrats seront clairement étiquetés. S'il s'agit d'un contrat, il devrait y avoir des "données d'entrée" qui contiennent un appel de fonction.
De tous ces concepts, le premier à bien comprendre est celui d'un EOA par rapport à une adresse de contrat. Les contrats sont déployés par des EOA et peuvent être appelés dans le champ «to» d'une transaction. Si vous cliquez sur une adresse, les explorateurs afficheront en haut à gauche s'il s'agit d'un contrat ou d'un compte. Sur Dune, vous pouvez rejoindre la table ethereum.creation_traces pour vérifier s'il s'agit d'un contrat. Notez que seuls les EOA peuvent être les signataires de la tx «from».
Il est important de comprendre quelles données proviennent directement de la chaîne et quelles données ont été ajoutées par l'explorateur/les interfaces utilisateur. Tout dans la blockchain est représenté sous forme de hexadécimal (parfois appelé binaire ou octets), donc un appel à l'échange 1inch aura cette chaîne de données d'entrée :
Les 4 premiers octets (8 caractères) sont la « signature de la fonction », qui est la hachage keccakdu nom de la fonction et des types d'entrée. Etherscan dispose d'un joli bouton «décoder» pour certains contrats, vous donnant cette forme lisible:
Comme vous pouvez le voir, de nombreuses variables sont regroupées dans cette longue chaîne hexadécimale précédente. La façon dont elles sont codées suit la spécification de l'interface binaire d'application (ABI) des contrats intelligents.
Les ABI sont comme la documentation API pour les contrats intelligents (comme les spécifications OpenAPI), vous pouvez en lire plus sur le détails techniques iciLa plupart des développeurs vérifieront que leur ABI correspond au contrat et téléchargeront l'ABI pour que tout le monde puisse s'y référer lors du décodage. De nombreux contrats peuvent être liés à MEV/trading, où le développeur souhaite garder les choses confidentielles et privées - donc nous n'obtenons aucun décodage de leur part.
Dans Dune, nous avons décodé des tableauxbasé sur les ABI de contrat soumisà une table de contrats (c'est-à-dire ethereum.contrats), les fonctions et les événements sont convertis en signatures de bytes (ethereum.signatures) qui sont ensuite comparés aux traces et aux journaux pour vous donner des tables décodées telles que uniswap_v2_ethereum.Pair_evt_Swap qui stocke tous les échanges pour tous les contrats de paires créés par l'usine de paires Uniswap v2. Vous pouvez filtrer les échanges sur une paire spécifique en regardant la table contract_address pour les événements.
Sur Dune, vous voudriez interroger cette table pour cet appel de fonction oneinch_ethereum.AggregationRouterV6_call_swap. Vous verrez que le nom de cette table est en haut des résultats de la requête dans le chercheur de table au début du guide.
Pour les sections suivantes sur les traces et les journaux, nous utiliserons la même transaction d'échange de l'agrégateur 1inch. C'est un bon exemple car un routeur va échanger des jetons à travers de nombreux contrats DEX, nous obtiendrons ainsi une bonne diversité de traces et de journaux à investiGate.
Parlons ensuite des journaux d'événements. Les journaux peuvent être émis à n'importe quel moment lors d'un appel de fonction. Les développeurs émettront généralement un journal à la fin d'une fonction, après que tous les transferts/logiques aient été effectués sans erreurs. Jetons un coup d'œil à l'événement de swap uniswap v3 émis lors de la transaction précédente :
Vous verrez qu'il y a un champ topic0, topic1, topic2 et data. topic0 est similaire à la signature de la fonction, sauf qu'il est composé de 32 octets au lieu de seulement 4 octets (toujours haché de la même manière). Les événements peuvent avoir des champs "indexés" pour un filtrage plus rapide des données, qui peuvent apparaître dans topic1, topic2 ou topic3. Tous les autres champs sont encodés ensemble dans l'objet "data". Encore une fois, ils suivent les mêmes règles d'encodage que les transactions et les traces. Le "28" est l'indice de l'événement dans tout le bloc. Il peut parfois être utile de faire une jointure lorsque vous voulez le premier échange ou transfert dans une transaction.
Pour trouver la logique derrière l'endroit et la manière dont cet événement a été émis, je vais devoir plonger dans le code de solidité. Je vais cliquer sur l'adresse liée de l'événement, aller à l'onglet du contrat et chercher « émettre un échange » car je sais que tous les événements ont « émettre » juste avant d'être invoqués dans le code.
Il s'agit du contrat uniswapv3poolqui est créé en usine pour chaque paire.
Je vois que ceci est émis à la ligne 786 du contrat, dans le cadre de la fonction "swap".
Être en mesure de naviguer les fonctions et les événements de la lignée à travers les contrats sera une compétence clé que vous devrez acquérir pour comprendre avec précision la lignée des données que vous interrogez. Vous n'avez pas besoin d'apprendre la solidity en profondeur pour naviguer dans ces fichiers, il suffit de savoir comment comprendreinterfaces de contratet quand les fonctions/événements sont appelés (function et emit sont vos mots-clés).
Pour un exemple approfondi de recherche du code des fonctions et des événements,Consultez cette analyse des contrats et des données de Sudoswap.
En utilisant la requête de recherche de table précédente, je peux voir que la table pour laquelle je devrais interroger cet échange est uniswap_v3_ethereum.Pair_evt_Swap et qu'elle est émise après l'appel de la fonction swap()
Les traces peuvent rapidement devenir très difficiles à naviguer, en raison des appels imbriqués entre différents contrats. Commençons par comprendre les types de traces :
Vous devez également comprendre la colonne/l’index trace_address. C’est le modèle [0,1,1,1,1] que vous voyez souvent. Imaginez qu’il s’agisse de puces, où le nombre de nombres dans le tableau indique la profondeur et l’ordre des appels de fonction.
A (null) — la première entrée de la transaction a une trace_address de []
APPEL B (0)
CALLs C (0,0)
APPELs D (1)
APPELS E (1,0) APPELS F (1,0,0)APPELS G (1,1)
APPEL H (2)
Comme vous pouvez le constater à partir de notre capture d'écran de transactions internes (traces) précédentes, etherscan n'est pas un endroit convivial pour visualiser les traces. Je préfère utiliser phalcon blocksec à la place, qui déroule la transaction comme ceci :
Cela peut sembler écrasant, mais c’est en fait un moyen très facile d’explorer toutes les fonctions, tous les événements et tous les arguments dans le flux d’une transaction. Une fois que vous êtes en mesure de comprendre cela, vous pouvez dire en toute sécurité que vous comprenez toutes les données d’une transaction. Remarquez que mon recherche de table est une copie presque exacte de cette disposition, j'ai été largement inspiré par eux !
Notez que sur Dune, nous décodons automatiquement à la fois les appels de transactions et les traces de la même fonction vers la même table. Vous vous demandez peut-être si vous pouvez facilement joindre les événements et les traces/transactions dans l'ordre agréablement affiché dans Phalcon. Sur Dune, vous pouvez vous joindre sur le hachage de transaction pour lier généralement les données, mais vous ne pouvez pas vous joindre sur un index quelconque pour recréer l'ordre exact des interactions. C'est une limitation malheureuse pour le moment qui nécessite un indexeur personnalisé.
Si vous comprenez les concepts que j'ai exposés dans ce guide, alors vous êtes prêt à creuser plus profondément et à écrire des requêtes plus complexes. Naviguer dans les données à travers les transactions en utilisant plusieurs outils différents sera l'une des compétences les plus importantes dont vous aurez besoin pour exceller dans cet espace.
Il y a probablement 10 explorateurs différents que j'utilise chaque semaine, et le nombre d'outils est 10 fois supérieur à cela. J'écris un guide annuel qui couvre l'évolution de l'ensemble des outils de données et ce que vous devriez utiliser pour chaque outil :
Si vous avez déjà effectué une transaction sur Ethereum (ou sur n'importe quelle blockchain activée par des contrats intelligents), alors vous avez probablement cherché des informations sur un explorateur de blocs comme etherscan.io et vu cette masse d'informations :
Onglet Aperçu des Transactions
Et si vous avez essayé de regarder les journaux ou les traces (transactions internes), vous avez peut-être vu ces pages confuses :
Onglet Journaux (vous êtes chanceux s'ils sont bien décodés comme ça)
Onglet Traces (oui, cela ressemble à un tas de non-sens)
Apprendre à lire les détails d'une transaction sur les explorateurs de blocs sera la base de toutes vos analyses de données et connaissances sur Ethereum, alors couvrons toutes les parties et comment travailler avec elles en SQL.
Je ne vais expliquer que les concepts de manière générale; si vous voulez apprendre à décoder manuellement, vous devrez vous familiariser avec la manière dont ils sont structurés.les données sont encodées(c'est la même chose pour les transactions/les traces/les journaux) et comment les utiliserLes fonctions bytearray/hex de Dunealler entre différents types.
À la fin de ce guide, vous serez capable de comprendre et de naviguer dans les tables de données pour tout contrat en utilisant cette requête de recherche de table de transaction :
Lien de requête(Insérez n'importe quelle transaction, chaîne et numéro de bloc)
Une fois que vous aurez appris les concepts de ce guide, vous devriez également apprendre à utiliser monTableau de bord de démarrage rapide EVMpour commencer toute analyse de contrat.
·
30 décembre 2022
Les transactions ne sont que la partie visible de l'iceberg des données, toutes les traces et journaux sont invoqués APRÈS que les données d'entrée initiales déclenchent la fonction de niveau supérieur. Commençons d'abord par étiqueter tous les champs que vous verrez sur la page de transaction de l'explorateur de blocs :
Ce sont les mêmes champs que vous verrez lorsque vous interrogez "ethereum.transactions" sur Dune. L'élément clé à apprendre à identifier ici est si le "to" est un contrat ou non. Normalement, les contrats seront clairement étiquetés. S'il s'agit d'un contrat, il devrait y avoir des "données d'entrée" qui contiennent un appel de fonction.
De tous ces concepts, le premier à bien comprendre est celui d'un EOA par rapport à une adresse de contrat. Les contrats sont déployés par des EOA et peuvent être appelés dans le champ «to» d'une transaction. Si vous cliquez sur une adresse, les explorateurs afficheront en haut à gauche s'il s'agit d'un contrat ou d'un compte. Sur Dune, vous pouvez rejoindre la table ethereum.creation_traces pour vérifier s'il s'agit d'un contrat. Notez que seuls les EOA peuvent être les signataires de la tx «from».
Il est important de comprendre quelles données proviennent directement de la chaîne et quelles données ont été ajoutées par l'explorateur/les interfaces utilisateur. Tout dans la blockchain est représenté sous forme de hexadécimal (parfois appelé binaire ou octets), donc un appel à l'échange 1inch aura cette chaîne de données d'entrée :
Les 4 premiers octets (8 caractères) sont la « signature de la fonction », qui est la hachage keccakdu nom de la fonction et des types d'entrée. Etherscan dispose d'un joli bouton «décoder» pour certains contrats, vous donnant cette forme lisible:
Comme vous pouvez le voir, de nombreuses variables sont regroupées dans cette longue chaîne hexadécimale précédente. La façon dont elles sont codées suit la spécification de l'interface binaire d'application (ABI) des contrats intelligents.
Les ABI sont comme la documentation API pour les contrats intelligents (comme les spécifications OpenAPI), vous pouvez en lire plus sur le détails techniques iciLa plupart des développeurs vérifieront que leur ABI correspond au contrat et téléchargeront l'ABI pour que tout le monde puisse s'y référer lors du décodage. De nombreux contrats peuvent être liés à MEV/trading, où le développeur souhaite garder les choses confidentielles et privées - donc nous n'obtenons aucun décodage de leur part.
Dans Dune, nous avons décodé des tableauxbasé sur les ABI de contrat soumisà une table de contrats (c'est-à-dire ethereum.contrats), les fonctions et les événements sont convertis en signatures de bytes (ethereum.signatures) qui sont ensuite comparés aux traces et aux journaux pour vous donner des tables décodées telles que uniswap_v2_ethereum.Pair_evt_Swap qui stocke tous les échanges pour tous les contrats de paires créés par l'usine de paires Uniswap v2. Vous pouvez filtrer les échanges sur une paire spécifique en regardant la table contract_address pour les événements.
Sur Dune, vous voudriez interroger cette table pour cet appel de fonction oneinch_ethereum.AggregationRouterV6_call_swap. Vous verrez que le nom de cette table est en haut des résultats de la requête dans le chercheur de table au début du guide.
Pour les sections suivantes sur les traces et les journaux, nous utiliserons la même transaction d'échange de l'agrégateur 1inch. C'est un bon exemple car un routeur va échanger des jetons à travers de nombreux contrats DEX, nous obtiendrons ainsi une bonne diversité de traces et de journaux à investiGate.
Parlons ensuite des journaux d'événements. Les journaux peuvent être émis à n'importe quel moment lors d'un appel de fonction. Les développeurs émettront généralement un journal à la fin d'une fonction, après que tous les transferts/logiques aient été effectués sans erreurs. Jetons un coup d'œil à l'événement de swap uniswap v3 émis lors de la transaction précédente :
Vous verrez qu'il y a un champ topic0, topic1, topic2 et data. topic0 est similaire à la signature de la fonction, sauf qu'il est composé de 32 octets au lieu de seulement 4 octets (toujours haché de la même manière). Les événements peuvent avoir des champs "indexés" pour un filtrage plus rapide des données, qui peuvent apparaître dans topic1, topic2 ou topic3. Tous les autres champs sont encodés ensemble dans l'objet "data". Encore une fois, ils suivent les mêmes règles d'encodage que les transactions et les traces. Le "28" est l'indice de l'événement dans tout le bloc. Il peut parfois être utile de faire une jointure lorsque vous voulez le premier échange ou transfert dans une transaction.
Pour trouver la logique derrière l'endroit et la manière dont cet événement a été émis, je vais devoir plonger dans le code de solidité. Je vais cliquer sur l'adresse liée de l'événement, aller à l'onglet du contrat et chercher « émettre un échange » car je sais que tous les événements ont « émettre » juste avant d'être invoqués dans le code.
Il s'agit du contrat uniswapv3poolqui est créé en usine pour chaque paire.
Je vois que ceci est émis à la ligne 786 du contrat, dans le cadre de la fonction "swap".
Être en mesure de naviguer les fonctions et les événements de la lignée à travers les contrats sera une compétence clé que vous devrez acquérir pour comprendre avec précision la lignée des données que vous interrogez. Vous n'avez pas besoin d'apprendre la solidity en profondeur pour naviguer dans ces fichiers, il suffit de savoir comment comprendreinterfaces de contratet quand les fonctions/événements sont appelés (function et emit sont vos mots-clés).
Pour un exemple approfondi de recherche du code des fonctions et des événements,Consultez cette analyse des contrats et des données de Sudoswap.
En utilisant la requête de recherche de table précédente, je peux voir que la table pour laquelle je devrais interroger cet échange est uniswap_v3_ethereum.Pair_evt_Swap et qu'elle est émise après l'appel de la fonction swap()
Les traces peuvent rapidement devenir très difficiles à naviguer, en raison des appels imbriqués entre différents contrats. Commençons par comprendre les types de traces :
Vous devez également comprendre la colonne/l’index trace_address. C’est le modèle [0,1,1,1,1] que vous voyez souvent. Imaginez qu’il s’agisse de puces, où le nombre de nombres dans le tableau indique la profondeur et l’ordre des appels de fonction.
A (null) — la première entrée de la transaction a une trace_address de []
APPEL B (0)
CALLs C (0,0)
APPELs D (1)
APPELS E (1,0) APPELS F (1,0,0)APPELS G (1,1)
APPEL H (2)
Comme vous pouvez le constater à partir de notre capture d'écran de transactions internes (traces) précédentes, etherscan n'est pas un endroit convivial pour visualiser les traces. Je préfère utiliser phalcon blocksec à la place, qui déroule la transaction comme ceci :
Cela peut sembler écrasant, mais c’est en fait un moyen très facile d’explorer toutes les fonctions, tous les événements et tous les arguments dans le flux d’une transaction. Une fois que vous êtes en mesure de comprendre cela, vous pouvez dire en toute sécurité que vous comprenez toutes les données d’une transaction. Remarquez que mon recherche de table est une copie presque exacte de cette disposition, j'ai été largement inspiré par eux !
Notez que sur Dune, nous décodons automatiquement à la fois les appels de transactions et les traces de la même fonction vers la même table. Vous vous demandez peut-être si vous pouvez facilement joindre les événements et les traces/transactions dans l'ordre agréablement affiché dans Phalcon. Sur Dune, vous pouvez vous joindre sur le hachage de transaction pour lier généralement les données, mais vous ne pouvez pas vous joindre sur un index quelconque pour recréer l'ordre exact des interactions. C'est une limitation malheureuse pour le moment qui nécessite un indexeur personnalisé.
Si vous comprenez les concepts que j'ai exposés dans ce guide, alors vous êtes prêt à creuser plus profondément et à écrire des requêtes plus complexes. Naviguer dans les données à travers les transactions en utilisant plusieurs outils différents sera l'une des compétences les plus importantes dont vous aurez besoin pour exceller dans cet espace.
Il y a probablement 10 explorateurs différents que j'utilise chaque semaine, et le nombre d'outils est 10 fois supérieur à cela. J'écris un guide annuel qui couvre l'évolution de l'ensemble des outils de données et ce que vous devriez utiliser pour chaque outil :