Nikhil18 (OP)
Newbie
Offline
Activity: 14
Merit: 0
|
|
October 02, 2016, 12:42:38 AM |
|
import sys import shelve import fileinput import bsddb # import ipdb # from IPython.core.debugger import Tracer
from math import sqrt from time import sleep import datetime from calendar import timegm
sys.path.append('.') sys.path.append('bitcointools') sys.path.append('BitcoinArmory') print sys.path
from armoryengine import * from armoryengine.BDM import BDM_BLOCKCHAIN_READY, TheBDM from bitcointools.deserialize import extract_public_key from bitcointools.util import short_hex, long_hex
# Run with: # PYTHONPATH=$PYTHONPATH:/home/<username>/bitcoin/armory/; python armory_block_reader.py --satoshi-datadir ~/.bitcoin_backup
def get_block_datetime(timestamp): # block_datetime = datetime.utcfromtimestamp(timestamp) block_datetime = datetime.utcfromtimestamp(timestamp) return "%d-%02d-%02d-%02d-%02d-%02d"%(block_datetime.year, block_datetime.month, block_datetime.day, block_datetime.hour, block_datetime.minute, block_datetime.second)
class BlockReader: def __init__(self): self.index_db = shelve.open('armory_index'); self.bdm = TheBDM self.verbose = False self.coinbase = '0000000000000000000000000000000000000000000000000000000000000000' # self.pk_dict = {} self.pk_dict = bsddb.hashopen('pk_dict.bdb', 'n', cachesize=2000000)
def cursory_check(self, t, lo=None, hi=None): if lo is None or hi is None: return False
loblk = self.bdm.getHeaderByHeight(lo) lopblk = PyBlockHeader().fromCpp(loblk)
hiblk = self.bdm.getHeaderByHeight(hi) hipblk = PyBlockHeader().fromCpp(hiblk)
if self.verbose: print 'Block: %i, @ %s' % (lo, get_block_datetime(lopblk.timestamp)) print 'Block: %i, @ %s' % (hi, get_block_datetime(hipblk.timestamp))
return lopblk.timestamp < t and hipblk.timestamp > t
def binary_search(self, t, lo, hi): pos = int((lo + hi) / 2) blk = self.bdm.getHeaderByHeight(pos) pblk = PyBlockHeader().fromCpp(blk)
# Write to db if not self.index_db.has_key(str(pos)): self.index_db[str(pos)] = get_block_datetime(pblk.timestamp) if self.verbose: print 'Lo: %i, Hi: %i, Pos: %i(%s)' % (lo, hi, pos, get_block_datetime(pblk.timestamp))
if (hi - lo) < 2: return self.binary_search(t, lo-1, lo+1) if (hi - lo) == 2: return pos if pblk.timestamp < t: return self.binary_search(t, pos, hi) elif pblk.timestamp > t: return self.binary_search(t, lo, pos)
def load_block_chain(self): start = datetime.datetime.now() self.bdm.setBlocking(True) self.bdm.setOnlineMode(True)
# The setOnlineMode should block until blockchain loading is complete print 'Loading blockchain took %0.1f sec' % (datetime.datetime.now() - start)
# Indexing print 'Indexing ...' if not self.index_db.has_key('top_block_height'): self.index_db['top_block_height'] = self.bdm.getTopBlockHeight()
print 'Top Block Height: ', self.index_db['top_block_height'] # t1 = timegm(datetime(2011,01,01,0,0,0).timetuple()) # t2 = timegm(datetime(2011,01,02,0,0,0).timetuple())
# silkroad-arrestg t1 = timegm(datetime(2013,3,25,18,0,0).timetuple()) t2 = timegm(datetime(2013,10,25,18,0,0).timetuple())
# # silkroad-arrest # t1 = timegm(datetime(2013,10,23,0,0,0).timetuple()) # t2 = timegm(datetime(2013,10,26,0,0,0).timetuple())
print '------------------------------------------' t1_check = self.cursory_check(t1, lo=0, hi=self.bdm.getTopBlockHeight()) t2_check = self.cursory_check(t2, lo=0, hi=self.bdm.getTopBlockHeight()) print 'Cursory Check t1 %s: %s' % (get_block_datetime(t1), t1_check) print 'Cursory Check t2 %s: %s' % (get_block_datetime(t2), t2_check)
print '------------------------------------------' t1_pos = self.binary_search(t1, lo=0, hi=self.bdm.getTopBlockHeight()) # t1_pos = 0; t2_pos = self.binary_search(t2, lo=0, hi=self.bdm.getTopBlockHeight()) print 'Binary Search t1 %s: %s' % (get_block_datetime(t1), t1_pos) print 'Binary Search t2 %s: %s' % (get_block_datetime(t2), t2_pos)
print '- Range [%i, %i] --------------------------' % (t1_pos, t2_pos+1) return range(t1_pos, t2_pos+1)
# pblk = PyBlockHeader().fromCpp(TheBDM.getTopBlockHeader()) # block_datetime = datetime.utcfromtimestamp(pblk.timestamp) # dt = "%d-%02d-%02d-%02d-%02d-%02d"%(block_datetime.year, block_datetime.month, # block_datetime.day, block_datetime.hour, # block_datetime.minute, block_datetime.second) # print 'Block: %s, @ %s\n' % (pblk.pprint(), dt) # print '-PBLK-------------------------------------' # print pblk.pprint() # print '------------------------------------------' # print '-BLK--------------------------------------' # print blk.pprint() # print '------------------------------------------'
# topBlock = TheBDM.getTopBlockHeight()
# print '\n\nCurrent Top Block is:', topBlock # TheBDM.getTopBlockHeader().pprint()
# PyBlock # ============== # version = # hashPrev = Prev Hash # hashMerkleRoot = MerkleRoot # nTime = Timestamp # nBits # nNonce = Nonce # transactions = getTxRefPtrList()
# PyTx # ============== # hash = TxHash # version = Version # lockTime = LockTime # = nInputs # = nOutputs
# PyTxIn # ============== # prevout_hash <=> PrevTxHash # prevout_n <=> TxOutIndex # scriptSig <=> Script # sequence <=> Seq
# PyTxOut # value <=> Value # scriptPubKey <= Script: PubKey() OP_CHECKSIG?? def ptx_print(self, tx, dt, writeout=False): # out = 'TImeslot dt: ', dt out = '' # out = {} ptx = PyTx().fromCpp(tx) tx_hash = ptx.getHashHex(endianness=BIGENDIAN) n_inputs = len(ptx.inputs) n_outputs = len(ptx.outputs) lock_time = ptx.lockTime
# Get TxIn info for i in range(tx.getNumTxIn()): ptxin = PyTxIn().fromCpp(tx.getTxIn(i)) # print '==> TxIn:', i # print ptxin.pprint() prev_tx_hash = binary_to_hex(ptxin.outpoint.txHash, BIGENDIAN)
# Only if writing if not writeout: continue
if prev_tx_hash == self.coinbase: out = ''.join([out, 'in\t' + tx_hash + '\tcoinbase\t' + dt + '\n']) else: inAddr160 = TxInScriptExtractAddr160IfAvail(ptxin)
pk = '(None)' if len(inAddr160)>0: pk = hash160_to_addrStr(inAddr160)
# if pk == '(None)' and prev_tx_hash != self.coinbase: # print '========================= ' # print '(None) ==== ', inAddr160 # print 'tx_hash ', tx_hash # print 'ptx_hash ', prev_tx_hash # print '========================= ' # # print ptx.pprint() # # print '========================= ' # # print ptxin.pprint() # sys.exit(1)
out = ''.join([out, 'in\t' + tx_hash + '\t' + prev_tx_hash + '\t' + \ str(ptxin.outpoint.txOutIndex) + '\t' + \ pk + '\t' + dt + '\n']) # print out
index = 0; for i in range(tx.getNumTxOut()): ptxout = PyTxOut().fromCpp(tx.getTxOut(i)) # print '==> TxOut:', i # print ptxout.pprint() recip = hash160_to_addrStr(tx.getTxOut(i).getRecipientAddr()); pk = TxOutScriptExtractAddrStr(ptxout.binScript) if writeout: out = ''.join([out, 'out\t' + tx_hash + '\t' + str(index) + '\t' + pk + \ '\t' + str(float(ptxout.value)/1.0e8) + '\t' + dt + '\n']) index += 1
# if prev_tx_hash == self.coinbase: # self.pk_dict[str(tx_hash)] = str(pk) # print '========================= ' # print 'Prev Tx Hash: ', prev_tx_hash # print 'Tx Hash: ', tx_hash # print 'pk: ', pk, tx.getNumTxOut() # print '========================= '
return out
def load_block(self, blockj, writeout=False): # Block info blk = self.bdm.getHeaderByHeight(blockj) pblk = PyBlockHeader().fromCpp(blk) if self.verbose: print '-PBLK-------------------------------------' print pblk.pprint() print '------------------------------------------' # print '-BLK--------------------------------------' # print blk.pprint() # print '------------------------------------------' dt = get_block_datetime(pblk.timestamp)
# Block tx list # Tracer()() txList = blk.getTxRefPtrList() # print '===> TxLIst: ', len(txList)
# For each tx in list out = [] for txref in txList: tx = txref.getTxCopy() # print '==========================' try: if writeout: out.append(self.ptx_print(tx, dt, writeout=True)) else: self.ptx_print(tx, dt, writeout=False) except: pass
if self.verbose: print '==========================' print out print '==========================' # print tx.pprint() return len(txList), ''.join(out)
if __name__ == "__main__": reader = BlockReader() blocks = reader.load_block_chain();
total_tx = 0; files = ['transactions-0.txt'] f = open(files[-1], 'w') for idx,block in enumerate(range(min(blocks), max(blocks))): if idx % 1000 == 0 and idx > 0: sys.stdout.write('%i blocks (%i transactions), ' % (idx, total_tx)) sys.stdout.flush()
if idx % 10000 == 0 and idx > 0: f.close() files.append('transactions-%i.txt' % idx) f = open(files[-1], 'w')
# Write out only if block in range writeout = block in blocks num_tx, info = reader.load_block(block, writeout=writeout) if writeout: total_tx += num_tx f.write(info) if f is not None: f.close() print 'Done: %i blocks (%i transactions) ' % (idx, total_tx)
|