Exemple #1
0
    def from_bytes(b):
        """ Creates a BlockHeader object from a serialized
        bytestream. This function "eats" the bytestream and
        returns the remainder of the stream after deserializing
        the fields of the BlockHeader.

        Args:
            b (bytes): bytes beginning with the (4-byte) version.

        Returns:
            bh, b (tuple): A tuple containing two elements - a BlockHeader object
            and the remainder of the bytestream after deserialization.
        """
        version, b = unpack_u32(b)
        prev_block_hash, b = Hash(b[0:32]), b[32:]
        merkle_root_hash, b = Hash(b[0:32]), b[32:]
        time, b = unpack_u32(b)
        bits, b = unpack_u32(b)
        nonce, b = unpack_u32(b)

        return (
            BlockHeader(version,
                        prev_block_hash,
                        merkle_root_hash,
                        time,
                        bits,
                        nonce),
            b
        )
Exemple #2
0
def _login_():
    if session.get("logged_in"):
        return {"error": Messages.ALREADY_LOGGED_IN}

    post = request.get_json()

    username = post.get("login")
    password = post.get("password")

    if not username:
        return {"error": Messages.USERNAME_REQUIRED}, 400

    if not password:
        return {"error": Messages.PASSWORD_REQUIRED}, 400

    user = Users.query.filter_by(username=username).first()

    if not user:
        return {"error": Messages.WRONG_LOGIN_DATA}, 401

    if not Hash.verify_password(user.password, password):
        return {"error": Messages.WRONG_LOGIN_DATA}, 401

    session['logged_in'] = True
    session['user_id'] = user.id

    return {"ok": Messages.SUCCESSFUL_LOGIN}
Exemple #3
0
    def hash(self):
        """ Computes the double SHA-256 hash of the serialized object.

        Returns:
            Hash: object containing the hash
        """
        return Hash.dhash(bytes(self))
Exemple #4
0
    def hash(self):
        """ Computes the hash of the transaction.

        Returns:
            dhash (bytes): Double SHA-256 hash of the serialized transaction.
        """
        return Hash.dhash(bytes(self))
    def _op_hash256(self):
        """ The input is hashed two times with SHA-256.
        """
        self._check_stack_len(1)

        x = self._stack.pop()
        self._stack.append(bytes(Hash.dhash(x)))
Exemple #6
0
    def _complete_merkle_edge(self):
        if self._cb_txn is None:
            # TODO: raise an error?
            return

        cur_hash = self._cb_txn.hash

        for e in self.merkle_edge:
            cur_hash = Hash.dhash(bytes(cur_hash) + bytes(e))

        self.block_header.merkle_root_hash = cur_hash
Exemple #7
0
    def __init__(self, height, version, prev_block_hash, time, bits, nonce, txns):
        self.block_header = BlockHeader(version,
                                        prev_block_hash,
                                        Hash(bytes(32)),  # Fake merkle_root for now
                                        time,
                                        bits,
                                        nonce)            # Fake nonce also

        self.height = height
        self.txns = txns

        self.merkle_tree = None
        self.invalidate()
Exemple #8
0
    def __init__(self, height, version, prev_block_hash, time, bits, merkle_edge, cb_txn=None):
        self.block_header = BlockHeader(version,
                                        prev_block_hash,
                                        Hash(bytes(32)),  # Fake merkle_root for now
                                        time,
                                        bits,
                                        0)                # Fake nonce also
        self.height = height
        self.merkle_edge = merkle_edge

        if cb_txn is not None:
            self.coinbase_transaction = cb_txn
        else:
            self._cb_txn = None
Exemple #9
0
    def _invalidate_coinbase(self, merkle_node=None):
        if merkle_node is None:
            merkle_node = self.merkle_tree

        if(merkle_node.left_child is None and
           merkle_node.right_child is None):
            # This is the node corresponding to the coinbase, update hash
            merkle_node.hash = self.coinbase_transaction.hash
            return
        else:
            self._invalidate_coinbase(merkle_node.left_child)

        merkle_node.hash = Hash.dhash(bytes(merkle_node.left_child.hash) +
                                      bytes(merkle_node.right_child.hash))

        # If we're back at the root, update the blockheader
        if merkle_node is self.merkle_tree:
            self.block_header.merkle_root_hash = self.merkle_tree.hash
Exemple #10
0
    def from_bytes(b):
        """ Deserializes a byte stream into a TransactionInput.

        Args:
            b (bytes): byte stream starting with the outpoint.

        Returns:
            tuple:
                 First element of the tuple is the TransactionInput
                 object and the second is the remaining byte stream.
        """
        outpoint = b[0:32]
        outpoint_index, b1 = unpack_u32(b[32:])
        script, b1 = Script.from_bytes(b1)
        sequence_num, b1 = unpack_u32(b1)

        return (TransactionInput(Hash(outpoint), outpoint_index, script,
                                 sequence_num), b1)
