Beispiel #1
0
 def test_generate_key_pair(self):
     private_value_base58, public_value_compressed_base58 = generate_key_pair(
     )
     assert PrivateKey.encode(
         PrivateKey.decode(private_value_base58)) == private_value_base58
     assert PublicKey.encode(*PublicKey.decode(
         public_value_compressed_base58)) == public_value_compressed_base58
Beispiel #2
0
    def test_invalid_transactions_in_block(self, b, user_public_key, ):
        # invalid transaction
        valid_input = b.get_owned_ids(user_public_key).pop()
        tx_invalid = b.create_transaction('a', 'b', valid_input, 'c')

        block = b.create_block([tx_invalid])
        assert invalid_transactions == [tx_invalid]

        # create a block with invalid transactions
        block = {
            'timestamp': b.timestamp(),
            'transactions': [tx_invalid],
            'node_pubkey': b.me,
            'voters': b.federation_nodes
        }

        block_data = b.serialize(block)
        block_hash = hash_data(block_data)
        block_signature = PrivateKey(b.me_private).sign(block_data)

        block = {
            'id': block_hash,
            'block': block,
            'signature': block_signature,
            'votes': []
        }

        with pytest.raises(exceptions.TransactionOwnerError) as excinfo:
            b.validate_block(block)

        assert excinfo.value.args[0] == 'current_owner `a` does not own the input `{}`'.format(valid_input)
Beispiel #3
0
    def vote(self, block, previous_block_id, decision, invalid_reason=None):
        """Cast your vote on the block given the previous_block_hash and the decision (valid/invalid)
        return the block to the updated in the database.

        Args:
            block (dict): Block to vote.
            previous_block_id (str): The id of the previous block.
            decision (bool): Whether the block is valid or invalid.
            invalid_reason (Optional[str]): Reason the block is invalid

        """
        vote = {
            'voting_for_block': block['id'],
            'previous_block': previous_block_id,
            'is_block_valid': decision,
            'invalid_reason': invalid_reason,
            'timestamp': self.timestamp()
        }

        vote_data = self.serialize(vote)
        signature = PrivateKey(self.me_private).sign(vote_data)

        vote_signed = {
            'node_pubkey': self.me,
            'signature': signature,
            'vote': vote
        }

        return vote_signed
Beispiel #4
0
    def create_block(self, validated_transactions):
        """Creates a block given a list of `validated_transactions`.

        Note that this method does not validate the transactions. Transactions should be validated before
        calling create_block.

        Args:
            validated_transactions (list): list of validated transactions.

        Returns:
            dict: created block.

        """
        # Create the new block
        block = {
            'timestamp': self.timestamp(),
            'transactions': validated_transactions,
            'node_pubkey': self.me,
            'voters': self.federation_nodes + [self.me]
        }

        # Calculate the hash of the new block
        block_data = self.serialize(block)
        block_hash = hash_data(block_data)
        block_signature = PrivateKey(self.me_private).sign(block_data)

        block = {
            'id': block_hash,
            'block': block,
            'signature': block_signature,
            'votes': []
        }

        return block
Beispiel #5
0
    def sign_transaction(self, transaction, private_key):
        """Sign a transaction

        A transaction signed with the `current_owner` corresponding private key.

        Args:
            transaction (dict): transaction to sign.
            private_key (str): base58 encoded private key to create a signature of the transaction.

        Returns:
            dict: transaction with the `signature` field included.

        """
        private_key = PrivateKey(private_key)
        signature = private_key.sign(self.serialize(transaction))
        signed_transaction = transaction.copy()
        signed_transaction.update({'signature': signature})
        return signed_transaction
Beispiel #6
0
    def sign_transaction(self, transaction, private_key, public_key=None):
        """Sign a transaction

        A transaction signed with the `current_owner` corresponding private key.

        Args:
            transaction (dict): transaction to sign.
            private_key (str): base58 encoded private key to create a signature of the transaction.
            public_key (str): (optional) base58 encoded public key to identify each signature of a multisig transaction.
        Returns:
            dict: transaction with the `signature` field included.

        """
        private_key = PrivateKey(private_key)
        if len(transaction['transaction']['current_owners']) == 1:
            signatures_updated = private_key.sign(self.serialize(transaction))
        else:
            # multisig, sign for each input and store {pub_key: signature_for_priv_key}
            if public_key is None:
                raise ValueError(
                    'public_key must be provided for signing multisig transactions'
                )
            transaction_without_signatures = transaction.copy()
            signatures = transaction_without_signatures.pop('signatures') \
                if 'signatures' in transaction_without_signatures else []
            signatures_updated = signatures.copy()
            signatures_updated = [
                s for s in signatures_updated
                if not s['public_key'] == public_key
            ]
            signatures_updated.append({
                'public_key':
                public_key,
                'signature':
                private_key.sign(
                    self.serialize(transaction_without_signatures))
            })

        signed_transaction = transaction.copy()
        signed_transaction.update({'signatures': signatures_updated})
        return signed_transaction
Beispiel #7
0
 def test_sign_verify(self):
     message = 'Hello World!'
     public_key = PublicKey(self.PUBLIC_VALUE_COMPRESSED_B58)
     private_key = PrivateKey(self.PRIVATE_VALUE_B58)
     assert public_key.verify(message, private_key.sign(message)) is True
Beispiel #8
0
 def test_private_key_decode(self):
     private_value = PrivateKey.decode(self.PRIVATE_VALUE_B58)
     assert private_value == self.PRIVATE_VALUE
Beispiel #9
0
 def test_private_key_encode(self):
     private_value_base58 = PrivateKey.encode(self.PRIVATE_VALUE)
     assert private_value_base58 == self.PRIVATE_VALUE_B58
 def test_generate_key_pair(self):
     private_value_base58, public_value_compressed_base58 = generate_key_pair()
     assert PrivateKey.encode(
         PrivateKey.decode(private_value_base58)) == private_value_base58
     assert PublicKey.encode(
         *PublicKey.decode(public_value_compressed_base58)) == public_value_compressed_base58
 def test_sign_verify(self):
     message = 'Hello World!'
     public_key = PublicKey(self.PUBLIC_VALUE_COMPRESSED_B58)
     private_key = PrivateKey(self.PRIVATE_VALUE_B58)
     assert public_key.verify(message, private_key.sign(message)) == True
 def test_private_key_decode(self):
     private_value = PrivateKey.decode(self.PRIVATE_VALUE_B58)
     assert private_value == self.PRIVATE_VALUE
 def test_private_key_encode(self):
     private_value_base58 = PrivateKey.encode(self.PRIVATE_VALUE)
     assert private_value_base58 == self.PRIVATE_VALUE_B58