Wie führt ein Miner Hashing durch?

Ich versuche, meinen Weg durch den Prozess zu gehen, mit dem ein Miner hasht.

Nehmen wir an, die getworkAnfrage gibt ein dataFeld zurück von:

0000000244de6ceba49e1c8d438c0d8c584eefd9c8590545bfdfbf380000025c00000000fb3a091de1b4bbe5dc7acfe6bdacbc3fc3bb09bf1030adef8e2854db1b6ac42f5075c0051a057e08456c6f69000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000

Soweit ich weiß, besteht der erste Schritt darin, den Mittelzustand zu berechnen. Dazu nehmen wir zunächst die erste Hälfte des Datenstrings:

0000000244de6ceba49e1c8d438c0d8c584eefd9c8590545bfdfbf380000025c00000000fb3a091de1b4bbe5dc7acfe6bdacbc3fc3bb09bf1030adef8e2854db

Wir kehren dann die Endianness jedes 32-Bit-Ganzzahl ohne Vorzeichen um (dargestellt als 8 Hexadezimalziffern in der Zeichenfolge), was ergibt:

02000000eb6cde448d1c9ea48c0d8c43d9ef4e58450559c838bfdfbf5c020000000000001d093afbe5bbb4e1e6cf7adc3fbcacbdbf09bbc3efad3010db54288e

Als nächstes wandeln wir dies in sechzehn 32-Bit-Ints ohne Vorzeichen um:

33554432, 3949780548, 2367463076, 2349698115, 3656339032, 1157978568, 952098751, 1543634944, 0, 487144187, 3854284001, 3872357084, 1069329597, 3205086147, 4021104656, 3679725710

Wir geben dieses int-Array dann in die interne Funktion von SHA-256 ein, wobei die zweite Eingabe die acht 32-Bit-Zahlen sind, die auf Seite 13 der SHA-256-Spezifikationen angegeben sind .

Die Ausgabe dieses vorläufigen Hashs ergibt die folgenden acht 32-Bit-Ganzzahlen als unseren Mittelzustand:

3045448562, 361056177, 1940413978, 3803584651, 1661283772, 3478943551, 2906109005, 300125848

Von diesem Punkt an bin ich mir nicht sicher, wie korrekt die Schritte sind. Korrekturen sind sehr willkommen!

Als nächstes sehen wir uns die zweite Hälfte der Eingabezeichenfolge an:

1b6ac42f5075c0051a057e08456c6f69000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000

Wieder einmal kehren wir die Endianness um, da alles eine 8-stellige Hex-Zeichenfolge ist, die 32-Bit-Ints ohne Vorzeichen darstellt:

2fc46a1b05c07550087e051a696f6c45800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280

Nun teilen wir dies in sechzehn 32-Bit-Ints auf:801401371, 96499024, 142476570, 1768909893, 2147483648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 640

Die fünfte Zahl ( 21474836481) sollte laut dieser Beschreibung die Nonce sein .

(Warum ist diese Nonce nicht Null?)

Beginnend bei der angegebenen Nonce verwenden wir nun die SHA-256-Funktion, um die sechzehn 32-Bit-Ints aus der zweiten Hälfte der Daten zu hashen, wobei wir den Mittelzustand als die anderen acht Int-Eingaben verwenden. Dies ergibt:3993002029, 2278477219, 3977673643, 191934125, 2075691039, 4115259165, 601235791, 2598049038

Was verwende ich nun als Eingaben für die zweite Hash-Funktion im "Double-Hash"? Oder zählte die Berechnung des Midstates als erste Hash-Berechnung?

Und wenn die Nonce überläuft, sollte ich eine weitere getworkAnfrage stellen oder warten, bis ich die Nonce im Bereich von [0, original_nonce_value) überprüft habe? (Angenommen, meine Analyse, dass die angegebene Nonce 21474836481korrekt ist?)

Schließlich, wenn unser targetWert aus der getworkAnfrage ist:

ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000

