diff options
Diffstat (limited to 'src/rpc/rawtransaction.cpp')
-rw-r--r-- | src/rpc/rawtransaction.cpp | 228 |
1 files changed, 123 insertions, 105 deletions
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 91de72b70e..cce62bacef 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2018 The Bitcoin Core developers +// Copyright (c) 2009-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -66,28 +66,31 @@ static UniValue getrawtransaction(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw std::runtime_error( - RPCHelpMan{"getrawtransaction", - "\nNOTE: By default this function only works for mempool transactions. If the -txindex option is\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 outputs.\n" - - "\nReturn the raw transaction data.\n" - "\nIf verbose is 'true', returns an Object with information about 'txid'.\n" - "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.\n" - , + RPCHelpMan{ + "getrawtransaction", + "\nReturn the raw transaction data.\n" + + "\nBy default this function only works for mempool transactions. When called with a blockhash\n" + "argument, getrawtransaction will return the transaction if the specified block is available and\n" + "the transaction is found in that block. When called without a blockhash argument, getrawtransaction\n" + "will return the transaction if it is in the mempool, or if -txindex is enabled and the transaction\n" + "is in a block in the blockchain.\n" + + "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n" + "Or use gettransaction for wallet transactions.\n" + + "\nIf verbose is 'true', returns an Object with information about 'txid'.\n" + "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.\n", { {"txid", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "The transaction id"}, {"verbose", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "false", "If false, return a string, otherwise return a json object"}, {"blockhash", RPCArg::Type::STR_HEX, /* opt */ true, /* default_val */ "null", "The block in which to look for the transaction"}, - }} - .ToString() + - "\nResult (if verbose is not set or set to false):\n" + }, + { + RPCResult{"if verbose is not set or set to false", "\"data\" (string) The serialized, hex-encoded data for 'txid'\n" - - "\nResult (if verbose is set to true):\n" + }, + RPCResult{"if verbose is set to true", "{\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 data for 'txid'\n" @@ -133,14 +136,16 @@ static UniValue getrawtransaction(const JSONRPCRequest& request) " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"time\" : ttt, (numeric) Same as \"blocktime\"\n" "}\n" - - "\nExamples:\n" - + HelpExampleCli("getrawtransaction", "\"mytxid\"") + }, + }, + RPCExamples{ + HelpExampleCli("getrawtransaction", "\"mytxid\"") + HelpExampleCli("getrawtransaction", "\"mytxid\" true") + HelpExampleRpc("getrawtransaction", "\"mytxid\", true") + HelpExampleCli("getrawtransaction", "\"mytxid\" false \"myblockhash\"") + HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"") - ); + }, + }.ToString()); bool in_active_chain = true; uint256 hash = ParseHashV(request.params[0], "parameter 1"); @@ -175,7 +180,7 @@ static UniValue getrawtransaction(const JSONRPCRequest& request) CTransactionRef tx; uint256 hash_block; - if (!GetTransaction(hash, tx, Params().GetConsensus(), hash_block, true, blockindex)) { + if (!GetTransaction(hash, tx, Params().GetConsensus(), hash_block, blockindex)) { std::string errmsg; if (blockindex) { if (!(blockindex->nStatus & BLOCK_HAVE_DATA)) { @@ -219,10 +224,12 @@ static UniValue gettxoutproof(const JSONRPCRequest& request) }, }, {"blockhash", RPCArg::Type::STR_HEX, /* opt */ true, /* default_val */ "null", "If specified, looks for txid in the block with this hash"}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n" + }, + RPCExamples{""}, + }.ToString() ); std::set<uint256> setTxids; @@ -270,7 +277,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request) if (pblockindex == nullptr) { CTransactionRef tx; - if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull()) + if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock) || hashBlock.IsNull()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block"); pblockindex = LookupBlockIndex(hashBlock); if (!pblockindex) { @@ -305,10 +312,12 @@ static UniValue verifytxoutproof(const JSONRPCRequest& request) "and throwing an RPC error if the block is not in our best chain\n", { {"proof", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "The hex-encoded proof generated by gettxoutproof"}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof can not be validated.\n" + }, + RPCExamples{""}, + }.ToString() ); CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); @@ -494,17 +503,17 @@ static UniValue createrawtransaction(const JSONRPCRequest& request) {"locktime", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "0", "Raw locktime. Non-0 value also locktime-activates inputs"}, {"replaceable", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "false", "Marks this transaction as BIP125-replaceable.\n" " Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "\"transaction\" (string) hex string of the transaction\n" - - "\nExamples:\n" - + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"") + }, + RPCExamples{ + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"") + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"address\\\":0.01}]\"") + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"") - ); + }, + }.ToString()); } RPCTypeCheck(request.params, { @@ -530,9 +539,8 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request) {"hexstring", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "The transaction hex string"}, {"iswitness", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "depends on heuristic tests", "Whether the transaction hex is a serialized witness transaction\n" " If iswitness is not present, heuristic tests will be used in decoding"}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "{\n" " \"txid\" : \"id\", (string) The transaction id\n" " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n" @@ -572,11 +580,12 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request) " ,...\n" " ],\n" "}\n" - - "\nExamples:\n" - + HelpExampleCli("decoderawtransaction", "\"hexstring\"") + }, + RPCExamples{ + HelpExampleCli("decoderawtransaction", "\"hexstring\"") + HelpExampleRpc("decoderawtransaction", "\"hexstring\"") - ); + }, + }.ToString()); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); @@ -603,9 +612,8 @@ static UniValue decodescript(const JSONRPCRequest& request) "\nDecode a hex-encoded script.\n", { {"hexstring", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "the hex-encoded script"}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "{\n" " \"asm\":\"asm\", (string) Script public key\n" " \"hex\":\"hex\", (string) hex-encoded public key\n" @@ -617,10 +625,12 @@ static UniValue decodescript(const JSONRPCRequest& request) " ],\n" " \"p2sh\",\"address\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n" "}\n" - "\nExamples:\n" - + HelpExampleCli("decodescript", "\"hexstring\"") + }, + RPCExamples{ + HelpExampleCli("decodescript", "\"hexstring\"") + HelpExampleRpc("decodescript", "\"hexstring\"") - ); + }, + }.ToString()); RPCTypeCheck(request.params, {UniValue::VSTR}); @@ -706,14 +716,14 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request) {"hexstring", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "A transaction hash"}, }, }, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "\"hex\" (string) The hex-encoded raw transaction with signature(s)\n" - - "\nExamples:\n" - + HelpExampleCli("combinerawtransaction", "[\"myhex1\", \"myhex2\", \"myhex3\"]") - ); + }, + RPCExamples{ + HelpExampleCli("combinerawtransaction", "[\"myhex1\", \"myhex2\", \"myhex3\"]") + }, + }.ToString()); UniValue txs = request.params[0].get_array(); @@ -953,9 +963,8 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) " \"NONE|ANYONECANPAY\"\n" " \"SINGLE|ANYONECANPAY\"\n" }, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "{\n" " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n" " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n" @@ -970,11 +979,12 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) " ,...\n" " ]\n" "}\n" - - "\nExamples:\n" - + HelpExampleCli("signrawtransactionwithkey", "\"myhex\"") + }, + RPCExamples{ + HelpExampleCli("signrawtransactionwithkey", "\"myhex\"") + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\"") - ); + }, + }.ToString()); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); @@ -1015,11 +1025,11 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) { {"hexstring", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "The hex string of the raw transaction"}, {"allowhighfees", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "false", "Allow high fees"}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "\"hex\" (string) The transaction hash in hex\n" - "\nExamples:\n" + }, + RPCExamples{ "\nCreate a transaction\n" + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") + "Sign the transaction, and get back the hex\n" @@ -1028,7 +1038,8 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) + HelpExampleCli("sendrawtransaction", "\"signedhex\"") + "\nAs a JSON-RPC call\n" + HelpExampleRpc("sendrawtransaction", "\"signedhex\"") - ); + }, + }.ToString()); std::promise<void> promise; @@ -1118,9 +1129,8 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request) }, }, {"allowhighfees", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "false", "Allow high fees"}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "[ (array) The result of the mempool acceptance test for each raw transaction in the input array.\n" " Length is exactly one for now.\n" " {\n" @@ -1129,7 +1139,8 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request) " \"reject-reason\" (string) Rejection string (only present when 'allowed' is false)\n" " }\n" "]\n" - "\nExamples:\n" + }, + RPCExamples{ "\nCreate a transaction\n" + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") + "Sign the transaction, and get back the hex\n" @@ -1138,7 +1149,8 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request) + HelpExampleCli("testmempoolaccept", "[\"signedhex\"]") + "\nAs a JSON-RPC call\n" + HelpExampleRpc("testmempoolaccept", "[\"signedhex\"]") - ); + }, + }.ToString()); } RPCTypeCheck(request.params, {UniValue::VARR, UniValue::VBOOL}); @@ -1212,9 +1224,8 @@ UniValue decodepsbt(const JSONRPCRequest& request) "\nReturn a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction.\n", { {"psbt", RPCArg::Type::STR, /* opt */ false, /* default_val */ "", "The PSBT base64 string"}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "{\n" " \"tx\" : { (json object) The decoded network-serialized unsigned transaction.\n" " ... The layout is the same as the output of decoderawtransaction.\n" @@ -1301,10 +1312,11 @@ UniValue decodepsbt(const JSONRPCRequest& request) " ]\n" " \"fee\" : fee (numeric, optional) The transaction fee paid if all UTXOs slots in the PSBT have been filled.\n" "}\n" - - "\nExamples:\n" - + HelpExampleCli("decodepsbt", "\"psbt\"") - ); + }, + RPCExamples{ + HelpExampleCli("decodepsbt", "\"psbt\"") + }, + }.ToString()); RPCTypeCheck(request.params, {UniValue::VSTR}); @@ -1492,19 +1504,23 @@ UniValue combinepsbt(const JSONRPCRequest& request) {"psbt", RPCArg::Type::STR, /* opt */ false, /* default_val */ "", "A base64 string of a PSBT"}, }, }, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ " \"psbt\" (string) The base64-encoded partially signed transaction\n" - "\nExamples:\n" - + HelpExampleCli("combinepsbt", "[\"mybase64_1\", \"mybase64_2\", \"mybase64_3\"]") - ); + }, + RPCExamples{ + HelpExampleCli("combinepsbt", "[\"mybase64_1\", \"mybase64_2\", \"mybase64_3\"]") + }, + }.ToString()); RPCTypeCheck(request.params, {UniValue::VARR}, true); // Unserialize the transactions std::vector<PartiallySignedTransaction> psbtxs; UniValue txs = request.params[0].get_array(); + if (txs.empty()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter 'txs' cannot be empty"); + } for (unsigned int i = 0; i < txs.size(); ++i) { PartiallySignedTransaction psbtx; std::string error; @@ -1546,19 +1562,19 @@ UniValue finalizepsbt(const JSONRPCRequest& request) {"psbt", RPCArg::Type::STR, /* opt */ false, /* default_val */ "", "A base64 string of a PSBT"}, {"extract", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "true", "If true and the transaction is complete,\n" " extract and return the complete transaction in normal network serialization instead of the PSBT."}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ "{\n" " \"psbt\" : \"value\", (string) The base64-encoded partially signed transaction if not extracted\n" " \"hex\" : \"value\", (string) The hex-encoded network transaction if extracted\n" " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n" " ]\n" "}\n" - - "\nExamples:\n" - + HelpExampleCli("finalizepsbt", "\"psbt\"") - ); + }, + RPCExamples{ + HelpExampleCli("finalizepsbt", "\"psbt\"") + }, + }.ToString()); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true); @@ -1637,13 +1653,14 @@ UniValue createpsbt(const JSONRPCRequest& request) {"locktime", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "0", "Raw locktime. Non-0 value also locktime-activates inputs"}, {"replaceable", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "false", "Marks this transaction as BIP125 replaceable.\n" " Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ " \"psbt\" (string) The resulting raw transaction (base64-encoded string)\n" - "\nExamples:\n" - + HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") - ); + }, + RPCExamples{ + HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") + }, + }.ToString()); RPCTypeCheck(request.params, { @@ -1688,16 +1705,17 @@ UniValue converttopsbt(const JSONRPCRequest& request) " If iswitness is not present, heuristic tests will be used in decoding. If true, only witness deserializaion\n" " will be tried. If false, only non-witness deserialization will be tried. Only has an effect if\n" " permitsigdata is true."}, - }} - .ToString() + - "\nResult:\n" + }, + RPCResult{ " \"psbt\" (string) The resulting raw transaction (base64-encoded string)\n" - "\nExamples:\n" + }, + RPCExamples{ "\nCreate a transaction\n" + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") + "\nConvert the transaction to a PSBT\n" + HelpExampleCli("converttopsbt", "\"rawtransaction\"") - ); + }, + }.ToString()); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VBOOL}, true); |