Subtract fee from amount
Fixes #2724 and #1570. Adds the automatically-subtract-the-fee-from-the-amount-and-send-whats-left feature to the GUI and RPC (sendtoaddress,sendmany).
This commit is contained in:
committed by
Wladimir J. van der Laan
parent
90a43c1e93
commit
292623adf5
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "addresstablemodel.h"
|
||||
#include "guiconstants.h"
|
||||
#include "guiutil.h"
|
||||
#include "paymentserver.h"
|
||||
#include "recentrequeststablemodel.h"
|
||||
#include "transactiontablemodel.h"
|
||||
@@ -192,8 +193,9 @@ bool WalletModel::validateAddress(const QString &address)
|
||||
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl)
|
||||
{
|
||||
CAmount total = 0;
|
||||
bool fSubtractFeeFromAmount = false;
|
||||
QList<SendCoinsRecipient> recipients = transaction.getRecipients();
|
||||
std::vector<std::pair<CScript, CAmount> > vecSend;
|
||||
std::vector<CRecipient> vecSend;
|
||||
|
||||
if(recipients.empty())
|
||||
{
|
||||
@@ -206,6 +208,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||
// Pre-check input data for validity
|
||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||
{
|
||||
if (rcp.fSubtractFeeFromAmount)
|
||||
fSubtractFeeFromAmount = true;
|
||||
|
||||
if (rcp.paymentRequest.IsInitialized())
|
||||
{ // PaymentRequest...
|
||||
CAmount subtotal = 0;
|
||||
@@ -217,7 +222,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||
subtotal += out.amount();
|
||||
const unsigned char* scriptStr = (const unsigned char*)out.script().data();
|
||||
CScript scriptPubKey(scriptStr, scriptStr+out.script().size());
|
||||
vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, out.amount()));
|
||||
CAmount nAmount = out.amount();
|
||||
CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount};
|
||||
vecSend.push_back(recipient);
|
||||
}
|
||||
if (subtotal <= 0)
|
||||
{
|
||||
@@ -239,7 +246,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||
++nAddresses;
|
||||
|
||||
CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
|
||||
vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, rcp.amount));
|
||||
CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount};
|
||||
vecSend.push_back(recipient);
|
||||
|
||||
total += rcp.amount;
|
||||
}
|
||||
@@ -260,17 +268,21 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
|
||||
transaction.newPossibleKeyChange(wallet);
|
||||
|
||||
CAmount nFeeRequired = 0;
|
||||
int nChangePosRet = -1;
|
||||
std::string strFailReason;
|
||||
|
||||
CWalletTx *newTx = transaction.getTransaction();
|
||||
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
||||
bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, strFailReason, coinControl);
|
||||
bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
|
||||
transaction.setTransactionFee(nFeeRequired);
|
||||
if (fSubtractFeeFromAmount && fCreated)
|
||||
transaction.reassignAmounts(nChangePosRet);
|
||||
|
||||
if(!fCreated)
|
||||
{
|
||||
if((total + nFeeRequired) > nBalance)
|
||||
if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
|
||||
{
|
||||
return SendCoinsReturn(AmountWithFeeExceedsBalance);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user