# Python 2.5
# I made this and I'm releasing it to the public domain.
# also check http://www.bitbin.it/AJUiYzbX
import time, hashlib
def hash256(x): return hashlib.sha256(hashlib.sha256(x).digest()).digest()
class fstring(): # file methods for strings
def __init__(self, somestring):
self.pos=0
self.string=somestring
def read(self, length=None):
if length==None: length=len(self.string)
out=self.string[self.pos:self.pos+length]; self.pos+=length
return out
def seek(self, point): self.pos=point
def tell(self): return self.pos
class txinput():
def __init__(self, handle):
if type(handle)==str: handle=fstring(handle)
startingpos = handle.tell()
self.prevouthash = handle.read(32)[::-1].encode('hex')
self.prevoutn = sum([ord(handle.read(1))*(256**x) for x in range(4)])
if self.prevouthash=='0'*64:
self.coinbasesize = ord(handle.read(1))
if self.coinbasesize>=253: self.coinbasesize = sum([ord(handle.read(1))*(256**x) for x in range(2*(self.coinbasesize-252))])
self.coinbase = handle.read(self.coinbasesize)
self.sequence = sum([ord(handle.read(1))*(256**x) for x in range(4)])
else:
self.scriptsize = ord(handle.read(1))
if self.scriptsize>=253: self.scriptsize = sum([ord(handle.read(1))*(256**x) for x in range(2*(self.scriptsize-252))])
self.script = handle.read(self.scriptsize)
self.sequence = sum([ord(handle.read(1))*(256**x) for x in range(4)])
class txoutput():
def __init__(self, handle):
if type(handle)==str: handle=fstring(handle)
startingpos = handle.tell()
self.value = sum([ord(handle.read(1))*(256**x) for x in range(8)])
self.scriptsize = ord(handle.read(1))
if self.scriptsize>=253: self.scriptsize = sum([ord(handle.read(1))*(256**x) for x in range(2*(self.scriptsize-252))])
self.script = handle.read(self.scriptsize)
#self.asm
class transaction():
def __init__(self, handle):
if type(handle)==str: handle=fstring(handle)
startingpos = handle.tell()
self.version = sum([ord(handle.read(1))*(256**x) for x in range(4)])
self.numinputs = ord(handle.read(1))
if self.numinputs>=253: self.numinputs = sum([ord(handle.read(1))*(256**x) for x in range(2*(self.numinputs-252))])
self.inputs = [txinput(handle) for inputnum in range(self.numinputs)]
self.numoutputs = ord(handle.read(1))
if self.numoutputs>=253: self.numoutputs = sum([ord(handle.read(1))*(256**x) for x in range(2*(self.numoutputs-252))])
self.outputs = [txoutput(handle) for outputnum in range(self.numoutputs)]
self.locktime = sum([ord(handle.read(1))*(256**x) for x in range(4)])
self.size = handle.tell() - startingpos; handle.seek(startingpos)
self.raw = handle.read(self.size)
self.hash = hash256(self.raw)[::-1].encode('hex')
class block():
def __init__(self, handle):
if type(handle)==str: handle=fstring(handle)
self.unknown = handle.read(8) # I don't know what this is
startingpos = handle.tell()
self.version = sum([ord(handle.read(1))*(256**x) for x in range(4)])
self.prevblock = handle.read(32)[::-1].encode('hex')
self.merkleroot = handle.read(32)[::-1].encode('hex')
self.timestamp = time.gmtime(sum([ord(handle.read(1))*(256**x) for x in range(4)]))
self.bits = sum([ord(handle.read(1))*(256**x) for x in range(4)])
self.nonce = sum([ord(handle.read(1))*(256**x) for x in range(4)])
handle.seek(startingpos)
self.header = handle.read(80)
self.hash = hash256(self.header)[::-1].encode('hex')
self.txcount = ord(handle.read(1))
if self.txcount>=253: self.txcount = sum([ord(handle.read(1))*(256**x) for x in range(2*(self.txcount-252))])
self.tx = [transaction(handle) for txn in range(self.txcount)]
self.size = handle.tell() - startingpos; handle.seek(startingpos)
self.raw = handle.read(self.size)
#self.merkletree
#self.isvalid() to verify merkle tree, hash, and difficulty
class blkfile():
def __init__(self, filename): self.file=file(filename,'rb+')
def tell(self): return self.file.tell()
def getblock(self): return block(self.file)
def readblock(self): return block(self.file).raw
# small demo
# defrag file if getblock is too slow. or simply copy in the same dir, delete original, and rename copy.
#blk0001=blkfile('some directory/blk0001.dat') # change this
#genesisblock=blk0001.getblock()
#for property in ['hash','prevblock','merkleroot','bits','nonce','version','txcount','timestamp','size']:
# print property,':',vars(genesisblock)[property]