Exemple #11
0
    def get_signature_for_input(self, input_index, hash_type, private_key,
                                sub_script):
        """ Returns the signature for an input.

        This function only returns the signature for an input, it
        does not insert the signature into the script member of
        the input. It also does not validate that the given private key
        matches any public keys in the sub_script.

        Args:
            input_index (int): The index of the input to sign.
            hash_type (int): What kind of signature hash to do.
            private_key (crypto.PrivateKey): private key with which
                to sign the transaction.
            sub_script (Script): the scriptPubKey of the corresponding
                utxo being spent if the outpoint is P2PKH or the redeem
                script if the outpoint is P2SH.

        Returns:
            tuple:
                A tuple containing the signature object and the message that
                was signed.
        """
        if input_index < 0 or input_index >= len(self.inputs):
            raise ValueError("Invalid input index.")

        tmp_script = sub_script.remove_op("OP_CODESEPARATOR")
        if hash_type & 0x1f == self.SIG_HASH_SINGLE and len(self.inputs) > len(
                self.outputs):
            # This is to deal with the bug where specifying an index
            # that is out of range (wrt outputs) results in a
            # signature hash of 0x1 (little-endian)
            msg_to_sign = 0x1.to_bytes(32, 'little')
        else:
            txn_copy = self._copy_for_sig(input_index, hash_type, tmp_script)

            msg_to_sign = bytes(
                Hash.dhash(bytes(txn_copy) + pack_u32(hash_type)))

        sig = private_key.sign(msg_to_sign, False)

        return sig, msg_to_sign
Exemple #12
0
 def _compute_merkle_tree(self):
     """ Computes the merkle tree from the transactions in self.transactions.
         The merkle root is the top node in the tree and can be accessed as
         self.merkle_tree.merkle_hash.
     """
     # Tree gets built bottom up
     level_nodes = [MerkleNode(t.hash, None, None) for t in self.txns]
     while True:
         if len(level_nodes) == 1:
             self.merkle_tree = level_nodes[0]  # This is the root
             return
         if len(level_nodes) % 2 != 0:
             # Make sure there are an even number of nodes
             level_nodes.append(level_nodes[-1])
         new_level = []
         for i in range(0, len(level_nodes), 2):
             left = level_nodes[i]
             right = level_nodes[i+1]
             n = MerkleNode(Hash.dhash(bytes(left.hash) + bytes(right.hash)), left, right)
             new_level.append(n)
         level_nodes = new_level
Exemple #13
0
class CoinbaseInput(TransactionInput):
    """ See https://bitcoin.org/en/developer-reference#coinbase

    Args:
        height (uint): The height of the block coinbase is part of
                       will go into.  Not required for version 1
                       blocks.
        raw_script (bytes): the bytes of the coinbase script. For
                            block_version > 1 the height portion
                            should NOT be included in this script.
        sequence (int): Unless you are Satoshi with a version 1 block,
                        the default is fine. If you are Satoshi, send
                        me some of your private keys and set this to
                        0.
        block_version (int): The version of the block this coinbase is
                             a part of or will go into. If raw_script
                             already contains the height of the block,
                             this must be 1.
    """
    NULL_OUTPOINT = Hash(bytes(32))
    MAX_INT = 0xffffffff

    def __init__(self, height, raw_script, sequence=MAX_INT, block_version=3):
        self.height = height
        if block_version == 1:
            scr = raw_script
        else:
            scr = Script.build_push_int(self.height) + raw_script

        # Coinbase scripts are basically whatever, so we don't
        # try to create a script object from them.

        super().__init__(self.NULL_OUTPOINT, self.MAX_INT, scr, sequence)

    def get_addresses(self, testnet=False):
        """ Returns all addresses associated with the script in this input.

        Args:
            testnet (bool): True if the transaction is a testnet transaction.

        Returns:
            list (str): A list of all addresses found in the script.
        """
        return []

    def __str__(self):
        """ Returns a human readable formatting of this input.

        Returns:
            s (str): A string containing the human readable input.
        """
        return ("CoinbaseInput(" + "Outpoint: %s " % (self.outpoint) +
                "Outpoint Index: 0x%08x " % (self.outpoint_index) +
                "Script: %s " % (bytes_to_str(self.script)) +
                "Sequence: 0x%08x)" % (self.sequence_num))

    def __bytes__(self):
        """ Serializes the object into a byte stream.

        Returns:
            b (bytes): byte stream containing the serialized coinbase input.
        """
        return (bytes(self.outpoint) + pack_u32(self.outpoint_index) +
                pack_var_str(self.script) + pack_u32(self.sequence_num))