diff options
Diffstat (limited to 'src/rpc/rawtransaction_util.cpp')
-rw-r--r-- | src/rpc/rawtransaction_util.cpp | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp index c471986a44..a62f90215a 100644 --- a/src/rpc/rawtransaction_util.cpp +++ b/src/rpc/rawtransaction_util.cpp @@ -70,7 +70,7 @@ void AddInputs(CMutableTransaction& rawTx, const UniValue& inputs_in, std::optio } } -void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in) +UniValue NormalizeOutputs(const UniValue& outputs_in) { if (outputs_in.isNull()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output argument must be non-null"); @@ -94,11 +94,15 @@ void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in) } outputs = std::move(outputs_dict); } + return outputs; +} +std::vector<std::pair<CTxDestination, CAmount>> ParseOutputs(const UniValue& outputs) +{ // Duplicate checking std::set<CTxDestination> destinations; + std::vector<std::pair<CTxDestination, CAmount>> parsed_outputs; bool has_data{false}; - for (const std::string& name_ : outputs.getKeys()) { if (name_ == "data") { if (has_data) { @@ -106,11 +110,12 @@ void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in) } has_data = true; std::vector<unsigned char> data = ParseHexV(outputs[name_].getValStr(), "Data"); - - CTxOut out(0, CScript() << OP_RETURN << data); - rawTx.vout.push_back(out); + CTxDestination destination{CNoDestination{CScript() << OP_RETURN << data}}; + CAmount amount{0}; + parsed_outputs.emplace_back(destination, amount); } else { - CTxDestination destination = DecodeDestination(name_); + CTxDestination destination{DecodeDestination(name_)}; + CAmount amount{AmountFromValue(outputs[name_])}; if (!IsValidDestination(destination)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + name_); } @@ -118,13 +123,23 @@ void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in) if (!destinations.insert(destination).second) { throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_); } + parsed_outputs.emplace_back(destination, amount); + } + } + return parsed_outputs; +} + +void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in) +{ + UniValue outputs(UniValue::VOBJ); + outputs = NormalizeOutputs(outputs_in); - CScript scriptPubKey = GetScriptForDestination(destination); - CAmount nAmount = AmountFromValue(outputs[name_]); + std::vector<std::pair<CTxDestination, CAmount>> parsed_outputs = ParseOutputs(outputs); + for (const auto& [destination, nAmount] : parsed_outputs) { + CScript scriptPubKey = GetScriptForDestination(destination); - CTxOut out(nAmount, scriptPubKey); - rawTx.vout.push_back(out); - } + CTxOut out(nAmount, scriptPubKey); + rawTx.vout.push_back(out); } } @@ -159,11 +174,11 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std:: for (unsigned int i = 0; i < txin.scriptWitness.stack.size(); i++) { witness.push_back(HexStr(txin.scriptWitness.stack[i])); } - entry.pushKV("witness", witness); + entry.pushKV("witness", std::move(witness)); entry.pushKV("scriptSig", HexStr(txin.scriptSig)); entry.pushKV("sequence", (uint64_t)txin.nSequence); entry.pushKV("error", strMessage); - vErrorsRet.push_back(entry); + vErrorsRet.push_back(std::move(entry)); } void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins) @@ -316,6 +331,6 @@ void SignTransactionResultToJSON(CMutableTransaction& mtx, bool complete, const if (result.exists("errors")) { vErrors.push_backV(result["errors"].getValues()); } - result.pushKV("errors", vErrors); + result.pushKV("errors", std::move(vErrors)); } } |