El algoritmo de minería de bitcoin desde el punto de vista de un programador

Esta página: Blocks dijo que la minería es en realidad para resolver un problema matemático, pero leer el algoritmo hash de Block no brinda mucha ayuda. También intenté leer el código fuente de bitcoind, pero leer el código lleva mucho más tiempo que leer la documentación :)

Y he escrito un cliente json-rpc simple para llamar al método getwork() para obtener los "datos", pero ¿qué debo hacer junto a estos "datos"?

¿Alguien podría explicar el proceso de minería desde el punto de vista del programador?

but what should I do next to this "data"?Aquí hay una breve implementación de referencia. github.com/jgarzik/pyminer/blob/master/pyminer.py
Además, explain the mining process in programmer's viewes una pregunta bastante amplia. ¿Qué problema específico estás tratando de resolver?
@NickODell ¡Gracias por tu código! Ahora entiendo cómo crear nuevos bloques. Pero, ¿cada bloque enviado es válido (la red bitcoin enviará bitcoins a esta persona)? Encontré que Bitcoin wiki decía que solo se crearán 6 bloques cada hora. Suponga que 100 personas obtienen el encabezado del bloque usando getwork al mismo tiempo con la misma dificultad, creo que estas personas crearán mucho más de 6 bloques. ¿Tengo razón?
Respondiendo en orden: No. No.
@NickODell Perdón por mi retraso, tengo algo emergente en estos días. Si no todos los trabajos enviados son válidos, ¿cómo puede la red bitcoin saber qué solución enviada es válida? Gracias

Respuestas (3)

El algoritmo de minería es el siguiente:

  • Paso 0: recupera el hash del bloque anterior de la red.

  • Paso 1: recopile una lista de posibles transacciones conocidas como "bloque". Esta lista de transacciones proviene de la red bitcoin peer-to-peer.

  • Paso 2: calcule un hash para un bloque de transacciones potenciales junto con un número aleatorio.
  • Paso 3: si el hash es mayor que el nivel de dificultad establecido actualmente, entonces has extraído ese bloque. De lo contrario, comience de nuevo desde el Paso 1. Cualquier adición a la lista de transacciones del Paso 1 junto con el cambio en el número aleatorio del Paso 2 significa que existe la posibilidad de que se cumpla el criterio en la siguiente ronda.

Desde el punto de vista de un programador, el pseudocódigo podría verse así:

P := El hash del bloque previamente minado
B := Un bloque de transacciones
H := Una función hash
D := Nivel de dificultad

0 Recuperar P
1 Construir/Modificar B
2 SI H(P, B, algún número aleatorio) > D FIN
3 IR A 1

Debo advertirle que hay algunas inexactitudes en esa descripción, pero en su mayor parte, eso debería ser suficiente. Y aquí hay algunas aclaraciones más útiles:

¿Qué es un hachís?

Un hash es una función que convierte datos en un número dentro de un cierto rango. El hash tiene la propiedad de que conocer su salida es esencialmente impredecible (dentro del rango dado). La función hash específica utilizada para la minería de bitcoins es SHA256 aplicada dos veces.

¿Cómo funciona el nivel de dificultad?

Esta naturaleza impredecible de la función hash significa que ingresar datos aleatorios (la transacción + el número aleatorio) producirá esencialmente un número aleatorio dentro de un cierto rango. Restringir aún más el rango del resultado deseado afecta la probabilidad de encontrarlo en una sola ronda. Esto crea una forma de determinar probabilísticamente con qué frecuencia se encontrará una solución en función de la cantidad de veces que se puede ejecutar el algoritmo en la red. Específicamente, cuando escuche el término "gigahashes" o "terahashes", esto se refiere a la cantidad de veces que se puede ejecutar el paso 3. A medida que crece la cantidad de hashes por segundo en toda la red, la red aumenta automáticamente la dificultad de modo que se encuentra una solución en aproximadamente 10 minutos.

