Explorer les cryptoKitties - Partie 1: Extraction de données

Source: https://www.cryptokitties.co/kitty/101

Si vous lisez ceci, vous avez probablement entendu parler du jeu qui a attiré l’attention de tout le monde sur le réseau Ethereum au cours des derniers mois: CryptoKitties!

En bref, le jeu consiste à collecter des chats virtuels. Les chats sont créés par les joueurs du jeu, qui peuvent en élever deux pour en générer un nouveau. Chaque chat a sa propre séquence génétique, qui détermine leurs attributs physiques. Leur génome est fonction des gènes de leurs parents et de quelques aléas. En plus de l'élevage, Axiom Zen, la société à l'origine du jeu, peut créer jusqu'à 50 000 chats aux caractéristiques prédéfinies. Il existe un marché pour l'achat et la vente de chats et un autre pour la «location» de chats à des fins de reproduction. Vous pouvez en savoir plus sur le jeu ici.

Block Science est une société de recherche et d'analyse en technologie spécialisée dans la conception et l'évaluation de systèmes économiques décentralisés. Analyser certains aspects de l’économie des CryptoKitties semblait être une excellente occasion d’améliorer nos outils d’extraction de données tout en mettant la main sur des données réelles issues d’une application décentralisée en direct (et dynamique!).

Cet article de blog a été divisé en deux parties:

  • La première partie (cet article) couvre les aspects techniques liés à l'extraction et à la transformation des données de la blockchain Ethereum.
  • La partie 2 contient l'analyse réelle de certaines données de jeu.

Extraire des données de la Ethercha Blockchain

Même si tout ce qui s'est déjà passé sur le réseau Ethereum est enregistré sur la blockchain, la transformation de ces bits en données significatives n'est pas toujours simple. Il est simple d'extraire des données de transaction indiquant que, dans un compte de bloc donné, A a envoyé de l'éther (ETH) au compte B et a défini un certain prix de gaz pour que cette transaction soit traitée. Toutefois, lorsque nous travaillons sur des transactions envoyées à des contrats, le décodage de données de chaînes de blocs revient à implémenter une ETL à partir de plusieurs fichiers texte à largeur fixe dont les formats sont décrits uniquement dans le code source du logiciel qui les a créés.

Transactions qui appellent des fonctions dans des contrats intelligents

Prenons par exemple une transaction envoyée au contrat 0xb1690c08e213a35ed9bab7b318de14420fb57d8c avec le contenu suivant dans le champ de données

0x454a2ab3000000000000000000000000000000000000000000000000000000000000000871ad

Qu'est ce que ça fait?

La première partie du champ de données (0x454a2ab3) fait référence à la fonction dans le contrat intelligent appelé par la transaction. Ce sont les quatre premiers octets du hachage de la signature de la fonction, qui est défini comme le nom de la fonction suivi des types de données de ses paramètres.

keccak256 (“ (, <…>, )”)

Les octets restants sont les valeurs des paramètres de la fonction. Vous pouvez lire à ce sujet en détail ici.

Même en connaissant ces 4 octets, comment pouvons-nous savoir quelle fonction est appelée ou combien de paramètres elle a? Dans ce cas particulier, nous savons que le contrat 0xb1690c… est le contrat intelligent de vente aux enchères CryptoKitties - le marché de l’achat et de la vente de chats. Et parce que son code source a été rendu public, nous savons qu’il a une fonction appelée offre

/// Offres sur une enchère ouverte, complétant l'enchère et
/// transférant la propriété du NFT si suffisamment d'Ether est fourni.
/// param _tokenID: ID du jeton sur lequel enchérir.
enchère de fonction (uint256 _tokenId)

Si nous calculons le hachage de la signature de la fonction d'enchère, nous pouvons voir que les quatre premiers octets sont exactement ceux présents dans les données de transaction.

keccak256 (“bid (uint256)”) = 454a2ab3c602fd9…

Et comme la fonction ne prend qu'un argument, nous pouvons dire que tout ce qui suit les quatre premiers octets dans les données de transaction est ce paramètre. En d'autres termes, la transaction enchérit sur le numéro de chat 0x871ad (553389).

Contrats intelligents qui enregistrent des informations

Il est courant que les contrats intelligents enregistrent les informations pendant leur exécution. Les journaux enregistrés par un contrat peuvent être obtenus en appelant la méthode eth_getlogs de l'API JSON RPC. Comme pour les transactions appelant des fonctions de contrat, nous devons connaître le code source du contrat afin de décoder les données renvoyées par cette API. Par exemple, que signifie un journal contenant les données suivantes?

numéro de bloc: 0x51968f
Sujets: [0x0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad5] Données: 0x0000000000000000000000001b8f7b13b14a59d9770f7c1789cf727046f7e542000000000000000000000000000000000000000000000000000000000009fac1000000000000000000000000000000000000000000000000000000000009f80e000000000000000000000000000000000000000000000000000000000008957200004a50b390a6738697012a030ac21d585b4c8214ae39446194054b98e0b98f

Les journaux sont enregistrés lorsqu'un contrat déclenche un événement. Le premier élément du tableau topic (qui ne comporte qu'un élément dans notre exemple) est le hachage de la signature de l'événement. Dans le cas de CryptoKitties, les journaux sont enregistrés lorsqu'un chat tombe enceinte et à la naissance d'un chat, par exemple.

/// L'événement enceinte est déclenché lorsque deux chats se reproduisent avec succès
/// et le chronomètre de grossesse commence pour la matrone.
événement Enceinte (adresse du propriétaire, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock);
/// L'événement de naissance est déclenché chaque fois qu'un nouveau chaton entre en
/// existence. Cela inclut évidemment chaque fois qu'un chat est créé
/// via la méthode giveBirth, mais elle est aussi appelée quand
/// un nouveau chat gen0 est créé.
événement Naissance (adresse propriétaire, uint256 kittyId, uint256 matronId, uint256 sireId, gènes uint256);

Voyez comment le hachage de la signature de l'événement de naissance correspond à la valeur du journal de notre exemple

keccak256 (“Birth (adresse, uint256, uint256, uint256, uint256)”) = 0x0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39sb8e39825b2c50ad5

Jusqu'ici, nous savons que sur le numéro de bloc 51968F (5346959) une cryptokitty était née! La prochaine étape de notre processus de décodage consiste à scinder le champ de données en fonction des cinq paramètres de l'événement Birth. Le premier paramètre est une adresse Ethereum, longue de 160 bits, mais codée à 256 bits (des zéros sont ajoutés à gauche de l'adresse). Les autres paramètres sont des entiers 256 bits. Le champ de données est donc divisé en 5 parties, chacune avec 256 bits (64 caractères hexadécimaux).

propriétaire: 00000000000000000000000000001b8f7b13b14a59d9770f7c1789cf727046f7e542
KittyId:
0000000000000000000000000000000000000000000000000000000000000009fac1
matronId:
0000000000000000000000000000000000000000000000000000000000000009f80e
sireId:
00000000000000000000000000000000000000000000000000000000000000089572
gènes:
00004a50b390a6738697012a030ac21d585b4c8214ae39446194054b98e0b98f

Vous voyez ce que je voulais dire par «implémentation d’une ETL à partir de plusieurs fichiers texte de largeur fixe dont les formats sont décrits uniquement dans le code source du logiciel qui les a créés»? :-)

Passez à la deuxième partie, où nous partagerons quelques faits intéressants que nous avons découverts lors de l’analyse des données de jeu CryptoKitties!

Un merci spécial à l'équipe de Block Science pour ses recherches, ses idées et ses analyses.