Bitcoin Forum
May 25, 2024, 03:01:07 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Recalculating the hash in python  (Read 3665 times)
Martin P. Hellwig (OP)
Newbie
*
Offline Offline

Activity: 33
Merit: 0


View Profile
June 10, 2011, 02:19:13 PM
 #1

Hi all,

I am trying to recalculate the hash but I think I am making somewhere a giant snafu.
I attached my code, would anyone be willing to hint me in the right direction?

Thanks

<code>
import hashlib

def i2w(integer):
    """Convert integer to 4 byte word in a string.
    Will raise exception if overflows."""
    work = bin(integer)[2::].zfill(32)
    if len(work) > 32:
        raise(OverflowError(integer))
   
    tmp = list()
    while len(work) > 7:
        part = work[:8]
        work = work[8:]
        char = chr(int(part, 2))
        tmp.append(char)
       
    return(''.join(tmp))


if __name__ == '__main__':
    # Contents of genesis block: http://blockexplorer.com/b/0
    #"hash":"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
    #"ver":1,
    #"prev_block":"0000000000000000000000000000000000000000000000000000000000000000",
    #"mrkl_root":"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
    #"time":1231006505,
    #"bits":486604799,
    #"nonce":2083236893,
    #
    hash = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
    # Try to reproduce the above hash with below data
    v = 1
    p = "0000000000000000000000000000000000000000000000000000000000000000"
    m = "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
    t = 1231006505
    b = 486604799
    n = 2083236893
   
    tmp = i2w(v) + p.decode('hex') + m.decode('hex') + i2w(t) + i2w(b) + i2w(n)
   
    one = hashlib.sha256()
    one.update(tmp)
    hash_one = one.digest()
   
    two = hashlib.sha256()
    two.update(hash_one)
    hash_two = two.digest()
   
    print(hash)
    print(hash_two.encode('hex'))

<output>
>>> 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
>>> f40519089bfd56ee63f6207f11e69707ac85e5ca20ab0e4aeaa468dbc72e7ae0
       
Martin P. Hellwig (OP)
Newbie
*
Offline Offline

Activity: 33
Merit: 0


View Profile
June 10, 2011, 03:11:44 PM
 #2

Never mind I see already a couple of errors, I'll try to convert http://pastebin.com/Ya3604J0
And will update this here once I get something working.
Martin P. Hellwig (OP)
Newbie
*
Offline Offline

Activity: 33
Merit: 0


View Profile
June 10, 2011, 06:28:40 PM
 #3

As promised:


Code:
#! /usr/bin/env python
# The Python Equivalent of http://pastebin.com/Ya3604J0
import hashlib

# This is the data from the 'genesis' block, see: http://blockexplorer.com/b/0
VERSION = 1
PREV_BLOCK = "0000000000000000000000000000000000000000000000000000000000000000"
MERKLE_ROOT = "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
TIMESTAMP = 1231006505
BITS = 486604799
NONCE = 2083236893

def _hex_word_from_integer(integer):
    """Convert integer to 4 byte word in a string.
    Will raise exception if overflows."""
    work = bin(integer)[2::].zfill(32)
    if len(work) > 32:
        raise(OverflowError(integer))
   
    tmp = list()
    while len(work) > 7:
        part = work[:8]
        work = work[8:]
        char = chr(int(part, 2))
        tmp.append(char)
   
    return(''.join(tmp).encode('hex'))

def _hex_value_byteswap(hex_string):
    "Swap the byte order in a hex string."
    work = hex_string[::]
    temp = list()
    while len(work) > 1:
        # Split string up in parts of two
        part = work[0:2]
        work = work[2::]
        temp.append(part)
   
    temp = temp[::-1] # reverse temp
    return(''.join(temp))
   
def main():
    # Building up the header
    header = list()
    header.append(_hex_word_from_integer(VERSION))
    header.append(PREV_BLOCK)
    header.append(MERKLE_ROOT)
    header.append(_hex_word_from_integer(TIMESTAMP))
    header.append(_hex_word_from_integer(BITS))
    header.append(_hex_word_from_integer(NONCE))
   
    # In place byteswap the items in the header list
    for index in range(len(header)):
        header[index] = _hex_value_byteswap(header[index])
       
    # Generic information
    header = ''.join(header).decode('hex')
    print('sizeof(block_header) = %s' % len(header))
    text = "Block header (in human readable hexadecimal representation): %s"
    print(text % header.encode('hex'))
   
    # The first hashing
    hash = hashlib.sha256()
    hash.update(header)
    text = "Useless First Pass Checksum: %s"
    text = text % _hex_value_byteswap(hash.hexdigest())
    print(text)
   
    # The second hashing
    next = hash.digest()
    hash = hashlib.sha256()
    hash.update(next)
    text = "Target Second Pass Checksum: %s"
    text = text % _hex_value_byteswap(hash.hexdigest())
    print(text)
   
if __name__ == '__main__':
    main()
titeuf_87
Member
**
Offline Offline

Activity: 111
Merit: 10


View Profile
June 11, 2011, 01:48:47 AM
 #4

Looking at your code, you have some byte order issues:

First, the i2w function. I'm too tired to actually fix this, so I went ahead and used the struct module (you should look into using it, it makes life a lot easier):
Code:
def i2w(integer):
    """Convert integer to 4 byte word in a string.
    Will raise exception if overflows."""
    #the < stands for little endian, and I for unsigned int
    return struct.pack("<I", integer)

Then, when assembling the header, you still need to reverse p and m:
Code:
tmp = i2w(v) + p.decode('hex')[::-1] + m.decode('hex')[::-1] + i2w(t) + i2w(b) + i2w(n)

And lastly, when printing out the result, you need to reverse it too:
Code:
print(hash_two[::-1].encode('hex'))

15kfBM3TQ4PGzL7cKncU3su2pH7ZJmiLtr
Martin P. Hellwig (OP)
Newbie
*
Offline Offline

Activity: 33
Merit: 0


View Profile
June 11, 2011, 10:07:48 AM
 #5

Hi,

As you can see I have found my errors, corrected it and posted the updated code before you replied, sorry for wasting your time.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!