Пример #1
0
    def test_transaction_add_signature(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        signature = wallet.sign_transaction(transaction)
        transaction.add_signature(signature)

        self.assertTrue(hasattr(transaction, "signature"))
Пример #2
0
    def test_transaction_to_json(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        content = transaction.to_json()

        self.assertIsInstance(content, str)
        self.assertGreater(len(content), 0)
Пример #3
0
    def test_transaction_verify_transaction_signature_too_large_signature(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        transaction.add_signature("3379cc2f08e4cde5d24af02611c32693b18f406d4b58fbcd2bbd0acc67b1d")
        verify = transaction.verify_transaction_signature()

        self.assertFalse(verify)
Пример #4
0
    def test_transaction_to_dict(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        content = transaction.to_dict()

        self.assertIsInstance(content, dict)
        self.assertEqual(list(content.keys()), ["sender", "recipient", "value", "fee"])
Пример #5
0
    def test_transaction_verify_transaction_signature(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        signature = wallet.sign_transaction(transaction)
        transaction.add_signature(signature)
        verify = transaction.verify_transaction_signature()

        self.assertTrue(verify)
Пример #6
0
    def test_block_initialize(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        signature = wallet.sign_transaction(transaction)
        transaction.add_signature(signature)
        block = Block(0, [transaction], datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"), "0")

        self.assertIsInstance(block, Block)
Пример #7
0
    def test_blockchain_add_new_transaction_not_enough_balance(self):
        wallet = Wallet()
        blockchain = Blockchain(wallet)
        transaction = Transaction(wallet.pubkey, "CityU", 100)
        signature = wallet.sign_transaction(transaction)
        transaction.add_signature(signature)
        blockchain.add_new_transaction(transaction)

        self.assertEqual(len(blockchain.unconfirmed_transactions), 0)
Пример #8
0
    def test_block_to_dict(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        signature = wallet.sign_transaction(transaction)
        transaction.add_signature(signature)
        block = Block(0, [transaction.to_json()], datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"), "0")
        content = block.to_dict()

        self.assertIsInstance(content, dict)
        self.assertEqual(list(content.keys()), ["index", "timestamp", "previous_hash", "merkle_root", "nonce", "difficulty"])
Пример #9
0
    def test_block_to_json(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        signature = wallet.sign_transaction(transaction)
        transaction.add_signature(signature)
        block = Block(0, [transaction.to_json()], datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"), "0")
        content = block.to_json()

        self.assertIsInstance(content, str)
        self.assertGreater(len(content), 0)
Пример #10
0
    def test_block_compute_hash(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        signature = wallet.sign_transaction(transaction)
        transaction.add_signature(signature)
        block = Block(0, [transaction.to_json()], datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"), "0")
        hash_val = block.compute_hash()

        self.assertIsInstance(hash_val, str)
        self.assertGreater(len(hash_val), 0)
Пример #11
0
    def test_blockchain_proof_of_work_bad_block(self):
        wallet = Wallet()
        blockchain = Blockchain(wallet)
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        signature = wallet.sign_transaction(transaction)
        transaction.add_signature(signature)
        previous_hash = blockchain.last_block["hash"]
        block = Block(0, [transaction.to_json()], datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"), previous_hash)
        delattr(block, "transaction")

        self.assertRaises(AttributeError, blockchain.proof_of_work, block)
Пример #12
0
 def test_blockchain_proof_of_work(self):
     wallet = Wallet()
     blockchain = Blockchain(wallet)
     transaction = Transaction(wallet.pubkey, "CityU", 1)
     signature = wallet.sign_transaction(transaction)
     transaction.add_signature(signature)
     previous_hash = blockchain.last_block["hash"]
     block = Block(0, [transaction.to_json()], datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"), previous_hash)
     computed_hash = blockchain.proof_of_work(block)
     
     self.assertGreater(len(computed_hash), 0)
Пример #13
0
    def test_blockchain_add_block_wrong_previous_hash(self):
        wallet = Wallet()
        blockchain = Blockchain(wallet)
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        signature = wallet.sign_transaction(transaction)
        transaction.add_signature(signature)
        block = Block(0, [transaction.to_json()], datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"), "Wrong")
        computed_hash = blockchain.proof_of_work(block)
        result = blockchain.add_block(block, computed_hash)

        self.assertFalse(result)
Пример #14
0
 def add_new_transaction(self, transaction: Transaction) -> bool:
     '''
     add a new transaction to the block
     after checking balance
     '''
     if transaction.verify_transaction_signature():
         # Check balance and fee before confirming a transaction
         total_charge = float(transaction.value) + float(transaction.fee)
         if transaction.sender != "Block_Reward" and \
                 self.check_balance(transaction.sender) >= total_charge:
             self.unconfirmed_transactions.append(transaction.to_json())
             return True
     return False
Пример #15
0
def new_transaction_signed():
    values = request.form
    required = ['sender', 'recipient_address', 'value', 'signature']
    # Check that the required fields are in the POST data
    if not all(k in values for k in required):
        return 'Missing values', 400
    transaction = Transaction(values['sender'], values['recipient_address'], values['value'])
    transaction.signature = values['signature']
    transaction_result = blockchain.add_new_transaction(transaction)
    if transaction_result:
        response = {'message': 'Transaction will be added to Block'}
        return jsonify(response), 201
    else:
        response = {'message': 'Invalid Transaction!'}
        return jsonify(response), 406
Пример #16
0
def merkle_path():
    values = request.form
    required = ['sender', 'recipient', 'value']
    # Check that the required fields are in the POST data
    if not all(k in values for k in required):
        return 'Missing values', 400
    transaction = Transaction(values.get('sender'), values.get('recipient'), values.get('value'))
    if values.get('signature'):
        transaction.signature = values.get('signature')
    path = blockchain.merkle_path(transaction)

    if len(path) > 0:
        root = path[-1]
        path = path[:-1]
    return jsonify(path), 200
Пример #17
0
def partial_validation():
    values = request.form
    required = ['root', 'path', 'sender', 'recipient', 'value']
    # Check that the required fields are in the POST data
    if not all(k in values for k in required):
        return 'Missing values', 400
    root = values.get('root')
    path = json.loads(values.get('path'))
    transaction = Transaction(values.get('sender'), values.get('recipient'), values.get('value'))
    if values.get('signature'):
        transaction.signature = values.get('signature')
    h = sha256(str(transaction.to_json()).encode()).hexdigest()
    new_root = blockchain.partialValidation(path, h)
    result = root == new_root
    return jsonify(result), 200
Пример #18
0
    def search_block_with_transaction(self, transactionHash):
        '''return block that matches given transaction hash'''
        fullchain = [json.loads(block) for block in self.chain]
        for block in fullchain[::-1]:
            for trans in block['transaction']:
                trans = json.loads(trans)
                new_trans = Transaction(trans['sender'], trans['recipient'],
                                        trans['value'])
                if 'signature' in trans.keys():
                    new_trans.signature = trans['signature']
                new_transHash = sha256(str(
                    new_trans.to_json()).encode()).hexdigest()

                if transactionHash == new_transHash:
                    return block
        return False
Пример #19
0
    def test_wallet_sign_transaction_valid(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        signature = wallet.sign_transaction(transaction)

        self.assertIsInstance(signature, str)
        self.assertGreater(len(signature), 0)
Пример #20
0
def new_transaction():
    '''This API adds transactions to the transaction pool'''
    values = request.form
    required = ['recipient_address', 'value']
    # Check that the required fields are in the POST data
    if not all(k in values for k in required):
        return 'Missing values', 400
    transaction = Transaction(myWallet.pubkey, values['recipient_address'], values['value'])
    transaction.add_signature(myWallet.sign_transaction(transaction))
    transaction_result = blockchain.add_new_transaction(transaction)
    if transaction_result:
        response = {'message': 'Transaction will be added to Block'}
        return jsonify(response), 201
    else:
        response = {'message': 'Invalid Transaction!'}
        return jsonify(response), 406
Пример #21
0
 def create_interest_transactions(self, addresses) -> List[Transaction]:
     '''check balance of each address and generate interest transaction'''
     interest_txs = []
     for address in addresses:
         balance = self.check_balance(address)
         interest = balance * self.INTEREST
         interest_tx = Transaction("Block_Reward", address, str(interest))
         interest_txs.append(interest_tx)
     return interest_txs
Пример #22
0
 def sign_transaction(self, transaction: Transaction) -> str:
     '''
     method to return the signature that is coming from the actual owner in a transaction
     implemented in the Wallet class instead of Transaction class to protect the private key from illegal access
     '''
     signer = PKCS1_v1_5.new(self._private_key)
     payload = str(transaction.to_dict()).encode('utf-8')
     h = SHA.new(payload)
     return binascii.hexlify(signer.sign(h)).decode('ascii')
Пример #23
0
 def create_genesis_block(self, wallet: Wallet):
     '''method to create and puts the genesis block into the blockchain'''
     block_reward = Transaction("Block_Reward", wallet.pubkey,
                                "5.0").to_json()
     genesis_block = Block(
         0, [block_reward],
         datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"), "0")
     # Hash of genesis block cannot be computed directly, proof of work is needed
     genesis_block.hash = self.proof_of_work(genesis_block)
     self.chain.append(genesis_block.to_json())
Пример #24
0
    def mine(self, wallet: Wallet) -> Union[Block, bool]:
        '''
        method to generate new blocks and claim the block reward and all the transaction fees
        It confirms all unconfirmed transactions into blocks by using the proof-of-work method.
        convert to JSON to store transaction in the blockchain
        '''
        # get all available wallet addresses in the network
        addresses = self.get_addresses_from_transactions()
        # create Transaction objects for interest
        interest_txs = self.create_interest_transactions(addresses)
        for interest_tx in interest_txs:
            self.unconfirmed_transactions.insert(0, interest_tx.to_json())

        # add up all the transaction fee from all unconfirmed transactions
        tx_fees = [
            float(json.loads(transaction)['fee'])
            for transaction in self.unconfirmed_transactions
        ]
        total_tx_fee = sum(tx_fees)
        # create and add a transaction into the list of unconfirmed transactions
        # for sending out a block reward, which also include all of their transaction fees
        block_reward = Transaction("Block_Reward", wallet.pubkey,
                                   str(5.0 + total_tx_fee))
        self.unconfirmed_transactions.insert(0, block_reward.to_json())

        # if there are no unconfirmed transactions, return False
        if not self.unconfirmed_transactions:
            return False

        new_block = Block(
            index=self.last_block['index'] + 1,
            transaction=self.unconfirmed_transactions,
            timestamp=datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"),
            previous_hash=self.last_block['hash'])
        new_block.difficulty = self.next_difficulty(self.last_block)

        proof = self.proof_of_work(new_block)
        if self.add_block(new_block, proof):
            self.unconfirmed_transactions = []
            return new_block
        else:
            return False
Пример #25
0
    def merkle_path(self, transaction: Transaction):
        '''return merkle path of given transaction'''
        path = []
        transactionHash = sha256(str(
            transaction.to_json()).encode()).hexdigest()

        block = self.search_block_with_transaction(transactionHash)
        leaves = []
        if block:
            for trans in block['transaction']:
                trans = json.loads(trans)
                new_trans = Transaction(trans['sender'], trans['recipient'],
                                        trans['value'])
                if 'signature' in trans.keys():
                    new_trans.signature = trans['signature']
                new_transHash = sha256(str(
                    new_trans.to_json()).encode()).hexdigest()
                leaves.append(new_transHash)
            path = self._merklePath(leaves, transactionHash, [])
            path.append(block['merkle_root'])
        return path
Пример #26
0
    def valid_chain(self, chain: List[str]) -> bool:
        '''check if a blockchain (all blocks) is valid'''
        current_index = 0
        chain = json.loads(chain)

        # load and check every block from the blockchain
        while current_index < len(chain):
            block = json.loads(chain[current_index])
            current_block = Block(block['index'], block['transaction'],
                                  block['timestamp'], block['previous_hash'])
            current_block.merkle_root = block['merkle_root']
            current_block.nonce = block['nonce']
            current_block.difficulty = block['difficulty']

            # if the current block is NOT the last block
            if current_index + 1 < len(chain):
                # if the hash value of the current block != previous block's hash value of the next block, then reject
                if current_block.compute_hash() != json.loads(
                        chain[current_index + 1])['previous_hash']:
                    return False
            # check if the current block is an instance from the list of chain
            if isinstance(current_block.transaction, list):
                for transaction in current_block.transaction:
                    transaction = json.loads(transaction)
                    # Skip block reward because it does not have signature
                    if transaction['sender'] == 'Block_Reward':
                        continue
                    current_transaction = Transaction(transaction['sender'],
                                                      transaction['recipient'],
                                                      transaction['value'])
                    current_transaction.signature = transaction['signature']
                    # check if digital signature of each transaction is valid, if not then reject
                    if not current_transaction.verify_transaction_signature():
                        return False
                # check if hash value of the current block is not valid, if yes then reject
                if not self.is_valid_proof(current_block, block['hash']):
                    return False
            current_index += 1
        return True
Пример #27
0
    def test_transaction_verify_transaction_signature_no_signature(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)
        verify = transaction.verify_transaction_signature()

        self.assertFalse(verify)
Пример #28
0
    def test_transaction_initialize(self):
        wallet = Wallet()
        transaction = Transaction(wallet.pubkey, "CityU", 1)

        self.assertIsInstance(transaction, Transaction)