Skip to content

Instantly share code, notes, and snippets.

@dungeonsnd
Last active June 30, 2017 02:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dungeonsnd/4f4b74c15251846dad921ad18fbac4e7 to your computer and use it in GitHub Desktop.
Save dungeonsnd/4f4b74c15251846dad921ad18fbac4e7 to your computer and use it in GitHub Desktop.
Calculate the bitcoin block hash.
# -*- coding: utf-8 -*-
# python 2.7
import hashlib
import binascii
import time
def uint32(x):
return x & 0xffffffffL
def byteReverse(x):
return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) | (((x) >> 8) & 0x0000ff00) | ((x) >> 24) ))
def hexstrReverse(s):
grouplen =2 # 16进制串是2个字符一组
l =[s[i:i+grouplen] for i in range(0, len(s), grouplen)]
l.reverse()
return ''.join(l)
def int2uint(i):
return i+2**32
def CalBlockHash(bockNumber, Version, hashPrevBlock, hashMerkleRoot, Time, Bits, Nonce):
if isinstance(Version, str):
if Version[0:2]=='0x':
Version =Version[2:]
else:
Version =hex(byteReverse(Version))[2:-1]
Version =Version.ljust(8,'0')
utc_delta =0 # blockexplorer.com
#utc_delta =3600*8 # blockchain.info
Time =int(time.mktime(time.strptime(Time, '%Y-%m-%d %H:%M:%S'))) + utc_delta
Time =hexstrReverse(str(hex(Time))[2:])
if isinstance(Bits, str):
if Bits[0:2]=='0x':
Bits =Bits[2:]
Bits =hexstrReverse(Bits)
else:
Bits =hex(byteReverse(Bits))[2:-1]
Nonce =hex(byteReverse(Nonce))[2:-1]
print 'Version=',Version
print 'hashPrevBlock=',hashPrevBlock
print 'hashMerkleRoot=',hashMerkleRoot
print 'Time=',Time
print 'Bits=',Bits
print 'Nonce=',Nonce
header_bin = binascii.unhexlify(Version+
hexstrReverse(hashPrevBlock)+
hexstrReverse(hashMerkleRoot)+
Time+Bits+Nonce)
hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
print 'Block Hash of #{0} : {1}\n'.format(bockNumber, binascii.hexlify(hash[::-1]))
def main():
# Block #125552 , https://blockexplorer.com/block/00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d
bockNumber =125552
Version ="0x01000000" # Version 1 01000000
hashPrevBlock ="00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81"
hashMerkleRoot ="2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3"
# blockchain.info + 8h 2011-05-21 17:26:31
# blockexplorer.com ok 2011-05-22 01:26:31
Time ="2011-05-22 01:26:31" # 时间戳 c7f5d74d
Bits ="1a44b9f2" # 计算目标 "f2b9441a", 16进制需要时 str 类型
Nonce =2504433986 # 随机数 "42a14695", 10进制需要 int 类型
# Test OK.
CalBlockHash(bockNumber, Version, hashPrevBlock, hashMerkleRoot, Time, Bits, Nonce)
# Block #473360 , https://blockexplorer.com/block/0000000000000000003e0d2c40f8fd444c389a295ad134ffea7127836019ef3a
bockNumber =473360
Version =536870912
hashPrevBlock ="000000000000000000ec1e51406b39ac67d298fcebec7c8b4cc24037e1197a8e"
hashMerkleRoot ="4d8f6da5972fc13d13bc1f11e103502930c8056a578673f1891ea192feb5f3da"
Time ="2017-06-29 16:06:01"
Bits ="18018b7e"
Nonce =426804529
# Test ERROR! Block Hash of #473360 : d69e40c66c882514b9adbd29936a6511b1d4afae1082b154e1b089571526d592
CalBlockHash(bockNumber, Version, hashPrevBlock, hashMerkleRoot, Time, Bits, Nonce)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment