Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/rawtransaction.cpp
Show First 20 Lines • Show All 403 Lines • ▼ Show 20 Lines | if (pindex->nTx == merkleBlock.txn.GetNumTransactions()) { | ||||
for (const uint256 &hash : vMatch) { | for (const uint256 &hash : vMatch) { | ||||
res.push_back(hash.GetHex()); | res.push_back(hash.GetHex()); | ||||
} | } | ||||
} | } | ||||
return res; | return res; | ||||
} | } | ||||
static UniValue createrawtransaction(const Config &config, | CMutableTransaction ConstructTransaction(const CChainParams ¶ms, | ||||
const JSONRPCRequest &request) { | const UniValue &inputs_in, | ||||
if (request.fHelp || request.params.size() < 2 || | const UniValue &outputs_in, | ||||
request.params.size() > 3) { | const UniValue &locktime) { | ||||
throw std::runtime_error( | if (inputs_in.isNull() || outputs_in.isNull()) { | ||||
// clang-format off | |||||
"createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] [{\"address\":amount},{\"data\":\"hex\"},...] ( locktime )\n" | |||||
"\nCreate a transaction spending the given inputs and creating new outputs.\n" | |||||
"Outputs can be addresses or data.\n" | |||||
"Returns hex-encoded raw transaction.\n" | |||||
"Note that the transaction's inputs are not signed, and\n" | |||||
"it is not stored in the wallet or transmitted to the network.\n" | |||||
"\nArguments:\n" | |||||
"1. \"inputs\" (array, required) A json array of " | |||||
"json objects\n" | |||||
" [\n" | |||||
" {\n" | |||||
" \"txid\":\"id\", (string, required) The transaction id\n" | |||||
" \"vout\":n, (numeric, required) The output number\n" | |||||
" \"sequence\":n (numeric, optional) The sequence number\n" | |||||
" } \n" | |||||
" ,...\n" | |||||
" ]\n" | |||||
"2. \"outputs\" (array, required) a json array with outputs (key-value pairs)\n" | |||||
" [\n" | |||||
" {\n" | |||||
" \"address\": x.xxx, (obj, optional) A key-value pair. The key (string) is the bitcoin address, the value (float or string) is the amount in " + CURRENCY_UNIT + "\n" | |||||
" },\n" | |||||
" {\n" | |||||
" \"data\": \"hex\" (obj, optional) A key-value pair. The key must be \"data\", the value is hex encoded data\n" | |||||
" }\n" | |||||
" ,... More key-value pairs of the above form. For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n" | |||||
" accepted as second parameter.\n" | |||||
" ]\n" | |||||
"3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n" | |||||
"\nResult:\n" | |||||
"\"transaction\" (string) hex string of the transaction\n" | |||||
"\nExamples:\n" | |||||
+ 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\\\"}]\"") | |||||
// clang-format on | |||||
); | |||||
} | |||||
RPCTypeCheck(request.params, | |||||
{UniValue::VARR, | |||||
UniValueType(), // ARR or OBJ, checked later | |||||
UniValue::VNUM, UniValue::VBOOL}, | |||||
true); | |||||
if (request.params[0].isNull() || request.params[1].isNull()) { | |||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_INVALID_PARAMETER, | RPC_INVALID_PARAMETER, | ||||
"Invalid parameter, arguments 1 and 2 must be non-null"); | "Invalid parameter, arguments 1 and 2 must be non-null"); | ||||
} | } | ||||
UniValue inputs = request.params[0].get_array(); | UniValue inputs = inputs_in.get_array(); | ||||
const bool outputs_is_obj = request.params[1].isObject(); | const bool outputs_is_obj = outputs_in.isObject(); | ||||
UniValue outputs = outputs_is_obj ? request.params[1].get_obj() | UniValue outputs = | ||||
: request.params[1].get_array(); | outputs_is_obj ? outputs_in.get_obj() : outputs_in.get_array(); | ||||
CMutableTransaction rawTx; | CMutableTransaction rawTx; | ||||
if (!request.params[2].isNull()) { | if (!locktime.isNull()) { | ||||
int64_t nLockTime = request.params[2].get_int64(); | int64_t nLockTime = locktime.get_int64(); | ||||
if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max()) { | if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max()) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
"Invalid parameter, locktime out of range"); | "Invalid parameter, locktime out of range"); | ||||
} | } | ||||
rawTx.nLockTime = nLockTime; | rawTx.nLockTime = nLockTime; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | CMutableTransaction ConstructTransaction(const CChainParams ¶ms, | ||||
for (const std::string &name_ : outputs.getKeys()) { | for (const std::string &name_ : outputs.getKeys()) { | ||||
if (name_ == "data") { | if (name_ == "data") { | ||||
std::vector<uint8_t> data = | std::vector<uint8_t> data = | ||||
ParseHexV(outputs[name_].getValStr(), "Data"); | ParseHexV(outputs[name_].getValStr(), "Data"); | ||||
CTxOut out(Amount::zero(), CScript() << OP_RETURN << data); | CTxOut out(Amount::zero(), CScript() << OP_RETURN << data); | ||||
rawTx.vout.push_back(out); | rawTx.vout.push_back(out); | ||||
} else { | } else { | ||||
CTxDestination destination = | CTxDestination destination = DecodeDestination(name_, params); | ||||
DecodeDestination(name_, config.GetChainParams()); | |||||
if (!IsValidDestination(destination)) { | if (!IsValidDestination(destination)) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
std::string("Invalid Bitcoin address: ") + | std::string("Invalid Bitcoin address: ") + | ||||
name_); | name_); | ||||
} | } | ||||
if (!destinations.insert(destination).second) { | if (!destinations.insert(destination).second) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_INVALID_PARAMETER, | RPC_INVALID_PARAMETER, | ||||
std::string("Invalid parameter, duplicated address: ") + | std::string("Invalid parameter, duplicated address: ") + | ||||
name_); | name_); | ||||
} | } | ||||
CScript scriptPubKey = GetScriptForDestination(destination); | CScript scriptPubKey = GetScriptForDestination(destination); | ||||
Amount nAmount = AmountFromValue(outputs[name_]); | Amount nAmount = AmountFromValue(outputs[name_]); | ||||
CTxOut out(nAmount, scriptPubKey); | CTxOut out(nAmount, scriptPubKey); | ||||
rawTx.vout.push_back(out); | rawTx.vout.push_back(out); | ||||
} | } | ||||
} | } | ||||
return rawTx; | |||||
} | |||||
static UniValue createrawtransaction(const Config &config, | |||||
const JSONRPCRequest &request) { | |||||
if (request.fHelp || request.params.size() < 2 || | |||||
request.params.size() > 3) { | |||||
throw std::runtime_error( | |||||
// clang-format off | |||||
"createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] [{\"address\":amount},{\"data\":\"hex\"},...] ( locktime )\n" | |||||
"\nCreate a transaction spending the given inputs and creating new outputs.\n" | |||||
"Outputs can be addresses or data.\n" | |||||
"Returns hex-encoded raw transaction.\n" | |||||
"Note that the transaction's inputs are not signed, and\n" | |||||
"it is not stored in the wallet or transmitted to the network.\n" | |||||
"\nArguments:\n" | |||||
"1. \"inputs\" (array, required) A json array of " | |||||
"json objects\n" | |||||
" [\n" | |||||
" {\n" | |||||
" \"txid\":\"id\", (string, required) The transaction id\n" | |||||
" \"vout\":n, (numeric, required) The output number\n" | |||||
" \"sequence\":n (numeric, optional) The sequence number\n" | |||||
" } \n" | |||||
" ,...\n" | |||||
" ]\n" | |||||
"2. \"outputs\" (array, required) a json array with outputs (key-value pairs)\n" | |||||
" [\n" | |||||
" {\n" | |||||
" \"address\": x.xxx, (obj, optional) A key-value pair. The key (string) is the bitcoin address, the value (float or string) is the amount in " + CURRENCY_UNIT + "\n" | |||||
" },\n" | |||||
" {\n" | |||||
" \"data\": \"hex\" (obj, optional) A key-value pair. The key must be \"data\", the value is hex encoded data\n" | |||||
" }\n" | |||||
" ,... More key-value pairs of the above form. For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n" | |||||
" accepted as second parameter.\n" | |||||
" ]\n" | |||||
"3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n" | |||||
"\nResult:\n" | |||||
"\"transaction\" (string) hex string of the transaction\n" | |||||
"\nExamples:\n" | |||||
+ 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\\\"}]\"") | |||||
// clang-format on | |||||
); | |||||
} | |||||
RPCTypeCheck(request.params, | |||||
{UniValue::VARR, | |||||
UniValueType(), // ARR or OBJ, checked later | |||||
UniValue::VNUM}, | |||||
true); | |||||
CMutableTransaction rawTx = | |||||
ConstructTransaction(config.GetChainParams(), request.params[0], | |||||
request.params[1], request.params[2]); | |||||
return EncodeHexTx(CTransaction(rawTx)); | return EncodeHexTx(CTransaction(rawTx)); | ||||
} | } | ||||
static UniValue decoderawtransaction(const Config &config, | static UniValue decoderawtransaction(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( | ||||
"decoderawtransaction \"hexstring\"\n" | "decoderawtransaction \"hexstring\"\n" | ||||
▲ Show 20 Lines • Show All 765 Lines • Show Last 20 Lines |