def __init__(self, sender_pub, receiver_pub, amount, tx_inputs): self.sender = sender_pub self.receiver = receiver_pub self.amount = amount self.tx_inputs = tx_inputs self.time_stamp = time.time() self.tx_id = apply_sha256(sender_pub, receiver_pub, amount) self.signature = b""
def get_sign_data(self): """ Calculates the hash for the sender, recipient, amount and time stamp. @return: Sha hash string. """ # TODO: Include more members in sign data. data = apply_sha256(self.sender + self.receiver + str(self.amount)) return data
def _add_utxo_to_tx(transaction, sender_amount, recipient_amount, miner_amount): """ Creates and adds the UTXO to the transaction. @param transaction: TokenTX instance. @param sender_amount: Amount to send. @param recipient_amount: Amount to receive. @param miner_amount: Miners fee. @return: UTXO for the sender. """ recipient_utxo = TransactionOutput(apply_sha256(transaction.receiver), recipient_amount, transaction.tx_id, 0) sender_utxo = TransactionOutput(apply_sha256(transaction.sender), sender_amount, transaction.tx_id, 1) # miner_utxo = TransactionOutput(apply_sha256(self.coinbase.pk_str), miner_amount, transaction.tx_id, 2) transaction.tx_outputs = [recipient_utxo, sender_utxo] # Return UTXO return TransactionOutput(apply_sha256(transaction.sender), sender_amount, transaction.tx_id, 1)
def get_balance(self): """ Counts the total balance given all the UTXO. :return: Wallet balance. """ total = 0 hashed_pk = apply_sha256(self.pk_str) for tx_output in self.utxo: if tx_output.receiver == hashed_pk: total += tx_output.amount return total
def create_genesis_block(self, first_wallet, coinbase): amount = 21000000 genesis_tx = CoinTX(coinbase.pk_str, first_wallet.pk_str, amount, []) genesis_block = Block(0, [genesis_tx], "0") coinbase.sign_transaction(genesis_tx) self.utxo.add( TransactionOutput(apply_sha256(first_wallet.pk_str), amount, genesis_tx.tx_id, 0)) self.tx_position[genesis_tx.tx_id] = TXPosition(0, 0) genesis_block.hash = genesis_block.compute_hash() self.chain.append(genesis_block)
def get_balance(): total = 0 public_key = apply_sha256(request.args.get("public_key")) utxo = [] # Add all UTXO for tx_output in blockchain.utxo: if tx_output.receiver == public_key: total += tx_output.amount utxo.append(tx_output) return json.dumps({ "balance": total, "utxo": utxo }, default=JsonSerializable.dumper, indent=4)
def prepare_tx(self, recipient, amount): """ Creates and prepares a transaction that can later be sent to the network. NotEnoughFundsException will be raised if this wallet doesn't have enough funds. :param recipient: Recipient public key. :param amount: Amount to send. :return: Transaction object. """ tx_inputs = [] tx_remove = [] total = 0 hashed_pk = apply_sha256(self.pk_str) print("PREPAPE:", len(self.utxo)) for tx_output in self.utxo: if tx_output.receiver != hashed_pk: continue total += tx_output.amount tx_inputs.append(tx_output) tx_remove.append(tx_output) if total > amount: break if total < amount: raise NotEnoughFundsException for tx_output in tx_remove: self.utxo.remove(tx_output) new_tx = CoinTX(self.pk_str, recipient.pk_str, amount, tx_inputs) self.sign_transaction(new_tx) return new_tx
def _process_token_tx(transaction): """ Function to process and validate a TokenTX. Will check that referenced input-transactions exist and are valid in the block chain. Will be added to the mempool if it's valid. @param transaction: TokenTX instance. @return: True if valid, false if not. """ sender = apply_sha256(transaction.sender) tx_total = 0 try: _token_tx_is_valid(transaction) # Check that all input is valid. for input_tx in transaction.tx_inputs: # Check UTXO recipient key and sender key. if input_tx.receiver != sender: raise UtxoError("Public key does not match") # Check if input is unspent. if input_tx not in blockchain.utxo and input_tx not in blockchain.utxo_pool: raise UtxoNotFoundError # Find location of parent TX. block_idx, tx_idx = blockchain.tx_position[input_tx.parent_tx_id] # Check if parent TX is valid. if block_idx == len(blockchain.chain): origin_tx = blockchain.memory_pool[tx_idx] _token_tx_is_valid(origin_tx) else: origin_tx = blockchain.chain[block_idx].transactions[tx_idx] _token_tx_is_valid(origin_tx) tx_total += input_tx.amount # Check that the amount is not smaller than all inputs combined. if tx_total < transaction.amount: raise NotEnoughFundsException # Calculate left_over = tx_total - transaction.amount miner_amount = transaction.amount * 0.01 recipient_amount = transaction.amount # sender_amount = left_over - miner_amount sender_amount = left_over tx_pos = TXPosition(len(blockchain.chain), len(blockchain.memory_pool)) blockchain.tx_position[transaction.tx_id] = tx_pos utxo = _add_utxo_to_tx(transaction, sender_amount, recipient_amount, miner_amount) blockchain.memory_pool.add(transaction) blockchain.utxo_pool.add(utxo) return utxo except InvalidSignature: print("Invalid signature - Transaction failed.") return except NotEnoughFundsException: print("Not enough funds in all inputs - Transaction failed.") return except UtxoNotFoundError: print("UTXO of input does not exist - Transaction failed.") return except UtxoError: print("UTXO addresses does not match - Transaction failed.") return
def __hash__(self): return hash(apply_sha256(self.receiver, self.amount, self.parent_tx_id, self.vout))
def get_sign_data(self): return apply_sha256(self.file_hash)
from node.chain.blockchain import Blockchain from util.hash import apply_sha256 from wallet.network import genesis_wallet, coinbase peers = set() print("Start wallet:", apply_sha256(genesis_wallet.pk_str)[0:10]) blockchain = Blockchain() blockchain.create_genesis_block(genesis_wallet, coinbase=coinbase)
def get_sign_data(self): return public_key_to_string(self.sender) + apply_sha256( json.dumps(self.data, default=str))