Grund für das Hashing der Nonce in prevBlockHash?

Ich verstehe die Rolle, die die Nonce im Block-Header spielt, um einen Hash für einen gültigen Arbeitsnachweis zu berechnen.

Aber was ich frage, ist: Berücksichtigen wir die Nonce in der prevBlockHashBerechnung des vorherigen Blocks, weil sie ja bereits im Blockkopf steht (für die Proof-of-Work-Berechnung) und es dumm wäre, eine calcPrevBlockHashFunktion zu schreiben, die berechnet den Header des vorherigen Blocks durch Ignorieren der Nonce?

Oder gibt es eine bestimmte Sicherheitseigenschaft oder Zusicherung, die wir erhalten, wenn wir die Nonce in die prevBlockHashBerechnung des nachfolgenden Blocks einbeziehen?

Sie könnten beispielsweise argumentieren, dass wir den Zeitstempel hashen, weil wir die Zeit erfassen möchten, zu der der Block generiert wurde. Siehe Antwort hier: Warum die Zeitstempelkomponente des Blockheaders? Ich denke, Sie können dasselbe für das Nonce-Feld argumentieren.

Aber ich behaupte, dass wir die Nonce immer noch im Block-Header haben könnten und sie nicht während der prevBlockHashBerechnung des nachfolgenden Blocks hashen, und die Dinge würden immer noch funktionieren. Sie wären immer noch (a) in der Lage, diesen Block zu validieren, und (b) nicht in der Lage, mit den Transaktionen im Block herumzuspielen, da dies das hashMerkeRootFeld ändern und den Block somit ungültig machen würde.

Es ist nicht. Ich verstehe, warum die Nonce geändert werden muss, ich frage mich, warum sie in den Block-Header aufgenommen und somit gehasht werden muss.
Du musst die Nonce noch irgendwie in den Block-Hash einbauen, was änderst du sonst, um einen guten Proof-of-Work zu finden? Und in diesem Fall muss jeder, der versucht, den Block zu validieren, die Nonce erhalten oder eine Menge zusätzlicher Arbeit leisten, um ihn zu rekonstruieren. Wenn Sie es nicht in den Block stecken, müssen Sie es auf andere Weise verteilen.
@NateEldredge: 1. "Du musst die Nonce trotzdem irgendwie in den Block-Hash einbauen, was änderst du sonst, um einen guten Proof-of-Work zu finden?" Die Nonce natürlich. Warum müssen Sie es jedoch in den Block-Hash aufnehmen? 2. "Wenn Sie es nicht in den Block stecken, müssen Sie es auf andere Weise verteilen." Aber ich habe nie vorgeschlagen, die Nonce nicht in den Block aufzunehmen. Meine Frage hat damit zu tun, warum wir es in den Blockheader aufnehmen . Gibt es einen Grund, warum es gehasht werden muss, oder ist es eine "nur weil" -Sache.
@Kostas: Sie haben also einen Blockheader. Sie berechnen den Hash davon. Das Ergebnis hat nicht genügend führende Nullen, um ein gültiger Proof-of-Work zu sein. Was jetzt? Sie können mit dem Nonce machen, was Sie wollen, aber es ist irrelevant: Wenn es nicht im Header ist, ändern sich die Daten, die Sie hashen, nicht, und wenn Sie es erneut hashen, erhalten Sie nur das gleiche Nicht- ausreichender Hash-Wert. Die Hash-Funktion ist schließlich eine Funktion ; Wenn man ihm dieselbe Eingabe gibt, erhält man immer dieselbe Ausgabe.
@NateEldredge: Wir sprechen über verschiedene Hashing-Prozesse. Es gibt den Prozess, bei dem Sie versuchen, einen Block-Header-Hash zu finden, der niedriger als das Ziel ist. Es macht durchaus Sinn, hier die Nonce zu betrachten. (Tatsächlich ist die Nonce ein Schlüsselelement in dieser Hash-Berechnung.) Darauf beziehen Sie sich, und wir stimmen zu. Ich beziehe mich jedoch auf den anderen Hashing-Prozess, der auftritt, wenn ich Block n+1 erstellen möchte, und auf Block n durch seine verweisen möchte prevBlockHash.
Was ich dann frage, ist: Gibt es eine bestimmte Eigenschaft, die vorschreibt, warum wir die Nonce in diesen prevBlockHashHash aufnehmen müssen? Oder ist es so etwas wie: "Nun, es ist Teil des Headers, weil wir es dort brauchen, um den Proof-of-Work zu berechnen. Wir müssen es eigentlich nicht einbeziehen, wenn wir das prevBlockHashDing machen (bekommen wir nicht keine zusätzlichen Garantien), aber es wäre übertrieben, eine calcPrevBlockHashFunktion zu programmieren, die das Feld ignoriert nonce, also schließen wir es einfach auch in unsere prevBlockHashBerechnung ein."
@Kostas: Ok, jetzt glaube ich verstehe ich deine Frage. So wie es aussieht, sind die beiden Prozesse ein und dasselbe! Ich nehme an, im Prinzip könnten Sie sie trennen und die Nonce von der letzteren ausschließen, aber es bringt nichts und fügt unnötige Komplexität hinzu.
@NateEldredge: Richtig. hashBlockHeader()verwenden Sie für die Proof-of-Work-Berechnung und die prevBlockHashBerechnung jetzt. (Hinweis: erfundene Funktionsnamen.) Ich frage mich nur: Wenn Sie prevBlockHashmit einer calcPrevBlockHash()Funktion rechnen würden, die das Nonce-Feld ignoriert, würde das irgendetwas kaputt machen? Würden Sie alle Sicherheitseigenschaften verlieren, die Sie derzeit haben würden?

