Beispielarbeitsnachweis in Ruby, was mache ich falsch?

Wie überprüfe ich angesichts des folgenden Blocks den Arbeitsnachweis? Ich habe diese Daten von bitcoin-cli getblock bekommen und in einen Ruby-Hash namens data geparst:

{"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"}

Ich habe folgendes versucht:

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

Das Problem ist meine Antwort ist diese:

b7dc9db86cdf47bf1b13274f88b14211a1ce58c52ac1e41c987b4ad65cf50f4f

aber die gegebene Antwort (in data["hash"]) ist

00000000000000001354e21fea9c1ec9ac337c8a6c0bda736ec1096663383429

Was mache ich falsch?

Danke für jede Hilfe, Kevin

Antworten (1)

Ein paar Dinge, die hier behoben werden müssen:

  1. Endianness - Die Daten, die Ihnen in JSON gegeben werden, sind fast vollständig in Big Endian, aber Bitcoin verwendet Little Endian, um Blockheader vor dem Hashing zu serialisieren.
  2. Sie müssen das Ergebnis mit SHA256 doppelt hashen, dh es einmal auf den Header anwenden und dann den Algorithmus erneut auf das Ergebnis des ersten Hashs anwenden.
  3. Konvertierung in binär vor dem Hashing. Sie können die ASCII-Zeichen nicht einfach hashen, da dies nur eine Codierung für die zugrunde liegende Binärdatei ist, die gehasht werden soll.

Ich bin mit Ruby nicht sehr vertraut, aber ich habe ein kurzes Python-Skript erstellt, das Sie als Referenz verwenden können.

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))

Die Ergebnisse:

02000000aaf8ab82362344f49083ee4edef795362cf135293564c4070000000000000000c009bb6222e9bc4cdb8f26b2e8a2f8d163509691a4038fa692abf9a474c9b21476800755c02e17181fe6c1c3
00000000000000001354e21fea9c1ec9ac337c8a6c0bda736ec1096663383429
Vielen Dank dafür, es sieht so aus, als ob Ihr vorheriges nicht richtig umgekehrt wurde oder ich missverstehe, was Sie tun: letzte 5 von vorherigem: bf8aa Ihre Drehzahl von vorherigem in Kopfzeile: aaf8a
Sie müssen die Bytes in umgekehrter Reihenfolge auflisten. Jedes Byte besteht aus zwei Hexadezimalzeichen. Der vorherige Block ist 0000...f8aa. Sie müssen nur die Bytes in umgekehrter Reihenfolge als auflisten aaf8...0000. dh 1234 Byte-umgekehrt ist 3412.
ok, ich verstehe, also ist es sowohl Byte-umgekehrt als auch Endian-umgekehrt?
Endian umgekehrt bedeutet nur, dass Sie die Bytes in der umgekehrten Reihenfolge auflisten müssen. Denken Sie daran, Antworten als richtig zu markieren, wenn sie Ihre Frage beantwortet haben.
Entschuldigung, dass ich nicht klar bin, ich verstehe, was Endian Reversed bedeutet. Ich habe versucht, eine Bestätigung zu erhalten, dass zwei unterschiedliche Verarbeitungsschritte erforderlich sind: 1) Reverse Endian (Swap der Hex-Bytes) und 2) Umkehren der Zeichenfolge
Das Umkehren der Endianness ist dasselbe wie das Umkehren der Bytes in der Zeichenfolge.