Implement raw transaction RPC calls

Implement listunspent / getrawtransaction / createrawtransaction /
signrawtransaction, to support creation and
signing-on-multiple-device multisignature transactions.
This commit is contained in:
Gavin Andresen
2012-05-31 16:01:16 -04:00
parent 899d373b3c
commit a2709fad7f
12 changed files with 750 additions and 56 deletions

View File

@@ -46,10 +46,16 @@ static std::string strRPCUserColonPass;
static int64 nWalletUnlockTime;
static CCriticalSection cs_nWalletUnlockTime;
extern Value getconnectioncount(const Array& params, bool fHelp);
extern Value getconnectioncount(const Array& params, bool fHelp); // in rpcnet.cpp
extern Value getpeerinfo(const Array& params, bool fHelp);
extern Value dumpprivkey(const Array& params, bool fHelp);
extern Value dumpprivkey(const Array& params, bool fHelp); // in rpcdump.cpp
extern Value importprivkey(const Array& params, bool fHelp);
extern Value getrawtransaction(const Array& params, bool fHelp); // in rcprawtransaction.cpp
extern Value listunspent(const Array& params, bool fHelp);
extern Value createrawtransaction(const Array& params, bool fHelp);
extern Value decoderawtransaction(const Array& params, bool fHelp);
extern Value signrawtransaction(const Array& params, bool fHelp);
extern Value sendrawtransaction(const Array& params, bool fHelp);
const Object emptyobj;
@@ -159,7 +165,7 @@ HexBits(unsigned int nBits)
return HexStr(BEGIN(uBits.cBits), END(uBits.cBits));
}
static std::string
std::string
HelpRequiringPassphrase()
{
return pwalletMain->IsCrypted()
@@ -167,7 +173,7 @@ HelpRequiringPassphrase()
: "";
}
static inline void
void
EnsureWalletIsUnlocked()
{
if (pwalletMain->IsLocked())
@@ -2048,44 +2054,6 @@ Value getblock(const Array& params, bool fHelp)
return blockToJSON(block, pblockindex);
}
Value sendrawtx(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 1)
throw runtime_error(
"sendrawtx <hex string>\n"
"Submits raw transaction (serialized, hex-encoded) to local node and network.");
// parse hex string from parameter
vector<unsigned char> txData(ParseHex(params[0].get_str()));
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
CTransaction tx;
// deserialize binary data stream
try {
ssData >> tx;
}
catch (std::exception &e) {
throw JSONRPCError(-22, "TX decode failed");
}
// push to local node
CTxDB txdb("r");
if (!tx.AcceptToMemoryPool(txdb))
throw JSONRPCError(-22, "TX rejected");
SyncWithWallets(tx, NULL, true);
// relay to network
CInv inv(MSG_TX, tx.GetHash());
RelayInventory(inv);
return tx.GetHash().GetHex();
}
@@ -2147,7 +2115,12 @@ static const CRPCCommand vRPCCommands[] =
{ "listsinceblock", &listsinceblock, false },
{ "dumpprivkey", &dumpprivkey, false },
{ "importprivkey", &importprivkey, false },
{ "sendrawtx", &sendrawtx, false },
{ "listunspent", &listunspent, false },
{ "getrawtransaction", &getrawtransaction, false },
{ "createrawtransaction", &createrawtransaction, false },
{ "decoderawtransaction", &decoderawtransaction, false },
{ "signrawtransaction", &signrawtransaction, false },
{ "sendrawtransaction", &sendrawtransaction, false },
};
CRPCTable::CRPCTable()
@@ -3021,6 +2994,13 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "sendmany" && n > 2) ConvertTo<boost::int64_t>(params[2]);
if (strMethod == "addmultisigaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "addmultisigaddress" && n > 1) ConvertTo<Array>(params[1]);
if (strMethod == "listunspent" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "listunspent" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1]);
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2]);
return params;
}