Passer au contenu principal
Change page

Ethash

Dernière mise à jour de la page : 15 avril 2026

Ethash était l'algorithme de minage par preuve de travail d'Ethereum. La preuve de travail a maintenant été entièrement désactivée et Ethereum est désormais sécurisé par la preuve d'enjeu. En savoir plus sur The Merge, proof-of-stake et staking. Cette page n'a qu'un intérêt historique !

Ethash est une version modifiée de l'algorithme Dagger-Hashimoto. La preuve de travail Ethash est à mémoire difficile (opens in a new tab), ce qui était censé rendre l'algorithme résistant aux ASIC. Les Ethash ASIC ont finalement été développés, mais le minage via GPU restait encore une option viable jusqu’à ce que la preuve de travail soit désactivée. Ethash est toujours utilisé pour miner d'autres jetons sur des réseaux autres qu'Ethereum fonctionnant avec la preuve de travail.

Comment fonctionne Ethash ?

La complexité de la mémoire est obtenue avec un algorithme de preuve de travail qui nécessite de choisir des sous-ensembles d'une ressource donnée dépendant de l'en-tête du nonce et du bloc. Cette ressource (quelques gigaoctets de taille) est appelée DAG. Le DAG change tous les 30 000 blocs, une fenêtre de 125 heures appelée une époque (soit environ 5,2 jours) et prend un certain temps à se générer. Comme le DAG ne dépend que de la taille du bloc, il peut être pré-généré, mais si ce n'est pas le cas, le client doit attendre la fin de ce processus pour produire un bloc. Si les clients ne génèrent pas et ne mettent pas en cache les DAG à l'avance, le réseau peut rencontrer un retard dans la création de blocs pour chaque transition d'epoch. Notez que le DAG n'a pas besoin d'être généré pour vérifier la preuve de travail essentiellement en permettant la vérification à la fois avec un CPU lent et avec une mémoire réduite.

Le parcours habituel de l'algorithme est le suivant :

  1. Il existe une graine qui peut être calculée pour chaque bloc en scannant les en-têtes de bloc jusqu'à ce point.
  2. À partir de la graine, on peut calculer un cache pseudo-aléatoire de 16 Mo. Les clients légers stockent le cache.
  3. À partir du cache, nous pouvons générer un jeu de données de 1 Go, avec la propriété que chaque élément du jeu de données ne dépend que d'un petit nombre d'éléments du cache. Les clients et les mineurs au complet stockent le jeu de données. Le jeu de données croît linéairement avec le temps.
  4. Le minage consiste à saisir des tranches aléatoires de l'ensemble des données et à les hacher ensemble. La vérification peut être faite avec peu de mémoire en utilisant le cache pour régénérer les morceaux spécifiques du jeu de données dont vous avez besoin, ainsi, vous avez uniquement besoin de stocker le cache.

Le grand ensemble de données est mis à jour une fois tous les 30 000 blocs, de sorte que la grande majorité des efforts d'un mineur sera de lire l'ensemble des données, et non d'y apporter des modifications.

Définitions

Nous utilisons les définitions suivantes :

L'utilisation de 'SHA3'

Le développement d'Ethereum a coïncidé avec le développement de la norme SHA3, et le processus de normes a réalisé un changement tardif dans le remplissage de l'algorithme de hachage finalisé de sorte que les hachages Ethereum "sha3_256" et "sha3_512" ne soient pas des hashs sha3 standard, mais une variante appelée souvent « Keccak-256 » et « Keccak-512 » dans d'autres contextes. Voir la discussion, par exemple, ici (opens in a new tab), ici (opens in a new tab), ou ici (opens in a new tab).

Veuillez garder cela à l'esprit, car les hachages « sha3 » sont mentionnés dans la description de l'algorithme ci-dessous.

Paramètres

Les paramètres du cache et du jeu de données d'Ethash dépendent du numéro du bloc. La taille du cache et de la taille de l'ensemble des données augmentent linéairement ; cependant, nous prenons toujours le nombre premier le plus haut en dessous du seuil de croissance linéaire afin de réduire le risque de régularités accidentelles conduisant à un comportement cyclique.

Les tables de jeu de données et les valeurs de taille de cache sont fournies dans l'annexe.

Génération du cache

Maintenant, nous spécifions la fonction pour produire un cache :

