3

I have the following python sript, which double hashes a hex value:

import hashlib
linestring = open('block_header.txt', 'r').read()
header_hex = linestring.encode("hex") // Problem!!!
print header_hex
header_bin = header_hex.decode('hex')
hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()

hash.encode('hex_codec')
print hash[::-1].encode('hex_codec')

My text file "block_header.txt" (hex) looks like this:

0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a14695

Unfortunately, the result from printing the variable header_hex looks like this (not like the txt file):

303130303030303038316364303261623765353639653862636439333137653266653939663264653434643439616232623838353162613461333038303030303030303030303030653332306236633266666663386437353034323364623862316562393432616537313065393531656437393766376166666338383932623066316663313232626337663564373464663262393434316134326131343639350a

I think the problem is in this line:

header_hex = linestring.encode("hex")

If I remove the ".encode("hex")"-part, then I get the error

unhandled TypeError "Odd-length string"

Can anyone give me a hint what might be wrong? Thank you a lot :)

3
  • What happens if you do a linestring = linestring.strip() before passing it to the encoder? You might have some whitespaces/EOF's in the read string. Commented Sep 21, 2015 at 17:39
  • You almost certainly don't want to header_hex = linestring.encode("hex") at the beginning. Like others said, strip() and then decode. Commented Sep 21, 2015 at 17:46
  • Just decode and the last part of the answer qill do what you want bitcoin.stackexchange.com/a/5679 Commented Sep 21, 2015 at 18:05

1 Answer 1

1

You're doing too much encoding/decoding.

Like others mentioned, if your input data is hex, then it's a good idea to strip leading / trailing whitespace with strip().

Then, you can use decode('hex') to turn the hex ASCII into binary. After performing whatever hashing you want, you'll have the binary digest.

If you want to be able to "see" that digest, you can turn it back into hex with encode('hex').

The following code works on your input file with any kinds of whitespace added at the beginning or end.

import hashlib

def multi_sha256(data, iterations):
    for i in xrange(iterations):
        data = hashlib.sha256(data).digest()
    return data

with open('block_header.txt', 'r') as f:
    hdr = f.read().strip().decode('hex')
    _hash = multi_sha256(hdr, 2)

    # Print the hash (in hex)
    print 'Hash (hex):', _hash.encode('hex')

    # Save the hash to a hex file
    open('block_header_hash.hex', 'w').write(_hash.encode('hex'))

    # Save the hash to a binary file
    open('block_header_hash.bin', 'wb').write(_hash)
Sign up to request clarification or add additional context in comments.

1 Comment

If I substitute the block_header.txt code block with my own defined property header_hex which contains six typical header fields Version, hashPrevBlock, hashMerkleRoot, Time, Bits, Nonce I get a "Undefined variable 'xrange'" error as well as a "Unused variable 'i'" error. Why would that be? Is it because this xrange loop type is meant for a single hash string?

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.