Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/rawtransaction.cpp
Show All 30 Lines | |||||
#include "wallet/rpcwallet.h" | #include "wallet/rpcwallet.h" | ||||
#include "wallet/wallet.h" | #include "wallet/wallet.h" | ||||
#endif | #endif | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <univalue.h> | #include <univalue.h> | ||||
void ScriptPubKeyToJSON(const Config &config, const CScript &scriptPubKey, | void TxToJSON(const CTransaction &tx, const uint256 hashBlock, | ||||
UniValue &out, bool fIncludeHex) { | UniValue &entry) { | ||||
txnouttype type; | // Call into TxToUniv() in bitcoin-common to decode the transaction hex. | ||||
std::vector<CTxDestination> addresses; | // | ||||
int nRequired; | // Blockchain contextual information (confirmations and blocktime) is not | ||||
// available to code in bitcoin-common, so we query them here and push the | |||||
out.pushKV("asm", ScriptToAsmStr(scriptPubKey)); | // data into the returned UniValue. | ||||
if (fIncludeHex) { | TxToUniv(tx, uint256(), entry); | ||||
out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())); | |||||
} | |||||
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) { | |||||
out.pushKV("type", GetTxnOutputType(type)); | |||||
return; | |||||
} | |||||
out.pushKV("reqSigs", nRequired); | |||||
out.pushKV("type", GetTxnOutputType(type)); | |||||
UniValue a(UniValue::VARR); | |||||
for (const CTxDestination &addr : addresses) { | |||||
a.push_back(EncodeDestination(addr)); | |||||
} | |||||
out.pushKV("addresses", a); | |||||
} | |||||
void TxToJSON(const Config &config, const CTransaction &tx, | |||||
const uint256 hashBlock, UniValue &entry) { | |||||
entry.pushKV("txid", tx.GetId().GetHex()); | |||||
entry.pushKV("hash", tx.GetHash().GetHex()); | |||||
entry.pushKV("size", | |||||
int(::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); | |||||
entry.pushKV("version", tx.nVersion); | |||||
entry.pushKV("locktime", int64_t(tx.nLockTime)); | |||||
UniValue vin(UniValue::VARR); | |||||
for (unsigned int i = 0; i < tx.vin.size(); i++) { | |||||
const CTxIn &txin = tx.vin[i]; | |||||
UniValue in(UniValue::VOBJ); | |||||
if (tx.IsCoinBase()) { | |||||
in.pushKV("coinbase", | |||||
HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); | |||||
} else { | |||||
in.pushKV("txid", txin.prevout.GetTxId().GetHex()); | |||||
in.pushKV("vout", int64_t(txin.prevout.GetN())); | |||||
UniValue o(UniValue::VOBJ); | |||||
o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true)); | |||||
o.pushKV("hex", | |||||
HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); | |||||
in.pushKV("scriptSig", o); | |||||
} | |||||
in.pushKV("sequence", int64_t(txin.nSequence)); | |||||
vin.push_back(in); | |||||
} | |||||
entry.pushKV("vin", vin); | |||||
UniValue vout(UniValue::VARR); | |||||
for (unsigned int i = 0; i < tx.vout.size(); i++) { | |||||
const CTxOut &txout = tx.vout[i]; | |||||
UniValue out(UniValue::VOBJ); | |||||
out.pushKV("value", ValueFromAmount(txout.nValue)); | |||||
out.pushKV("n", int64_t(i)); | |||||
UniValue o(UniValue::VOBJ); | |||||
ScriptPubKeyToJSON(config, txout.scriptPubKey, o, true); | |||||
out.pushKV("scriptPubKey", o); | |||||
vout.push_back(out); | |||||
} | |||||
entry.pushKV("vout", vout); | |||||
if (!hashBlock.IsNull()) { | |||||
entry.pushKV("blockhash", hashBlock.GetHex()); | |||||
BlockMap::iterator mi = mapBlockIndex.find(hashBlock); | |||||
if (mi != mapBlockIndex.end() && (*mi).second) { | |||||
CBlockIndex *pindex = (*mi).second; | |||||
if (chainActive.Contains(pindex)) { | |||||
entry.pushKV("confirmations", | |||||
1 + chainActive.Height() - pindex->nHeight); | |||||
entry.pushKV("time", pindex->GetBlockTime()); | |||||
entry.pushKV("blocktime", pindex->GetBlockTime()); | |||||
} else { | |||||
entry.pushKV("confirmations", 0); | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
static UniValue getrawtransaction(const Config &config, | static UniValue getrawtransaction(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() < 1 || | ||||
request.params.size() > 2) { | request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"getrawtransaction \"txid\" ( verbose )\n" | "getrawtransaction \"txid\" ( verbose )\n" | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | static UniValue getrawtransaction(const Config &config, | ||||
std::string strHex = EncodeHexTx(*tx, RPCSerializationFlags()); | std::string strHex = EncodeHexTx(*tx, RPCSerializationFlags()); | ||||
if (!fVerbose) { | if (!fVerbose) { | ||||
return strHex; | return strHex; | ||||
} | } | ||||
UniValue result(UniValue::VOBJ); | UniValue result(UniValue::VOBJ); | ||||
result.pushKV("hex", strHex); | result.pushKV("hex", strHex); | ||||
TxToJSON(config, *tx, hashBlock, result); | TxToUniv(*tx, hashBlock, result); | ||||
return result; | return result; | ||||
} | } | ||||
static UniValue gettxoutproof(const Config &config, | static UniValue gettxoutproof(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || | if (request.fHelp || | ||||
(request.params.size() != 1 && request.params.size() != 2)) { | (request.params.size() != 1 && request.params.size() != 2)) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
▲ Show 20 Lines • Show All 380 Lines • ▼ Show 20 Lines | static UniValue decoderawtransaction(const Config &config, | ||||
CMutableTransaction mtx; | CMutableTransaction mtx; | ||||
if (!DecodeHexTx(mtx, request.params[0].get_str())) { | if (!DecodeHexTx(mtx, request.params[0].get_str())) { | ||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | ||||
} | } | ||||
UniValue result(UniValue::VOBJ); | UniValue result(UniValue::VOBJ); | ||||
TxToJSON(config, CTransaction(std::move(mtx)), uint256(), result); | TxToUniv(CTransaction(std::move(mtx)), uint256(), result); | ||||
return result; | return result; | ||||
} | } | ||||
static UniValue decodescript(const Config &config, | static UniValue decodescript(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
Show All 27 Lines | static UniValue decodescript(const Config &config, | ||||
if (request.params[0].get_str().size() > 0) { | if (request.params[0].get_str().size() > 0) { | ||||
std::vector<uint8_t> scriptData( | std::vector<uint8_t> scriptData( | ||||
ParseHexV(request.params[0], "argument")); | ParseHexV(request.params[0], "argument")); | ||||
script = CScript(scriptData.begin(), scriptData.end()); | script = CScript(scriptData.begin(), scriptData.end()); | ||||
} else { | } else { | ||||
// Empty scripts are valid. | // Empty scripts are valid. | ||||
} | } | ||||
ScriptPubKeyToJSON(config, script, r, false); | ScriptPubKeyToUniv(script, r, false); | ||||
UniValue type; | UniValue type; | ||||
type = find_value(r, "type"); | type = find_value(r, "type"); | ||||
if (type.isStr() && type.get_str() != "scripthash") { | if (type.isStr() && type.get_str() != "scripthash") { | ||||
// P2SH cannot be wrapped in a P2SH. If this script is already a P2SH, | // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH, | ||||
// don't return the address for a P2SH of the P2SH. | // don't return the address for a P2SH of the P2SH. | ||||
r.pushKV("p2sh", EncodeDestination(CScriptID(script))); | r.pushKV("p2sh", EncodeDestination(CScriptID(script))); | ||||
▲ Show 20 Lines • Show All 584 Lines • Show Last 20 Lines |