0

Given the following block, how do I verify the proof of work? I got this data from bitcoin-cli getblock and parsed in to a Ruby hash called data:

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

I have tried the following:

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

The problem is my answer is this:

b7dc9db86cdf47bf1b13274f88b14211a1ce58c52ac1e41c987b4ad65cf50f4f

but the given answer (in data["hash"]) is

00000000000000001354e21fea9c1ec9ac337c8a6c0bda736ec1096663383429

What am I doing wrong?

Thanks for any help, Kevin

1 Answer 1

1

A few things that need to be fixed here:

  1. Endianness - The data given to you in JSON is almost completely in big endian but bitcoin uses little endian to serialize block headers before hashing.
  2. You need to double hash the result with SHA256, meaning apply it once on the header and then apply the algorithm again on the result of the first hash.
  3. Conversion to binary before hashing. You can't just hash the ascii characters, as those are just an encoding for the underlying binary, which is what is meant to be hashed.

I'm not very familiar with Ruby, but I made a short python script that you can use as a reference.

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

The results:

02000000aaf8ab82362344f49083ee4edef795362cf135293564c4070000000000000000c009bb6222e9bc4cdb8f26b2e8a2f8d163509691a4038fa692abf9a474c9b21476800755c02e17181fe6c1c3
00000000000000001354e21fea9c1ec9ac337c8a6c0bda736ec1096663383429
6
  • Thanks for this, it looks like either your prev didn't reverse properly or I'm misunderstanding what you're doing: last 5 of prev: bf8aa your rev of prev in header: aaf8a Commented Mar 17, 2015 at 15:31
  • You have to list the bytes in reverse order. Each byte is two hex characters. The previous block is 0000...f8aa. You just have to list the bytes in the reverse order as aaf8...0000. i.e. 1234 byte-reversed is 3412.
    – morsecoder
    Commented Mar 17, 2015 at 17:36
  • ok, i see, so it's both byte reversed and Endian reversed? Commented Mar 18, 2015 at 0:32
  • Endian reversed just means you need to list the bytes in the opposite order. Remember to mark answers as correct if they answered your question.
    – morsecoder
    Commented Mar 18, 2015 at 12:32
  • sorry for not being clear, i understand what endian reversed meant, i was attempting get confirmation that two distinct processing steps are required 1) reverse endian (swap the hex bytes) and 2) reverse the string Commented Mar 19, 2015 at 3:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.