Wir müssen die Endianness dieses Werts ändern, was Folgendes ergibt:

00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Und dann konvertieren wir dies in acht 32-Bit-Ints ohne Vorzeichen, was ergibt:0, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295

Und ich glaube, nach dem zweiten SHA-256-Hash sollten wir acht 32-Bit-Ints ohne Vorzeichen haben. Zuletzt sollten wir diese acht Ausgabe-Ints mit unseren acht Ziel-Ints vergleichen (von links nach rechts im Array, also Output[0] mit der 0 des Ziels vergleichen, dann Output[1] mit 4294967295 usw.) und ob unsere Ausgabe so ist kleiner als das Ziel, konvertieren wir unsere acht int-Werte in Hex-Strings, ändern die Endianness, verketten sie in der gleichen Reihenfolge (der Hex-String von output[0] ist der erste Satz von acht Zeichen) und senden ihn zurück an den Pool Server in einer getworkFertigstellung POST.

Wie viel davon ist richtig, und wo interpretiere ich das Protokoll falsch?

Jede Hilfe ist willkommen; Vielen Dank!

Danke für die Bearbeitung! Ich habe mich gefragt, wie man diese Formatierung macht ...
Der folgende Thread scheint eine vollständigere Antwort zu sein: stackoverflow.com/questions/9245235/…

Antworten (1)

Diese Frage ist kompliziert, aber ich werde sehen, was ich tun kann, um sie zu beantworten. Außerdem werde ich nicht versuchen, das Problem der Endianness anzugehen, da es mir im Fall von Bitcoin Kopfschmerzen bereitet ...

Lassen Sie uns zunächst sehen, was wir in einem Block-Header haben, der uns von getwork gegeben wurde. Nehmen wir als Beispiel den Genesis-Block .

01000000 - version
0000000000000000000000000000000000000000000000000000000000000000 - prev block
3BA3EDFD7A7B12B27AC72C3E67768F617FC81BC3888A51323A9FB8AA4B1E5E4A - merkle root
29AB5F49 - timestamp
FFFF001D - bits
00000000 - nonce (it will be set to 1DAC2B7C later)
00 - number of transactions (always 0, this is the block header)
0000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000 - padding

Um den Midstate zu berechnen, teilen wir den Header in zwei Teile auf, die vom SHA-Algorithmus akzeptiert werden (jeweils 64 Bytes):

0100000000000000000000000000000000000000000000000000000000000000000000003BA3EDFD7A7B12B27AC72C3E67768F617FC81BC3888A51323A9FB8AA
4B1E5E4A29AB5F49FFFF001D00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000

Wir laden den ersten Teil in den SHA-Algorithmus. Wir speichern diesen Zustand für die spätere Verwendung (Mittelzustand) (Entschuldigung für das Fehlen von Beispielen, aber ich habe meine Hash-Algorithmen nicht zur Hand). Dann laden wir den zweiten Teil in den SHA-Algorithmus. Wir lesen die Ausgabe, dies ist der erste Hash. Wir nehmen diesen Ausgang, schließen ihn wieder an einen neuen Eingang an und erhalten sein Ergebnis. Das ist der zweite Hash. Angenommen, wir haben die richtige Nonce (in unserem Fall - 1DAC2B7C), sollte unser Ergebnis ungefähr so ​​​​aussehen:

000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

und vergleichen Sie es mit unserem Ziel:

00000000ffff0000000000000000000000000000000000000000000000000000

Als Zahl genommen, was ist größer? Das Ziel. Das bedeutet, dass wir die korrekte Nonce haben und unseren vollständigen Header als Ergebnis übermitteln können. Profitieren!

Soweit ich weiß, haben Sie versucht, die resultierenden Zahlen zu sehr aufzuschlüsseln, anstatt mit wirklich großen Zahlen zu arbeiten, wie es Bitcoin zu tun scheint. Andererseits ist Endianness auch ein großes Problem mit dem Protokoll und was nicht ...

Ich hoffe, das beantwortet Ihr Problem.