Mining-Block-Header-Bitumkehrung

Während ich versuche, den Mining-Prozess zu verstehen und Python einzuchecken ... bin ich verwirrt darüber, welche Informationen von / zu Pool in Little Endian sind, welche beim Erstellen des Blockheaders + Hashing rückgängig gemacht werden müssen und welche nicht. ??

Zum Beispiel ... Beginnen wir mit der Verbindung zu solo.ckpool.org als Antwort auf mining.authorize gibt mir ..... job_id,prevhash,coinb1,coinb2,merkle_branch,version,nbits,ntime,clean_jobs =

{'id': None, 'method': 'mining.notify', 'params': ['59bc8dfc0000029f',
        '0eba48f47bc0ab4bb35b230849868bf1d79aeb19006eed460000000000000000',
        '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff35039a6807000404d5bc5904fc873d140c',
        '0a636b706f6f6c112f736f6c6f2e636b706f6f6c2e6f72672fffffffff03c4626c4e000000001976a914fc6123f4bfd3a840b4387ab90e9801e98fb17cf888acb1caca00000000001976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac0000000000000000266a24aa21a9edab3b87f3963e55a23f3cea5e4435bf6637328fd5e329bb8fdac7d31c3a01d26200000000',
        ['c251d18568d2cdb07c376d5f3304a2161e3d09d289d1a7e53737199171d73ae6',
         '4f9bcac3ec00fc8238db04b7758a1b673bdf38b93e48159678b60b51517dd563',
         '2aadad2c9c8e6df5c71264524b090cdf89830f12949527f7872c243bc1dc552c',
         '8c5edf39c0d85c9853308eef3ce6f9b71c8d6584ca4120d411bc75987bb2f254',
         '48751c2ae0ddc05f5d504a3d6039e7d5afb3d5f2a6aaac93bd5822e5f8efc328',
         '3e9b5c6b986c2ddc09bf8604eb2bd2a3b49b46f11042c282331a206dadb4296e',
         'c65f502b11b325abc0fac847e8fc5cd300169160e7244b29dd5acc3d0e4b8605',
         'afe7d2287020c4291f609a772adbeafc952a8de0ced38a7346acb6c7103bec6d',
         '0caa545ae63de39d47baea100ea15a18061235d7e1a372fbca88edf9ca5ac797',
         'c5bfff15b4dd64e7faac98f1bba118fb11990e4ff146cb45c7f4af6b93e2ea03',
         'a8805201e8152c1f5835c9aa024752fb34aeb7fa55dd3af0ae6109918f328dbb'],
        '20000000',
        '1801310b',
        '59bcd504',
        True]}

Basierend auf der Pool-Antwort .... kann ich die Coinbase soeben bauen

coinbase = coinb1 + extranonce1 + extranonce2 + coinb2 
coinbase_hash_bin = hashlib.sha256(hashlib.sha256(binascii.unhexlify(coinbase)).digest()).digest()

und dasselbe in den Merkle-Baum mit Hashing aufzunehmen, um merkle_root zu erhalten. Ich bin mir nicht sicher, ob ich hier die Bits umkehren muss?

Aber um einen Blockheader zu bauen ... sollte ich das tun ...

header = version + prevhash + merkle_root + ntime + nbits + nonce

oder dieses..

header = binascii.hexlify(binascii.unhexlify(version)[::-1]).decode('utf-8') + \
prevhash + \
merkle_root + \
binascii.hexlify(binascii.unhexlify(ntime)[::-1]).decode('utf-8') + \
binascii.hexlify(binascii.unhexlify(nbits)[::-1]).decode('utf-8') + \
binascii.hexlify(binascii.unhexlify(nonce)[::-1]).decode('utf-8')

blockheader:000000200eba48f47bc0ab4bb35b230849868bf1d79aeb19006eed460000000000000000fb68998fe1dd4cc22fa1225c2592c27df5331d40d9b33ffce99b26c0aead8ef404d5bc590b3101181e3eef8c

Kann jemand bitte ein Beispiel für einen aktuellen BLOCK HEADER posten ... Ich glaube, ich mache etwas falsch!

Ich vergleiche diesen Hash

hash = hashlib.sha256(hashlib.sha256(binascii.unhexlify(header)).digest()).digest()[::-1]

mit dem Ziel "000000000001310b0000000000000000000000000000000000000000000000"

Antworten (2)

Schauen wir uns diesen Block an, denn er hat nur eine Transaktion (die Coinbase): 000000000000000000eb2d0ed97a7b2cff7f1408417dca83908004beb6fd9b95

Nehmen wir die rohen Hex-Daten:

0000002053f7ebc735f54ac8d4ebcc1eeb3d3bdea89603bdd27431000000000000000000ff964ec70ea5a5356a04fdb044ca6c59ffda2dd6be02c63d9ea58fb6d46e01991a22bb590b310118f6df26f801010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff3103b46707244d696e656420627920416e74506f6f6c6b2f4542312f4144362f4e59412f332059bb221ab8080000615c0300ffffffff02807c814a000000001976a914660371326d3a2e064c278b20107a65dad847e8a988ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000

