Mercurial > hg > bitcoin
annotate src/rpcrawtransaction.cpp @ 3588:7eb24f8cf224 draft
Document RPC error codes
Replace all "magic values" in RPCError(...) by constants.
author | Wladimir J. van der Laan <laanwj@gmail.com> |
---|---|
date | Thu, 04 Oct 2012 09:34:44 +0200 |
parents | 75fad4c8df94 |
children | abd3935e67df |
rev | line source |
---|---|
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
1 // Copyright (c) 2010 Satoshi Nakamoto |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
2 // Copyright (c) 2009-2012 The Bitcoin developers |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
3 // Distributed under the MIT/X11 software license, see the accompanying |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
5 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
6 #include <boost/assign/list_of.hpp> |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
7 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
8 #include "base58.h" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
9 #include "bitcoinrpc.h" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
10 #include "db.h" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
11 #include "init.h" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
12 #include "main.h" |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
13 #include "net.h" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
14 #include "wallet.h" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
15 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
16 using namespace std; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
17 using namespace boost; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
18 using namespace boost::assign; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
19 using namespace json_spirit; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
20 |
3374
8c4e49592ec8
Avoid leaving return types or function attributes on their own lines.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
21 void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
22 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
23 txnouttype type; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
24 vector<CTxDestination> addresses; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
25 int nRequired; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
26 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
27 out.push_back(Pair("asm", scriptPubKey.ToString())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
28 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
29 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
30 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
31 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
32 out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
33 return; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
34 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
35 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
36 out.push_back(Pair("reqSigs", nRequired)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
37 out.push_back(Pair("type", GetTxnOutputType(type))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
38 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
39 Array a; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
40 BOOST_FOREACH(const CTxDestination& addr, addresses) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
41 a.push_back(CBitcoinAddress(addr).ToString()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
42 out.push_back(Pair("addresses", a)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
43 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
44 |
3374
8c4e49592ec8
Avoid leaving return types or function attributes on their own lines.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
45 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
46 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
47 entry.push_back(Pair("txid", tx.GetHash().GetHex())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
48 entry.push_back(Pair("version", tx.nVersion)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
49 entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
50 Array vin; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
51 BOOST_FOREACH(const CTxIn& txin, tx.vin) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
52 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
53 Object in; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
54 if (tx.IsCoinBase()) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
55 in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
56 else |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
57 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
58 in.push_back(Pair("txid", txin.prevout.hash.GetHex())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
59 in.push_back(Pair("vout", (boost::int64_t)txin.prevout.n)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
60 Object o; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
61 o.push_back(Pair("asm", txin.scriptSig.ToString())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
62 o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
63 in.push_back(Pair("scriptSig", o)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
64 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
65 in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
66 vin.push_back(in); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
67 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
68 entry.push_back(Pair("vin", vin)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
69 Array vout; |
3156
505666711e5b
Use unsigned ints to fix signed/unsigned warnings
Gavin Andresen <gavinandresen@gmail.com>
parents:
3154
diff
changeset
|
70 for (unsigned int i = 0; i < tx.vout.size(); i++) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
71 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
72 const CTxOut& txout = tx.vout[i]; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
73 Object out; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
74 out.push_back(Pair("value", ValueFromAmount(txout.nValue))); |
3156
505666711e5b
Use unsigned ints to fix signed/unsigned warnings
Gavin Andresen <gavinandresen@gmail.com>
parents:
3154
diff
changeset
|
75 out.push_back(Pair("n", (boost::int64_t)i)); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
76 Object o; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
77 ScriptPubKeyToJSON(txout.scriptPubKey, o); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
78 out.push_back(Pair("scriptPubKey", o)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
79 vout.push_back(out); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
80 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
81 entry.push_back(Pair("vout", vout)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
82 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
83 if (hashBlock != 0) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
84 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
85 entry.push_back(Pair("blockhash", hashBlock.GetHex())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
86 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
87 if (mi != mapBlockIndex.end() && (*mi).second) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
88 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
89 CBlockIndex* pindex = (*mi).second; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
90 if (pindex->IsInMainChain()) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
91 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
92 entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
93 entry.push_back(Pair("time", (boost::int64_t)pindex->nTime)); |
3362
494bece0648d
JSON-RPC: Add "blocktime" and (for wallet transactions) "timereceived" to transaction Object outputs
Luke Dashjr <luke-jr+git@utopios.org>
parents:
3340
diff
changeset
|
94 entry.push_back(Pair("blocktime", (boost::int64_t)pindex->nTime)); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
95 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
96 else |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
97 entry.push_back(Pair("confirmations", 0)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
98 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
99 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
100 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
101 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
102 Value getrawtransaction(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
103 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
104 if (fHelp || params.size() < 1 || params.size() > 2) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
105 throw runtime_error( |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
106 "getrawtransaction <txid> [verbose=0]\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
107 "If verbose=0, returns a string that is\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
108 "serialized, hex-encoded data for <txid>.\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
109 "If verbose is non-zero, returns an Object\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
110 "with information about <txid>."); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
111 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
112 uint256 hash; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
113 hash.SetHex(params[0].get_str()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
114 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
115 bool fVerbose = false; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
116 if (params.size() > 1) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
117 fVerbose = (params[1].get_int() != 0); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
118 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
119 CTransaction tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
120 uint256 hashBlock = 0; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
121 if (!GetTransaction(hash, tx, hashBlock)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
122 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
123 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
124 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
125 ssTx << tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
126 string strHex = HexStr(ssTx.begin(), ssTx.end()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
127 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
128 if (!fVerbose) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
129 return strHex; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
130 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
131 Object result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
132 result.push_back(Pair("hex", strHex)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
133 TxToJSON(tx, hashBlock, result); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
134 return result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
135 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
136 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
137 Value listunspent(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
138 { |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
139 if (fHelp || params.size() > 3) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
140 throw runtime_error( |
3377
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
141 "listunspent [minconf=1] [maxconf=9999999] [\"address\",...]\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
142 "Returns array of unspent transaction outputs\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
143 "with between minconf and maxconf (inclusive) confirmations.\n" |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
144 "Optionally filtered to only include txouts paid to specified addresses.\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
145 "Results are an array of Objects, each of which has:\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
146 "{txid, vout, scriptPubKey, amount, confirmations}"); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
147 |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
148 RPCTypeCheck(params, list_of(int_type)(int_type)(array_type)); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
149 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
150 int nMinDepth = 1; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
151 if (params.size() > 0) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
152 nMinDepth = params[0].get_int(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
153 |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
154 int nMaxDepth = 9999999; |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
155 if (params.size() > 1) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
156 nMaxDepth = params[1].get_int(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
157 |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
158 set<CBitcoinAddress> setAddress; |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
159 if (params.size() > 2) |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
160 { |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
161 Array inputs = params[2].get_array(); |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
162 BOOST_FOREACH(Value& input, inputs) |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
163 { |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
164 CBitcoinAddress address(input.get_str()); |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
165 if (!address.IsValid()) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
166 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str()); |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
167 if (setAddress.count(address)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
168 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str()); |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
169 setAddress.insert(address); |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
170 } |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
171 } |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
172 |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
173 Array results; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
174 vector<COutput> vecOutputs; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
175 pwalletMain->AvailableCoins(vecOutputs, false); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
176 BOOST_FOREACH(const COutput& out, vecOutputs) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
177 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
178 if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
179 continue; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
180 |
3377
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
181 if(setAddress.size()) |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
182 { |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
183 CTxDestination address; |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
184 if(!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
185 continue; |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
186 |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
187 if (!setAddress.count(address)) |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
188 continue; |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
189 } |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
190 |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
191 int64 nValue = out.tx->vout[out.i].nValue; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
192 const CScript& pk = out.tx->vout[out.i].scriptPubKey; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
193 Object entry; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
194 entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
195 entry.push_back(Pair("vout", out.i)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
196 entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
197 entry.push_back(Pair("amount",ValueFromAmount(nValue))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
198 entry.push_back(Pair("confirmations",out.nDepth)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
199 results.push_back(entry); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
200 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
201 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
202 return results; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
203 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
204 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
205 Value createrawtransaction(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
206 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
207 if (fHelp || params.size() != 2) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
208 throw runtime_error( |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
209 "createrawtransaction [{\"txid\":txid,\"vout\":n},...] {address:amount,...}\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
210 "Create a transaction spending given inputs\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
211 "(array of objects containing transaction id and output number),\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
212 "sending to given address(es).\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
213 "Returns hex-encoded raw transaction.\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
214 "Note that the transaction's inputs are not signed, and\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
215 "it is not stored in the wallet or transmitted to the network."); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
216 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
217 RPCTypeCheck(params, list_of(array_type)(obj_type)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
218 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
219 Array inputs = params[0].get_array(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
220 Object sendTo = params[1].get_obj(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
221 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
222 CTransaction rawTx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
223 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
224 BOOST_FOREACH(Value& input, inputs) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
225 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
226 const Object& o = input.get_obj(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
227 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
228 const Value& txid_v = find_value(o, "txid"); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
229 if (txid_v.type() != str_type) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
230 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing txid key"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
231 string txid = txid_v.get_str(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
232 if (!IsHex(txid)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
233 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
234 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
235 const Value& vout_v = find_value(o, "vout"); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
236 if (vout_v.type() != int_type) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
237 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
238 int nOutput = vout_v.get_int(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
239 if (nOutput < 0) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
240 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
241 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
242 CTxIn in(COutPoint(uint256(txid), nOutput)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
243 rawTx.vin.push_back(in); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
244 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
245 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
246 set<CBitcoinAddress> setAddress; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
247 BOOST_FOREACH(const Pair& s, sendTo) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
248 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
249 CBitcoinAddress address(s.name_); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
250 if (!address.IsValid()) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
251 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
252 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
253 if (setAddress.count(address)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
254 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
255 setAddress.insert(address); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
256 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
257 CScript scriptPubKey; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
258 scriptPubKey.SetDestination(address.Get()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
259 int64 nAmount = AmountFromValue(s.value_); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
260 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
261 CTxOut out(nAmount, scriptPubKey); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
262 rawTx.vout.push_back(out); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
263 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
264 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
265 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
266 ss << rawTx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
267 return HexStr(ss.begin(), ss.end()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
268 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
269 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
270 Value decoderawtransaction(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
271 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
272 if (fHelp || params.size() != 1) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
273 throw runtime_error( |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
274 "decoderawtransaction <hex string>\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
275 "Return a JSON object representing the serialized, hex-encoded transaction."); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
276 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
277 RPCTypeCheck(params, list_of(str_type)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
278 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
279 vector<unsigned char> txData(ParseHex(params[0].get_str())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
280 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
281 CTransaction tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
282 try { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
283 ssData >> tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
284 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
285 catch (std::exception &e) { |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
286 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
287 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
288 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
289 Object result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
290 TxToJSON(tx, 0, result); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
291 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
292 return result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
293 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
294 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
295 Value signrawtransaction(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
296 { |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
297 if (fHelp || params.size() < 1 || params.size() > 4) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
298 throw runtime_error( |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
299 "signrawtransaction <hex string> [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [<privatekey1>,...] [sighashtype=\"ALL\"]\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
300 "Sign inputs for raw transaction (serialized, hex-encoded).\n" |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
301 "Second optional argument (may be null) is an array of previous transaction outputs that\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
302 "this transaction depends on but may not yet be in the blockchain.\n" |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
303 "Third optional argument (may be null) is an array of base58-encoded private\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
304 "keys that, if given, will be the only keys used to sign the transaction.\n" |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
305 "Fourth optional argument is a string that is one of six values; ALL, NONE, SINGLE or\n" |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
306 "ALL|ANYONECANPAY, NONE|ANYONECANPAY, SINGLE|ANYONECANPAY.\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
307 "Returns json object with keys:\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
308 " hex : raw transaction with signature(s) (hex-encoded string)\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
309 " complete : 1 if transaction has a complete set of signature (0 if not)" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
310 + HelpRequiringPassphrase()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
311 |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
312 RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)(str_type), true); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
313 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
314 vector<unsigned char> txData(ParseHex(params[0].get_str())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
315 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
316 vector<CTransaction> txVariants; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
317 while (!ssData.empty()) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
318 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
319 try { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
320 CTransaction tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
321 ssData >> tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
322 txVariants.push_back(tx); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
323 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
324 catch (std::exception &e) { |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
325 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
326 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
327 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
328 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
329 if (txVariants.empty()) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
330 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
331 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
332 // mergedTx will end up with all the signatures; it |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
333 // starts as a clone of the rawtx: |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
334 CTransaction mergedTx(txVariants[0]); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
335 bool fComplete = true; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
336 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
337 // Fetch previous transactions (inputs): |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
338 map<COutPoint, CScript> mapPrevOut; |
3289
0addd08564e8
Correctly handle missing inputs in signrawtransaction. Fixes #1654.
Gregory Maxwell <greg@xiph.org>
parents:
3225
diff
changeset
|
339 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
340 { |
3289
0addd08564e8
Correctly handle missing inputs in signrawtransaction. Fixes #1654.
Gregory Maxwell <greg@xiph.org>
parents:
3225
diff
changeset
|
341 CTransaction tempTx; |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
342 MapPrevTx mapPrevTx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
343 CTxDB txdb("r"); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
344 map<uint256, CTxIndex> unused; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
345 bool fInvalid; |
3289
0addd08564e8
Correctly handle missing inputs in signrawtransaction. Fixes #1654.
Gregory Maxwell <greg@xiph.org>
parents:
3225
diff
changeset
|
346 |
0addd08564e8
Correctly handle missing inputs in signrawtransaction. Fixes #1654.
Gregory Maxwell <greg@xiph.org>
parents:
3225
diff
changeset
|
347 // FetchInputs aborts on failure, so we go one at a time. |
0addd08564e8
Correctly handle missing inputs in signrawtransaction. Fixes #1654.
Gregory Maxwell <greg@xiph.org>
parents:
3225
diff
changeset
|
348 tempTx.vin.push_back(mergedTx.vin[i]); |
0addd08564e8
Correctly handle missing inputs in signrawtransaction. Fixes #1654.
Gregory Maxwell <greg@xiph.org>
parents:
3225
diff
changeset
|
349 tempTx.FetchInputs(txdb, unused, false, false, mapPrevTx, fInvalid); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
350 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
351 // Copy results into mapPrevOut: |
3289
0addd08564e8
Correctly handle missing inputs in signrawtransaction. Fixes #1654.
Gregory Maxwell <greg@xiph.org>
parents:
3225
diff
changeset
|
352 BOOST_FOREACH(const CTxIn& txin, tempTx.vin) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
353 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
354 const uint256& prevHash = txin.prevout.hash; |
3289
0addd08564e8
Correctly handle missing inputs in signrawtransaction. Fixes #1654.
Gregory Maxwell <greg@xiph.org>
parents:
3225
diff
changeset
|
355 if (mapPrevTx.count(prevHash) && mapPrevTx[prevHash].second.vout.size()>txin.prevout.n) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
356 mapPrevOut[txin.prevout] = mapPrevTx[prevHash].second.vout[txin.prevout.n].scriptPubKey; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
357 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
358 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
359 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
360 // Add previous txouts given in the RPC call: |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
361 if (params.size() > 1 && params[1].type() != null_type) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
362 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
363 Array prevTxs = params[1].get_array(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
364 BOOST_FOREACH(Value& p, prevTxs) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
365 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
366 if (p.type() != obj_type) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
367 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
368 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
369 Object prevOut = p.get_obj(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
370 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
371 RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
372 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
373 string txidHex = find_value(prevOut, "txid").get_str(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
374 if (!IsHex(txidHex)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
375 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "txid must be hexadecimal"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
376 uint256 txid; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
377 txid.SetHex(txidHex); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
378 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
379 int nOut = find_value(prevOut, "vout").get_int(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
380 if (nOut < 0) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
381 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
382 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
383 string pkHex = find_value(prevOut, "scriptPubKey").get_str(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
384 if (!IsHex(pkHex)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
385 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "scriptPubKey must be hexadecimal"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
386 vector<unsigned char> pkData(ParseHex(pkHex)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
387 CScript scriptPubKey(pkData.begin(), pkData.end()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
388 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
389 COutPoint outpoint(txid, nOut); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
390 if (mapPrevOut.count(outpoint)) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
391 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
392 // Complain if scriptPubKey doesn't match |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
393 if (mapPrevOut[outpoint] != scriptPubKey) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
394 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
395 string err("Previous output scriptPubKey mismatch:\n"); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
396 err = err + mapPrevOut[outpoint].ToString() + "\nvs:\n"+ |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
397 scriptPubKey.ToString(); |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
398 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
399 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
400 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
401 else |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
402 mapPrevOut[outpoint] = scriptPubKey; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
403 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
404 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
405 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
406 bool fGivenKeys = false; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
407 CBasicKeyStore tempKeystore; |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
408 if (params.size() > 2 && params[2].type() != null_type) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
409 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
410 fGivenKeys = true; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
411 Array keys = params[2].get_array(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
412 BOOST_FOREACH(Value k, keys) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
413 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
414 CBitcoinSecret vchSecret; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
415 bool fGood = vchSecret.SetString(k.get_str()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
416 if (!fGood) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
417 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,"Invalid private key"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
418 CKey key; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
419 bool fCompressed; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
420 CSecret secret = vchSecret.GetSecret(fCompressed); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
421 key.SetSecret(secret, fCompressed); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
422 tempKeystore.AddKey(key); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
423 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
424 } |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
425 else |
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
426 EnsureWalletIsUnlocked(); |
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
427 |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
428 const CKeyStore& keystore = (fGivenKeys ? tempKeystore : *pwalletMain); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
429 |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
430 int nHashType = SIGHASH_ALL; |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
431 if (params.size() > 3 && params[3].type() != null_type) |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
432 { |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
433 static map<string, int> mapSigHashValues = |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
434 boost::assign::map_list_of |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
435 (string("ALL"), int(SIGHASH_ALL)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
436 (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
437 (string("NONE"), int(SIGHASH_NONE)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
438 (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
439 (string("SINGLE"), int(SIGHASH_SINGLE)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
440 (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
441 ; |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
442 string strHashType = params[3].get_str(); |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
443 if (mapSigHashValues.count(strHashType)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
444 nHashType = mapSigHashValues[strHashType]; |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
445 else |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
446 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param"); |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
447 } |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
448 |
3327
71eb723dde0e
When using SIGHASH_SINGLE, do not sign inputs that have no corresponding outputs.
Gavin Andresen <gavinandresen@gmail.com>
parents:
3289
diff
changeset
|
449 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); |
71eb723dde0e
When using SIGHASH_SINGLE, do not sign inputs that have no corresponding outputs.
Gavin Andresen <gavinandresen@gmail.com>
parents:
3289
diff
changeset
|
450 |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
451 // Sign what we can: |
3156
505666711e5b
Use unsigned ints to fix signed/unsigned warnings
Gavin Andresen <gavinandresen@gmail.com>
parents:
3154
diff
changeset
|
452 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
453 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
454 CTxIn& txin = mergedTx.vin[i]; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
455 if (mapPrevOut.count(txin.prevout) == 0) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
456 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
457 fComplete = false; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
458 continue; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
459 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
460 const CScript& prevPubKey = mapPrevOut[txin.prevout]; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
461 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
462 txin.scriptSig.clear(); |
3327
71eb723dde0e
When using SIGHASH_SINGLE, do not sign inputs that have no corresponding outputs.
Gavin Andresen <gavinandresen@gmail.com>
parents:
3289
diff
changeset
|
463 // Only sign SIGHASH_SINGLE if there's a corresponding output: |
71eb723dde0e
When using SIGHASH_SINGLE, do not sign inputs that have no corresponding outputs.
Gavin Andresen <gavinandresen@gmail.com>
parents:
3289
diff
changeset
|
464 if (!fHashSingle || (i < mergedTx.vout.size())) |
71eb723dde0e
When using SIGHASH_SINGLE, do not sign inputs that have no corresponding outputs.
Gavin Andresen <gavinandresen@gmail.com>
parents:
3289
diff
changeset
|
465 SignSignature(keystore, prevPubKey, mergedTx, i, nHashType); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
466 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
467 // ... and merge in other signatures: |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
468 BOOST_FOREACH(const CTransaction& txv, txVariants) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
469 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
470 txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
471 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
472 if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, true, 0)) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
473 fComplete = false; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
474 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
475 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
476 Object result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
477 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
478 ssTx << mergedTx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
479 result.push_back(Pair("hex", HexStr(ssTx.begin(), ssTx.end()))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
480 result.push_back(Pair("complete", fComplete)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
481 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
482 return result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
483 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
484 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
485 Value sendrawtransaction(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
486 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
487 if (fHelp || params.size() < 1 || params.size() > 1) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
488 throw runtime_error( |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
489 "sendrawtransaction <hex string>\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
490 "Submits raw transaction (serialized, hex-encoded) to local node and network."); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
491 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
492 RPCTypeCheck(params, list_of(str_type)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
493 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
494 // parse hex string from parameter |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
495 vector<unsigned char> txData(ParseHex(params[0].get_str())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
496 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
497 CTransaction tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
498 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
499 // deserialize binary data stream |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
500 try { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
501 ssData >> tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
502 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
503 catch (std::exception &e) { |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
504 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
505 } |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
506 uint256 hashTx = tx.GetHash(); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
507 |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
508 // See if the transaction is already in a block |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
509 // or in the memory pool: |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
510 CTransaction existingTx; |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
511 uint256 hashBlock = 0; |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
512 if (GetTransaction(hashTx, existingTx, hashBlock)) |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
513 { |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
514 if (hashBlock != 0) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
515 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("transaction already in block ")+hashBlock.GetHex()); |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
516 // Not in block, but already in the memory pool; will drop |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
517 // through to re-relay it. |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
518 } |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
519 else |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
520 { |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
521 // push to local node |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
522 CTxDB txdb("r"); |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
523 if (!tx.AcceptToMemoryPool(txdb)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
524 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
525 |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
526 SyncWithWallets(tx, NULL, true); |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
527 } |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
528 RelayMessage(CInv(MSG_TX, hashTx), tx); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
529 |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
530 return hashTx.GetHex(); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
531 } |