Cálculo de la dificultad y verificación de un hash como solución

Tengo un esquema en este momento en el que las personas se comprometen con un contrato a una solución a un problema similar al protocolo de prueba de trabajo de Bitcoin. Este es el flujo básico... el contrato calcula un hash de inicialización y las personas están tratando de generarlo (fuera de la cadena usando su propio equipo) mientras incrementan un nonce hasta que encuentran una solución dentro de un cierto subconjunto del rango de 256 bits (0 a 2^256 - 1). Estoy tratando de averiguar (1) qué dificultad debería haber si quiero que alguien con un poder de hash de 1 MH/s tenga un 95% de posibilidades de resolver dentro de una semana y (2) la forma correcta de verificar si el enviado solución satisface el requisito de estar dentro del rango preespecificado.

Para (1) así es como estoy calculando la dificultad D:

1 - ((D - 1) / D) ^ H = 0.95

Entonces, se puede pensar que D representa el número de lados de un dado. El primer "1" representa el 100 % de las posibilidades, el "((D - 1) / D)" representa el subconjunto de resultados que son incorrectos y la H representa el número de veces que se lanzan los dados. Por ejemplo, si quiero calcular las probabilidades de que saque un 1 en 4 tiradas, tengo 6/6 - (5/6)^4 = 671/1296 = ~51,7 %.

Estoy tratando de extrapolar esto a hashing. En ese caso, D representa en cuántas partes del pastel se divide el rango de 2^256 y H representa la cantidad de hash realizados. 1 semana @ 1MH/s = 604,8 gigahashes. Resolviendo para D obtengo ~201,887,199,781 pedazos de pastel. Mi primera pregunta es ¿tienen sentido estos cálculos? ¿Le tomará a alguien con 1 MH/s alrededor de una semana encontrar una solución dentro de una rebanada de pastel?

Para (2) estoy escribiendo un contrato ETH que necesita calcular si una solución enviada se encuentra dentro del rango especificado dada esa dificultad. Así es como estoy calculando eso:

if (uint(sha3(finalSeed, _nonce)) <  2 ** 256 / difficulty )

Así que tomo el rango completo de 2^256 y lo divido por la cantidad de sectores del pastel para llegar a cuántos números caben dentro de un solo segmento. Entonces, el rango en el que debe estar la solución es cero al tamaño de una rebanada de pastel menos 1. ¿Tiene esto sentido? ¿Es necesario convertir a uint para realizar esto? ¿Estoy desperdiciando una tonelada de recursos con el cálculo "2 ** 256 / dificultad"? ¿Hay una manera más fácil de lograr todo esto?

Cualquier ayuda sería muy apreciada.

En lugar de tratar de calcular un valor fijo, considere usar un sistema adaptativo, en el que mida el tiempo necesario para encontrar una solución y ajuste la dificultad en consecuencia. Puede que también le resulte más fácil razonar sobre maxvalueel valor hash válido más grande que sobre la dificultad.

Respuestas (1)

Tu cálculo es correcto.

Digamos que X=1el evento un hash es "válido", y X=0si no es válido (X se llama "variable aleatoria de Bernoulli" Distribución de Bernoulli ). Ahora tenemos P(X=1) = D/2^256donde D es el número de soluciones válidas (y P(X=0) = 1 - D/2^256).

Digamos que puedes hacer hashes H por semana. Entonces tenemos X_1, X_2,... X_Hque dice si el hash k-ism era válido o no. Si decimos Y = X_1 + X_2 + ..+ X_H. Quiere estimar D tal que P(Y>=1) >= 0.95.

Aquí podemos usar el truco de que P(Y>=1) = 1 - P(Y=0). Tener al menos un hash válido es lo contrario de no tener ningún hash válido. Ahora bien, ya que la validez de cada hash es independiente de los demás P(Y=0) = P(X_1=0)...P(X_H=0) = (1 - D/2^256)^H.

Poniendo todo esto junto tenemos eso P(Y>=1) = 1 - P(Y=0) = 1 - (1 - D/2^256)^H >= 0.95.

Entonces tenemos 0.05 >= (1 - D/2^256)^H ==> (0.05)^(1/H) >= 1-D/2^256 ==> D/2^256 = 1 - (0.05)^(1/H). Resolviendo H = 604800000000obtuve D>=573548326756918809146437109998407756092224692540954418775767121920. Ahora tu dificultad será la 2^256 / D <= 201,887,240,944.5476que se acerque bastante a tus cálculos.

¡Gracias por tu pregunta! Fue una muy buena práctica para mis exámenes de Teoría de la probabilidad.