Es gibt 6 Dinge, die den Block-Header ausmachen:

  1. Zuerst haben wir die Version (4 Bytes), 00000020, die umgekehrte Bytes von sind 0x20000000.
  2. Dann haben wir den vorherigen Block-Hash (32 Bytes), ebenfalls in umgekehrter Byte-Reihenfolge, 53f7ebc735f54ac8d4ebcc1eeb3d3bdea89603bdd27431000000000000000000was dieser Block ist .
  3. Als nächstes haben wir die Merkle-Wurzel der Transaktionen (32 Bytes), in umgekehrter Byte-Reihenfolge, ff964ec70ea5a5356a04fdb044ca6c59ffda2dd6be02c63d9ea58fb6d46e0199. Da es nur eine Transaktion gibt, die Coinbase-Transaktion, ist die Merkle-Wurzel genau gleich dieser Transaktions -txid.
  4. Dann haben wir den Zeitstempel (4 Bytes) in umgekehrter Byte-Reihenfolge, 1a22bb59der 0x59bb221ahexadezimal oder 1505436186dezimal ist.
  5. Dann haben wir die umgekehrten Bytes des 'Bits'-Feldes (4 Bytes), 0b310118das heißt0x1801310b
  6. Und dann die Nonce (4 Bytes), f6df26f8die ist0xf826dff6

Dann haben wir nach dem Header das Byte 01, was bedeutet, dass es eine Transaktion gibt, die folgt. Diese eine Transaktion ist nur die verschlüsselte Coinbase-Transaktion, wie Sie hier sehen können .

Natürlich muss nur der Blockheader gehasht werden, nicht auch die Transaktionen.

Das ist fantastisch !! Danke ... Alles ist jetzt sehr klar ... außer der Merkle-Wurzel. binascii.hexlify(hashlib.sha256(hashlib.sha256(binascii.unhexlify('0100000000010100000000..........4e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000')).digest()).digest()) This gives me "cb7ac0ad06517d90cd5a936aebb8b32205fefec268ac6970c04b528313f3ce26" and not "99016ed4b68fa59e3dc602bed62ddaff596cca44b0fd046a35a5a50ec74e96ff"
Das ist eine Witness-Transaktion, also müssen Sie sie ein wenig modifizieren, bevor Sie sie hashen, um die txid zu finden (Sie haben derzeit die wtxid gefunden). Aber das ist eine separate Frage, denken Sie daran, meine Antwort auf Ihre Frage zu akzeptieren, wenn sie Sie übrigens zufriedenstellt :)
Ja, Ihre Antwort ist perfekt, wonach ich gesucht habe.
Also ist alles im übermittelten Header des Blocks Byte-umgekehrt vom tatsächlichen Wert? Mit anderen Worten, wenn Sie die Version aus dem Blockheader wissen möchten, kehren Sie sie byteweise um, und Sie erhalten den Wert. Dieses Design ist so unnötig verwirrend.

Die Antwort von MeshCollider ist großartig. Ich möchte eine Anmerkung hinzufügen. Warum müssen der vorherige Block-Header-Hash und der Merkle-Root-Hash Bytes umkehren? Und warum brauchen andere Bereiche es nicht?

Eigentlich, wenn Sie den Hash einer Transaktion wollen, müssen Sie den sha256-Hash verdoppeln. Der Punkt ist also: Wenn einige Daten sha256-Digest benötigen und Digest-Speicher im Computer Little-Endian sind, müssen einige Fälle in Big-Endian in Big Int umgewandelt werden, also die Bytes umkehren. Und Sie erhalten den doppelten sha256-Hash in Bitcoin. In einigen Fällen ist das Big-Endian erforderlich. zB big-int(block-header-hash) < Mining Target?

Wenn Sie Transaktionshash benötigen, ist das Ergebnis ebenfalls Big-Endian.

Ein rohes Transaktions-Hex ist beispielsweise:

0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000

dann brauchen Sie Transaktionshash:

>>> import hashlib
>>> d = '0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000'
>>> hashlib.sha256(bytes.fromhex(d)).hexdigest()
'240cf324ec3cf59609733e2a45e1408673306be8dcd4caf3067aa9355a0269e3'
>>> hashlib.sha256(bytes.fromhex('240cf324ec3cf59609733e2a45e1408673306be8dcd4caf3067aa9355a0269e3')).hexdigest()
'169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f4'

169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f4ist Little-Endian-Hash, in Bitcoin ist der gesamte Double-Sha256-Hash Big-Endian.

Tatsächlich ist die Kennung dieser Transaktion ein Big-Endian-Hash: f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.

Wenn Sie Informationen zu dieser Transaktion benötigen, müssen Sie den Big-Endian-Hash eingeben: https://www.blockchain.com/btc/tx/f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16

und Little-Endian-Hash findet man nichts.

Hast du es verstanden?

  • Der vorherige Block-Header-Hash muss Bytes umkehren, da Bitcoin Big-Endian benötigt.
  • Der aktuelle Block-Header-Hash muss Bytes umkehren, da Bitcoin Big-Endian benötigt.
  • Transaktionshash muss Bytes umkehren, da Bitcoin Big-Endian benötigt.
  • Merkle-Root-Hash muss Bytes umkehren, da Bitcoin Big-Endian benötigt.

OMG! Wieso den? Ich fand, dass der Bitcoin-Core-Entwickler den Grund nicht kannte.

Aufgrund eines historischen Unfalls sind die tx- und Block-Hashes, die der Bitcoin-Kern verwendet, Byte-umgekehrt. Ich bin mir nicht ganz sicher warum. Kann so etwas wie die Verwendung von openssl bignum sein, um Hashes oder ähnliches zu speichern und sie dann als Zahl auszugeben.

Referenz: http://learnmeabitcoin.com/glossary/txid

Es wäre nicht erforderlich, Big/Little Endianes zu überprüfen und Bytes umzukehren, wenn alle Daten als Bytes und nicht einige als uint32 gespeichert würden. Zum Beispiel stellt getblocktemplate das bits-Feld als hexadezimale Zeichenfolge bereit, sie hätten dasselbe für Version, curtime/ntime tun können. Diesem Design mangelt es an Einfachheit und es ist unnötigerweise verdreht. Es ist dumm. Ich kann nicht glauben, dass Bitcoin etwas wert ist.