Sample proof of work in Ruby, what am I doing wrong? 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"=&gt;"00000000000000001354e21fea9c1ec9ac337c8a6c0bda736ec1096663383429",
 "confirmations"=&gt;2, "size"=&gt;529935, "height"=&gt;347928, "version"=&gt;2,
 "merkleroot"=&gt;"14b2c974a4f9ab92a68f03a491965063d1f8a2e8b2268fdb4cbce92262bb09c0", 
"tx"=&gt;"..removed for space convenience...", "time"=&gt;1426554998, 
"nonce"=&gt;3284264479, "bits"=&gt;"18172ec0", "difficulty"=&gt;47427554950.6483, 
"chainwork"=&gt;"000000000000000000000000000000000000000000056f68a6406c831f16c1bd", 
"previousblockhash"=&gt;"000000000000000007c464352935f12c3695f7de4eee8390f444233682abf8aa",     
"nextblockhash"=&gt;"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
A few things that need to be fixed here:


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