Antworten (2)

Nach den Kommentaren denke ich, dass Ihre Frage auf Folgendes hinausläuft:

Könnten wir für das prevBlockHashFeld eines Block-Headers bei der Berechnung des Hashs des Headers des vorherigen Blocks dessen Nonce-Wert ausschließen?

Ich kann mir keine praktischen oder Sicherheitsprobleme vorstellen, die sich daraus ergeben würden. Ein Hash von allem außer der Nonce würde immer noch alle wichtigen Daten aus dem Block zertifizieren, einschließlich der darin enthaltenen Transaktionen, und seine eigenen prevBlockHash, die alle vorherigen Blöcke als Referenz enthalten.

Es hätte jedoch keinen Sinn, dies zu tun. Wir müssen bereits den Hash des vorherigen Headers einschließlich der Nonce berechnen, um zu überprüfen, ob es sich um einen Proof-of-Work der entsprechenden Schwierigkeit handelt. Danach können wir diesen Wert genauso gut als "Block-ID" für alle Zwecke verwenden, einschließlich der prevBlockHash. Die Berechnung eines anderen Hash-Werts, mit Ausnahme der Nonce, würde mehr Code, mehr Entwicklerzeit und mehr Rechenzeit erfordern; würde Potenzial für Fehler im Hash-Code selbst hinzufügen; und würde zu einer Menge potenzieller Verwirrung führen, wenn Leute versuchen, nachzuverfolgen, welcher Teil des Codes welchen Hash verwendet. All dies im Austausch für keinerlei Vorteil, soweit ich das beurteilen kann.

Ich denke auch in die gleiche Richtung, wollte nur bestätigen, dass ich nichts übersehe. Danke, dass Sie mir geholfen haben, die Frage zu klären.
Danke, mit Ihrer Antwort habe ich endlich verstanden, worum es bei der Frage ging. :)

Ja, du hast Recht. Ohne die Nonce könnten wir immer noch gültige Blöcke generieren. Um jedoch einen anderen Hash zu erhalten, müssen wir die Eingabe für den Hash ändern. Die Eingabe für den Hash ist der Blockheader.

Wenn es keine Nonce gäbe, müssten wir für jeden Versuch etwas anderes am Blockheader ändern. Das würde nur den Zeitstempel oder die Merkle-Wurzel übrig lassen. Andere Header-Elemente sind festgelegt.
Der Zeitstempel ist eklig, weil wir möchten, dass er die tatsächliche Zeit anzeigt. Also müssten wir die Merkle-Wurzel ändern.

Die Merkle-Wurzel, die durch Hashing aller Transaktionen im Merkle-Baum, in dem sie aufgelistet sind, berechnet wird. Wenn wir zB die Coinbase oder die Reihenfolge der Transaktionen im Baum ändern, könnten wir auch eine andere Kombination zum Ausprobieren gewinnen. Aber dazu müssten wir die Merkle-Wurzel neu berechnen.

Stattdessen fügen wir direkt eine Nonce in den Header ein, die es uns ermöglicht, denselben Blockkandidaten für eine Reihe verschiedener Hashing-Versuche zu verwenden.

Daher wird die Nonce verwendet, um Zufälligkeit in den Blockheader einzuführen . Deshalb ist es

a) muss geändert werden und
b) muss im Blockheader stehen. ;)

Dies beantwortet meine Frage nicht, aber es ist nicht deine Schuld :) Ich habe die Frage umgeschrieben, um meinen Standpunkt klarer zu machen. Ich verstehe die Verwendung der Nonce. Ich frage mich, warum es bei der Berechnung des prevBlockHash(im nächsten Block) berücksichtigt werden muss.
Ich habe gerade Ihre Frage noch einmal gelesen und verstehe nicht, was Sie fragen wollen. Wenn die Nonce nicht Teil dessen wäre, was gehasht wurde, würde sie a) nicht zum Blockhash beitragen, b) könnte willkürlich sein und c) würde keinen Zweck erfüllen. Wenn es sich nicht im gehashten Teil des Blocks befindet, warum sollten Sie es dann überhaupt hinzufügen? Ich habe jedoch bereits in meiner Antwort behandelt, was seine Funktion ist. Also ich bin jetzt echt verwirrt.
Ich denke, was fehlt, ist, dass ich mich auf den prevBlockHashHash beziehe, während Sie sich auf die Proof-of-Work-Hash-Berechnung beziehen. Ich frage nur, ob Dinge kaputt gehen würden (oder ob Sie eine wichtige Sicherheitseigenschaft verlieren würden), wenn Sie eine calcPrevHashFunktion schreiben würden, die das Nonce-Feld ignoriert. Ich habe die Frage noch einmal umgeschrieben, um dies klarer zu machen.