¿Qué sucede cuando se extrae un bloque?

Cuando se extrae un bloque, el minero envía el bloque a todos los demás mineros de la red como prueba de que lo ha encontrado. Este bloque contiene una lista de transacciones, el hash encontrado, el número aleatorio específico y una referencia al hash anterior. A medida que cada minero recibe el bloque recién extraído, elimina todas las transacciones que está minando actualmente y que existen dentro del bloque (porque ya han sido confirmadas en la cadena de bloques) y transmite el bloque a otros mineros que hacen lo mismo. La propagación ocurre bastante rápido.

Nota: el minero original del bloque recibe una "tarifa de mineros", que es una recompensa que consiste en las monedas no gastadas de las transacciones además de una recompensa de "coinbase". La recompensa de coinbase comenzó en 50 bitcoins y se reduce a la mitad después de cada 210 000 bloques (aproximadamente una vez cada 4 años). La recompensa de la base de monedas eventualmente será tan pequeña que será minúscula en comparación con las tarifas de los mineros.

La recompensa se reduce a la mitad cada 210000 bloques. -> Acabo de ver eso ahora y creo que está bien: bitcoinclock.com
Ah, y la dificultad se ajusta cada 2016 bloques asumiendo que la red continuará operando con la tasa de hash promedio de dichos últimos bloques de 2016 y estableciendo la nueva dificultad de modo que esta tasa de hash resulte en un ciclo de bloque de aproximadamente 10 minutos.
Podría estar equivocado, pero creo que el bloque también contiene el hash del último bloque. Y así es como los bloques se encadenan al revés, lo que lleva al término blockchain.
@Murch, la dificultad en realidad se ajusta a cada bloque en función del tiempo que llevó encontrar el bloque anterior y, en este punto, la dificultad solo puede aumentar. Cada 2016 bloques se ajusta la dificultad respecto a los últimos 2016 y se puede subir o bajar. Esto ayuda a protegerse contra caídas repentinas en el poder de cómputo, que de lo contrario daría como resultado que el tiempo para encontrar un bloque aumente a más de 10 minutos.
@Tarandeep-Gill, ¡eso es correcto! El hash del bloque anterior se codifica junto con la lista de transacciones. Esto realmente me hace pensar que mi explicación del hash es un poco incompleta: la función hash específica no es SHA256 aplicada dos veces como se indicó, sino que esa función se aplica a varias partes del bloque (incluidas las transacciones y el hash del bloque anterior) En maneras diferentes. Esta es una de esas "inexactitudes" de las que te advertí. Me pregunto si puedes encontrar a los otros...
¿Estamos hablando de dificultad de red o de alguna otra dificultad? Debido a que la dificultad de la red no cambia cada bloque, cambia exclusivamente cada 2016 bloques. Ver por ejemplo: en.bitcoin.it/wiki/…
Creo que omitir el hash del bloque anterior de la explicación es una mala idea, incluso si hace que la respuesta sea más fácil de leer. La gente podría decir "Ajá", de ahí viene el nombre blockchain cuando leen esta respuesta sugerida por @TarandeepGill
@AntonA., creo que es importante no combinar respuestas que no necesariamente tienen nada que ver entre sí. Si bien acepto que esta información es útil, el término "cadena de bloques" no se menciona específicamente en la pregunta ni en mi respuesta. Esta información puede ser más útil aquí: ethereum.stackexchange.com/questions/459/…

Cualquier hash es un hash válido. La pregunta es si tu hachís cumple con nuestros criterios. Lo que hash es en realidad un par de cosas (volveremos a esto) que alineadas juntas forman una cadena que es una cadena de una longitud específica. Luego hash toda esa cadena. Piense en su hash resultante como un número. Lo que queremos es que el número resultante sea menor que un número objetivo. Es como lanzar un dado de mil millones de caras y obtener un número debajo del número objetivo. Ese número objetivo se considera "dificultad". A medida que más personas tiran el dado, reducimos el número objetivo para reducir la probabilidad de que una tirada de dado acierte.

