¿Cómo se calcula la dificultad?

¿Alguien puede explicarme en inglés sencillo cómo se calcula la dificultad? Tengo un entendimiento muy aproximado de que se calcula en función de la cantidad de poder de hash en toda la comunidad de bitcoin durante un período de tiempo específico. Pero esto es muy vago.

También entiendo que puede cambiar muy rápidamente. ¿Solo puede aumentar? ¿Hay alguna fórmula para calcularlo o predecirlo?

Gracias por una respuesta detallada, Meni Rosenfeld. Sólo para asegurarme de que tengo todo bien. Estoy resumiendo todo el tiempo que se tardó en generar los últimos bloques de 2016. Y luego aplicar la fórmula.

Creo que las preguntas de seguimiento son mejores como comentarios a la respuesta. Básicamente sí, pero en realidad no se necesita sumar: solo puede tomar las marcas de tiempo del último bloque y del bloque 2016 anterior, y restar.

Respuestas (3)

La dificultad de Bitcoin comenzó en 1 (y nunca puede bajar de eso). Luego, por cada 2016 bloques que se encuentran, las marcas de tiempo de los bloques se comparan para averiguar cuánto tiempo llevó encontrar 2016 bloques, llámelo T. Queremos que 2016 bloques tarden 2 semanas, así que si T es diferente, multiplicamos la dificultad por (2 semanas / T) - de esta manera, si el hashrate continúa como estaba, ahora tomará 2 semanas encontrar 2016 bloques.

Por ejemplo, si tomó solo 10 días, significa que la dificultad es demasiado baja y, por lo tanto, aumentará en un 40%.

La dificultad puede aumentar o disminuir dependiendo de si tomó menos o más de 2 semanas para encontrar los bloques de 2016. En general, la dificultad disminuirá después de que caiga el hashrate de la red.

Si el factor de corrección es superior a 4 (o inferior a 1/4), entonces se utilizan 4 o 1/4 para evitar que el cambio sea demasiado brusco.

Hay un error en la implementación, debido a que el cálculo se basa en el tiempo para encontrar los últimos bloques de 2015 en lugar de 2016. Solucionarlo requeriría una bifurcación dura y, por lo tanto, se pospone por ahora.

Es posible dar una estimación aproximada del próximo cambio de dificultad, en función del tiempo para encontrar los bloques recientes. Nadie puede hacer predicciones a largo plazo para la dificultad futura de manera confiable, pero cualquiera es libre de especular en función de las tendencias del tipo de cambio, la ley de Moore y otros avances de hardware.

