class BlockIndexSerializer(): BLOCKINDEX = Structure([Field("<I", "version"), Uint256Serializer("hash_next"), Field("<I", "file"), Field("<I", "blockpos"), Field("<I", "height"), BlockheaderSerializer()], "txindex") def __init__(self): pass def serialize(self, blockindex_obj): return (self.BLOCKINDEX.serialize([blockindex_obj.version, blockindex_obj.hash_next, blockindex_obj.file, blockindex_obj.blockpos, blockindex_obj.height, blockindex_obj.blockheader])) def deserialize(self, data, cursor=0): result, cursor = self.BLOCKINDEX.deserialize(data, cursor) (version, hash_next, file, blockpos, height, blockheader) = result return (DbBlockIndex(version, hash_next, file, blockpos, height, blockheader), cursor)
def __init__( self, hash_prev, block_height, # version 2 blocks see BIP-34 coinbase_txout_list, transactions, time, bits, nonce=0, extra_nonce=0, coinbase_flags=["/P2SH/"]): self.nonce = nonce self.extra_nonce = extra_nonce self.hash_prev = hash_prev self.block_height = block_height self.coinbase_txout_list = coinbase_txout_list self.transactions = transactions self.time = time self.bits = bits self.coinbase_flags = coinbase_flags self.serializer = BlockheaderSerializer() self.rebuild_template()
def test_blockheader_serialize(self): h = BlockHeader( version=1, hash_prev=Uint256.from_hexstr( "1e4baab89f3a3251818c31bc87f6a33b4a5a88ef76673e2cc77ab2127b7afded" ), #hash_prev hash_merkle=Uint256.from_hexstr( "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b" ), #merkle time=1237006505, bits=486605799, nonce=2083236893) self.assertEquals( hexstr(BlockheaderSerializer().serialize(h)), "01000000edfd7a7b12b27ac72c3e6776ef885a4a3ba3f687bc318c8151323a9fb8aa4b1e3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4aa938bb49e703011d1dac2b7c" )
def _index_transactions(self, blockhash, block=None): block_handle = self.get_block_handle(blockhash) #Add all transactions to the indexdb if not block: block = block_handle.get_block() size_blockheader = BlockheaderSerializer().get_size(block.blockheader) size_tx_size = VarintSerializer().get_size(len(block.transactions)) tx_serializer = TxSerializer() blockpos = block_handle.blockindex.blockpos txpos = block_handle.blockindex.blockpos + size_blockheader + size_tx_size for i, tx in enumerate(block.transactions): txindex = DbTxIndex(1, DiskTxPos(1, blockpos, txpos), [DiskTxPos() for _ in range(tx.output_count())]) self.indexdb.set_transactionindex(hash_tx(tx), txindex) #TODO: speed this up... if tx.rawdata: txpos += len(tx.rawdata) else: txpos += tx_serializer.get_size(tx)
def __init__(self, hash_prev, block_height, # version 2 blocks see BIP-34 coinbase_txout_list, transactions, time, bits, nonce=0, extra_nonce=0, coinbase_flags=["/P2SH/"]): self.nonce = nonce self.extra_nonce = extra_nonce self.hash_prev = hash_prev self.block_height = block_height self.coinbase_txout_list = coinbase_txout_list self.transactions = transactions self.time = time self.bits = bits self.coinbase_flags = coinbase_flags self.serializer = BlockheaderSerializer() self.rebuild_template()
from coinpy.lib.serialization.structures.s11n_blockheader import BlockheaderSerializer from coinpy.model.protocol.structures.uint256 import Uint256 from coinpy.tools.bitcoin.sha256 import doublesha256 BLOCK_SERIALIZE = BlockheaderSerializer() def hash_blockheader(blockheader): if blockheader.hash: return blockheader.hash if not blockheader.rawdata: blockheader.rawdata = BLOCK_SERIALIZE.serialize(blockheader) blockheader.hash = Uint256.from_bytestr(doublesha256(blockheader.rawdata)) return blockheader.hash def hash_block(block): return (hash_blockheader(block.blockheader))
class BlockheaderTemplate(): def __init__( self, hash_prev, block_height, # version 2 blocks see BIP-34 coinbase_txout_list, transactions, time, bits, nonce=0, extra_nonce=0, coinbase_flags=["/P2SH/"]): self.nonce = nonce self.extra_nonce = extra_nonce self.hash_prev = hash_prev self.block_height = block_height self.coinbase_txout_list = coinbase_txout_list self.transactions = transactions self.time = time self.bits = bits self.coinbase_flags = coinbase_flags self.serializer = BlockheaderSerializer() self.rebuild_template() def rebuild_template(self): """Rebuild a version 2 blockheader and serialize it. oldest satoshi client coinbase script contains: nBits, bnExtraNonce (nBits = GetNextWorkRequired(pindexPrev);) later timestamp was used instead of "bits" to ensure coinbase txn is unique even if address is the same (github:83f4cd156e9d52bd7c4351336dfa4806a43ee4e4=. now in version 2 blocks the height is included instead of the timestamp. """ coinbase_script = Script( [push_bignum_instruction(self.block_height)] + [push_bignum_instruction(self.extra_nonce)] + [push_data_instruction(flag) for flag in self.coinbase_flags]) coinbase_txin = TxIn(Outpoint.null(), coinbase_script, sequence=TxIn.NSEQUENCE_FINAL) coinbase_tx = Tx(version=1, in_list=[coinbase_txin], out_list=self.coinbase_txout_list, locktime=0) self.block_transactions = [coinbase_tx] + self.transactions self.blockheader = BlockHeader(version=2, hash_prev=self.hash_prev, hash_merkle=compute_merkle_root( self.block_transactions), time=self.time, bits=self.bits, nonce=self.nonce) self.serialized = self.serializer.serialize(self.blockheader) def set_nonce(self, nonce): """Change the Nonce; Currently reserializes all. This needs to be optimized to just change the nonce bytes""" self.nonce = nonce self.rebuild_template() def set_time(self, time): self.time = time self.rebuild_template() def set_extra_nonce(self, extra_nonce): self.extra_nonce = extra_nonce self.rebuild_template() def get_serialized(self): return self.serialized def get_block(self): return Block(self.blockheader, self.block_transactions)
def __init__(self, flags=0): self.BLOCK = Structure([ BlockheaderSerializer(flags), VarsizelistSerializer(VarintSerializer("txn_count"), TxSerializer()) ], "block")
class BlockheaderTemplate(): def __init__(self, hash_prev, block_height, # version 2 blocks see BIP-34 coinbase_txout_list, transactions, time, bits, nonce=0, extra_nonce=0, coinbase_flags=["/P2SH/"]): self.nonce = nonce self.extra_nonce = extra_nonce self.hash_prev = hash_prev self.block_height = block_height self.coinbase_txout_list = coinbase_txout_list self.transactions = transactions self.time = time self.bits = bits self.coinbase_flags = coinbase_flags self.serializer = BlockheaderSerializer() self.rebuild_template() def rebuild_template(self): """Rebuild a version 2 blockheader and serialize it. oldest satoshi client coinbase script contains: nBits, bnExtraNonce (nBits = GetNextWorkRequired(pindexPrev);) later timestamp was used instead of "bits" to ensure coinbase txn is unique even if address is the same (github:83f4cd156e9d52bd7c4351336dfa4806a43ee4e4=. now in version 2 blocks the height is included instead of the timestamp. """ coinbase_script = Script([push_bignum_instruction(self.block_height)] + [push_bignum_instruction(self.extra_nonce)] + [push_data_instruction(flag) for flag in self.coinbase_flags]) coinbase_txin = TxIn(Outpoint.null(), coinbase_script, sequence=TxIn.NSEQUENCE_FINAL) coinbase_tx = Tx(version=1, in_list=[coinbase_txin], out_list=self.coinbase_txout_list, locktime=0) self.block_transactions = [coinbase_tx] + self.transactions self.blockheader = BlockHeader(version=2, hash_prev=self.hash_prev, hash_merkle=compute_merkle_root(self.block_transactions), time=self.time, bits=self.bits, nonce=self.nonce) self.serialized = self.serializer.serialize(self.blockheader) def set_nonce(self, nonce): """Change the Nonce; Currently reserializes all. This needs to be optimized to just change the nonce bytes""" self.nonce = nonce self.rebuild_template() def set_time(self, time): self.time = time self.rebuild_template() def set_extra_nonce(self, extra_nonce): self.extra_nonce = extra_nonce self.rebuild_template() def get_serialized(self): return self.serialized def get_block(self): return Block(self.blockheader, self.block_transactions)