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)

        
Exemple #2
0
 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()
Exemple #3
0
 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"
     )
Exemple #4
0
 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)
Exemple #5
0
 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()
Exemple #6
0
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))



Exemple #7
0
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)
Exemple #8
0
 def __init__(self, flags=0):
     self.BLOCK = Structure([
         BlockheaderSerializer(flags),
         VarsizelistSerializer(VarintSerializer("txn_count"),
                               TxSerializer())
     ], "block")
Exemple #9
0
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)