¿Ese bicho sigue ahí? ¿No debería haber un problema de GitHub para que las personas puedan realizar un seguimiento del estado... Con tales errores en el protocolo, será difícil para el ecosistema de Bitcoin alejarse de la situación en la que se establecieron los desarrolladores del cliente Satoshi? todas las reglas.
@StevenRoose: AFAIK lo es, pero dejaré que comenten las personas que están más involucradas con el código central... Esto es adecuado para una pregunta SE separada.
Buena respuesta, pero se elude un punto pequeño, pero capital: ¿cómo se ponen de acuerdo los nodos en la red sobre cuál es la dificultad?
@deadalnix: La dificultad de un bloque es un cálculo determinista basado en los datos de los bloques anteriores. Todos los nodos independientemente hacen el mismo cálculo y obtienen el mismo resultado.
@MeniRosenfeld gracias por esa respuesta. Pero para mí, simplemente mueve el problema. Según tengo entendido tu respuesta, el cómputo se hace a partir de la marca de tiempo disponible en los bloques. Pero entonces, ¿cómo se pone de acuerdo una red p2p sobre la marca de tiempo?
@deadalnix: La marca de tiempo es parte del bloque, lo que significa que quienquiera que encuentre el bloque decide qué poner en él. La marca de tiempo no debe ser anterior a la mediana de los últimos 11 bloques. Además, si un nodo recibe un bloque con una marca de tiempo de más de 2 horas en el futuro, lo rechazará y no lo propagará.
Las referencias a las especificaciones o código base de Bitcoin serían muy apreciadas. Es preferible revisar su respuesta en lugar de meter cosas en los comentarios.
@Indolering: las cosas en los comentarios no son parte de la respuesta principal. Son respuestas a preguntas específicas de seguimiento.
@Meni, entonces, si quiero calcular la finalización de la ronda, ¿debería hacer CURRENT_BLOCK_COUNT_IN_THIS_ROUND/2015 en lugar de CURRENT_BLOCK_COUNT_IN_THIS_ROUND/2016?
@mixdev: La "ronda" (retarget de dificultad) se realiza cada 2016 bloques. Pero el nuevo cálculo actualmente no es prev_target TIME_FOR_LAST_2016_Blocks/1209600, es prev_target TIME_FOR_LAST_2015_Blocks/1209600.
Entonces, ¿esto significa básicamente que los errores se sumarán cada vez que solo se considere la última época? Esto significaría que afirmar que en 2140 se extraerá el último bitcoin es incorrecto, ya que podrían pasar años o incluso décadas antes de eso.
@tobi: El error off-by-one es responsable de que los bloques se encuentren un 0,05 % más lentos en promedio que el 2016 "oficial" cada dos semanas. Hay un problema aparte que provoca otra ralentización del 0,05 %. Juntos ascienden a solo 1 mes de desaceleración durante un siglo. Sin embargo, hay un efecto separado que hace que los bloques se encuentren más rápido debido al aumento en el hashrate. Esto es más significativo y la última moneda se extraerá probablemente 1 o 2 años antes debido a esto.
@tobi: La cantidad total de aceleración debido al aumento de la tasa de hash se puede calcular aproximadamente como log (dificultad) * 2 semanas. Esta es la razón principal por la que las fiestas de reducción a la mitad del bloque tienen una fecha diferente cada vez: noviembre de 2012, julio de 2016, etc.
sí, me refería a la aceleración debido al aumento de la tasa de hash y no al error de bloques de 2015
@tobi: Ah, está bien. Los comentarios anteriores fueron sobre el error, y los "errores" insinuaron que es el error, así que supuse que estábamos hablando de eso. Entonces sí. Si asumimos que alrededor de 2140 el hashrate será de alrededor de *1B de lo que es ahora, el cronograma se adelantará 96 semanas, o casi dos años. Pero todavía hay otro efecto: un retraso causado por el hecho de que, al principio, la dificultad era 1, aunque el hashrate no era suficiente para justificarlo.

La respuesta de Meni es buena. Solo quiero brindar un método práctico detallado sobre el cálculo de la dificultad, quizás útil para futuras vistas de la respuesta de esta pregunta.

Echemos un vistazo al encabezado del bloque de génesis de Satoshi (parte de la información relacionada):

$ bitcoin-cli getblockhash 0
000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

$ bitcoin-cli getblockheader 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
{
  ...
  "height": 0,
  ...
  "bits": "1d00ffff",
  "difficulty": 1,
  ...
}

Como podemos ver arriba, el bloque génesis tiene una dificultad '1' y bits '1d00ffff'. Los bits de bitcoin significan el valor hash 'objetivo', el nuevo bloque generado debe cumplir una condición: el valor hash doble SHA-256 del encabezado del bloque debe ser menor que este valor 'objetivo'.

El valor de bits '1d00ffff' en el bloque de génesis significa el valor 'objetivo':

[0x00000000,0xffff,{0x00..0x00}]
                   {0x00..0x00} at above has 26 bytes 0x00.

Luego, para encontrar un nuevo bloque, debe buscar ese valor nNonce de 32 bits (y nTimes y hashMerkleRoot también) hasta que el valor hash del bloque tenga 4 bytes cero a la izquierda. Por cierto, el nNonce es uno de los campos en la estructura del encabezado del bloque:

 struct header_structure{            // BYTES   NAME
     uint32_t nVersion;              // 4       version
     uint8_t hashPrevBlock[32];      // 32      previous block header hash
     uint8_t hashMerkleRoot[32];     // 32      merkle root hash
     uint32_t nTime;                 // 4       time
     uint32_t nBits;                 // 4       target
     uint32_t nNonce;                // 4       nonce
 };

Debido a que el algoritmo SHA-256 (así como cualquier algoritmo hash criptográficamente seguro) produce una salida que aparecerá como una secuencia aleatoria uniforme , el método práctico de "prueba y error" es la única forma de encontrar un nuevo bloque para cumplir con la condición. La probabilidad de encontrar un bloque con el valor hash inicial cero de 4 bytes es 1/(2^32), lo que significa que los números promedio de "prueba y error" son exactamente 2^32 (es decir, 4G).

