Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/rawtransaction.cpp
Show First 20 Lines • Show All 1,106 Lines • ▼ Show 20 Lines | UniValue SignTransaction(interfaces::Chain &chain, CMutableTransaction &mtx, | ||||
return result; | return result; | ||||
} | } | ||||
static UniValue signrawtransactionwithkey(const Config &config, | static UniValue signrawtransactionwithkey(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 2 || | if (request.fHelp || request.params.size() < 2 || | ||||
request.params.size() > 4) { | request.params.size() > 4) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"signrawtransactionwithkey", | "signrawtransactionwithkey", | ||||
"\nSign inputs for raw transaction (serialized, hex-encoded).\n" | "\nSign inputs for raw transaction (serialized, hex-encoded).\n" | ||||
"The second argument is an array of base58-encoded private\n" | "The second argument is an array of base58-encoded private\n" | ||||
"keys that will be the only keys used to sign the " | "keys that will be the only keys used to sign the " | ||||
"transaction.\n" | "transaction.\n" | ||||
"The third optional argument (may be null) is an array of " | "The third optional argument (may be null) is an array of " | ||||
"previous transaction outputs that\n" | "previous transaction outputs that\n" | ||||
"this transaction depends on but may not yet be in the block " | "this transaction depends on but may not yet be in the block " | ||||
"chain.\n", | "chain.\n", | ||||
{ | { | ||||
{"hexstring", RPCArg::Type::STR_HEX, /* opt */ false, | {"hexstring", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", "The transaction hex string"}, | /* default_val */ "", "The transaction hex string"}, | ||||
{ | { | ||||
"privkeys", | "privkeys", | ||||
RPCArg::Type::ARR, | RPCArg::Type::ARR, | ||||
/* opt */ false, | /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"A json array of base58-encoded private keys for " | "A json array of base58-encoded private keys for " | ||||
"signing", | "signing", | ||||
{ | { | ||||
{"privatekey", RPCArg::Type::STR, | {"privatekey", RPCArg::Type::STR, | ||||
/* opt */ false, /* default_val */ "", | /* opt */ false, /* default_val */ "", | ||||
"private key in base58-encoding"}, | "private key in base58-encoding"}, | ||||
}, | }, | ||||
}, | }, | ||||
{ | { | ||||
"prevtxs", | "prevtxs", | ||||
RPCArg::Type::ARR, | RPCArg::Type::ARR, | ||||
/* opt */ true, | /* opt */ true, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"A json array of previous dependent transaction " | "A json array of previous dependent transaction " | ||||
"outputs", | "outputs", | ||||
{ | { | ||||
{ | { | ||||
"", | "", | ||||
RPCArg::Type::OBJ, | RPCArg::Type::OBJ, | ||||
/* opt */ true, | /* opt */ true, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"", | "", | ||||
{ | { | ||||
{"txid", RPCArg::Type::STR_HEX, | {"txid", RPCArg::Type::STR_HEX, | ||||
/* opt */ false, /* default_val */ "", | /* opt */ false, /* default_val */ "", | ||||
"The transaction id"}, | "The transaction id"}, | ||||
{"vout", RPCArg::Type::NUM, /* opt */ false, | {"vout", RPCArg::Type::NUM, /* opt */ false, | ||||
/* default_val */ "", "The output number"}, | /* default_val */ "", "The output number"}, | ||||
{"scriptPubKey", RPCArg::Type::STR_HEX, | {"scriptPubKey", RPCArg::Type::STR_HEX, | ||||
/* opt */ false, /* default_val */ "", | /* opt */ false, /* default_val */ "", | ||||
"script key"}, | "script key"}, | ||||
{"redeemScript", RPCArg::Type::STR_HEX, | {"redeemScript", RPCArg::Type::STR_HEX, | ||||
/* opt */ true, /* default_val */ "", | /* opt */ true, /* default_val */ "", | ||||
"(required for P2SH) redeem script"}, | "(required for P2SH) redeem script"}, | ||||
{"amount", RPCArg::Type::AMOUNT, | {"amount", RPCArg::Type::AMOUNT, | ||||
/* opt */ false, /* default_val */ "", | /* opt */ false, /* default_val */ "", | ||||
"The amount spent"}, | "The amount spent"}, | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
{"sighashtype", RPCArg::Type::STR, /* opt */ true, | {"sighashtype", RPCArg::Type::STR, /* opt */ true, | ||||
/* default_val */ "ALL|FORKID", | /* default_val */ "ALL|FORKID", | ||||
"The signature hash type. Must be one of:\n" | "The signature hash type. Must be one of:\n" | ||||
" \"ALL|FORKID\"\n" | " \"ALL|FORKID\"\n" | ||||
" \"NONE|FORKID\"\n" | " \"NONE|FORKID\"\n" | ||||
" \"SINGLE|FORKID\"\n" | " \"SINGLE|FORKID\"\n" | ||||
" \"ALL|FORKID|ANYONECANPAY\"\n" | " \"ALL|FORKID|ANYONECANPAY\"\n" | ||||
" \"NONE|FORKID|ANYONECANPAY\"\n" | " \"NONE|FORKID|ANYONECANPAY\"\n" | ||||
" \"SINGLE|FORKID|ANYONECANPAY\""}, | " \"SINGLE|FORKID|ANYONECANPAY\""}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{"{\n" | ||||
"\nResult:\n" | " \"hex\" : \"value\", (string) The " | ||||
"{\n" | "hex-encoded raw transaction with signature(s)\n" | ||||
" \"hex\" : \"value\", (string) The hex-encoded " | |||||
"raw transaction with signature(s)\n" | |||||
" \"complete\" : true|false, (boolean) If the " | " \"complete\" : true|false, (boolean) If the " | ||||
"transaction has a complete set of signatures\n" | "transaction has a complete set of signatures\n" | ||||
" \"errors\" : [ (json array of objects) " | " \"errors\" : [ (json array of " | ||||
"Script verification errors (if there are any)\n" | "objects) Script verification errors (if there are any)\n" | ||||
" {\n" | " {\n" | ||||
" \"txid\" : \"hash\", (string) The hash of the " | " \"txid\" : \"hash\", (string) The " | ||||
"referenced, previous transaction\n" | "hash of the referenced, previous transaction\n" | ||||
" \"vout\" : n, (numeric) The index of the " | " \"vout\" : n, (numeric) The " | ||||
"output to spent and used as input\n" | "index of the output to spent and used as input\n" | ||||
" \"scriptSig\" : \"hex\", (string) The hex-encoded " | " \"scriptSig\" : \"hex\", (string) The " | ||||
"signature script\n" | "hex-encoded signature script\n" | ||||
" \"sequence\" : n, (numeric) Script sequence " | " \"sequence\" : n, (numeric) Script " | ||||
"number\n" | "sequence number\n" | ||||
" \"error\" : \"text\" (string) Verification or " | " \"error\" : \"text\" (string) " | ||||
"signing error related to the input\n" | "Verification or signing error related to the input\n" | ||||
" }\n" | " }\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ]\n" | " ]\n" | ||||
"}\n" | "}\n"}, | ||||
RPCExamples{ | |||||
"\nExamples:\n" + | |||||
HelpExampleCli("signrawtransactionwithkey", "\"myhex\"") + | HelpExampleCli("signrawtransactionwithkey", "\"myhex\"") + | ||||
HelpExampleRpc("signrawtransactionwithkey", "\"myhex\"")); | HelpExampleRpc("signrawtransactionwithkey", "\"myhex\"")}, | ||||
} | |||||
.ToStringWithResultsAndExamples()); | |||||
} | } | ||||
RPCTypeCheck( | RPCTypeCheck( | ||||
request.params, | request.params, | ||||
{UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); | {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); | ||||
CMutableTransaction mtx; | CMutableTransaction mtx; | ||||
if (!DecodeHexTx(mtx, request.params[0].get_str())) { | if (!DecodeHexTx(mtx, request.params[0].get_str())) { | ||||
Show All 15 Lines | static UniValue signrawtransactionwithkey(const Config &config, | ||||
return SignTransaction(*g_rpc_interfaces->chain, mtx, request.params[2], | return SignTransaction(*g_rpc_interfaces->chain, mtx, request.params[2], | ||||
&keystore, true, request.params[3]); | &keystore, true, request.params[3]); | ||||
} | } | ||||
static UniValue sendrawtransaction(const Config &config, | static UniValue sendrawtransaction(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(RPCHelpMan{ | ||||
RPCHelpMan{"sendrawtransaction", | "sendrawtransaction", | ||||
"\nSubmits raw transaction (serialized, hex-encoded) to " | "\nSubmits raw transaction (serialized, hex-encoded) to " | ||||
"local node and network.\n" | "local node and network.\n" | ||||
"\nAlso see createrawtransaction and " | "\nAlso see createrawtransaction and " | ||||
"signrawtransactionwithkey calls.\n", | "signrawtransactionwithkey calls.\n", | ||||
{ | { | ||||
{"hexstring", RPCArg::Type::STR_HEX, /* opt */ false, | {"hexstring", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", "The hex string of the raw transaction"}, | ||||
"The hex string of the raw transaction"}, | |||||
{"allowhighfees", RPCArg::Type::BOOL, /* opt */ true, | {"allowhighfees", RPCArg::Type::BOOL, /* opt */ true, | ||||
/* default_val */ "false", "Allow high fees"}, | /* default_val */ "false", "Allow high fees"}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | "\"hex\" (string) The transaction hash in hex\n"}, | ||||
"\"hex\" (string) The transaction hash in hex\n" | RPCExamples{ | ||||
"\nExamples:\n" | |||||
"\nCreate a transaction\n" + | "\nCreate a transaction\n" + | ||||
HelpExampleCli( | HelpExampleCli( | ||||
"createrawtransaction", | "createrawtransaction", | ||||
"\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" " | "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" " | ||||
"\"{\\\"myaddress\\\":0.01}\"") + | "\"{\\\"myaddress\\\":0.01}\"") + | ||||
"Sign the transaction, and get back the hex\n" + | "Sign the transaction, and get back the hex\n" + | ||||
HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") + | HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") + | ||||
"\nSend the transaction (signed hex)\n" + | "\nSend the transaction (signed hex)\n" + | ||||
HelpExampleCli("sendrawtransaction", "\"signedhex\"") + | HelpExampleCli("sendrawtransaction", "\"signedhex\"") + | ||||
"\nAs a JSON-RPC call\n" + | "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("sendrawtransaction", "\"signedhex\"")); | HelpExampleRpc("sendrawtransaction", "\"signedhex\"")}, | ||||
} | |||||
.ToStringWithResultsAndExamples()); | |||||
} | } | ||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); | RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); | ||||
// parse hex string from parameter | // parse hex string from parameter | ||||
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"); | ||||
Show All 16 Lines | static UniValue sendrawtransaction(const Config &config, | ||||
return txid.GetHex(); | return txid.GetHex(); | ||||
} | } | ||||
static UniValue testmempoolaccept(const Config &config, | static UniValue testmempoolaccept(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(RPCHelpMan{ | ||||
RPCHelpMan{"testmempoolaccept", | "testmempoolaccept", | ||||
"\nReturns if raw transaction (serialized, hex-encoded) " | "\nReturns if raw transaction (serialized, hex-encoded) " | ||||
"would be accepted by mempool.\n" | "would be accepted by mempool.\n" | ||||
"\nThis checks if the transaction violates the " | "\nThis checks if the transaction violates the " | ||||
"consensus or policy rules.\n" | "consensus or policy rules.\n" | ||||
"\nSee sendrawtransaction call.\n", | "\nSee sendrawtransaction call.\n", | ||||
{ | { | ||||
{ | { | ||||
"rawtxs", | "rawtxs", | ||||
RPCArg::Type::ARR, | RPCArg::Type::ARR, | ||||
/* opt */ false, | /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"An array of hex strings of raw transactions.\n" | "An array of hex strings of raw transactions.\n" | ||||
" Length " | " Length " | ||||
"must be one for now.", | "must be one for now.", | ||||
{ | { | ||||
{"rawtx", RPCArg::Type::STR_HEX, | {"rawtx", RPCArg::Type::STR_HEX, | ||||
/* opt */ false, /* default_val */ "", ""}, | /* opt */ false, /* default_val */ "", ""}, | ||||
}, | }, | ||||
}, | }, | ||||
{"allowhighfees", RPCArg::Type::BOOL, /* opt */ true, | {"allowhighfees", RPCArg::Type::BOOL, /* opt */ true, | ||||
/* default_val */ "false", "Allow high fees"}, | /* default_val */ "false", "Allow high fees"}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | "[ (array) The result of the mempool " | ||||
"[ (array) The result of the mempool acceptance " | "acceptance test for each raw transaction in the input array.\n" | ||||
"test for each raw transaction in the input array.\n" | |||||
" Length is exactly one for now.\n" | " Length is exactly one for now.\n" | ||||
" {\n" | " {\n" | ||||
" \"txid\" (string) The transaction hash in hex\n" | " \"txid\" (string) The transaction hash in hex\n" | ||||
" \"allowed\" (boolean) If the mempool allows this tx to " | " \"allowed\" (boolean) If the mempool allows this tx " | ||||
"be inserted\n" | "to be inserted\n" | ||||
" \"reject-reason\" (string) Rejection string (only present when " | " \"reject-reason\" (string) Rejection string (only present " | ||||
"'allowed' is false)\n" | "when 'allowed' is false)\n" | ||||
" }\n" | " }\n" | ||||
"]\n" | "]\n"}, | ||||
"\nExamples:\n" | RPCExamples{ | ||||
"\nCreate a transaction\n" + | "\nCreate a transaction\n" + | ||||
HelpExampleCli( | HelpExampleCli( | ||||
"createrawtransaction", | "createrawtransaction", | ||||
"\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" " | "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" " | ||||
"\"{\\\"myaddress\\\":0.01}\"") + | "\"{\\\"myaddress\\\":0.01}\"") + | ||||
"Sign the transaction, and get back the hex\n" + | "Sign the transaction, and get back the hex\n" + | ||||
HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") + | HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") + | ||||
"\nTest acceptance of the transaction (signed hex)\n" + | "\nTest acceptance of the transaction (signed hex)\n" + | ||||
HelpExampleCli("testmempoolaccept", "\"signedhex\"") + | HelpExampleCli("testmempoolaccept", "[\"signedhex\"]") + | ||||
"\nAs a JSON-RPC call\n" + | "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("testmempoolaccept", "[\"signedhex\"]")); | HelpExampleRpc("testmempoolaccept", "[\"signedhex\"]")}, | ||||
} | |||||
.ToStringWithResultsAndExamples()); | |||||
} | } | ||||
RPCTypeCheck(request.params, {UniValue::VARR, UniValue::VBOOL}); | RPCTypeCheck(request.params, {UniValue::VARR, UniValue::VBOOL}); | ||||
if (request.params[0].get_array().size() != 1) { | if (request.params[0].get_array().size() != 1) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_INVALID_PARAMETER, | RPC_INVALID_PARAMETER, | ||||
"Array must contain exactly one raw transaction for now"); | "Array must contain exactly one raw transaction for now"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | for (uint32_t num : keypath) { | ||||
} | } | ||||
} | } | ||||
return keypath_str; | return keypath_str; | ||||
} | } | ||||
static UniValue decodepsbt(const Config &config, | static UniValue decodepsbt(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(RPCHelpMan{ | ||||
RPCHelpMan{"decodepsbt", | "decodepsbt", | ||||
"\nReturn a JSON object representing the serialized, " | "\nReturn a JSON object representing the serialized, " | ||||
"base64-encoded partially signed Bitcoin transaction.\n", | "base64-encoded partially signed Bitcoin transaction.\n", | ||||
{ | { | ||||
{"psbt", RPCArg::Type::STR, /* opt */ false, | {"psbt", RPCArg::Type::STR, /* opt */ false, | ||||
/* default_val */ "", "The PSBT base64 string"}, | /* default_val */ "", "The PSBT base64 string"}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | |||||
"{\n" | "{\n" | ||||
" \"tx\" : { (json object) The decoded " | " \"tx\" : { (json object) The decoded " | ||||
"network-serialized unsigned transaction.\n" | "network-serialized unsigned transaction.\n" | ||||
" ... The layout is the " | " ... The layout is " | ||||
"same as the output of decoderawtransaction.\n" | "the same as the output of decoderawtransaction.\n" | ||||
" },\n" | " },\n" | ||||
" \"unknown\" : { (json object) The unknown global " | " \"unknown\" : { (json object) The unknown " | ||||
"fields\n" | "global fields\n" | ||||
" \"key\" : \"value\" (key-value pair) An unknown " | " \"key\" : \"value\" (key-value pair) An " | ||||
"key-value pair\n" | "unknown key-value pair\n" | ||||
" ...\n" | " ...\n" | ||||
" },\n" | " },\n" | ||||
" \"inputs\" : [ (array of json objects)\n" | " \"inputs\" : [ (array of json objects)\n" | ||||
" {\n" | " {\n" | ||||
" \"utxo\" : { (json object, optional) Transaction " | " \"utxo\" : { (json object, optional) " | ||||
"output for UTXOs\n" | "Transaction output for UTXOs\n" | ||||
" \"amount\" : x.xxx, (numeric) The value in " + | " \"amount\" : x.xxx, (numeric) The value " | ||||
"in " + | |||||
CURRENCY_UNIT + | CURRENCY_UNIT + | ||||
"\n" | "\n" | ||||
" \"scriptPubKey\" : { (json object)\n" | " \"scriptPubKey\" : { (json object)\n" | ||||
" \"asm\" : \"asm\", (string) The asm\n" | " \"asm\" : \"asm\", (string) The asm\n" | ||||
" \"hex\" : \"hex\", (string) The hex\n" | " \"hex\" : \"hex\", (string) The hex\n" | ||||
" \"type\" : \"pubkeyhash\", (string) The type, eg " | " \"type\" : \"pubkeyhash\", (string) The type, eg " | ||||
"'pubkeyhash'\n" | "'pubkeyhash'\n" | ||||
" \"address\" : \"address\" (string) Bitcoin address " | " \"address\" : \"address\" (string) Bitcoin " | ||||
"if there is one\n" | "address if there is one\n" | ||||
" }\n" | " }\n" | ||||
" },\n" | " },\n" | ||||
" \"partial_signatures\" : { (json object, " | " \"partial_signatures\" : { (json object, " | ||||
"optional)\n" | "optional)\n" | ||||
" \"pubkey\" : \"signature\", (string) The public " | " \"pubkey\" : \"signature\", (string) The " | ||||
"key and signature that corresponds to it.\n" | "public key and signature that corresponds to it.\n" | ||||
" ,...\n" | " ,...\n" | ||||
" }\n" | " }\n" | ||||
" \"sighash\" : \"type\", (string, optional) " | " \"sighash\" : \"type\", (string, " | ||||
"The sighash type to be used\n" | "optional) The sighash type to be used\n" | ||||
" \"redeem_script\" : { (json object, optional)\n" | " \"redeem_script\" : { (json object, optional)\n" | ||||
" \"asm\" : \"asm\", (string) The asm\n" | " \"asm\" : \"asm\", (string) The asm\n" | ||||
" \"hex\" : \"hex\", (string) The hex\n" | " \"hex\" : \"hex\", (string) The hex\n" | ||||
" \"type\" : \"pubkeyhash\", (string) The type, eg " | " \"type\" : \"pubkeyhash\", (string) The type, eg " | ||||
"'pubkeyhash'\n" | "'pubkeyhash'\n" | ||||
" }\n" | " }\n" | ||||
" \"bip32_derivs\" : { (json object, optional)\n" | " \"bip32_derivs\" : { (json object, optional)\n" | ||||
" \"pubkey\" : { (json object, " | " \"pubkey\" : { (json object, " | ||||
"optional) The public key with the derivation path as the value.\n" | "optional) The public key with the derivation path as the " | ||||
" \"master_fingerprint\" : \"fingerprint\" (string) " | "value.\n" | ||||
"The fingerprint of the master key\n" | " \"master_fingerprint\" : \"fingerprint\" " | ||||
" \"path\" : \"path\", (string) " | "(string) The fingerprint of the master key\n" | ||||
"The path\n" | " \"path\" : \"path\", " | ||||
"(string) The path\n" | |||||
" }\n" | " }\n" | ||||
" ,...\n" | " ,...\n" | ||||
" }\n" | " }\n" | ||||
" \"final_scriptsig\" : { (json object, optional)\n" | " \"final_scriptsig\" : { (json object, optional)\n" | ||||
" \"asm\" : \"asm\", (string) The asm\n" | " \"asm\" : \"asm\", (string) The asm\n" | ||||
" \"hex\" : \"hex\", (string) The hex\n" | " \"hex\" : \"hex\", (string) The hex\n" | ||||
" }\n" | " }\n" | ||||
" \"unknown\" : { (json object) The unknown " | " \"unknown\" : { (json object) The " | ||||
"global fields\n" | "unknown global fields\n" | ||||
" \"key\" : \"value\" (key-value pair) An " | " \"key\" : \"value\" (key-value pair) An " | ||||
"unknown key-value pair\n" | "unknown key-value pair\n" | ||||
" ...\n" | " ...\n" | ||||
" },\n" | " },\n" | ||||
" }\n" | " }\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ]\n" | " ]\n" | ||||
" \"outputs\" : [ (array of json objects)\n" | " \"outputs\" : [ (array of json objects)\n" | ||||
" {\n" | " {\n" | ||||
" \"redeem_script\" : { (json object, optional)\n" | " \"redeem_script\" : { (json object, optional)\n" | ||||
" \"asm\" : \"asm\", (string) The asm\n" | " \"asm\" : \"asm\", (string) The asm\n" | ||||
" \"hex\" : \"hex\", (string) The hex\n" | " \"hex\" : \"hex\", (string) The hex\n" | ||||
" \"type\" : \"pubkeyhash\", (string) The type, eg " | " \"type\" : \"pubkeyhash\", (string) The type, eg " | ||||
"'pubkeyhash'\n" | "'pubkeyhash'\n" | ||||
" }\n" | " }\n" | ||||
" \"bip32_derivs\" : [ (array of json objects, " | " \"bip32_derivs\" : [ (array of json objects, " | ||||
"optional)\n" | "optional)\n" | ||||
" {\n" | " {\n" | ||||
" \"pubkey\" : \"pubkey\", (string) " | " \"pubkey\" : \"pubkey\", " | ||||
"The public key this path corresponds to\n" | "(string) The public key this path corresponds to\n" | ||||
" \"master_fingerprint\" : \"fingerprint\" (string) " | " \"master_fingerprint\" : \"fingerprint\" " | ||||
"The fingerprint of the master key\n" | "(string) The fingerprint of the master key\n" | ||||
" \"path\" : \"path\", (string) " | " \"path\" : \"path\", " | ||||
"The path\n" | "(string) The path\n" | ||||
" }\n" | " }\n" | ||||
" }\n" | " }\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ],\n" | " ],\n" | ||||
" \"unknown\" : { (json object) The unknown " | " \"unknown\" : { (json object) The " | ||||
"global fields\n" | "unknown global fields\n" | ||||
" \"key\" : \"value\" (key-value pair) An " | " \"key\" : \"value\" (key-value pair) An " | ||||
"unknown key-value pair\n" | "unknown key-value pair\n" | ||||
" ...\n" | " ...\n" | ||||
" },\n" | " },\n" | ||||
" }\n" | " }\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ]\n" | " ]\n" | ||||
" \"fee\" : fee (numeric, optional) The " | " \"fee\" : fee (numeric, optional) The " | ||||
"transaction fee paid if all UTXOs slots in the PSBT have been " | "transaction fee paid if all UTXOs slots in the PSBT have been " | ||||
"filled.\n" | "filled.\n" | ||||
"}\n" | "}\n"}, | ||||
RPCExamples{HelpExampleCli("decodepsbt", "\"psbt\"")}, | |||||
"\nExamples:\n" + | } | ||||
HelpExampleCli("decodepsbt", "\"psbt\"")); | .ToStringWithResultsAndExamples()); | ||||
} | } | ||||
RPCTypeCheck(request.params, {UniValue::VSTR}); | RPCTypeCheck(request.params, {UniValue::VSTR}); | ||||
// Unserialize the transactions | // Unserialize the transactions | ||||
PartiallySignedTransaction psbtx; | PartiallySignedTransaction psbtx; | ||||
std::string error; | std::string error; | ||||
if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) { | if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) { | ||||
▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | static UniValue decodepsbt(const Config &config, | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
static UniValue combinepsbt(const Config &config, | static UniValue combinepsbt(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(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"combinepsbt", | "combinepsbt", | ||||
"\nCombine multiple partially signed Bitcoin transactions into " | "\nCombine multiple partially signed Bitcoin transactions into " | ||||
"one transaction.\n" | "one transaction.\n" | ||||
"Implements the Combiner role.\n", | "Implements the Combiner role.\n", | ||||
{ | { | ||||
{ | { | ||||
"txs", | "txs", | ||||
RPCArg::Type::ARR, | RPCArg::Type::ARR, | ||||
/* opt */ false, | /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"A json array of base64 strings of partially signed " | "A json array of base64 strings of partially signed " | ||||
"transactions", | "transactions", | ||||
{ | { | ||||
{"psbt", RPCArg::Type::STR, /* opt */ false, | {"psbt", RPCArg::Type::STR, /* opt */ false, | ||||
/* default_val */ "", "A base64 string of a PSBT"}, | /* default_val */ "", "A base64 string of a PSBT"}, | ||||
}, | }, | ||||
}, | }, | ||||
}} | }, | ||||
.ToString() + | RPCResult{" \"psbt\" (string) The base64-encoded " | ||||
"\nResult:\n" | "partially signed transaction\n"}, | ||||
" \"psbt\" (string) The base64-encoded partially signed " | RPCExamples{HelpExampleCli( | ||||
"transaction\n" | "combinepsbt", | ||||
"\nExamples:\n" + | "[\"mybase64_1\", \"mybase64_2\", \"mybase64_3\"]")}, | ||||
HelpExampleCli("combinepsbt", | } | ||||
"[\"mybase64_1\", \"mybase64_2\", \"mybase64_3\"]")); | .ToStringWithResultsAndExamples()); | ||||
} | } | ||||
RPCTypeCheck(request.params, {UniValue::VARR}, true); | RPCTypeCheck(request.params, {UniValue::VARR}, true); | ||||
// Unserialize the transactions | // Unserialize the transactions | ||||
std::vector<PartiallySignedTransaction> psbtxs; | std::vector<PartiallySignedTransaction> psbtxs; | ||||
UniValue txs = request.params[0].get_array(); | UniValue txs = request.params[0].get_array(); | ||||
for (size_t i = 0; i < txs.size(); ++i) { | for (size_t i = 0; i < txs.size(); ++i) { | ||||
Show All 17 Lines | static UniValue combinepsbt(const Config &config, | ||||
ssTx << merged_psbt; | ssTx << merged_psbt; | ||||
return EncodeBase64((uint8_t *)ssTx.data(), ssTx.size()); | return EncodeBase64((uint8_t *)ssTx.data(), ssTx.size()); | ||||
} | } | ||||
static UniValue finalizepsbt(const Config &config, | static UniValue finalizepsbt(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(RPCHelpMan{ | ||||
RPCHelpMan{"finalizepsbt", | "finalizepsbt", | ||||
"Finalize the inputs of a PSBT. If the transaction is " | "Finalize the inputs of a PSBT. If the transaction is " | ||||
"fully signed, it will produce a\n" | "fully signed, it will produce a\n" | ||||
"network serialized transaction which can be broadcast " | "network serialized transaction which can be broadcast " | ||||
"with sendrawtransaction. Otherwise a PSBT will be\n" | "with sendrawtransaction. Otherwise a PSBT will be\n" | ||||
"created which has the final_scriptSigfields filled for " | "created which has the final_scriptSigfields filled for " | ||||
"inputs that are complete.\n" | "inputs that are complete.\n" | ||||
"Implements the Finalizer and Extractor roles.\n", | "Implements the Finalizer and Extractor roles.\n", | ||||
{ | { | ||||
{"psbt", RPCArg::Type::STR, /* opt */ false, | {"psbt", RPCArg::Type::STR, /* opt */ false, | ||||
/* default_val */ "", "A base64 string of a PSBT"}, | /* default_val */ "", "A base64 string of a PSBT"}, | ||||
{"extract", RPCArg::Type::BOOL, /* opt */ true, | {"extract", RPCArg::Type::BOOL, /* opt */ true, | ||||
/* default_val */ "true", | /* default_val */ "true", | ||||
"If true and the transaction is complete,\n" | "If true and the transaction is complete,\n" | ||||
" extract and return " | " extract and return " | ||||
"the complete transaction in normal network " | "the complete transaction in normal network " | ||||
"serialization instead of the PSBT."}, | "serialization instead of the PSBT."}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | |||||
"{\n" | "{\n" | ||||
" \"psbt\" : \"value\", (string) The base64-encoded " | " \"psbt\" : \"value\", (string) The base64-encoded " | ||||
"partially signed transaction if not extracted\n" | "partially signed transaction if not extracted\n" | ||||
" \"hex\" : \"value\", (string) The hex-encoded network " | " \"hex\" : \"value\", (string) The hex-encoded " | ||||
"transaction if extracted\n" | "network transaction if extracted\n" | ||||
" \"complete\" : true|false, (boolean) If the transaction has a " | " \"complete\" : true|false, (boolean) If the transaction " | ||||
"complete set of signatures\n" | "has a complete set of signatures\n" | ||||
" ]\n" | " ]\n" | ||||
"}\n" | "}\n"}, | ||||
RPCExamples{HelpExampleCli("finalizepsbt", "\"psbt\"")}, | |||||
"\nExamples:\n" + | } | ||||
HelpExampleCli("finalizepsbt", "\"psbt\"")); | .ToStringWithResultsAndExamples()); | ||||
} | } | ||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true); | RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true); | ||||
// Unserialize the transactions | // Unserialize the transactions | ||||
PartiallySignedTransaction psbtx; | PartiallySignedTransaction psbtx; | ||||
std::string error; | std::string error; | ||||
if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) { | if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) { | ||||
Show All 24 Lines | static UniValue finalizepsbt(const Config &config, | ||||
return result; | return result; | ||||
} | } | ||||
static UniValue createpsbt(const Config &config, | static UniValue createpsbt(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 2 || | if (request.fHelp || request.params.size() < 2 || | ||||
request.params.size() > 3) { | request.params.size() > 3) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"createpsbt", | "createpsbt", | ||||
"\nCreates a transaction in the Partially Signed " | "\nCreates a transaction in the Partially Signed " | ||||
"Transaction format.\n" | "Transaction format.\n" | ||||
"Implements the Creator role.\n", | "Implements the Creator role.\n", | ||||
{ | { | ||||
{ | { | ||||
"inputs", | "inputs", | ||||
RPCArg::Type::ARR, | RPCArg::Type::ARR, | ||||
/* opt */ false, | /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"A json array of json objects", | "A json array of json objects", | ||||
{ | { | ||||
{ | { | ||||
"", | "", | ||||
RPCArg::Type::OBJ, | RPCArg::Type::OBJ, | ||||
/* opt */ false, | /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"", | "", | ||||
{ | { | ||||
{"txid", RPCArg::Type::STR_HEX, | {"txid", RPCArg::Type::STR_HEX, | ||||
/* opt */ false, /* default_val */ "", | /* opt */ false, /* default_val */ "", | ||||
"The transaction id"}, | "The transaction id"}, | ||||
{"vout", RPCArg::Type::NUM, /* opt */ false, | {"vout", RPCArg::Type::NUM, /* opt */ false, | ||||
/* default_val */ "", "The output number"}, | /* default_val */ "", "The output number"}, | ||||
{"sequence", RPCArg::Type::NUM, | {"sequence", RPCArg::Type::NUM, | ||||
/* opt */ true, /* default_val */ "", | /* opt */ true, /* default_val */ "", | ||||
"The sequence number"}, | "The sequence number"}, | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
{ | { | ||||
"outputs", | "outputs", | ||||
RPCArg::Type::ARR, | RPCArg::Type::ARR, | ||||
/* opt */ false, | /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"a json array with outputs (key-value pairs).\n" | "a json array with outputs (key-value pairs).\n" | ||||
"For compatibility reasons, a dictionary, which holds " | "For compatibility reasons, a dictionary, which holds " | ||||
"the key-value pairs directly, is also\n" | "the key-value pairs directly, is also\n" | ||||
" accepted as second " | " accepted as second " | ||||
"parameter.", | "parameter.", | ||||
{ | { | ||||
{ | { | ||||
"", | "", | ||||
RPCArg::Type::OBJ, | RPCArg::Type::OBJ, | ||||
/* opt */ true, | /* opt */ true, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"", | "", | ||||
{ | { | ||||
{"address", RPCArg::Type::AMOUNT, | {"address", RPCArg::Type::AMOUNT, | ||||
/* opt */ false, /* default_val */ "", | /* opt */ false, /* default_val */ "", | ||||
"A key-value pair. The key (string) is " | "A key-value pair. The key (string) is " | ||||
"the bitcoin address, the value (float or " | "the bitcoin address, the value (float or " | ||||
"string) is the amount in " + | "string) is the amount in " + | ||||
CURRENCY_UNIT}, | CURRENCY_UNIT}, | ||||
}, | }, | ||||
}, | }, | ||||
{ | { | ||||
"", | "", | ||||
RPCArg::Type::OBJ, | RPCArg::Type::OBJ, | ||||
/* opt */ true, | /* opt */ true, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"", | "", | ||||
{ | { | ||||
{"data", RPCArg::Type::STR_HEX, | {"data", RPCArg::Type::STR_HEX, | ||||
/* opt */ false, /* default_val */ "", | /* opt */ false, /* default_val */ "", | ||||
"A key-value pair. The key must be " | "A key-value pair. The key must be " | ||||
"\"data\", the value is hex-encoded data"}, | "\"data\", the value is hex-encoded data"}, | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
{"locktime", RPCArg::Type::NUM, /* opt */ true, | {"locktime", RPCArg::Type::NUM, /* opt */ true, | ||||
/* default_val */ "0", | /* default_val */ "0", | ||||
"Raw locktime. Non-0 value also locktime-activates " | "Raw locktime. Non-0 value also locktime-activates " | ||||
"inputs"}, | "inputs"}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{" \"psbt\" (string) The resulting raw " | ||||
"\nResult:\n" | "transaction (base64-encoded string)\n"}, | ||||
" \"psbt\" (string) The resulting raw transaction " | RPCExamples{HelpExampleCli( | ||||
"(base64-encoded string)\n" | "createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]" | ||||
"\nExamples:\n" + | "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")}, | ||||
HelpExampleCli("createpsbt", | } | ||||
"\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" " | .ToStringWithResultsAndExamples()); | ||||
"\"[{\\\"data\\\":\\\"00010203\\\"}]\"")); | |||||
} | } | ||||
RPCTypeCheck(request.params, | RPCTypeCheck(request.params, | ||||
{ | { | ||||
UniValue::VARR, | UniValue::VARR, | ||||
UniValueType(), // ARR or OBJ, checked later | UniValueType(), // ARR or OBJ, checked later | ||||
UniValue::VNUM, | UniValue::VNUM, | ||||
}, | }, | ||||
Show All 19 Lines | static UniValue createpsbt(const Config &config, | ||||
return EncodeBase64((uint8_t *)ssTx.data(), ssTx.size()); | return EncodeBase64((uint8_t *)ssTx.data(), ssTx.size()); | ||||
} | } | ||||
static UniValue converttopsbt(const Config &config, | static UniValue converttopsbt(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(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"converttopsbt", | "converttopsbt", | ||||
"\nConverts a network serialized transaction to a PSBT. " | "\nConverts a network serialized transaction to a PSBT. " | ||||
"This should be used only with createrawtransaction and " | "This should be used only with createrawtransaction and " | ||||
"fundrawtransaction\n" | "fundrawtransaction\n" | ||||
"createpsbt and walletcreatefundedpsbt should be used " | "createpsbt and walletcreatefundedpsbt should be used " | ||||
"for new applications.\n", | "for new applications.\n", | ||||
{ | { | ||||
{"hexstring", RPCArg::Type::STR_HEX, /* opt */ false, | {"hexstring", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", "The hex string of a raw transaction"}, | ||||
"The hex string of a raw transaction"}, | |||||
{"permitsigdata", RPCArg::Type::BOOL, /* opt */ true, | {"permitsigdata", RPCArg::Type::BOOL, /* opt */ true, | ||||
/* default_val */ "false", | /* default_val */ "false", | ||||
"If true, any signatures in the input will be discarded " | "If true, any signatures in the input will be discarded " | ||||
"and conversion\n" | "and conversion.\n" | ||||
" will continue. If false, " | " will continue. If false, " | ||||
"RPC will fail if any signatures are present."}, | "RPC will fail if any signatures are present."}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{" \"psbt\" (string) The resulting raw " | ||||
"\nResult:\n" | "transaction (base64-encoded string)\n"}, | ||||
" \"psbt\" (string) The resulting raw transaction " | RPCExamples{ | ||||
"(base64-encoded string)\n" | |||||
"\nExamples:\n" | |||||
"\nCreate a transaction\n" + | "\nCreate a transaction\n" + | ||||
HelpExampleCli("createrawtransaction", | HelpExampleCli("createrawtransaction", | ||||
"\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" " | "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]" | ||||
"\"[{\\\"data\\\":\\\"00010203\\\"}]\"") + | "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") + | ||||
"\nConvert the transaction to a PSBT\n" + | "\nConvert the transaction to a PSBT\n" + | ||||
HelpExampleCli("converttopsbt", "\"rawtransaction\"")); | HelpExampleCli("converttopsbt", "\"rawtransaction\"")}, | ||||
} | |||||
.ToStringWithResultsAndExamples()); | |||||
} | } | ||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true); | RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true); | ||||
// parse hex string from parameter | // parse hex string from parameter | ||||
CMutableTransaction tx; | CMutableTransaction tx; | ||||
if (!DecodeHexTx(tx, request.params[0].get_str())) { | if (!DecodeHexTx(tx, request.params[0].get_str())) { | ||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | ||||
▲ Show 20 Lines • Show All 58 Lines • Show Last 20 Lines |