默克爾根 2 程式碼
在嘗試從我從礦池獲得的數據中計算 python 中的默克爾根時……我發現有 2 個不同的程式碼。
程式碼1:
def build_merkle_root(coinbase_hash_bin, merkle_branch): merkle_root = coinbase_hash_bin for h in merkle_branch: merkle_root = hashlib.sha256(hashlib.sha256(merkle_root + binascii.unhexlify(h)).digest()).digest() return binascii.hexlify(merkle_root).decode('utf-8')
這在此處的 shlushpool 層文件和此處的山寨幣 sia 探勘協議中進行了解釋。所以我認為它應該是正確的。 但是下面還有一段程式碼,
程式碼2:
def build_merkle_root(hash_list): if len(hash_list) < 2: return hash_list[0] new_hash_list = [] # Process pairs. For odd length, the last is skipped for i in range(0, len(hash_list) - 1, 2): new_hash_list.append(hash2(hash_list[i], hash_list[i + 1])) # odd, hash last item twice if len(hash_list) % 2 == 1: new_hash_list.append(hash2(hash_list[-1], hash_list[-1])) return build_merkle_root(new_hash_list) #========================================================================== def hash2(a, b): # Reverse inputs before and after hashing due to big-endian / little-endian nonsense a1 = binascii.unhexlify(a)[::-1] b1 = binascii.unhexlify(b)[::-1] h = hashlib.sha256(hashlib.sha256(a1 + b1).digest()).digest() return binascii.hexlify(h[::-1])
從 merkle 樹結構的角度來看,這看起來更合乎邏輯,它分別對每一對進行雜湊處理。
為了測試它們,下面以從池中獲得的作業為例….
[{'id': None, 'method': 'mining.notify', 'params': ['59bc8dfc00003829', 'ceeefd1381f491d9a0ba90b26a495a225e8bfc9f00ecc4250000000000000000', '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3503226b07000455abc259040bf12d090c', '0a636b706f6f6c112f736f6c6f2e636b706f6f6c2e6f72672fffffffff035976a953000000001976a914fc6123f4bfd3a840b4387ab90e9801e98fb17cf888ac8756d800000000001976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac0000000000000000266a24aa21a9edc963e012cb380138e3d16283a094454782879557714d3b0d73fecfe612d01f0600000000', ['b32abe89497354ceaa2dff35cc41995d58c19893d517e92e30b4ead75a66970c', 'ca93a597a29860178f4cd01326f43b080f516f3f81ba6b86b0ff35f5cb206b7f', '213f7e41a5b228ec554c1a2e3fe18b1f3e1c23821b1b2b3aa1319d3d616044ca', '0941052c2e5864e57a18bfc82d1e7ab15740d4ed7b852cda92bffd3ff622e59d', '7ad5af30a3daa89c1244016227cde139d5d54232a673cbf7954f6a1aa26bbc05', 'e24a96489d5782c6bcde209952a12826cd225b97b9a3ad3142c87dd062136d0b', '383a433dc503c8ab4b7beb9dc4a3e07811a1cb9681e2da019cec16966fc727be', 'f10804628f630bcead6cd1b667d4352cdfb93aea382662456c2caadda3e1b0c9', '03e9bf5b6053fe86d272dac8c2a32f08ace6d045799ae499ed7087af21c737c6', '3cf338c75d7ef47b0c029d16b5b02340a62ce0a7846910175b021d919dcccc6f', '40319623d80cae8a5b1a3e319a962110a08ff40daf40ebf421b9454f20e54dcc', 'c29e3826153dfc1d10e9e173281d21ad2103bba86bc2930440e7258afca2b957'], '20000000', '1800ff18', '59c2ab55', False]}]
程式碼 1 給了我 merkle root as
7cbd55a748aa8e778e0795e33d5bd5a07c9f465cd3de1fef3bf36ea3ac4d56f9
而程式碼 2 給了 as6681ae1409685d71a51ced80ae0c7eacb78d5facb401ece2287543b6cc17e4cf
由於兩者都不相同,那麼哪一個是錯誤的?我需要 merkle root 作為塊頭。在上述兩種情況下,我都將 extranonce2 全為零作為
0000000000000000
並建構 coinbase,01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3503226b07000455abc259040bf12d090cff47c35900000000000000000a636b706f6f6c112f736f6c6f2e636b706f6f6c2e6f72672fffffffff035976a953000000001976a914fc6123f4bfd3a840b4387ab90e9801e98fb17cf888ac8756d800000000001976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac0000000000000000266a24aa21a9edc963e012cb380138e3d16283a094454782879557714d3b0d73fecfe612d01f0600000000
它給出了一個 coinbase 雜湊20d0b9a72f1e940e29b064e428f5e037f948c9ede27dfb7e77b1df7d289d1861
Stratum 協議為您提供了 merkle 樹中特定分支的一些雜湊值。它們在樹中可能不在同一深度(我不認為它們是)。提供它們只是為了讓礦工可以通過增加額外隨機數然後將其合併到 merkle 根中來更改 coinbase 交易。Code 1 merkle root 應該是正確的,因為這是 Stratum 協議文件告訴您的方法。另一個程式碼用於從交易列表創建 merkle 根,而不是 Stratum 提供的分支雜湊列表。