Para que los humanos comprendan fácilmente este valor hash de 'objetivo', definimos el término 'dificultad', que significa los números promedio de 'prueba y error' para encontrar un bloque que cumpla con la condición de 'objetivo'. Y definimos la unidad de 'dificultad' : 1 'dificultad' = hash 4G

Entonces, hasta hoy, la altura de la cadena de bloques de bitcoin alcanza 501509, echemos un vistazo a su encabezado:

$ bitcoin-cli getblockheader 0000000000000000006c5532f4fd9ee03e07f94df165c556b89c495e97680147
{
  ...
  "height": 501509,
  ...
  "bits": "18009645",
  "difficulty": 1873105475221.611,
  ...
}

Los bits del bloque 501509 = 0x18009645, es el formato compacto de entero de 256 bits, su formato de 256 bits es:

[0x00000000,0x00000000,0x009645,{0x00..0x00}]
                                {0x00..0x00} at above has 21 bytes 0x00.
that is  0x009645 * (256 ^ 21) 
The genesis block's target is  ( 0x00ffff * 256 ^ 26 )which is the difficulty unit '1.0'.
So, the difficulty 
= (0x00ffff * 256 ^ 26)/ (0x009645 * 256 ^ 21)
= 65535/38469 * (256^5)
= 1.703579505575918 * 2^40
= 1873105475221.611

Hasta aquí tienes todo el detalle sobre cómo calcular la 'dificultad'. En algunos casos, también usamos el formato simple 1.7T para decir la dificultad, en el ejemplo anterior:

 (1.703579505575918 * 2^40) = 1.703579505575918T
 1T = 2^40 = 1024^4
1d es 29 en diciembre (no 26). SHS es SHA
gracias @BorisIvanov, el error tipográfico SHSse ha solucionado. Pero 1d, de hecho, significa 26 bytes de cola cero en lugar de 29, lea el detalle del ejemplo que se muestra arriba.
Ah sí. significante

Me gustaría dar mis 2 centavos aquí, explicando la relación entre la probabilidad de minar un bloque dado el objetivo actual ty la dificultad correspondiente dtal como se calcula en el núcleo de bitcoin.

Entonces, las funciones hash criptográficas están idealizadas por la abstracción aleatoria del oráculo [ https://en.wikipedia.org/wiki/Random_oracle] . Por lo tanto, podemos modelar la salida de la doubleSHA256función hash utilizada en PoW como una variable uniforme en el espacio {0,1}^256, es decir, matrices de 256 bits. Por lo tanto, la probabilidad de que un solo hash hsea un hash válido es:

p = P(h < t) = t /( 2^{256} - 1 )

Por otro lado dse calcula de la siguiente manera, tal como explicó @gary antes solo transformado a decimales:

d = ( (2^{16} - 1) * 2^{8*26} ) / t = ( (2^{16} -1) * 2^{208} ) / t

La implementación está en [ https://github.com/bitcoin/bitcoin/blob/master/src/rpc/blockchain.cpp] , línea 60, función GetDifficulty. En realidad, si alguien puede explicar cómo se asigna exactamente el código a la fórmula anterior, sería útil. Combinando esas dos fórmulas obtenemos:

d = ( (2^{16} -1) * 2^{208} ) / ( p * (2^{256} - 1) ) ~ 2^{-32} / p

Analizando esta última expresión la dificultad es la relación entre la probabilidad de obtener un hash menor que 2^{224}(que es el número decimal más bajo que tiene una representación binaria usando 256 bits comenzando con 32 bits cero) y la probabilidad de obtener un hash válido en base a la objetivo actual t. Esta es una implicación directa de definir, en el bloque génesis, como dificultad 1 la asociada al objetivo hexadecimal 0x1d00ffff , expresado en lo que creo que se llama la forma compacta de 32 bits para números de 256 bits.

Creo que una buena pregunta es por qué se eligió esta forma compacta específica para representar el objetivo.

¡Votado! La forma compacta proporciona los 3 bytes más significativos para el objetivo, en la dificultad mínima, los 3 bytes más significativos son 00ffff.