Le processus de production du cache implique d'abord de remplir séquentiellement 32 Mo de mémoire, puis d'effectuer deux passes de l'algorithme RandMemoHash de Sergio Demian Lerner, tiré de Strict Memory Hard Hashing Functions (2014) (opens in a new tab). La sortie est un ensemble de valeurs de 524288 de 64 octets.

Fonction d'agrégation de données

Nous utilisons un algorithme inspiré du hachage FNV (opens in a new tab) dans certains cas comme substitut non associatif pour XOR. Notez que nous multiplions le premier par l'entrée 32 bits, contrairement à la spécification FNV-1 qui multiplie le premier avec un octet à son tour.

FNV_PRIME = 0x01000193

def fnv(v1, v2):
    return ((v1 * FNV_PRIME) ^ v2) % 2**32

Veuillez noter que même le papier jaune spécifie fnv comme v1*(FNV_PRIME ^ v2), toutes les implémentations actuelles utilisent systématiquement la définition ci-dessus.

Calcul du jeu de données complet

Chaque élément de 64 octets dans le jeu de données complet de 1 Go est calculé comme suit :

Essentiellement, nous combinons des données à partir de 256 nœuds de cache sélectionnés de façon pseudologique, et de hachage pour calculer le noeud de l'ensemble de données. L'ensemble du jeu de données est ensuite généré par :

def calc_dataset(full_size, cache):
    return [calc_dataset_item(cache, i) for i in range(full_size // HASH_BYTES)]

Boucle principale

Maintenant, nous spécifions la boucle principale « hashimoto », où nous agrégeons les données du jeu de données complet, afin de produire notre valeur finale pour un en-tête et un nonce. Dans le code ci-dessous, header représente le hachage SHA3-256 de la représentation RLP d'un en-tête de bloc tronqué, c'est-à-dire d'un en-tête excluant les champs mixHash et nonce. nonce représente les huit octets d'un entier non signé de 64 bits dans l'ordre big-endian. Ainsi, nonce[::-1] est la représentation little-endian sur huit octets de cette valeur :

Essentiellement, nous maintenons un "mix" de 128 octets de large, et récupérons de manière répétée et séquentielle 128 octets du jeu de données complet pour les combiner avec le mix à l'aide de la fonction fnv. 128 octets d'accès séquentiel sont utilisés de sorte que chaque tour de l'algorithme récupère toujours une page complète de la RAM. Minimiser le tampon de lecture de la traduction loupe ce que l'ASIC serait théoriquement en mesure d'éviter.

Si la sortie de cet algorithme est en dessous de la cible souhaitée, alors le nonce est valide. Notez que l'application supplémentaire de sha3_256 à la fin garantit qu'il existe un nonce intermédiaire qui peut être fourni pour prouver qu'au moins une petite quantité de travail a été effectuée ; cette vérification PoW externe rapide peut être utilisée à des fins d'anti-DDoS. Cela sert également à fournir une assurance statistique que le résultat est un nombre non biaisé de 256 bits.

Minage

L'algorithme de minage est défini comme suit :

def mine(full_size, dataset, header, difficulty):
    # remplissage par des zéros de la cible pour la comparer au hachage sur le même chiffre
    target = zpad(encode_int(2**256 // difficulty), 64)[::-1]
    from random import randint
    nonce = randint(0, 2**64)
    while hashimoto_full(full_size, dataset, header, nonce) > target:
        nonce = (nonce + 1) % 2**64
    return nonce

Définition du hachage de la graine

Afin de calculer le hachage de la graine qui serait utilisé pour miner au-dessus d'un bloc donné, nous utilisons l'algorithme suivant :

 def get_seedhash(block):
     s = '\x00' * 32
     for i in range(block.number // EPOCH_LENGTH):
         s = serialize_hash(sha3_256(s))
     return s

Notez que pour un minage et une vérification en douceur, nous recommandons de calculer au préalable les futures semences et les jeux de données dans un fil séparé.

En savoir plus

Une ressource communautaire vous a aidé ? Modifiez cette page et ajoutez-la !

Annexe

Le code suivant devrait être préfixé si vous souhaitez exécuter la spécification python ci-dessus en tant que code.

Tailles des données

Les tables de recherche suivantes fournissent environ 2048 epochs tabulées de la taille des données et de la taille des caches.

Cet article vous a-t-il été utile ?