Инверсия бита заголовка блока майнинга

Пытаясь понять процесс майнинга и проверяя python..... я озадачен тем, какая информация из/в пул находится в Little Endian, какую нужно реверсировать при построении заголовка блока + хэширование, а какую нет. ??

Например... Давайте начнем с подключения к solo.ckpool.org ответ на майнинг.authorize дает мне..... 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]}

Основываясь на ответе пула... я могу построить базу монет, просто

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

и то же самое включить в дерево merkle с хешированием, чтобы получить merkle_root. Я не уверен, нужно ли мне поменять местами биты здесь?

Но чтобы построить заголовок блока... должен ли я это сделать...

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

или это..

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

Может кто-нибудь опубликовать пример недавнего ЗАГОЛОВКА БЛОКА... я думаю, что я делаю что-то не так!

я сравниваю этот хэш

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

с целью "000000000001310b00000000000000000000000000000000000000000000000000"

Ответы (2)

Давайте посмотрим на этот блок, потому что он имеет только одну транзакцию (coinbase): 0000000000000000000eb2d0ed97a7b2cff7f1408417dca83908004beb6fd9b95

Давайте возьмем необработанные шестнадцатеричные данные:

0000002053f7ebc735f54ac8d4ebcc1eeb3d3bdea89603bdd27431000000000000000000ff964ec70ea5a5356a04fdb044ca6c59ffda2dd6be02c63d9ea58fb6d46e01991a22bb590b310118f6df26f801010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff3103b46707244d696e656420627920416e74506f6f6c6b2f4542312f4144362f4e59412f332059bb221ab8080000615c0300ffffffff02807c814a000000001976a914660371326d3a2e064c278b20107a65dad847e8a988ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000

Заголовок блока состоит из 6 элементов:

  1. Сначала у нас есть версия (4 байта) 00000020, которая представляет собой перевернутые байты 0x20000000.
  2. Затем у нас есть хэш предыдущего блока (32 байта), также в обратном порядке байтов, 53f7ebc735f54ac8d4ebcc1eeb3d3bdea89603bdd27431000000000000000000то есть этот блок .
  3. Далее у нас есть корень меркла транзакций (32 байта) в обратном порядке байтов, ff964ec70ea5a5356a04fdb044ca6c59ffda2dd6be02c63d9ea58fb6d46e0199. Поскольку существует только одна транзакция, транзакция coinbase, корень merkle просто равен txid этой транзакции .
  4. Затем у нас есть отметка времени (4 байта) в обратном порядке байтов, 1a22bb59то есть 0x59bb221aв шестнадцатеричном или 1505436186десятичном формате.
  5. Затем у нас есть перевернутые байты поля «биты» (4 байта), 0b310118которые0x1801310b
  6. И затем одноразовый номер (4 байта), f6df26f8который0xf826dff6

Затем после заголовка у нас есть байт, 01который означает, что за ним следует одна транзакция. Эта транзакция — просто закодированная транзакция coinbase, как вы можете видеть здесь .

Разумеется, хешировать нужно только заголовок блока, а не транзакции.

Это круто !! Спасибо... Теперь все очень ясно... кроме корня Меркла. binascii.hexlify(hashlib.sha256(hashlib.sha256(binascii.unhexlify('0100000000010100000000..........4e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000')).digest()).digest()) This gives me "cb7ac0ad06517d90cd5a936aebb8b32205fefec268ac6970c04b528313f3ce26" and not "99016ed4b68fa59e3dc602bed62ddaff596cca44b0fd046a35a5a50ec74e96ff"
Это транзакция-свидетель, поэтому вам нужно немного изменить ее, прежде чем хешировать, чтобы найти txid (в настоящее время вы нашли wtxid). Но это отдельный вопрос, не забудьте принять мой ответ на ваш вопрос, если он вас удовлетворит, кстати :)
Да, ваш ответ идеален, то, что я искал.
Таким образом, все в представленном заголовке блока перевернуто по байтам фактического значения? Другими словами, если вы хотите узнать версию из заголовка блока, переверните ее на байт, и вы получите значение. Этот дизайн излишне сбивает с толку.

Ответ MeshCollider потрясающий. Я хочу добавить заметку. Почему предыдущий хэш заголовка блока и хэш корня Меркла должны переворачивать байты? А почему другим полям это не нужно?

На самом деле, если вам нужен хэш любой транзакции, вам нужно удвоить хэш sha256. Итак, дело в том, что если для некоторых данных требуется дайджест sha256, а дайджест хранится на компьютере с прямым порядком байтов, в некоторых случаях необходимо преобразовать в big int в обратном порядке байты. И вы получаете хэш двойного sha256 в биткойнах. В некоторых случаях необходим обратный порядок байтов. например, big-int(block-header-hash) < Mining Target?

Если вам нужен хэш транзакции, результат тоже будет с обратным порядком байтов.

Например, необработанный шестнадцатеричный код транзакции:

0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000

затем вам нужен хэш транзакции:

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

169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f4это хеш с прямым порядком байтов, в биткойне все хэши с двойным sha256 имеют прямой порядок байтов.

На самом деле идентификатором этой транзакции является хэш с обратным порядком байтов: f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.

Когда вам нужно найти некоторую информацию об этой транзакции, вам нужно ввести хэш с обратным порядком байтов: https://www.blockchain.com/btc/tx/f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16 .

и хэш с прямым порядком байтов вы ничего не можете найти.

Ты понял?

  • предыдущий хэш заголовка блока должен инвертировать байты, потому что биткойн нуждается в обратном порядке.
  • Текущий хэш заголовка блока должен переворачивать байты, потому что биткойну нужен обратный порядок байтов.
  • хеш транзакции должен переворачивать байты, потому что биткойну нужен обратный порядок байтов.
  • Корневой хэш merkle должен переворачивать байты, потому что биткойну нужен обратный порядок байтов.

МОЙ БОГ! Зачем? Я обнаружил, что разработчик ядра биткойнов не знал причину.

Из-за исторической случайности хэши транзакций и блоков, используемые ядром биткойна, перевернуты байтами. Я не совсем уверен, почему. Может быть что-то вроде использования openssl bignum для хранения хэшей или чего-то в этом роде, а затем вывода их в виде числа.

ссылка: http://learnmeabitcoin.com/glossary/txid

Не было бы необходимости проверять большие/малые порядковые номера и выполнять реверсирование байтов, если бы все данные хранились в виде байтов, а не некоторые как uint32. Например, getblocktemplate предоставляет поле битов в виде шестнадцатеричной строки, они могли бы сделать то же самое для версии, curtime/ntime. Этому дизайну не хватает простоты, и он излишне закручен. Это глупо. Не могу поверить, что биткойн чего-то стоит.