|
|
|
@ -289,9 +289,9 @@ UniValue verifytxoutproof(const JSONRPCRequest& request)
@@ -289,9 +289,9 @@ UniValue verifytxoutproof(const JSONRPCRequest& request)
|
|
|
|
|
|
|
|
|
|
UniValue createrawtransaction(const JSONRPCRequest& request) |
|
|
|
|
{ |
|
|
|
|
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) |
|
|
|
|
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) |
|
|
|
|
throw std::runtime_error( |
|
|
|
|
"createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...} ( locktime )\n" |
|
|
|
|
"createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...} ( locktime ) ( optintorbf )\n" |
|
|
|
|
"\nCreate a transaction spending the given inputs and creating new outputs.\n" |
|
|
|
|
"Outputs can be addresses or data.\n" |
|
|
|
|
"Returns hex-encoded raw transaction.\n" |
|
|
|
@ -315,6 +315,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
@@ -315,6 +315,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|
|
|
|
" ,...\n" |
|
|
|
|
" }\n" |
|
|
|
|
"3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n" |
|
|
|
|
"4. optintorbf (boolean, optional, default=false) Allow this transaction to be replaced by a transaction with higher fees\n" |
|
|
|
|
"\nResult:\n" |
|
|
|
|
"\"transaction\" (string) hex string of the transaction\n" |
|
|
|
|
|
|
|
|
@ -341,6 +342,8 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
@@ -341,6 +342,8 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|
|
|
|
rawTx.nLockTime = nLockTime; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool rbfOptIn = request.params.size() > 3 ? request.params[3].isTrue() : false; |
|
|
|
|
|
|
|
|
|
for (unsigned int idx = 0; idx < inputs.size(); idx++) { |
|
|
|
|
const UniValue& input = inputs[idx]; |
|
|
|
|
const UniValue& o = input.get_obj(); |
|
|
|
@ -354,17 +357,27 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
@@ -354,17 +357,27 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|
|
|
|
if (nOutput < 0) |
|
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); |
|
|
|
|
|
|
|
|
|
uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max()); |
|
|
|
|
uint32_t nSequence; |
|
|
|
|
if (rbfOptIn) { |
|
|
|
|
nSequence = std::numeric_limits<uint32_t>::max() - 2; |
|
|
|
|
} else if (rawTx.nLockTime) { |
|
|
|
|
nSequence = std::numeric_limits<uint32_t>::max() - 1; |
|
|
|
|
} else { |
|
|
|
|
nSequence = std::numeric_limits<uint32_t>::max(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// set the sequence number if passed in the parameters object
|
|
|
|
|
const UniValue& sequenceObj = find_value(o, "sequence"); |
|
|
|
|
if (sequenceObj.isNum()) { |
|
|
|
|
int64_t seqNr64 = sequenceObj.get_int64(); |
|
|
|
|
if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max()) |
|
|
|
|
if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max()) { |
|
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range"); |
|
|
|
|
else |
|
|
|
|
} else if (seqNr64 <= std::numeric_limits<uint32_t>::max() - 2 && request.params.size() > 3 && request.params[3].isFalse()) { |
|
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter combination: Sequence number contradicts optintorbf option"); |
|
|
|
|
} else { |
|
|
|
|
nSequence = (uint32_t)seqNr64; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence); |
|
|
|
|
|
|
|
|
|