sha256 - (bitcoin) Calcule el hash desde la función de red: ¿cómo hacerlo?
sha-256 algorithm (3)
cuando llamo a getwork en mi servidor de bitcoind, obtengo lo siguiente:
./bitcoind getwork
{
"midstate" : "695d56ae173bbd0fd5f51d8f7753438b940b7cdd61eb62039036acd1af5e51e3",
"data" : "000000013d9dcbbc2d120137c5b1cb1da96bd45b249fd1014ae2c2b400001511000000009726fba001940ebb5c04adc4450bdc0c20b50db44951d9ca22fc5e75d51d501f4deec2711a1d932f00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000",
"hash1" : "00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000010000",
"target" : "00000000000000000000000000000000000000000000002f931d000000000000"
}
Este protocolo no parece estar documentado. ¿Cómo calculo el hash a partir de estos datos? Creo que esta información está en little endian. Entonces, ¿el primer paso es convertir todo a big endian? Una vez hecho esto, calculo el sha256 de los datos. Los datos se pueden dividir en dos chuncks de 64 bytes cada uno. El hash del primer mandril está dado por midstate y, por lo tanto, no tiene que calcularse.
Por lo tanto, debo marcar el chunck # 2 con sha256, usando el estado medio como los valores de hash iniciales. Una vez hecho esto, termino con un hash del fragmento 2, que es de 32 bytes. Calculo el hash de este fragmento una vez más para obtener un hash final.
Entonces, ¿convierto todo a little endian y envío el trabajo?
¿Para qué se utiliza hash1?
El cálculo de hash se documenta en el algoritmo de hashing de bloques . Comience allí por los conceptos básicos relativamente simples. Las estructuras de datos básicas están documentadas en la Especificación de protocolo - Bitcoin Wiki . Tenga en cuenta que la definición de protocolo (y la definición de trabajo) asume más o menos que los hashes SHA-256 son valores little-endian de 256 bits, en lugar de big-endian como lo indica la norma. Ver también
Getwork es más complicado y se encuentra con una confusión de pedidos de endian / byte más seria.
En primer lugar, tenga en cuenta que la API de red está optimizada para acelerar los pasos iniciales de la minería. Los valores de estado medio y hash1 son para estas optimizaciones de rendimiento y pueden ignorarse. Basta con mirar los "datos". Y cuando se usa una implementación estándar de sha256, solo los primeros 80 bytes (160 caracteres hexadecimales) de los "datos" están en hash.
Desafortunadamente, los datos JSON presentados en la estructura de datos de red tienen características endianas diferentes a las que se necesitan para el hashing en el ejemplo de bloque anterior.
Todos dicen que deben ir a la fuente de la respuesta, pero la fuente de C ++ puede ser grande y confusa. Una alternativa simple es el código poold.py . Hay una discusión de esto aquí: Nuevo grupo de minería para pruebas . Solo necesita mirar las primeras líneas de la rutina "checkwork", y las funciones "bufreverse" y "bytereverse", para obtener el orden de bytes correcto. Al final, es solo una cuestión de hacer una inversión de los bytes en cada segmento de 32 bits de los datos. Sí, muy extraño. Pero los problemas endianos son difíciles y pueden terminar de esa manera ...
Se puede encontrar otra información útil sobre la forma en que funciona "getwork" en las discusiones en:
Tenga en cuenta que encontrar la señal de ruido en el foro de Bitcoin original se está volviendo muy difícil, y actualmente hay una propuesta de Area51 para un sitio StackExchange para Bitcoin y Crypto Currency en general . ¡Ven y únete a nosotros!
Hablando francamente, el algoritmo de hash de bloques de Bitcoin no está descrito oficialmente por ninguna fuente.
"El cálculo de hash se documenta en el algoritmo de hash del bloque".
El cálculo de hash se "describe" en el algoritmo de hashing de bloques.
es.bitcoin.it/wiki/Block_hashing_algorithm
Por cierto, el código de ejemplo en PHP viene con un error (error tipográfico), el código de ejemplo en Python genera errores cuando se ejecuta con Python3.3 para Windows XP 32 (falta soporte para string.decode)
Suena bien, hay un script en javascript que calcula el hash pero no lo entiendo completamente, así que no sé, tal vez lo entiendas mejor si lo miras.
this.tryHash = function(midstate, half, data, hash1, target, nonce){
data[3] = nonce;
this.sha.reset();
var h0 = this.sha.update(midstate, data).state; // compute first hash
for (var i = 0; i < 8; i++) hash1[i] = h0[i]; // place it in the h1 holder
this.sha.reset(); // reset to initial state
var h = this.sha.update(hash1).state; // compute final hash
if (h[7] == 0) {
var ret = [];
for (var i = 0; i < half.length; i++)
ret.push(half[i]);
for (var i = 0; i < data.length; i++)
ret.push(data[i]);
return ret;
} else return null;
};