Mining-Pools

默克爾根 2 程式碼

  • September 20, 2017

在嘗試從我從礦池獲得的數據中計算 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 as7cbd55a748aa8e778e0795e33d5bd5a07c9f465cd3de1fef3bf36ea3ac4d56f9而程式碼 2 給了 as6681ae1409685d71a51ced80ae0c7eacb78d5facb401ece2287543b6cc17e4cf 由於兩者都不相同,那麼哪一個是錯誤的?我需要 merkle root 作為塊頭。

在上述兩種情況下,我都將 extranonce2 全為零作為0000000000000000並建構 coinbase,01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3503226b07000455abc259040bf12d090cff47c35900000000000000000a636b706f6f6c112f736f6c6f2e636b706f6f6c2e6f72672fffffffff035976a953000000001976a914fc6123f4bfd3a840b4387ab90e9801e98fb17cf888ac8756d800000000001976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac0000000000000000266a24aa21a9edc963e012cb380138e3d16283a094454782879557714d3b0d73fecfe612d01f0600000000它給出了一個 coinbase 雜湊20d0b9a72f1e940e29b064e428f5e037f948c9ede27dfb7e77b1df7d289d1861

Stratum 協議為您提供了 merkle 樹中特定分支的一些雜湊值。它們在樹中可能不在同一深度(我不認為它們是)。提供它們只是為了讓礦工可以通過增加額外隨機數然後將其合併到 merkle 根中來更改 coinbase 交易。Code 1 merkle root 應該是正確的,因為這是 Stratum 協議文件告訴您的方法。另一個程式碼用於從交易列表創建 merkle 根,而不是 Stratum 提供的分支雜湊列表。

引用自:https://bitcoin.stackexchange.com/questions/59773