Esempio n. 1
0
def construct_send_basic(wallet, arguments):
    if not wallet:
        print("please open a wallet")
        return False
    if len(arguments) < 3:
        print("Not enough arguments")
        return False

    arguments, from_address = get_from_addr(arguments)
    arguments, priority_fee = get_fee(arguments)
    arguments, user_tx_attributes = get_tx_attr_from_args(arguments)
    arguments, owners = get_owners_from_params(arguments)
    to_send = get_arg(arguments)
    address_to = get_arg(arguments, 1)
    amount = get_arg(arguments, 2)

    assetId = get_asset_id(wallet, to_send)
    if assetId is None:
        print("Asset id not found")
        return False

    scripthash_to = lookup_addr_str(wallet, address_to)
    if scripthash_to is None:
        logger.debug("invalid address")
        return False

    scripthash_from = None
    if from_address is not None:
        scripthash_from = lookup_addr_str(wallet, from_address)
        if scripthash_from is None:
            logger.debug("invalid address")
            return False

    # if this is a token, we will use a different
    # transfer mechanism
    if type(assetId) is NEP5Token:
        return do_token_transfer(assetId, wallet, from_address, address_to, amount_from_string(assetId, amount), tx_attributes=user_tx_attributes)

    f8amount = get_asset_amount(amount, assetId)
    if f8amount is False:
        logger.debug("invalid amount")
        return False
    if float(amount) == 0:
        print("amount cannot be 0")
        return False

    fee = Fixed8.Zero()
    if priority_fee is not None:
        fee = priority_fee
        if fee is False:
            logger.debug("invalid fee")
            return False

    output = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash_to)
    contract_tx = ContractTransaction(outputs=[output])
    return [contract_tx, scripthash_from, fee, owners, user_tx_attributes]
Esempio n. 2
0
def construct_contract_withdrawal_request(wallet,
                                          arguments,
                                          fee=Fixed8.FromDecimal(.001),
                                          check_holds=False):

    if len(arguments) < 4:
        print("not enough arguments")
        return False

    # AG5xbb6QqHSUgDw8cHdyU73R1xy4qD7WEE neo AdMDZGto3xWozB1HSjjVv27RL3zUM8LzpV 20
    from_address = get_arg(arguments, 0)
    to_send = get_arg(arguments, 1)
    to_address = get_arg(arguments, 2)
    amount = get_arg(arguments, 3)

    assetId = get_asset_id(wallet, to_send)

    f8amount = get_asset_amount(amount, assetId)

    scripthash_to = wallet.ToScriptHash(to_address)

    scripthash_from = wallet.ToScriptHash(from_address)

    withdraw_from_watch_only = get_withdraw_from_watch_only(
        wallet, scripthash_from)

    if f8amount is None or scripthash_to is None or withdraw_from_watch_only is None:
        print("Could not process to or from addr or amount")
        return False

    output = TransactionOutput(AssetId=assetId,
                               Value=f8amount,
                               script_hash=scripthash_to)
    withdraw_tx = InvocationTransaction(outputs=[output])

    exclude_vin = None

    if check_holds:

        exclude_vin = lookup_contract_holds(wallet, scripthash_from)

    withdraw_constructed_tx = wallet.MakeTransaction(
        tx=withdraw_tx,
        change_address=scripthash_from,
        fee=fee,
        from_addr=scripthash_from,
        use_standard=False,
        watch_only_val=withdraw_from_watch_only,
        exclude_vin=exclude_vin)

    if withdraw_constructed_tx is not None:
        return withdraw_constructed_tx
Esempio n. 3
0
def construct_withdrawal_tx(wallet, args):

    from_address = get_arg(args, 0)
    assetId = get_asset_id(wallet, get_arg(args, 1))
    to_address = get_arg(args, 2)
    f8amount = get_asset_amount(get_arg(args, 3), assetId)

    scripthash_to = wallet.ToScriptHash(to_address)
    scripthash_from = wallet.ToScriptHash(from_address)

    withdraw_from_watch_only = get_withdraw_from_watch_only(
        wallet, scripthash_from)

    if f8amount is None or scripthash_to is None or withdraw_from_watch_only is None:
        print("Could not process to or from addr or amount")
        return False

    requested_vins = get_contract_holds_for_address(wallet, scripthash_from,
                                                    scripthash_to)
    use_vins_for_asset = [requested_vins, assetId]

    output = TransactionOutput(AssetId=assetId,
                               Value=f8amount,
                               script_hash=scripthash_to)
    withdraw_tx = InvocationTransaction(outputs=[output])

    withdraw_constructed_tx = wallet.MakeTransaction(
        tx=withdraw_tx,
        change_address=scripthash_from,
        fee=Fixed8.FromDecimal(.001),
        from_addr=scripthash_from,
        use_standard=False,
        watch_only_val=withdraw_from_watch_only,
        use_vins_for_asset=use_vins_for_asset)

    if withdraw_constructed_tx is not None:
        return withdraw_constructed_tx
Esempio n. 4
0
def construct_send_many(wallet, arguments):
    if not wallet:
        print("please open a wallet")
        return False
    if len(arguments) is 0:
        print("Not enough arguments")
        return False

    outgoing = get_arg(arguments, convert_to_int=True)
    if outgoing is None:
        print("invalid outgoing number")
        return False
    if outgoing < 1:
        print("outgoing number must be >= 1")
        return False

    arguments, from_address = get_from_addr(arguments)
    arguments, change_address = get_change_addr(arguments)
    arguments, priority_fee = get_fee(arguments)
    arguments, owners = get_owners_from_params(arguments)
    arguments, user_tx_attributes = get_tx_attr_from_args(arguments)

    output = []
    for i in range(outgoing):
        print('Outgoing Number ', i + 1)
        to_send = prompt("Asset to send: ")
        assetId = get_asset_id(wallet, to_send)
        if assetId is None:
            print("Asset id not found")
            return False
        if type(assetId) is NEP5Token:
            print('Sendmany does not support NEP5 tokens')
            return False
        address_to = prompt("Address to: ")
        scripthash_to = lookup_addr_str(wallet, address_to)
        if scripthash_to is None:
            logger.debug("invalid address")
            return False
        amount = prompt("Amount to send: ")
        f8amount = get_asset_amount(amount, assetId)
        if f8amount is False:
            logger.debug("invalid amount")
            return False
        if float(amount) == 0:
            print("amount cannot be 0")
            return False
        tx_output = TransactionOutput(AssetId=assetId,
                                      Value=f8amount,
                                      script_hash=scripthash_to)
        output.append(tx_output)
    contract_tx = ContractTransaction(outputs=output)

    scripthash_from = None

    if from_address is not None:
        scripthash_from = lookup_addr_str(wallet, from_address)
        if scripthash_from is None:
            logger.debug("invalid address")
            return False

    scripthash_change = None

    if change_address is not None:
        scripthash_change = lookup_addr_str(wallet, change_address)
        if scripthash_change is None:
            logger.debug("invalid address")
            return False

    fee = Fixed8.Zero()
    if priority_fee is not None:
        fee = priority_fee
        if fee is False:
            logger.debug("invalid fee")
            return False

    print("sending with fee: %s " % fee.ToString())
    return [
        contract_tx, scripthash_from, scripthash_change, fee, owners,
        user_tx_attributes
    ]
