Der folgende Text wurde aus der Bitcoin Developer Reference auf bitcoin.org kopiert:
Wenn ein Block drei oder mehr Transaktionen hat, werden dazwischenliegende Merkle-Tree-Zeilen gebildet. Die TXIDs werden geordnet und gepaart, beginnend mit der TXID der Coinbase-Transaktion. Jedes Paar wird als 64 Rohbytes verkettet und SHA256(SHA256()) gehasht, um eine zweite Reihe von Hashes zu bilden. Wenn es eine ungerade (nicht gerade) Anzahl von TXIDs gibt, wird die letzte TXID mit einer Kopie von sich selbst verkettet und gehasht. Wenn mehr als zwei Hashes in der zweiten Zeile vorhanden sind, wird der Vorgang wiederholt, um eine dritte Zeile zu erstellen (und, falls erforderlich, weiter wiederholt, um zusätzliche Zeilen zu erstellen). Sobald eine Zeile mit nur zwei Hashes erhalten wurde, werden diese Hashes verkettet und gehasht, um die Merkle-Wurzel zu erzeugen.
Ich versuche, diese Logik zu verwenden, um die Merkle-Wurzel für Block # 100000 neu zu erstellen. Es gibt 4 Transaktionen in diesem Block. Ich beginne damit, den Transaktions-Hash für die Coinbase-Transaktion und die folgende nacheinander in einen Sha256-Rechner zu kopieren, um den Hash zu erhalten. Dann hash ich diesen Hash noch einmal: Sha256(sha256()). Ich wiederhole diesen Vorgang noch einmal mit den zweiten beiden Transaktionen im Block. Abschließend wiederhole ich den Vorgang erneut mit den resultierenden Hashes, um die Merkle-Root zu erhalten. Leider knüpft dies nicht an die Merkle Root an, die im Blockheader bei blockchain.info angezeigt wird.
Kann jemand erklären, wo ich falsch gelaufen bin?
Vielen Dank.
Sie müssen die Transaktions-IDs byte-tauschen, bevor Sie sie hashen, jeden untergeordneten Knoten hashen und den endgültigen gehashten Hex-Wert byte-tauschen.
Transaktion 1 (Coibase-Transaktion) 8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87
Zum Byteswap können Sie Folgendes verwenden:
a = "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87" "".join(reversed([a[i:i+2] for i in range(0, len(a), 2)])) @Greg Hewgill
Vertauschte Bytes = 876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148c
Transaktion 2 fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4 Bytetausch = c40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b5231895b52292d02d4031895b52292d02d4031895b52d
Sie möchten die Byte-ausgetauschten Transaktionswerte von 1 und 2 verketten. Transaktion 1 geht zuerst.
876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148cc40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff
Um diese Hex-Zeichenfolge zu hashen, können Sie den folgenden Code verwenden, der Python in Ihrem Befehlsterminal ausführt:
Hashlib importieren
transaction12_hex = "876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148cc40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff"
transaktion12_bin = transaktion12_hex.decode('hex')
hash = hashlib.sha256(hashlib.sha256(transaction12_bin).digest()).digest()
hash.encode('hex_codec')
15b88c5107195bf09eb9da89b83d95b3d070079a3c5c5d3d17d0dcd873fbdacc
Transaktion 3 6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4 Byteswapped = c46e239ab7d28e2c019b6d66ad8fae98a56ef1f21aeecb94d1b1718186f05963
Transaktion 4 e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d Byteswapped = 1d0cb83721529a062d9675b98d6e5c587e4a770fc84ed00abc5a5de6e0458
Wenn Sie dasselbe für Transaktion 3 und 4 tun, lautet der endgültige Hash: 49aef42d78e3e9999c9e6ec9e1dddd6cb880bf3b076a03be1318ca789089308e
Unser letzter Schritt besteht darin, den endgültigen Hash-Wert von 1 & 2 und 3 & 4 zu kombinieren und ihn doppelt zu hashen und per Byte auszutauschen.
Unsere Antwort ist f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766 die Merkle Root.
876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148cc40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff
doppelt gehashtIch denke, die Fehler sind das korrekte Erstellen des Hashs, und ich hatte das gleiche Problem, jetzt möchte ich meine Erfahrung teilen.
Zum Erstellen des Hashs habe ich diese gute Bibliothek c++/java verwendet .
Ich werde versuchen, mich mit einfachem Code zu erklären.
Dies ist der Transaktions-Hash des Genesis-Blocks
string versionRawTransaction = "01000000";
string numbarTransactionInput = "01";
string output = "0000000000000000000000000000000000000000000000000000000000000000ffffffff";
string scriptLenght = "4d";
string scriptSing = "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73";
string sequences = "ffffffff";
string numbarTransactionOutput = "01";
string cAmmount = "00f2052a01000000";
string publicKeyScriptLenght = "43";
string publicKeyScript = "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac";
string lockTime = "00000000";
Der vollständige Hash ist01000000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF4D04FFFF001D0104455468652054696D65732030332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F66207365636F6E64206261696C6F757420666F722062616E6B73FFFFFFFF0100F2052A01000000434104678AFDB0FE5548271967F1A67130B7105CD6A828E03909A67962E0EA1F61DEB649F6BC3F4CEF38C4F35504E51EC112DE5C384DF7BA0B8D578A4C702B6BF11D5FAC00000000
Wenn Sie den Hash berechnen. kann ich diesen hash bekommen4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
bis hierher ist alles einfach
Der Wert Bitcoin wird in die Big-Endian-Konvention konvertiert, aber wenn der Hash berechnet wird, wurde der einzelne Typ in Little Endian konvertiert.
Während der Realform-Transaktion kann ich diese Passage ausführen
Ich habe C++ verwendet und diese Operation haben sie dank der Bitcoin-Bibliotheken geschafft, aber wenn Sie Python verwendet haben, können Sie dieses Beispiel zur Berechnung des Hashs verwenden.
Um den Baum zu erstellen, sind die Schritte einfach, stellen Sie nur sicher, dass Sie den Hash korrekt berechnen, daher schlage ich vor, dass Sie zuerst die Hash-Funktionen und dann die Baumkonstruktion testen, um unnötigen Zeitverlust durch triviale Fehler zu vermeiden
ps: Wenn Sie das Transaktionsskript im Rohformat haben (wenn Sie die Informationen aus den blk-Dateien lesen), sind sie bereits in Little-Endian konvertiert und sollten daher nicht weiter konvertiert werden. (hängt von Ihrem Deserialisierungsprozess ab)
Pieter Wuille
meshcollider
Adam Smith
meshcollider