Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/rawtransaction.cpp
Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | if (!hashBlock.IsNull()) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
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() > 3) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"getrawtransaction \"txid\" ( verbose )\n" | "getrawtransaction \"txid\" ( verbose \"blockhash\" )\n" | ||||
"\nNOTE: By default this function only works for mempool " | "\nNOTE: By default this function only works for mempool " | ||||
"transactions. If the -txindex option is\n" | "transactions. If the -txindex option is\n" | ||||
"enabled, it also works for blockchain transactions.\n" | "enabled, it also works for blockchain transactions. If the block " | ||||
"which contains the transaction\n" | |||||
"is known, its hash can be provided even for nodes without " | |||||
"-txindex. Note that if a blockhash is\n" | |||||
"provided, only that block will be searched and if the transaction " | |||||
"is in the mempool or other\n" | |||||
"blocks, or if this node does not have the given block available, " | |||||
"the transaction will not be found.\n" | |||||
"DEPRECATED: for now, it also works for transactions with unspent " | "DEPRECATED: for now, it also works for transactions with unspent " | ||||
"outputs.\n" | "outputs.\n" | ||||
"\nReturn the raw transaction data.\n" | "\nReturn the raw transaction data.\n" | ||||
"\nIf verbose is 'true', returns an Object with information about " | "\nIf verbose is 'true', returns an Object with information about " | ||||
"'txid'.\n" | "'txid'.\n" | ||||
"If verbose is 'false' or omitted, returns a string that is " | "If verbose is 'false' or omitted, returns a string that is " | ||||
"serialized, hex-encoded data for 'txid'.\n" | "serialized, hex-encoded data for 'txid'.\n" | ||||
"\nArguments:\n" | "\nArguments:\n" | ||||
"1. \"txid\" (string, required) The transaction id\n" | "1. \"txid\" (string, required) The transaction id\n" | ||||
"2. verbose (bool, optional, default=false) If false, return " | "2. verbose (bool, optional, default=false) If false, return a " | ||||
"a string, otherwise return a json object\n" | "string, otherwise return a json object\n" | ||||
"3. \"blockhash\" (string, optional) The block in which to look " | |||||
"for the transaction\n" | |||||
"\nResult (if verbose is not set or set to false):\n" | "\nResult (if verbose is not set or set to false):\n" | ||||
"\"data\" (string) The serialized, hex-encoded data for " | "\"data\" (string) The serialized, hex-encoded data for " | ||||
"'txid'\n" | "'txid'\n" | ||||
"\nResult (if verbose is set to true):\n" | "\nResult (if verbose is set to true):\n" | ||||
"{\n" | "{\n" | ||||
" \"in_active_chain\": b, (bool) Whether specified block is in " | |||||
"the active chain or not (only present with explicit \"blockhash\" " | |||||
"argument)\n" | |||||
" \"hex\" : \"data\", (string) The serialized, hex-encoded " | " \"hex\" : \"data\", (string) The serialized, hex-encoded " | ||||
"data for 'txid'\n" | "data for 'txid'\n" | ||||
" \"txid\" : \"id\", (string) The transaction id (same as " | " \"txid\" : \"id\", (string) The transaction id (same as " | ||||
"provided)\n" | "provided)\n" | ||||
" \"hash\" : \"id\", (string) The transaction hash " | " \"hash\" : \"id\", (string) The transaction hash " | ||||
"(differs from txid for witness transactions)\n" | "(differs from txid for witness transactions)\n" | ||||
" \"size\" : n, (numeric) The serialized transaction " | " \"size\" : n, (numeric) The serialized transaction " | ||||
"size\n" | "size\n" | ||||
Show All 37 Lines | if (request.fHelp || request.params.size() < 1 || | ||||
"seconds since epoch (Jan 1 1970 GMT)\n" | "seconds since epoch (Jan 1 1970 GMT)\n" | ||||
" \"blocktime\" : ttt (numeric) The block time in seconds " | " \"blocktime\" : ttt (numeric) The block time in seconds " | ||||
"since epoch (Jan 1 1970 GMT)\n" | "since epoch (Jan 1 1970 GMT)\n" | ||||
"}\n" | "}\n" | ||||
"\nExamples:\n" + | "\nExamples:\n" + | ||||
HelpExampleCli("getrawtransaction", "\"mytxid\"") + | HelpExampleCli("getrawtransaction", "\"mytxid\"") + | ||||
HelpExampleCli("getrawtransaction", "\"mytxid\" true") + | HelpExampleCli("getrawtransaction", "\"mytxid\" true") + | ||||
HelpExampleRpc("getrawtransaction", "\"mytxid\", true")); | HelpExampleRpc("getrawtransaction", "\"mytxid\", true") + | ||||
HelpExampleCli("getrawtransaction", | |||||
"\"mytxid\" false \"myblockhash\"") + | |||||
HelpExampleCli("getrawtransaction", | |||||
"\"mytxid\" true \"myblockhash\"")); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
bool in_active_chain = true; | |||||
TxId txid = TxId(ParseHashV(request.params[0], "parameter 1")); | TxId txid = TxId(ParseHashV(request.params[0], "parameter 1")); | ||||
CBlockIndex *blockindex = nullptr; | |||||
// Accept either a bool (true) or a num (>=1) to indicate verbose output. | // Accept either a bool (true) or a num (>=1) to indicate verbose output. | ||||
bool fVerbose = false; | bool fVerbose = false; | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
if (request.params[1].isNum()) { | fVerbose = request.params[1].isNum() | ||||
if (request.params[1].get_int() != 0) { | ? (request.params[1].get_int() != 0) | ||||
fVerbose = true; | : request.params[1].get_bool(); | ||||
} | |||||
} else if (request.params[1].isBool()) { | |||||
if (request.params[1].isTrue()) { | |||||
fVerbose = true; | |||||
} | } | ||||
} else { | |||||
throw JSONRPCError( | if (!request.params[2].isNull()) { | ||||
RPC_TYPE_ERROR, | uint256 blockhash = ParseHashV(request.params[2], "parameter 3"); | ||||
"Invalid type provided. Verbose parameter must be a boolean."); | if (!blockhash.IsNull()) { | ||||
BlockMap::iterator it = mapBlockIndex.find(blockhash); | |||||
if (it == mapBlockIndex.end()) { | |||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | |||||
"Block hash not found"); | |||||
} | |||||
blockindex = it->second; | |||||
in_active_chain = chainActive.Contains(blockindex); | |||||
} | } | ||||
} | } | ||||
CTransactionRef tx; | CTransactionRef tx; | ||||
uint256 hashBlock; | uint256 hash_block; | ||||
if (!GetTransaction(config, txid, tx, hashBlock, true)) { | if (!GetTransaction(config, txid, tx, hash_block, true, blockindex)) { | ||||
throw JSONRPCError( | std::string errmsg; | ||||
RPC_INVALID_ADDRESS_OR_KEY, | if (blockindex) { | ||||
std::string(fTxIndex ? "No such mempool or blockchain transaction" | if (!blockindex->nStatus.hasData()) { | ||||
: "No such mempool transaction. Use -txindex " | throw JSONRPCError(RPC_MISC_ERROR, "Block not available"); | ||||
"to enable blockchain transaction queries") + | } | ||||
errmsg = "No such transaction found in the provided block"; | |||||
} else { | |||||
errmsg = fTxIndex ? "No such mempool or blockchain transaction" | |||||
: "No such mempool transaction. Use -txindex to " | |||||
"enable blockchain transaction queries"; | |||||
} | |||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | |||||
errmsg + | |||||
". Use gettransaction for wallet transactions."); | ". Use gettransaction for wallet transactions."); | ||||
} | } | ||||
if (!fVerbose) { | if (!fVerbose) { | ||||
return EncodeHexTx(*tx, RPCSerializationFlags()); | return EncodeHexTx(*tx, RPCSerializationFlags()); | ||||
} | } | ||||
UniValue result(UniValue::VOBJ); | UniValue result(UniValue::VOBJ); | ||||
TxToJSON(*tx, hashBlock, result); | if (blockindex) { | ||||
result.pushKV("in_active_chain", in_active_chain); | |||||
} | |||||
TxToJSON(*tx, hash_block, 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 1,090 Lines • ▼ Show 20 Lines | static UniValue sendrawtransaction(const Config &config, | ||||
g_connman->ForEachNode([&inv](CNode *pnode) { pnode->PushInventory(inv); }); | g_connman->ForEachNode([&inv](CNode *pnode) { pnode->PushInventory(inv); }); | ||||
return txid.GetHex(); | return txid.GetHex(); | ||||
} | } | ||||
// clang-format off | // clang-format off | ||||
static const ContextFreeRPCCommand commands[] = { | static const ContextFreeRPCCommand commands[] = { | ||||
// category name actor (function) argNames | // category name actor (function) argNames | ||||
// ------------------- ------------------------ ---------------------- ---------- | // ------------------- ------------------------ ---------------------- ---------- | ||||
{ "rawtransactions", "getrawtransaction", getrawtransaction, {"txid","verbose"} }, | { "rawtransactions", "getrawtransaction", getrawtransaction, {"txid","verbose","blockhash"} }, | ||||
{ "rawtransactions", "createrawtransaction", createrawtransaction, {"inputs","outputs","locktime"} }, | { "rawtransactions", "createrawtransaction", createrawtransaction, {"inputs","outputs","locktime"} }, | ||||
{ "rawtransactions", "decoderawtransaction", decoderawtransaction, {"hexstring"} }, | { "rawtransactions", "decoderawtransaction", decoderawtransaction, {"hexstring"} }, | ||||
{ "rawtransactions", "decodescript", decodescript, {"hexstring"} }, | { "rawtransactions", "decodescript", decodescript, {"hexstring"} }, | ||||
{ "rawtransactions", "sendrawtransaction", sendrawtransaction, {"hexstring","allowhighfees"} }, | { "rawtransactions", "sendrawtransaction", sendrawtransaction, {"hexstring","allowhighfees"} }, | ||||
{ "rawtransactions", "combinerawtransaction", combinerawtransaction, {"txs"} }, | { "rawtransactions", "combinerawtransaction", combinerawtransaction, {"txs"} }, | ||||
{ "rawtransactions", "signrawtransaction", signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */ | { "rawtransactions", "signrawtransaction", signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */ | ||||
{ "rawtransactions", "signrawtransactionwithkey", signrawtransactionwithkey, {"hexstring","privkeys","prevtxs","sighashtype"} }, | { "rawtransactions", "signrawtransactionwithkey", signrawtransactionwithkey, {"hexstring","privkeys","prevtxs","sighashtype"} }, | ||||
Show All 10 Lines |