Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/rawtransaction.cpp
Show First 20 Lines • Show All 909 Lines • ▼ Show 20 Lines | if (request.params.size() > 1 && !request.params[1].isNull()) { | ||||
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"); | ||||
} | } | ||||
COutPoint out(txid, nOut); | |||||
std::vector<uint8_t> pkData(ParseHexO(prevOut, "scriptPubKey")); | std::vector<uint8_t> pkData(ParseHexO(prevOut, "scriptPubKey")); | ||||
CScript scriptPubKey(pkData.begin(), pkData.end()); | CScript scriptPubKey(pkData.begin(), pkData.end()); | ||||
{ | { | ||||
CCoinsModifier coins = view.ModifyCoins(txid); | const Coin &coin = view.AccessCoin(out); | ||||
if (coins->IsAvailable(nOut) && | if (!coin.IsSpent() && | ||||
coins->vout[nOut].scriptPubKey != scriptPubKey) { | coin.GetTxOut().scriptPubKey != scriptPubKey) { | ||||
std::string err("Previous output scriptPubKey mismatch:\n"); | std::string err("Previous output scriptPubKey mismatch:\n"); | ||||
err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + | err = err + ScriptToAsmStr(coin.GetTxOut().scriptPubKey) + | ||||
"\nvs:\n" + ScriptToAsmStr(scriptPubKey); | "\nvs:\n" + ScriptToAsmStr(scriptPubKey); | ||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err); | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err); | ||||
} | } | ||||
if ((unsigned int)nOut >= coins->vout.size()) { | CTxOut txout; | ||||
coins->vout.resize(nOut + 1); | txout.scriptPubKey = scriptPubKey; | ||||
} | txout.nValue = 0; | ||||
coins->vout[nOut].scriptPubKey = scriptPubKey; | |||||
coins->vout[nOut].nValue = 0; | |||||
if (prevOut.exists("amount")) { | if (prevOut.exists("amount")) { | ||||
coins->vout[nOut].nValue = | txout.nValue = | ||||
AmountFromValue(find_value(prevOut, "amount")); | AmountFromValue(find_value(prevOut, "amount")); | ||||
} else { | } else { | ||||
// amount param is required in replay-protected txs. | // amount param is required in replay-protected txs. | ||||
// Note that we must check for its presence here rather | // Note that we must check for its presence here rather | ||||
// than use RPCTypeCheckObj() above, since UniValue::VNUM | // than use RPCTypeCheckObj() above, since UniValue::VNUM | ||||
// parser incorrectly parses numerics with quotes, eg | // parser incorrectly parses numerics with quotes, eg | ||||
// "3.12" as a string when JSON allows it to also parse | // "3.12" as a string when JSON allows it to also parse | ||||
// as numeric. And we have to accept numerics with quotes | // as numeric. And we have to accept numerics with quotes | ||||
// because our own dogfood (our rpc results) always | // because our own dogfood (our rpc results) always | ||||
// produces decimal numbers that are quoted | // produces decimal numbers that are quoted | ||||
// eg getbalance returns "3.14152" rather than 3.14152 | // eg getbalance returns "3.14152" rather than 3.14152 | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Missing amount"); | throw JSONRPCError(RPC_INVALID_PARAMETER, "Missing amount"); | ||||
} | } | ||||
view.AddCoin(out, Coin(txout, 1, false), true); | |||||
} | } | ||||
// 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, { | ||||
▲ Show 20 Lines • Show All 228 Lines • Show Last 20 Lines |