Example #1
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