aboutsummaryrefslogtreecommitdiff
path: root/src/rpcrawtransaction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpcrawtransaction.cpp')
-rw-r--r--src/rpcrawtransaction.cpp83
1 files changed, 55 insertions, 28 deletions
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index 7d1db0b60..5f3363d09 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -4,6 +4,8 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
+#include "chain.h"
+#include "coins.h"
#include "consensus/validation.h"
#include "core_io.h"
#include "init.h"
@@ -18,7 +20,9 @@
#include "script/script_error.h"
#include "script/sign.h"
#include "script/standard.h"
+#include "txmempool.h"
#include "uint256.h"
+#include "utilstrencodings.h"
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#endif
@@ -27,7 +31,7 @@
#include <boost/assign/list_of.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -37,7 +41,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud
vector<CTxDestination> addresses;
int nRequired;
- out.push_back(Pair("asm", scriptPubKey.ToString()));
+ out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
if (fIncludeHex)
out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
@@ -69,7 +73,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
in.push_back(Pair("vout", (int64_t)txin.prevout.n));
UniValue o(UniValue::VOBJ);
- o.push_back(Pair("asm", txin.scriptSig.ToString()));
+ o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true)));
o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
in.push_back(Pair("scriptSig", o));
}
@@ -145,7 +149,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp)
" ],\n"
" \"vout\" : [ (array of json objects)\n"
" {\n"
- " \"value\" : x.xxx, (numeric) The value in btc\n"
+ " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
" \"n\" : n, (numeric) index\n"
" \"scriptPubKey\" : { (json object)\n"
" \"asm\" : \"asm\", (string) the asm\n"
@@ -312,10 +316,11 @@ UniValue verifytxoutproof(const UniValue& params, bool fHelp)
UniValue createrawtransaction(const UniValue& params, bool fHelp)
{
- if (fHelp || params.size() != 2)
+ if (fHelp || params.size() < 2 || params.size() > 3)
throw runtime_error(
- "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...}\n"
- "\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
+ "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"
@@ -324,33 +329,45 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
"1. \"transactions\" (string, required) A json array of json objects\n"
" [\n"
" {\n"
- " \"txid\":\"id\", (string, required) The transaction id\n"
+ " \"txid\":\"id\", (string, required) The transaction id\n"
" \"vout\":n (numeric, required) The output number\n"
" }\n"
" ,...\n"
" ]\n"
- "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n"
+ "2. \"outputs\" (string, required) a json object with outputs\n"
" {\n"
- " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the btc amount\n"
- " ,...\n"
+ " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the " + CURRENCY_UNIT + " amount\n"
+ " \"data\": \"hex\", (string, required) The key is \"data\", the value is hex encoded data\n"
+ " ...\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\\\"}\"")
);
LOCK(cs_main);
- RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ));
+ RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM), true);
+ if (params[0].isNull() || params[1].isNull())
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
UniValue inputs = params[0].get_array();
UniValue sendTo = params[1].get_obj();
CMutableTransaction rawTx;
+ if (params.size() > 2 && !params[2].isNull()) {
+ int64_t nLockTime = params[2].get_int64();
+ if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range");
+ rawTx.nLockTime = nLockTime;
+ }
+
for (unsigned int idx = 0; idx < inputs.size(); idx++) {
const UniValue& input = inputs[idx];
const UniValue& o = input.get_obj();
@@ -364,26 +381,36 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
if (nOutput < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
- CTxIn in(COutPoint(txid, nOutput));
+ uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());
+ CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
+
rawTx.vin.push_back(in);
}
set<CBitcoinAddress> setAddress;
vector<string> addrList = sendTo.getKeys();
BOOST_FOREACH(const string& name_, addrList) {
- CBitcoinAddress address(name_);
- if (!address.IsValid())
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_);
- if (setAddress.count(address))
- throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_);
- setAddress.insert(address);
+ if (name_ == "data") {
+ std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data");
+
+ CTxOut out(0, CScript() << OP_RETURN << data);
+ rawTx.vout.push_back(out);
+ } else {
+ CBitcoinAddress address(name_);
+ if (!address.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_);
- CScript scriptPubKey = GetScriptForDestination(address.Get());
- CAmount nAmount = AmountFromValue(sendTo[name_]);
+ if (setAddress.count(address))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_);
+ setAddress.insert(address);
- CTxOut out(nAmount, scriptPubKey);
- rawTx.vout.push_back(out);
+ CScript scriptPubKey = GetScriptForDestination(address.Get());
+ CAmount nAmount = AmountFromValue(sendTo[name_]);
+
+ CTxOut out(nAmount, scriptPubKey);
+ rawTx.vout.push_back(out);
+ }
}
return EncodeHexTx(rawTx);
@@ -418,7 +445,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp)
" ],\n"
" \"vout\" : [ (array of json objects)\n"
" {\n"
- " \"value\" : x.xxx, (numeric) The value in btc\n"
+ " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
" \"n\" : n, (numeric) index\n"
" \"scriptPubKey\" : { (json object)\n"
" \"asm\" : \"asm\", (string) the asm\n"
@@ -661,8 +688,8 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
CCoinsModifier coins = view.ModifyCoins(txid);
if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
string err("Previous output scriptPubKey mismatch:\n");
- err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
- scriptPubKey.ToString();
+ err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+
+ ScriptToAsmStr(scriptPubKey);
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
}
if ((unsigned int)nOut >= coins->vout.size())
@@ -794,7 +821,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp)
// push to local node and sync with wallets
CValidationState state;
bool fMissingInputs;
- if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
+ if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, false, !fOverrideFees)) {
if (state.IsInvalid()) {
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
} else {