Lo que es más importante, algunas de esas cosas que alineamos en la cadena que hacemos hash son cosas que podemos ajustar. Hashing no es exactamente como tirar el dado porque si tenemos lo mismo una y otra vez obtenemos el mismo resultado una y otra vez. Sin embargo, incluso un pequeño ajuste en lo que hacemos hash puede tener un gran impacto en lo que es el hash resultante. El elemento principal que podemos manipular se llama "nonce". Básicamente, elegimos un nonce para usar en la cadena, hacemos un hash de toda la cadena y vemos qué obtenemos. Si el hash no es un éxito, modificamos el nonce y lo intentamos de nuevo. El nonce en sí no es muy grande, por lo que hay un número limitado de variaciones del nonce que puede probar. El siguiente elemento que podemos cambiar es una marca de tiempo. También se nos permite mover la marca de tiempo. Cada movimiento de la marca de tiempo nos permite recorrer todo el conjunto de posibles valores de nonce de nuevo. Repetimos este proceso de agotar las posibilidades de nonce, luego movemos la marca de tiempo una y otra vez hasta que el hash resultante sea menor que el número objetivo de dificultad.

Cuando eso sucede, proclamamos al mundo que esta marca de tiempo más este nonce funcionan para resolver el bloqueo. Otros validan que sea cierto y se agrega a la cadena de bloques. Un bloque se considera "Validado" una vez que tiene una cierta cantidad de bloques "profundos" en la cadena de bloques, lo que significa que es un bloque histórico en comparación con el bloque actual. La validación es un nombre un poco inapropiado aquí porque no es que el bloque no se sepa que es válido. Lo que estamos validando es la prueba de trabajo, lo que significa que una vez que ese bloque histórico está lo suficientemente enterrado, la cantidad de esfuerzo involucrado para crear esa historia es insuperable para que otra persona intente crear una variación diferente de la historia. Tendrían que crear su propia versión de ese bloque (la única razón es escribir su propia versión de las transacciones, es decir, robar monedas), luego resolverlo ellos mismos, luego resolver el siguiente bloque y el siguiente y así sucesivamente y "atrapar arriba" con todos los demás. Esto significa que tendrían que competir con el mundo en el juego de tirar los dados. Tal vez una vez en la historia del universo, alguien podría tener suerte en el momento con dos o tres bloques seguidos, pero ¿con los 120 bloques que la mayoría de los pools de minería e intercambios requieren ahora? No va a pasar, nunca. Tal vez una vez en la historia del universo, alguien podría tener suerte en el momento con dos o tres bloques seguidos, pero ¿con los 120 bloques que la mayoría de los pools de minería e intercambios requieren ahora? No va a pasar, nunca. Tal vez una vez en la historia del universo, alguien podría tener suerte en el momento con dos o tres bloques seguidos, pero ¿con los 120 bloques que la mayoría de los pools de minería e intercambios requieren ahora? No va a pasar, nunca.

El propósito de resolver un 'rompecabezas' es (a) retrasar la extracción del bloque a un promedio de 10 minutos y (b) incurrir en costos reales para extraer un bloque (gastar potencia de CPU, por lo tanto, energía). Los costos están ahí para evitar un ataque de Sybil (poner muchas máquinas mineras en el trabajo para realizar un ataque del 51%).

La demora se implementa para permitir que un buen bloque se propague por todo el mundo a todos los demás mineros, sin darle al minero que acaba de acuñar el nuevo bloque una ventaja inicial. Para eso, el tiempo de bloqueo (10 minutos) debe ser un orden de magnitud mayor que el retraso de propagación (unos pocos segundos).

Entonces, el tipo de rompecabezas es en cierto sentido irrelevante, bien podría ser un Sudoku gigante.