示例#1
0
    def handleTxs(self, txs):
        result = []
        for tx in txs:
            if self.isValidTx(tx):
                result.append(tx)

                for inp in tx.inputs:
                    utxo = UTXO(inp.prevTxHash, inp.outputIndex)
                    self._pool.removeUTXO(utxo)

                for (i, out) in enumerate(tx.outputs):
                    utxo = UTXO(tx.hash, i)
                    self._pool.addUTXO(utxo, out)

        return result
示例#2
0
    def isValidTx(self, tx: Transaction):
        utxo_used_this_tx = []
        input_sum = 0
        output_sum = 0

        for i, inp in enumerate(tx.inputs):
            utxo = UTXO(inp.prev_tx_hash, inp.output_index)
            # (1)
            if not self.utxo_pool.contains(utxo):
                return False

            # (2)
            previous_tx_output_corresponding_to_inp = self.utxo_pool.get_transaction_output(
                utxo)
            public_key = previous_tx_output_corresponding_to_inp.address
            raw_tx_message = tx.get_raw_data_to_sign(i)
            if not Crypto.verify_signature(public_key, raw_tx_message,
                                           inp.signature):
                return False

            # (3)
            if utxo in utxo_used_this_tx:
                return False

            utxo_used_this_tx.append(utxo)
            input_sum += previous_tx_output_corresponding_to_inp.value

        # (4)
        for op in tx.outputs:
            if op.value < 0: return False
            output_sum += op.value

        # (5)
        return (input_sum >= output_sum)
示例#3
0
    def isValidTx(self, tx: Transaction) -> bool:
        inputSum = decimal.Decimal()
        pool = copy.deepcopy(self._pool)
        for (index, inp) in enumerate(tx.inputs):
            utxo = UTXO(inp.prevTxHash, inp.outputIndex)

            if not pool.contains(utxo):
                return False

            output = pool.getTxOutput(utxo)

            pubKey = output.address
            message = tx.getRawDataToSign(index)
            if not Crypto.verifySignature(pubKey, message, inp.signature):
                return False

            inputSum += output.value
            pool.removeUTXO(utxo)

        outputSum = decimal.Decimal()
        for out in tx.outputs:
            if out.value < 0:
                return False
            outputSum += out.value

        return inputSum >= outputSum
示例#4
0
    def handle_txs(self, possible_txs):
        valid_tx = []
        for tx in possible_txs:
            if not self.isValidTx(tx):
                continue

            valid_tx.append(tx)
            for inp in tx.inputs:
                used_utxo = UTXO(inp.prev_tx_hash, inp.output_index)
                self.utxo_pool.remove_utxo(used_utxo)

            tx_hashcode = tx.hashcode  # should this refresh ?
            for i, op in enumerate(tx.outputs):
                new_utxo = UTXO(tx_hashcode, i)
                self.utxo_pool.add_utxo(new_utxo, op)

        return valid_tx
示例#5
0
 def __init__(self):
     """Initialize the server to handle information."""
     parser_arguments = self.parse_commandline()
     (self.port, self.peers, self.difficulty, self.numtxinblock,
      self.numcores) = parser_arguments
     self.utxo = UTXO(self.numtxinblock, self.difficulty, self.numcores)
     self.message_map = self.message_mapping()  # Opcodes and message sizes
     self.socket = self.create_socket()
     self.close_status = mp.Value('i', 0)  # Checks close status
     self.socket_list = []  # Hold sockets for peers
     self.broadcasting = True
     self.listen_socket()  # Listen for clients
示例#6
0
def getBalance():
    if request.method == 'GET':
        return render_template('index.html', valid_email=True)
    elif request.method == 'POST':
        valid_email = True
        total_balance = -1
        utxo_acc = UTXO(request.form['email'])
        try:
            total_balance = utxo_acc.displayBalance()
        except:
            valid_email = False
        finally:
            return render_template('index.html',
                                   useremail=request.form['email'],
                                   total_balance=total_balance,
                                   valid_email=valid_email)
示例#7
0
 def add_coinbase_to_utxo_pool(self, block, utxo_pool):
     tx = block.coinbase
     for i, op in enumerate(tx.outputs):
         utxo = UTXO(tx.hashcode, i)
         utxo_pool.append(utxo, op)
示例#8
0
def generate_transaction(receiver, amount, commission):
    publicKey = Key._publicKey
    privateKey = Key._privateKey

    publicKey_ser = publicKey.serialize(compressed=False)

    total = 0
    in_counter = 0
    out_counter = 0
    vin = []
    vout = []
    tmpUTXO = []  # Temporary UTXOset for resulting transaction

    # Check if amount or commission is negative
    if amount <= 0 or commission < 0:
        print('Invalid input value')
        return False

    # Check if balance is sufficient
    for key, value in UTXOset._myUTXOset.iterator():
        d_value = json.loads(value)

        address_ser = base64.b64decode(d_value["address"])
        if address_ser != publicKey_ser:
            UTXOset.Pop_myUTXO(key, d_value["index"])
            continue

        tmpUTXO.append(
            UTXO(key, d_value["index"], d_value["address"], d_value["amount"]))
        total += d_value["amount"]
        if total > amount + commission:
            break

    # Insufficient balance
    if total < amount + commission:
        print('Insufficient BTC balance')
        return False

    # Generate inputs
    for output in tmpUTXO:
        total += output.amount
        in_counter += 1

        # Generate signatures
        unlockSig = privateKey.generate_sign(output.txOutid)
        unlock = privateKey.ecdsa_serialize(unlockSig)
        vin.append(Vin(output.txOutid, output.index, unlock))

    # Generate outputs
    vout.append(Vout(amount, receiver))
    change = total - commission - amount
    if change > 0:
        vout.append(Vout(change, publicKey_ser))

    # Generate tx_id
    SumString = str(in_counter)
    for input in vin:
        SumString = SumString + str(input.tx_id) + str(input.index) + str(
            input.unlock)
    SumString = SumString + str(out_counter)
    for output in vout:
        SumString = SumString + str(output.value) + str(output.lock)
    keccak_hash = keccak.new(digest_bits=256)
    keccak_hash.update(SumString.encode(
        'ascii'))  # keccak_hash == tx_id of current transaction

    # Add to UTXOset and myUTXOset
    address = base64.b64encode(receiver).decode('utf-8')
    UTXOset.Insert_UTXO(keccak_hash.hexdigest().encode(), 0, address,
                        float(amount))

    if (change > 0):
        address = base64.b64encode(publicKey_ser).decode('utf-8')
        UTXOset.Insert_UTXO(keccak_hash.hexdigest().encode(), 1, address,
                            float(amount))
        UTXOset.Insert_myUTXO(keccak_hash.hexdigest().encode(), 1, address,
                              float(amount))

    # Delete from UTXOset and myUTXOset
    for otuput in tmpUTXO:
        UTXOset.Pop_UTXO(output.txOutid, output.index)
        UTXOset.Pop_myUTXO(output.txOutid, output.index)

    # Add to memoryPool
    Transaction.Insert_MemoryPool(keccak_hash.hexdigest().encode(), in_counter,
                                  vin, out_counter, vout)

    return True
示例#9
0
 def removeInputWithUTXO(self, ut: UTXO):
     for index, inp in enumerate(self._inputs):
         u = UTXO(inp.prevTxHash, inp.outputIndex)
         if u == ut:
             self._inputs = self._inputs[:index] + self._inputs[index + 1:]
             return