mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 23:18:14 +01:00
Merge #9222: Add 'subtractFeeFromAmount' option to 'fundrawtransaction'.
453bda6 Add 'subtractFeeFromOutputs' option to 'fundrawtransaction'. (Chris Moore)
This commit is contained in:
@@ -2479,7 +2479,8 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
||||
throw runtime_error(
|
||||
"fundrawtransaction \"hexstring\" ( options )\n"
|
||||
"\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
|
||||
"This will not modify existing inputs, and will add one change output to the outputs.\n"
|
||||
"This will not modify existing inputs, and will add at most one change output to the outputs.\n"
|
||||
"No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
|
||||
"Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
|
||||
"The inputs added will not be signed, use signrawtransaction for that.\n"
|
||||
"Note that all existing inputs must have their previous output transaction be in the wallet.\n"
|
||||
@@ -2491,11 +2492,17 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
||||
"1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
|
||||
"2. options (object, optional)\n"
|
||||
" {\n"
|
||||
" \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n"
|
||||
" \"changePosition\" (numeric, optional, default random) The index of the change output\n"
|
||||
" \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
|
||||
" \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
|
||||
" \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n"
|
||||
" \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n"
|
||||
" \"changePosition\" (numeric, optional, default random) The index of the change output\n"
|
||||
" \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
|
||||
" \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
|
||||
" \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n"
|
||||
" \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n"
|
||||
" The fee will be equally deducted from the amount of each specified output.\n"
|
||||
" The outputs are specified by their zero-based index, before any change output is added.\n"
|
||||
" Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
|
||||
" If no outputs are specified here, the sender pays the fee.\n"
|
||||
" [vout_index,...]\n"
|
||||
" }\n"
|
||||
" for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
|
||||
"\nResult:\n"
|
||||
@@ -2523,6 +2530,8 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
||||
bool lockUnspents = false;
|
||||
CFeeRate feeRate = CFeeRate(0);
|
||||
bool overrideEstimatedFeerate = false;
|
||||
UniValue subtractFeeFromOutputs;
|
||||
set<int> setSubtractFeeFromOutputs;
|
||||
|
||||
if (request.params.size() > 1) {
|
||||
if (request.params[1].type() == UniValue::VBOOL) {
|
||||
@@ -2541,6 +2550,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
||||
{"includeWatching", UniValueType(UniValue::VBOOL)},
|
||||
{"lockUnspents", UniValueType(UniValue::VBOOL)},
|
||||
{"feeRate", UniValueType()}, // will be checked below
|
||||
{"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
|
||||
},
|
||||
true, true);
|
||||
|
||||
@@ -2567,6 +2577,9 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
||||
feeRate = CFeeRate(AmountFromValue(options["feeRate"]));
|
||||
overrideEstimatedFeerate = true;
|
||||
}
|
||||
|
||||
if (options.exists("subtractFeeFromOutputs"))
|
||||
subtractFeeFromOutputs = options["subtractFeeFromOutputs"].get_array();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2581,10 +2594,21 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
||||
if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > tx.vout.size()))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
|
||||
|
||||
for (unsigned int idx = 0; idx < subtractFeeFromOutputs.size(); idx++) {
|
||||
int pos = subtractFeeFromOutputs[idx].get_int();
|
||||
if (setSubtractFeeFromOutputs.count(pos))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, duplicated position: %d", pos));
|
||||
if (pos < 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, negative position: %d", pos));
|
||||
if (pos >= int(tx.vout.size()))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, position too large: %d", pos));
|
||||
setSubtractFeeFromOutputs.insert(pos);
|
||||
}
|
||||
|
||||
CAmount nFeeOut;
|
||||
string strFailReason;
|
||||
|
||||
if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress))
|
||||
if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, setSubtractFeeFromOutputs, changeAddress))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
|
||||
Reference in New Issue
Block a user