Saltar al contenido principal
Change page

Ethash

Ethash era el algoritmo de minería de prueba de trabajo de Ethereum. La prueba de trabajo ahora se ha desactivado por completo y Ethereum ya está protegido utilizando la prueba de participación en su lugar. Profundice sobre la Fusión, prueba de participación y la participación. ¡Esta página es de interés histórico!

Ethash es una versión modificada del algoritmo Dagger-Hashimoto. La prueba de trabajo de Ethash es con memoria dura (opens in a new tab), lo que se pensaba que hacía al algoritmo resistente a los ASIC. Finalmente se desarrollaron los ASIC de Ethash, pero la minería de GPU seguía siendo una opción viable hasta que se desactivó la prueba de trabajo. Ethash todavía se utiliza para minar otras monedas en otras redes de prueba de trabajo que no son de Ethereum.

¿Cómo funciona Ethash?

La dureza de la memoria se logra con un algoritmo de prueba de trabajo que requiere la elección de subconjuntos de un recurso fijo que depende del nonce y el encabezado del bloque. Este recurso (de unos cuantos gigabytes de tamaño) se llama DAG. El DAG se cambia cada 30.000 bloques, una ventana de ~125 horas llamada época (aproximadamente 5,2 días) y tarda un tiempo en generarse. Dado que el DAG solo depende de la altura del bloque, se puede generar previamente, pero si no es así, el cliente tiene que esperar hasta el final de este proceso para producir un bloque. Si los clientes no pregeneran y almacenan en caché los DAG con anticipación, la red puede experimentar un retraso masivo de bloqueo en cada transición de la época. Tenga en cuenta que no es necesario generar el DAG para verificar la prueba de trabajo, lo que esencialmente permite la verificación tanto con CPU baja como con una memoria pequeña.

La ruta general que toma el algoritmo es la siguiente:

  1. Existe una semilla que se puede calcular para cada bloque analizando los encabezados de los bloques hasta ese punto.
  2. A partir de la semilla, se puede calcular una caché pseudoaleatoria de 16 MB. Los clientes ligeros almacenan la caché.
  3. Desde la caché, podemos generar un conjunto de datos de 1 GB, con la propiedad de que cada elemento del conjunto de datos depende solo de un pequeño número de elementos de la caché. Los clientes completos y los mineros almacenan el conjunto de datos. El conjunto de datos crece linealmente con el tiempo.
  4. La minería implica extraer secciones aleatorias del conjunto de datos y agruparlas. La verificación se puede hacer con poca memoria utilizando la caché para regenerar las piezas específicas del conjunto de datos que necesita, por lo que solo tiene que almacenar la memoria caché.

El gran conjunto de datos se actualiza una vez cada 30000 bloques, por lo que la gran mayoría del esfuerzo de un minero será leer el conjunto de datos, no hacer cambios en él.

Definiciones

Utilizamos las siguientes definiciones:

El uso de 'SHA3'

El desarrollo de Ethereum coincidió con el desarrollo del estándar SHA3, y el proceso de estándares hizo un cambio tardío en el relleno del algoritmo hash finalizado, de modo que los hashes de Ethereum sha3_256 y sha3_512 no son hashes SHA3 estándar, sino una variante a la que se hace referencia a menudo referida a menudo como Keccak-256 y Keccak-512 en otros contextos. Véase la discusión, p. ej., aquí (opens in a new tab), aquí (opens in a new tab) o aquí (opens in a new tab).

Por favor, tenga esto en cuenta, ya que los hashes SHA3 se mencionan en la descripción del algoritmo a continuación.

Parámetros

Los parámetros de la memoria caché y del conjunto de datos de Ethash dependen del número de bloque. El tamaño de la memoria caché y el tamaño del conjunto de datos crecen linealmente; sin embargo, siempre tomamos el número primo más alto por debajo del umbral de crecimiento lineal para reducir el riesgo de regularidades accidentales que conducen a un comportamiento cíclico.

