Proof-of-Work
Ruby中的範例工作證明,我做錯了什麼?
給定以下塊,我如何驗證工作量證明?我從 bitcoin-cli getblock 獲得了這些數據,並解析為一個名為 data 的 Ruby 雜湊:
{"hash"=>"00000000000000001354e21fea9c1ec9ac337c8a6c0bda736ec1096663383429", "confirmations"=>2, "size"=>529935, "height"=>347928, "version"=>2, "merkleroot"=>"14b2c974a4f9ab92a68f03a491965063d1f8a2e8b2268fdb4cbce92262bb09c0", "tx"=>"..removed for space convenience...", "time"=>1426554998, "nonce"=>3284264479, "bits"=>"18172ec0", "difficulty"=>47427554950.6483, "chainwork"=>"000000000000000000000000000000000000000000056f68a6406c831f16c1bd", "previousblockhash"=>"000000000000000007c464352935f12c3695f7de4eee8390f444233682abf8aa", "nextblockhash"=>"000000000000000016e3530b3a7cdaaa495e6eb70aa8f3f15d02fd078235e931"}
我嘗試了以下方法:
version = "02000000" prev = data["previousblockhash"] merkle = data["merkleroot"] time = data["time"].to_s(16) #convert to hex bits = data["bits"] nonce = data["nonce"] hashable = version + prev + merkle + time + bits + nonce answer = Digest::SHA256.hexdigest hashable
問題是我的答案是這樣的:
b7dc9db86cdf47bf1b13274f88b14211a1ce58c52ac1e41c987b4ad65cf50f4f
但給定的答案(在 data[“hash”] 中)是
00000000000000001354e21fea9c1ec9ac337c8a6c0bda736ec1096663383429
我究竟做錯了什麼?
感謝您的幫助,凱文
這裡需要解決的一些問題:
- 字節序 - 在 JSON 中提供給您的數據幾乎完全是大字節序,但比特幣在散列之前使用小字節序序列化塊頭。
- 您需要使用 SHA256 對結果進行雙重散列,這意味著在標頭上應用一次,然後在第一個散列的結果上再次應用算法。
- 在散列之前轉換為二進制。您不能只散列 ascii 字元,因為它們只是底層二進製文件的編碼,這就是要散列的內容。
我對 Ruby 不是很熟悉,但我製作了一個簡短的 Python 腳本,您可以將其用作參考。
import hashlib import binascii def rev(string): revsed = "" for i in range(int(len(string)/2)): revsed = string[2*i : 2*i+2] + revsed return revsed def DoubleHash(string): bin = binascii.unhexlify(string) hash = hashlib.sha256(hashlib.sha256(bin).digest()).digest() raw = str(binascii.hexlify(hash))[2:-1] return rev(raw) # Straight from JSON version = "02000000" prev = "000000000000000007c464352935f12c3695f7de4eee8390f444233682abf8aa" merkle = "14b2c974a4f9ab92a68f03a491965063d1f8a2e8b2268fdb4cbce92262bb09c0" time = "55078076" # hex(1426554998) bits = "18172ec0" nonce = "c3c1e61f" # hex(3284264479) header = version + rev(prev) + rev(merkle) + rev(time) + rev(bits) + rev(nonce) print(header) print(DoubleHash(header))
結果:
02000000aaf8ab82362344f49083ee4edef795362cf135293564c4070000000000000000c009bb6222e9bc4cdb8f26b2e8a2f8d163509691a4038fa692abf9a474c9b21476800755c02e17181fe6c1c3 00000000000000001354e21fea9c1ec9ac337c8a6c0bda736ec1096663383429