Skip to content

Instantly share code, notes, and snippets.

@ondrejsika
Forked from phelixbtc/auxpowpuzzle.py
Last active August 29, 2015 14:19
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 ondrejsika/8af1b4f90ce49154ddb9 to your computer and use it in GitHub Desktop.
Save ondrejsika/8af1b4f90ce49154ddb9 to your computer and use it in GitHub Desktop.
import hashlib
import struct
####http://python-bitcoinlib.readthedocs.org/en/latest/_modules/bitcoin/core/serialize.html
def uint256_from_str(s):
"""Convert bytes to uint256"""
r = 0
t = struct.unpack(b"<IIIIIIII", s[:32])
for i in range(8):
r += t[i] << (i * 32)
return r
def uint256_from_compact(c):
"""Convert compact encoding to uint256
Used for the nBits compact encoding of the target in the block header. """
nbytes = (c >> 24) & 0xFF
v = (c & 0xFFFFFF) << (8 * (nbytes - 3))
return v
####
def reverse_byte_order(data):
return data[::-1]
def get_merkle_parents(data):
if len(data) % 2:
data.append(data[-1])
hashes = []
half = len(data) / 2
for i in range(half):
hashes.append((dsha256(data[i * 2] + data[i * 2 + 1])))
if len(hashes) == 1:
return hashes
return hashes + get_merkle_parents(hashes)
def get_merkle_tree(txs_data):
"""hex in, hex out"""
if len(txs_data) == 0:
return 0
if len(txs_data) == 1:
#return dsha256(txs_data[0])
return [txs_data[0]]
txs_data_rev = []
for t in txs_data:
txs_data_rev.append(reverse_byte_order(t.decode("hex")))
treeHashed = get_merkle_parents(txs_data_rev)
tree = []
for t in treeHashed:
tree.append(reverse_byte_order(t).encode("hex"))
tree = txs_data + tree
return tree
def get_merkle_root(txs_data):
return get_merkle_tree(txs_data)[-1]
def dsha256(data):
return hashlib.sha256(hashlib.sha256(data).digest()).digest()
def hash_block(B):
blkheader = ""
blkheader += struct.pack('<I', B['version'])
blkheader += B['previousblockhash'].decode("hex")[::-1]
blkheader += B["merkleroot"].decode("hex")[::-1]
blkheader += struct.pack('<I', B['time'])
blkheader += struct.pack('<I', B['bits'])
blkheader += struct.pack('<I', B['nonce'])
h = dsha256(blkheader)[::-1]
return h.encode("hex")
def check_pow(blockHash, bits):
target = uint256_from_compact(bits)
if len(blockHash) == 64:
blockHash = blockHash.decode("hex")
assert(len(blockHash) == 32)
blockHash = reverse_byte_order(blockHash) # why?
nHash = uint256_from_str(blockHash)
#print "target:", target
#print "nHash:", nHash
return nHash <= target
if __name__ == "__main__":
# block data as from client
b10001 = {u'merkleroot': u'41183c608fc0cac556f219330c418cf0381c178d3f25db5b254af204340aa4b8', u'nonce': 3453268730L, u'previousblockhash': u'000000000012aa6242ad0e4379d14fdf83bc2dba5367e93f9973a607dac8fc1b', u'hash': u'000000000012718050e3537c3c355f3746fc8cd6434d44e79417276d6683b7ab', u'version': 1, u'tx': [u'b3aa2222d2de49f5ff2b9113f0cb0c45b29f663cd251347fb6146a49cf21c7cf', u'7d06aed84b35f6f6ef9f6fb1665eb70b30c4269eb471b82dc056719cb654b22d', u'eb2a8459294cc20c2227241578fdbc727c3002b609474f7fe36dfa70cf91adb8', u'1bd4a9b1be61890f9cde4e6d56ef573aa620520cef7e50f4333b8310a6902d5c', u'6db3be97ec074e4b9bd7e65745fd5b2ce58c5690111223a9f424956973cb3248'], u'chainwork': u'a4fda2e48f1288', u'height': 10001, u'difficulty': 2815.22139486, u'nextblockhash': u'000000000012481355db977eb44e31899aba300971ee1ed179c0b9a1c8fe2509', u'confirmations': 211519, u'time': 1307729360, u'mrkl_tree': [u'b3aa2222d2de49f5ff2b9113f0cb0c45b29f663cd251347fb6146a49cf21c7cf', u'7d06aed84b35f6f6ef9f6fb1665eb70b30c4269eb471b82dc056719cb654b22d', u'eb2a8459294cc20c2227241578fdbc727c3002b609474f7fe36dfa70cf91adb8', u'1bd4a9b1be61890f9cde4e6d56ef573aa620520cef7e50f4333b8310a6902d5c', u'6db3be97ec074e4b9bd7e65745fd5b2ce58c5690111223a9f424956973cb3248', u'40bbf3ef9e9eb15de41d513eaf41f8cc299ad079f99d6e6fd2ccb314a4997b5a', u'f26f51abf6328dd6ee1e3adb031c0b9b5375fe4aa30fc6c2b67db724e9169958', u'1a5bb3dca1bec868ea8be12378a364229f9bee73e319fe5a974ba9e84074149d', u'c72d87e3668f8765dc05ad91d196242abca370bbc0490cd206df436cec466517', u'37a8417076dfc435379a2b6e4fc75a7bbbf1715ede28e16e6da245095e9e2525', u'41183c608fc0cac556f219330c418cf0381c178d3f25db5b254af204340aa4b8'], u'bits': 454510432, u'n_tx': 5, u'size': 1361}
b19199 = {u'merkleroot': u'0f8e8a23da3c8e53f9ef1f6722d0667e228b9275cd61e9a1460d717763d89894', u'nonce': 3605635432L, u'previousblockhash': u'0000000000006464e662d576efece67a239a59834dd9acb9329443722650d85b', u'hash': u'000000000000b19f0ad5cd46859fe8c9662e8828d8a75ff6da73167ac09a9036', u'chainwork': u'12615e52277c4040', u'mrkl_tree': [u'0f8e8a23da3c8e53f9ef1f6722d0667e228b9275cd61e9a1460d717763d89894'], u'height': 19199, u'difficulty': 94035.90217415, u'nextblockhash': u'd8a7c3e01e1e95bcee015e6fcc7583a2ca60b79e5a3aa0a171eddd344ada903d', u'confirmations': 202315, u'version': 65537, u'time': 1318063738, u'tx': [u'0f8e8a23da3c8e53f9ef1f6722d0667e228b9275cd61e9a1460d717763d89894'], u'bits': 453030505, u'n_tx': 1, u'size': 215}
b200000 = {u'merkleroot': u'ca714d4f72d212bbbb3521886ff2561f54506cdbb2515acb2d26842005fe7744', u'nonce': 0, u'previousblockhash': u'6e6eeda4f8e9c54dd3aef29d8fc5f26a9ec050aac675e9d7a0152a716a83e7e3', u'hash': u'bdec8422dcad4c6168041068ab8f00d73efb38556cd47cf5af157649ab39855d', u'chainwork': u'136f2f184e4580dcd02cc', u'mrkl_tree': [u'f33e53065568d534b2eeec23ec45b538926573de3577a1f34bbe90c5b59b661d', u'a847b4b57667016d7331f5455d4d31c7dfb868d12f4763050c56f6acdabdc807', u'14f710d587791b4181b8783205247b4aea9f79cc9d7ccb9d06b4cbe2423b08be', u'2f17cd80f7adb98b77ea62ab004cfe6ac87bdc8dd5602d0065aef5002c8a27d1', u'3770bee4d9e0f6b754046ffb3b3c5a03bc9add35d948e7025b0f4e3cd1d6dee3', u'6083f86f0fa2e313aa6e45369bd1517fb903139808910755fbc4c102aafaf44e', u'9f28e177aadcb3b1cfdab7da931a3458024c4d74c086620cb2308474c84141be', u'b5b0fa2f475613fd3ffb54dfa57fdccc3e559d79abcc3570928014a8f6e627f1', u'f08934b0358f1c56ea0c5f8a05283274cc7de6278b901905bd7f2e2dc1db198d', u'9c9e13553137d550fefe41af09a5189cf80765025b814c8ba619d611e39f53a4', u'03c6ed02702f0fc590e23d071b56233d67d5e1c1392754f36282a3fb9c93b746', u'4b393f30959bb0a2d6d7f0d2a0945ca11c4e4b82fd29c50ae225f4b3a95e66ca', u'2952505577d5ab86a4e37060ee12dbd462394dbacf7873dc66bc7d15757b09c4', u'a17cecb5ab8b7439fde09767803c71a3fc54f2095156e2d7bd4003bc2064be52', u'd915fbe8102930e1249af3ab3c1aed94816e92a5903a00cbe67f4e1d8c763e6c', u'c96ae6d7d24b78212005190cf7f91b924c7a82ab74d53a1d1069353729348bca', u'4d2bd3262ba4698990ae36ca05553ca19037c12154c7cc8f9fa05e0fd8e1c606', u'6524af47405cc2e47c2f6990ffec78ad4fd7ba249a612eb9cda73b9f80c7c4bd', u'cc8e65bf1b8e36f252fe9535fcfbefd92238d2fd1fd60f05c9e7722cd28143ab', u'ee24bf9f4f194fe8cae0a4fdd4ef76df3e8443e4b1817c7d2de3c376ea889fae', u'58f7780bdfd84eded5c3e18c7e53829e66239547190e10c6025e8a378caf0810', u'd32b0331c16f88f8f836f4c23dc2f9d02530e5ae49b8ef500a7639f2c81c84c5', u'1c50e4cf4fcf50dcda11720f291204ec5fbc512f09bd7f013aeec36dfa45bb35', u'549dbacd6d5abc19f05c1761ef5369c5cfd4918f19aabb52e064504e733a54d1', u'330db71a9ed24b914f95623b395aa55526fc01d56c62b9850ca0d208f6b15a57', u'18353b74933f4116168a2bc05d757c6630b05ebaa5775b28f4659c7d97500c0e', u'e992473e97cda1f5abc993bd4607771ce822dbde277f1b9acc413c93b775ac79', u'4a3f8f03fcd823c44ce4ecfae3ce6f516e7eb0fe6c561cce42bb15fe168b6962', u'1fbf4d63e338dccbd70e174dfaa1e392d4d7aee1c9b035cb50abdebecc7e7695', u'982b82573f49925b8efc7ff072c089e246eae77375ff6c0e1d070e7ef040c9bf', u'9ee43d83ca4d513c42ca78458a700e7c6354ccde730cd52e25bf9bb7bfa16049', u'5c4faddc290082e3a1d8a3bd245a61a5c22e50f6fd9a4ca54b20124dd6200381', u'c8a829f1bc8f10d688f15f5e38e8528432e98faaab25af31b208a36ec60900e4', u'7ec4104d20c300c0808b229264480978a0f07230e4421d104d8641d569c7d15a', u'8f65b8c16c94b61e356d981a8b8c078e4846e451352207e049a2b7b24ade6e3a', u'083f7fd6376ed42f98efc8570b992f607d9c5afd350a49ee64e477df9fec5438', u'543ee60e3bc7686ef15c42cbc6fd8bb611d11b913ca813ec9ecd46b018c4fb8f', u'd5363c328a6cb1c0c73b896a6edb36ad7127b5abc90ed2817b82a76a1a3a9c49', u'f6d9836ab2ac54ebe2884653e2d5c7c030377dd50d6277d388fdbe3e312f8959', u'78947c32815ce5c67e76dd6ac1d2b5eeeb2678339047fbd1831ae97c67531130', u'ff65c9a69c11450e2c79396ea1d6a36fafbd22e00c7271fc23713874b9bd56ef', u'a6225e23e49d1a30f2e552a8c241fcd0fd6394e0241e110d9aebb3ed04b02ee3', u'ab9487c3bf742d6b99ce520cd219da3185fe25b9ded28e6122b4206ee4fd7f02', u'c69f155593e8bc5dd7a1f8c2f1dde772c7c9de8169b192c0e9a9ebf91581e9d2', u'ca714d4f72d212bbbb3521886ff2561f54506cdbb2515acb2d26842005fe7744'], 'auxpow': {'index': 0, 'tx': {'blockhash': '0000000000000000183e0cfc43ebb003724588e3ed9bee2d2f4a40dbcb4e5c14', 'vout': [{'scriptPubKey': {'reqSigs': 1, 'hex': '76a914c825a1ecf2a6830c4401620c3a16f1995057c2ab88ac', 'addresses': ['NEpeRmS775fnti8TDgJA28m8KLEfNNRZvT'], 'asm': 'OP_DUP OP_HASH160 c825a1ecf2a6830c4401620c3a16f1995057c2ab OP_EQUALVERIFY OP_CHECKSIG', 'type': 'pubkeyhash'}, 'value': 25.12535979, 'n': 0}], 'hex': '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5703dff204e4b883e5bda9e7a59ee4bb99e9b1bcfabe6d6d356d64a20fac1368d78b4ba4a5b8e27255bae8cf3c80e103097398d375e1340510000000000000004f99243aff0b00404d696e6564206279206e65696d656e67ffffffff01ab41c295000000001976a914c825a1ecf2a6830c4401620c3a16f1995057c2ab88ac00000000', 'vin': [{'coinbase': '03dff204e4b883e5bda9e7a59ee4bb99e9b1bcfabe6d6d356d64a20fac1368d78b4ba4a5b8e27255bae8cf3c80e103097398d375e1340510000000000000004f99243aff0b00404d696e6564206279206e65696d656e67', 'sequence': 4294967295L}], 'txid': '152c9d0325f1d27e441c24e763d3719a91b7b79f6ffad51aa0fa3148468b1683', 'version': 1, 'locktime': 0}, 'chainmerklebranch': ['000000000000000000000000000000000000000000000000000000000000000a', 'c3fddb1013f670f8fce68b8526c18adae3a7af32881050d5fbe270c048d81c67', '9d2ed3d67aadc96a850915606c88516cdd831f5ff10b92ca5927709d94c77e9f', '008e33cde7fe18e179b242069d862f522e0aa076b4ff5d89ac983e69c50c7067'], 'parentblock': '02000000160ff099d70aa2a465b98d0fcfa4dc857163162f1e8e63100000000000000000878c3efb32dfd9a435faea0f929d5fcb3474437ffbbc2eab76a5b59ad9adeb1c555e345493b81f18627b8c93', 'merklebranch': ['a965c40043a877f19aff55cdb7b4aeb6758eb1d0d50354bbc56487da417d87f6', '00c55a17c3902d4fffbb73cf105f9ea1878fa35c28a2e3e8fcf6cd012ccd07b5', '73fe25f370dfd405e76b60f7cb449020e61a21badf98a3874e8388a72a4bc938', '8e5e3f91e7f83f1b8e8fefdaedd58400cff181a6915105c297e8ad0e22bc50db', '05354f432d97fa96f9df91db3f1076ddadafd6d1dd07edd3f8fbade41600e271', 'fca389690b311eb7956a89aec770e5a1f83a4ce5986ada7cb64c51938d023616', '7df17af53f9d6eee0a6e0b5f10767fc2968defff48d842549069902b60eea42b', 'bfe8968c0f8be6e24e35763a86d532e4b001553a40964e5f30f6227d49a1e880', '0b868f467910e8c13cd37768d2dd862266feb9ed5b102c772720b4d71b362af5', 'de4b60b438ed8911e4ec7b49d7cfebc49e522f124e75d0cd57cca50f84cd224c'], 'chainindex': 11}, u'height': 200000, u'difficulty': 21001778950.12816, u'nextblockhash': u'3d3b02de326e6f39e275df6486af3f9621482c2172a7fe53be7417c82fa70de7', u'confirmations': 21514, u'version': 65793, u'time': 1412718165, u'tx': [u'f33e53065568d534b2eeec23ec45b538926573de3577a1f34bbe90c5b59b661d', u'a847b4b57667016d7331f5455d4d31c7dfb868d12f4763050c56f6acdabdc807', u'14f710d587791b4181b8783205247b4aea9f79cc9d7ccb9d06b4cbe2423b08be', u'2f17cd80f7adb98b77ea62ab004cfe6ac87bdc8dd5602d0065aef5002c8a27d1', u'3770bee4d9e0f6b754046ffb3b3c5a03bc9add35d948e7025b0f4e3cd1d6dee3', u'6083f86f0fa2e313aa6e45369bd1517fb903139808910755fbc4c102aafaf44e', u'9f28e177aadcb3b1cfdab7da931a3458024c4d74c086620cb2308474c84141be', u'b5b0fa2f475613fd3ffb54dfa57fdccc3e559d79abcc3570928014a8f6e627f1', u'f08934b0358f1c56ea0c5f8a05283274cc7de6278b901905bd7f2e2dc1db198d', u'9c9e13553137d550fefe41af09a5189cf80765025b814c8ba619d611e39f53a4', u'03c6ed02702f0fc590e23d071b56233d67d5e1c1392754f36282a3fb9c93b746', u'4b393f30959bb0a2d6d7f0d2a0945ca11c4e4b82fd29c50ae225f4b3a95e66ca', u'2952505577d5ab86a4e37060ee12dbd462394dbacf7873dc66bc7d15757b09c4', u'a17cecb5ab8b7439fde09767803c71a3fc54f2095156e2d7bd4003bc2064be52', u'd915fbe8102930e1249af3ab3c1aed94816e92a5903a00cbe67f4e1d8c763e6c', u'c96ae6d7d24b78212005190cf7f91b924c7a82ab74d53a1d1069353729348bca', u'4d2bd3262ba4698990ae36ca05553ca19037c12154c7cc8f9fa05e0fd8e1c606', u'6524af47405cc2e47c2f6990ffec78ad4fd7ba249a612eb9cda73b9f80c7c4bd', u'cc8e65bf1b8e36f252fe9535fcfbefd92238d2fd1fd60f05c9e7722cd28143ab', u'ee24bf9f4f194fe8cae0a4fdd4ef76df3e8443e4b1817c7d2de3c376ea889fae', u'58f7780bdfd84eded5c3e18c7e53829e66239547190e10c6025e8a378caf0810', u'd32b0331c16f88f8f836f4c23dc2f9d02530e5ae49b8ef500a7639f2c81c84c5'], u'bits': 406084155, u'n_tx': 22, u'size': 14258}
for b in [b10001, b19199, b200000]:
print "block height:", b["height"]
print "original block hash:", b["hash"]
print "hashed block ok:", hash_block(b) == b["hash"]
print "calculated merkle root ok:", get_merkle_root(b["tx"]) == b["merkleroot"]
print "pow check:", check_pow(b["hash"], b["bits"])
print
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment