Exemplo n.º 1
0
QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address, const OutputType address_type)
{
    std::string strLabel = label.toStdString();
    std::string strAddress = address.toStdString();

    editStatus = OK;

    if(type == Send)
    {
        if(!walletModel->validateAddress(address))
        {
            editStatus = INVALID_ADDRESS;
            return QString();
        }
        // Check for duplicate addresses
        {
            LOCK(wallet->cs_wallet);
            if(wallet->mapAddressBook.count(DecodeDestination(strAddress)))
            {
                editStatus = DUPLICATE_ADDRESS;
                return QString();
            }
        }
    }
    else if(type == Receive)
    {
        // Generate a new address to associate with given label
        CPubKey newKey;
        if(!wallet->GetKeyFromPool(newKey))
        {
            WalletModel::UnlockContext ctx(walletModel->requestUnlock());
            if(!ctx.isValid())
            {
                // Unlock wallet failed or was cancelled
                editStatus = WALLET_UNLOCK_FAILURE;
                return QString();
            }
            if(!wallet->GetKeyFromPool(newKey))
            {
                editStatus = KEY_GENERATION_FAILURE;
                return QString();
            }
        }
        wallet->LearnRelatedScripts(newKey, address_type);
        strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type));
    }
    else
    {
        return QString();
    }

    // Add entry
    {
        LOCK(wallet->cs_wallet);
        wallet->SetAddressBook(DecodeDestination(strAddress), strLabel,
                               (type == Send ? "send" : "receive"));
    }
    return QString::fromStdString(strAddress);
}
QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address, const OutputType address_type)
{
    std::string strLabel = label.toStdString();
    std::string strAddress = address.toStdString();

    editStatus = OK;

    if(type == Send)
    {
        if(!walletModel->validateAddress(address))
        {
            editStatus = INVALID_ADDRESS;
            return QString();
        }
        // Check for duplicate addresses
        {
            if (walletModel->wallet().getAddress(
                    DecodeDestination(strAddress), /* name= */ nullptr, /* is_mine= */ nullptr, /* purpose= */ nullptr))
            {
                editStatus = DUPLICATE_ADDRESS;
                return QString();
            }
        }
    }
    else if(type == Receive)
    {
        // Generate a new address to associate with given label
        CPubKey newKey;
        if(!walletModel->wallet().getKeyFromPool(false /* internal */, newKey))
        {
            WalletModel::UnlockContext ctx(walletModel->requestUnlock());
            if(!ctx.isValid())
            {
                // Unlock wallet failed or was cancelled
                editStatus = WALLET_UNLOCK_FAILURE;
                return QString();
            }
            if(!walletModel->wallet().getKeyFromPool(false /* internal */, newKey))
            {
                editStatus = KEY_GENERATION_FAILURE;
                return QString();
            }
        }
        walletModel->wallet().learnRelatedScripts(newKey, address_type);
        CPubKey blinding_pubkey = walletModel->wallet().getBlindingPubKey(GetScriptForDestination(GetDestinationForKey(newKey, address_type)));
        strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type, blinding_pubkey));
    }
    else
    {
        return QString();
    }

    // Add entry
    walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel,
                           (type == Send ? "send" : "receive"));
    return QString::fromStdString(strAddress);
}
Exemplo n.º 3
0
void PaymentServer::fetchPaymentACK(CWallet* wallet, const SendCoinsRecipient& recipient, QByteArray transaction)
{
    const payments::PaymentDetails& details = recipient.paymentRequest.getDetails();
    if (!details.has_payment_url())
        return;

    QNetworkRequest netRequest;
    netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTACK);
    netRequest.setUrl(QString::fromStdString(details.payment_url()));
    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BIP71_MIMETYPE_PAYMENT);
    netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
    netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTACK);

    payments::Payment payment;
    payment.set_merchant_data(details.merchant_data());
    payment.add_transactions(transaction.data(), transaction.size());

    // Create a new refund address, or re-use:
    QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant);
    std::string strAccount = account.toStdString();
    CPubKey newKey;
    if (wallet->GetKeyFromPool(newKey)) {
        // BIP70 requests encode the scriptPubKey directly, so we are not restricted to address
        // types supported by the receiver. As a result, we choose the address format we also
        // use for change. Despite an actual payment and not change, this is a close match:
        // it's the output type we use subject to privacy issues, but not restricted by what
        // other software supports.
        wallet->LearnRelatedScripts(newKey, g_change_type);
        CTxDestination dest = GetDestinationForKey(newKey, g_change_type);
        wallet->SetAddressBook(dest, strAccount, "refund");

        CScript s = GetScriptForDestination(dest);
        payments::Output* refund_to = payment.add_refund_to();
        refund_to->set_script(&s[0], s.size());
    } else {
        // This should never happen, because sending coins should have
        // just unlocked the wallet and refilled the keypool.
        qWarning() << "PaymentServer::fetchPaymentACK: Error getting refund key, refund_to not set";
    }

    int length = payment.ByteSize();
    netRequest.setHeader(QNetworkRequest::ContentLengthHeader, length);
    QByteArray serData(length, '\0');
    if (payment.SerializeToArray(serData.data(), length)) {
        netManager->post(netRequest, serData);
    }
    else {
        // This should never happen, either.
        qWarning() << "PaymentServer::fetchPaymentACK: Error serializing payment message";
    }
}