Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/rawtransaction.cpp
Show First 20 Lines • Show All 747 Lines • ▼ Show 20 Lines | #endif | ||||
" \"txid\":\"id\", (string, required) The " | " \"txid\":\"id\", (string, required) The " | ||||
"transaction id\n" | "transaction id\n" | ||||
" \"vout\":n, (numeric, required) The " | " \"vout\":n, (numeric, required) The " | ||||
"output number\n" | "output number\n" | ||||
" \"scriptPubKey\": \"hex\", (string, required) script " | " \"scriptPubKey\": \"hex\", (string, required) script " | ||||
"key\n" | "key\n" | ||||
" \"redeemScript\": \"hex\", (string, required for P2SH " | " \"redeemScript\": \"hex\", (string, required for P2SH " | ||||
"or P2WSH) redeem script\n" | "or P2WSH) redeem script\n" | ||||
" \"amount\": \"value\" (string, required) The " | " \"amount\": value (numeric, required) The " | ||||
"decimal amount spent\n" | "amount spent\n" | ||||
" }\n" | " }\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ]\n" | " ]\n" | ||||
"3. \"privkeys\" (string, optional) A json array of " | "3. \"privkeys\" (string, optional) A json array of " | ||||
"base58-encoded private keys for signing\n" | "base58-encoded private keys for signing\n" | ||||
" [ (json array of strings, or 'null' if none " | " [ (json array of strings, or 'null' if none " | ||||
"provided)\n" | "provided)\n" | ||||
" \"privatekey\" (string) private key in base58-encoding\n" | " \"privatekey\" (string) private key in base58-encoding\n" | ||||
▲ Show 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | if (request.params.size() > 1 && !request.params[1].isNull()) { | ||||
UniValue prevOut = p.get_obj(); | UniValue prevOut = p.get_obj(); | ||||
RPCTypeCheckObj(prevOut, | RPCTypeCheckObj(prevOut, | ||||
{ | { | ||||
{"txid", UniValueType(UniValue::VSTR)}, | {"txid", UniValueType(UniValue::VSTR)}, | ||||
{"vout", UniValueType(UniValue::VNUM)}, | {"vout", UniValueType(UniValue::VNUM)}, | ||||
{"scriptPubKey", UniValueType(UniValue::VSTR)}, | {"scriptPubKey", UniValueType(UniValue::VSTR)}, | ||||
{"amount", UniValueType(UniValue::VSTR)}, | // "amount" is also required but check is done | ||||
// below due to UniValue::VNUM erroneously | |||||
// not accepting quoted numerics | |||||
// (which are valid JSON) | |||||
deadalnix: It's not about being valid json. It a string. We expect a (floating point) number. | |||||
}); | }); | ||||
uint256 txid = ParseHashO(prevOut, "txid"); | uint256 txid = ParseHashO(prevOut, "txid"); | ||||
int nOut = find_value(prevOut, "vout").get_int(); | int nOut = find_value(prevOut, "vout").get_int(); | ||||
if (nOut < 0) { | if (nOut < 0) { | ||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, | ||||
"vout must be positive"); | "vout must be positive"); | ||||
Show All 17 Lines | if (request.params.size() > 1 && !request.params[1].isNull()) { | ||||
coins->vout.resize(nOut + 1); | coins->vout.resize(nOut + 1); | ||||
} | } | ||||
coins->vout[nOut].scriptPubKey = scriptPubKey; | coins->vout[nOut].scriptPubKey = scriptPubKey; | ||||
coins->vout[nOut].nValue = 0; | coins->vout[nOut].nValue = 0; | ||||
if (prevOut.exists("amount")) { | if (prevOut.exists("amount")) { | ||||
coins->vout[nOut].nValue = | coins->vout[nOut].nValue = | ||||
AmountFromValue(find_value(prevOut, "amount")); | AmountFromValue(find_value(prevOut, "amount")); | ||||
} else { | |||||
// amount param is required in replay-protected txs. | |||||
// Note that we must check for its presence here rather | |||||
// than use RPCTypeCheckObj() above, since UniValue::VNUM | |||||
// parser incorrectly parses numerics with quotes, eg | |||||
// "3.12" as a string when JSON allows it to also parse | |||||
// as numeric. | |||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Missing amount"); | |||||
} | } | ||||
if (coins->vout[nOut].nValue <= 0LL) { | if (!MoneyRange(coins->vout[nOut].nValue)) { | ||||
// 'amount' param is now required to be >0 in signed tx | // 'amount' param is not a valid money range, so error | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
strprintf("Amount on previous output " | strprintf("amount on prevtx #%d, " | ||||
"%d must be >0", | "vout %d out of range", | ||||
nOut)); | int(idx), nOut)); | ||||
} | } | ||||
} | } | ||||
// If redeemScript given and not using the local wallet (private | // If redeemScript given and not using the local wallet (private | ||||
// keys given), add redeemScript to the tempKeystore so it can be | // keys given), add redeemScript to the tempKeystore so it can be | ||||
// signed: | // signed: | ||||
if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) { | if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) { | ||||
RPCTypeCheckObj( | RPCTypeCheckObj( | ||||
prevOut, { | prevOut, { | ||||
{"txid", UniValueType(UniValue::VSTR)}, | {"txid", UniValueType(UniValue::VSTR)}, | ||||
{"vout", UniValueType(UniValue::VNUM)}, | {"vout", UniValueType(UniValue::VNUM)}, | ||||
{"scriptPubKey", UniValueType(UniValue::VSTR)}, | {"scriptPubKey", UniValueType(UniValue::VSTR)}, | ||||
{"redeemScript", UniValueType(UniValue::VSTR)}, | {"redeemScript", UniValueType(UniValue::VSTR)}, | ||||
{"amount", UniValueType(UniValue::VSTR)}, | |||||
}); | }); | ||||
UniValue v = find_value(prevOut, "redeemScript"); | UniValue v = find_value(prevOut, "redeemScript"); | ||||
if (!v.isNull()) { | if (!v.isNull()) { | ||||
std::vector<unsigned char> rsData( | std::vector<unsigned char> rsData( | ||||
ParseHexV(v, "redeemScript")); | ParseHexV(v, "redeemScript")); | ||||
CScript redeemScript(rsData.begin(), rsData.end()); | CScript redeemScript(rsData.begin(), rsData.end()); | ||||
tempKeystore.AddCScript(redeemScript); | tempKeystore.AddCScript(redeemScript); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 228 Lines • Show Last 20 Lines |
It's not about being valid json. It a string. We expect a (floating point) number.