Exemplo n.º 1
0
    def parse_transactions(self, limit=0):
        """
        Parse raw transactions from Block, if transaction data is available in txs_data attribute. Creates
        Transaction objects in Block.transactions list

        :param limit: Maximum number of transactions to parse

        :return:
        """
        n = 0
        while self.txs_data and (limit == 0 or n < limit) and len(
                self.transactions) < self.tx_count:
            t = Transaction.parse_bytesio(
                self.txs_data, strict=False,
                network=self.network)  # , check_size=False
            self.transactions.append(t)
            n += 1
Exemplo n.º 2
0
    def from_raw(cls,
                 raw,
                 block_hash=None,
                 height=None,
                 parse_transactions=False,
                 limit=0,
                 network=DEFAULT_NETWORK):
        """
        Create Block object from raw serialized block in bytes.

        Get genesis block:

        >>> from bitcoinlib.services.services import Service
        >>> srv = Service()
        >>> b = srv.getblock(0)
        >>> b.block_hash.hex()
        '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'
        
        :param raw: Raw serialize block
        :type raw: bytes
        :param block_hash: Specify block hash if known to verify raw block. Value error will be raised if calculated block hash is different than specified.
        :type block_hash: bytes
        :param height: Specify height if known. Will be derived from coinbase transaction if not provided.
        :type height: int
        :param parse_transactions: Indicate if transactions in raw block need to be parsed and converted to Transaction objects. Default is False
        :type parse_transactions: bool
        :param limit: Maximum number of transactions to parse. Default is 0: parse all transactions. Only used if parse_transaction is set to True
        :type limit: int
        :param network: Name of network
        :type network: str

        :return Block:
        """
        block_hash_calc = double_sha256(raw[:80])[::-1]
        if not block_hash:
            block_hash = block_hash_calc
        elif block_hash != block_hash_calc:
            raise ValueError(
                "Provided block hash does not correspond to calculated block hash %s"
                % block_hash_calc.hex())

        version = raw[0:4][::-1]
        prev_block = raw[4:36][::-1]
        merkle_root = raw[36:68][::-1]
        time = raw[68:72][::-1]
        bits = raw[72:76][::-1]
        nonce = raw[76:80][::-1]
        tx_count, size = varbyteint_to_int(raw[80:89])
        txs_data = BytesIO(raw[80 + size:])

        # Parse coinbase transaction so we can extract extra information
        # transactions = [Transaction.parse(txs_data, network=network)]
        # txs_data = BytesIO(txs_data[transactions[0].size:])
        # block_txs_data = txs_data.read()
        txs_data_size = txs_data.seek(0, 2)
        txs_data.seek(0)
        transactions = []

        while parse_transactions and txs_data and txs_data.tell(
        ) < txs_data_size:
            if limit != 0 and len(transactions) >= limit:
                break
            t = Transaction.parse_bytesio(txs_data, strict=False)
            transactions.append(t)
            # t = transaction_deserialize(txs_data, network=network, check_size=False)
            # transactions.append(t)
            # txs_data = txs_data[t.size:]
            # TODO: verify transactions, need input value from previous txs
            # if verify and not t.verify():
            #     raise ValueError("Could not verify transaction %s in block %s" % (t.txid, block_hash))

        if parse_transactions and limit == 0 and tx_count != len(transactions):
            raise ValueError(
                "Number of found transactions %d is not equal to expected number %d"
                % (len(transactions), tx_count))

        block = cls(block_hash,
                    version,
                    prev_block,
                    merkle_root,
                    time,
                    bits,
                    nonce,
                    transactions,
                    height,
                    network=network)
        block.txs_data = txs_data
        block.tx_count = tx_count
        return block