Esempio n. 5
0
def construct_send_many(wallet, arguments):
    if len(arguments) is 0:
        print("Please specify the required parameter")
        return

    outgoing = get_arg(arguments, convert_to_int=True)
    if outgoing is None:
        print("Invalid outgoing number")
        return
    if outgoing < 1:
        print("Outgoing number must be >= 1")
        return

    arguments, from_address = get_from_addr(arguments)
    arguments, change_address = get_change_addr(arguments)
    arguments, priority_fee = get_fee(arguments)
    arguments, owners = get_owners_from_params(arguments)
    arguments, user_tx_attributes = get_tx_attr_from_args(arguments)

    output = []
    for i in range(outgoing):
        try:
            print('Outgoing Number ', i + 1)
            to_send = prompt("Asset to send: ")
            assetId = get_asset_id(wallet, to_send)
            if assetId is None:
                print("Asset id not found")
                return
            if type(assetId) is NEP5Token:
                print('sendmany does not support NEP5 tokens')
                return
            address_to = prompt("Address to: ")
            scripthash_to = lookup_addr_str(wallet, address_to)
            if scripthash_to is None:
                logger.debug("invalid destination address")
                return
            amount = prompt("Amount to send: ")
            f8amount = get_asset_amount(amount, assetId)
            if f8amount is False:
                logger.debug("invalid amount")
                return
            if float(amount) == 0:
                print("Amount cannot be 0")
                return
            tx_output = TransactionOutput(AssetId=assetId,
                                          Value=f8amount,
                                          script_hash=scripthash_to)
            output.append(tx_output)
        except KeyboardInterrupt:
            print('Transaction cancelled')
            return
    contract_tx = ContractTransaction(outputs=output)

    scripthash_from = None

    if from_address is not None:
        scripthash_from = lookup_addr_str(wallet, from_address)
        if scripthash_from is None:
            logger.debug("invalid source address")
            return

    scripthash_change = None

    if change_address is not None:
        scripthash_change = lookup_addr_str(wallet, change_address)
        if scripthash_change is None:
            logger.debug("invalid change address")
            return

    fee = Fixed8.Zero()
    if priority_fee is not None:
        fee = priority_fee
        if fee is False:
            logger.debug("invalid fee")
            return

    print(f"Sending with fee: {fee.ToString()}")
    return [
        contract_tx, scripthash_from, scripthash_change, fee, owners,
        user_tx_attributes
    ]
def RequestWithdrawFrom(wallet, asset_id, contract_hash, to_addr, amount, require_password=True):
    asset_type = asset_id.lower()
    if asset_type not in ['neo', 'gas']:
        raise Exception('please specify neo or gas to withdraw')

    readable_addr = to_addr
    asset_id = get_asset_id(wallet, asset_type)

    contract = Blockchain.Default().GetContract(contract_hash)

    shash = contract.Code.ScriptHash()

    contract_addr = Crypto.ToAddress(shash)

    to_addr = parse_param(to_addr, wallet)
    amount = get_asset_amount(amount, asset_id)

    if shash not in wallet._watch_only:
        print("Add withdrawal contract address to your watch only: import watch_addr %s " % contract_addr)
        return False
    if amount < Fixed8.Zero():
        print("Cannot withdraw negative amount")
        return False

    unspents = wallet.FindUnspentCoinsByAssetAndTotal(
        asset_id=asset_id, amount=amount, from_addr=shash, use_standard=False, watch_only_val=64, reverse=True
    )

    if not unspents or len(unspents) == 0:
        print("no eligible withdrawal vins")
        return False

    balance = GetWithdrawalBalance(wallet, shash, to_addr, asset_type)

    balance_fixed8 = Fixed8(balance)
    orig_amount = amount
    if amount <= balance_fixed8:
        sb = ScriptBuilder()

        for uns in unspents:
            if amount > Fixed8.Zero():
                to_spend = amount
                if to_spend > uns.Output.Value:
                    to_spend = uns.Output.Value
                amount_bytes = bytearray(to_spend.value.to_bytes(8, 'little'))
                data = to_addr + amount_bytes
                data = data + uns.RefToBytes()
                sb.EmitAppCallWithOperationAndData(shash, 'withdraw_%s' % asset_type, data)
                amount -= uns.Output.Value

        tx, fee, results, num_ops = test_invoke(sb.ToArray(), wallet, [])

        for item in results:
            if not item.GetBoolean():
                print("Error performitng withdrawals")
                return False

        if require_password:
            print("\n---------------------------------------------------------------")
            print("Will make withdrawal request for %s %s from %s to %s " % (orig_amount.ToString(), asset_type, contract_addr, readable_addr))
            print("FEE IS %s " % fee.ToString())
            print("GAS IS %s " % tx.Gas.ToString())
            print("------------------------------------------------------------------\n")

            print("Enter your password to complete this request")

            passwd = prompt("[Password]> ", is_password=True)

            if not wallet.ValidatePassword(passwd):
                print("incorrect password")
                return

        result = InvokeContract(wallet, tx, fee)
        return result
    else:
        print("insufficient balance")
        return False