<p>A few things that need to be fixed here:</p>

<ol>
<li>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. </li>
<li>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.</li>
<li>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. </li>
</ol>

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

<pre><code>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))
</code></pre>

<p>The results:</p>

<pre><code>02000000aaf8ab82362344f49083ee4edef795362cf135293564c4070000000000000000c009bb6222e9bc4cdb8f26b2e8a2f8d163509691a4038fa692abf9a474c9b21476800755c02e17181fe6c1c3
00000000000000001354e21fea9c1ec9ac337c8a6c0bda736ec1096663383429
</code></pre>

CC BY-SA 3.0
2015-03-17T15:31:02.687Z
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
user1130176
CC BY-SA 3.0
2015-03-17T17:36:19.640Z
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
CC BY-SA 3.0
2015-03-18T00:32:48.410Z
ok, i see, so it's both byte reversed and Endian reversed?
user1130176
CC BY-SA 3.0
2015-03-18T12:32:12.340Z
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
CC BY-SA 3.0
2015-03-19T03:12:18.303Z
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
user1130176
CC BY-SA 3.0
2015-03-30T15:24:24.260Z
Reversing the endianness is the same thing as reversing the bytes in the string.
morsecoder
CC BY-SA 3.0
2015-03-17T12:23:40.387Z
2015-03-17T12:23:40.387Z
morsecoder
<p>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:</p>

<pre><code>{"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"}
</code></pre>

<p>I have tried the following:</p>

<pre><code>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
</code></pre>

<p>The problem is my answer is this:</p>

<p>b7dc9db86cdf47bf1b13274f88b14211a1ce58c52ac1e41c987b4ad65cf50f4f</p>

<p>but the given answer (in data["hash"]) is </p>

<p>00000000000000001354e21fea9c1ec9ac337c8a6c0bda736ec1096663383429</p>

<p>What am I doing wrong?</p>

<p>Thanks for any help,
Kevin</p>

<proof-of-work><ruby>
Sample proof of work in Ruby, what am I doing wrong?
user1130176
# Sample proof of work in Ruby, what am I doing wrong?

(Asked by: username_0 on 2015-03-17)

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

**Tags:** proof-of-work, ruby


---

## 1 answers

### Answer by username_1 on 2015-03-17. Score: 1 | Accepted answer

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

> **Comments:**
> **username_0**: 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  
> **username_1**: 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.  
> **username_0**: ok, i see, so it's both byte reversed and Endian reversed?  
> **username_1**: 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.  
> **username_0**: 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  
> **username_1**: Reversing the endianness is the same thing as reversing the bytes in the string.  

---

