|
|
@ -2464,7 +2464,8 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) |
|
|
|
throw runtime_error( |
|
|
|
throw runtime_error( |
|
|
|
"fundrawtransaction \"hexstring\" ( options )\n" |
|
|
|
"fundrawtransaction \"hexstring\" ( options )\n" |
|
|
|
"\nAdd inputs to a transaction until it has enough in value to meet its out value.\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" |
|
|
|
"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" |
|
|
|
"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" |
|
|
|
"Note that all existing inputs must have their previous output transaction be in the wallet.\n" |
|
|
@ -2476,11 +2477,17 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) |
|
|
|
"1. \"hexstring\" (string, required) The hex string of the raw transaction\n" |
|
|
|
"1. \"hexstring\" (string, required) The hex string of the raw transaction\n" |
|
|
|
"2. options (object, optional)\n" |
|
|
|
"2. options (object, optional)\n" |
|
|
|
" {\n" |
|
|
|
" {\n" |
|
|
|
" \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\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" |
|
|
|
" \"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" |
|
|
|
" \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" |
|
|
|
" \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\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" |
|
|
|
" \"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" |
|
|
|
" }\n" |
|
|
|
" for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n" |
|
|
|
" for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n" |
|
|
|
"\nResult:\n" |
|
|
|
"\nResult:\n" |
|
|
@ -2509,6 +2516,8 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) |
|
|
|
bool lockUnspents = false; |
|
|
|
bool lockUnspents = false; |
|
|
|
CFeeRate feeRate = CFeeRate(0); |
|
|
|
CFeeRate feeRate = CFeeRate(0); |
|
|
|
bool overrideEstimatedFeerate = false; |
|
|
|
bool overrideEstimatedFeerate = false; |
|
|
|
|
|
|
|
UniValue subtractFeeFromOutputs; |
|
|
|
|
|
|
|
set<int> setSubtractFeeFromOutputs; |
|
|
|
|
|
|
|
|
|
|
|
if (request.params.size() > 1) { |
|
|
|
if (request.params.size() > 1) { |
|
|
|
if (request.params[1].type() == UniValue::VBOOL) { |
|
|
|
if (request.params[1].type() == UniValue::VBOOL) { |
|
|
@ -2527,6 +2536,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) |
|
|
|
{"includeWatching", UniValueType(UniValue::VBOOL)}, |
|
|
|
{"includeWatching", UniValueType(UniValue::VBOOL)}, |
|
|
|
{"lockUnspents", UniValueType(UniValue::VBOOL)}, |
|
|
|
{"lockUnspents", UniValueType(UniValue::VBOOL)}, |
|
|
|
{"feeRate", UniValueType()}, // will be checked below
|
|
|
|
{"feeRate", UniValueType()}, // will be checked below
|
|
|
|
|
|
|
|
{"subtractFeeFromOutputs", UniValueType(UniValue::VARR)}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
true, true); |
|
|
|
true, true); |
|
|
|
|
|
|
|
|
|
|
@ -2553,6 +2563,9 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) |
|
|
|
feeRate = CFeeRate(AmountFromValue(options["feeRate"])); |
|
|
|
feeRate = CFeeRate(AmountFromValue(options["feeRate"])); |
|
|
|
overrideEstimatedFeerate = true; |
|
|
|
overrideEstimatedFeerate = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (options.exists("subtractFeeFromOutputs")) |
|
|
|
|
|
|
|
subtractFeeFromOutputs = options["subtractFeeFromOutputs"].get_array(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2567,10 +2580,21 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) |
|
|
|
if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > tx.vout.size())) |
|
|
|
if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > tx.vout.size())) |
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds"); |
|
|
|
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; |
|
|
|
CAmount nFeeOut; |
|
|
|
string strFailReason; |
|
|
|
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); |
|
|
|
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); |
|
|
|
|
|
|
|
|
|
|
|
UniValue result(UniValue::VOBJ); |
|
|
|
UniValue result(UniValue::VOBJ); |
|
|
|