En el apéndice se proporcionan tablas de valores de conjuntos de datos y tamaño de caché.

Generación de la caché

A continuación, especifiquemos la función para producir una memoria caché:

El proceso de producción de la caché implica primero llenar secuencialmente hasta 32 MB de memoria, luego realizar dos pasadas del algoritmo RandMemoHash de Sergio Demian Lerner de Strict Memory Hard Hashing Functions (2014) (opens in a new tab). El resultado es un conjunto de 524.288 valores de 64 bytes.

Función de agregación de datos

Utilizamos un algoritmo inspirado en el hash FNV (opens in a new tab) en algunos casos como sustituto no asociativo de XOR. Tenga en cuenta que multiplicamos el número primo con la entrada completa de 32 bits, en contraste con la especificación FNV-1, que multiplica el número primo con un byte (octeto) a su vez.

FNV_PRIME = 0x01000193

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

Tenga en cuenta que incluso el papel amarillo especifica FNV como v1*(FNV_PRIME ^ v2), todas las implementaciones actuales utilizan consistentemente la definición anterior.

Cálculo completo del conjunto de datos

Cada elemento de 64 bytes en el conjunto de datos completo de 1 GB se calcula de la siguiente manera:

Esencialmente, combinamos datos de 256 nodos de caché seleccionados pseudoleatoriamente y hash para calcular el nodo del conjunto de datos. A continuación, todo el conjunto de datos es generado por:

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

Bucle principal

Seguidamente, especificamos el bucle principal similar a Hashimoto, donde agregamos datos del conjunto de datos completo para producir nuestro valor final para un encabezado y nonce en particular. En el código siguiente, header representa el hash SHA3-256 de la representación RLP de un encabezado de bloque truncado, es decir, de un encabezado que excluye los campos mixHash y nonce. nonce son los ocho bytes de un entero sin signo de 64 bits en orden big-endian. Por tanto, nonce[::-1] es la representación little-endian de ocho bytes de ese valor:

Esencialmente, mantenemos una "mezcla" de 128 bytes de ancho, y recuperamos secuencialmente y repetidamente 128 bytes del conjunto de datos completo y usamos la función fnv para combinarla con la mezcla. Se utilizan 128 bytes de acceso secuencial para que cada ronda del algoritmo siempre obtenga una página completa de la RAM, minimizando las faltas de búfer de traducción que los ASIC teóricamente podrían evitar.

Si el resultado de este algoritmo está por debajo del objetivo deseado, entonces el nonce es válido. Tenga en cuenta que la aplicación adicional de sha3_256 al final garantiza que existe un nonce intermedio que se puede proporcionar para demostrar que se realizó al menos una pequeña cantidad de trabajo; esta verificación externa rápida de la PoW (prueba de trabajo) se puede utilizar con fines anti-DDoS. También sirve para proporcionar una garantía estadística de que el resultado es un número imparcial de 256 bits.

Minería

El algoritmo de minería se define de la siguiente manera:

def mine(full_size, dataset, header, difficulty):
    # rellenar con ceros el objetivo para compararlo con el hash en el mismo dígito
    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

Definición del hash de la semilla

Para calcular el hash semilla que se usaría para minar en la parte superior de un bloque dado, utilizamos el siguiente algoritmo:

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

Tenga en cuenta que para una minería y verificación sin problemas, recomendamos precalcular futuros hashes semilla y conjuntos de datos en un hilo por separado.

Lecturas adicionales

¿Conoce algún recurso de la comunidad que le haya sido de ayuda? ¡Edite esta página y agréguela!

Apéndice

El siguiente código debe anteponese si está interesado en ejecutar la especificación de Python anterior como código.

Tamaños de los datos

Las siguientes tablas de búsqueda proporcionan aproximadamente 2048 épocas tabuladas de tamaños de datos y tamaños de caché.

Última actualización de la página: 15 de abril de 2026

¿Te resultó útil este artículo?