#include "walletdb.h"
#include "bitcoinrpc.h"
#include "init.h"
+#include "util.h"
+#include "ntp.h"
#include "base58.h"
using namespace json_spirit;
static CCriticalSection cs_nWalletUnlockTime;
extern int64_t nReserveBalance;
-extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry);
+extern void TxToJSON(const CTransaction& tx, const uint256& hashBlock, json_spirit::Object& entry);
std::string HelpRequiringPassphrase()
{
{
entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
entry.push_back(Pair("blockindex", wtx.nIndex));
- entry.push_back(Pair("blocktime", (boost::int64_t)(mapBlockIndex[wtx.hashBlock]->nTime)));
+ entry.push_back(Pair("blocktime", (int64_t)(mapBlockIndex[wtx.hashBlock]->nTime)));
}
entry.push_back(Pair("txid", wtx.GetHash().GetHex()));
- entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime()));
- entry.push_back(Pair("timereceived", (boost::int64_t)wtx.nTimeReceived));
+ entry.push_back(Pair("time", (int64_t)wtx.GetTxTime()));
+ entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
entry.push_back(Pair(item.first, item.second));
}
proxyType proxy;
GetProxy(NET_IPV4, proxy);
- Object obj, diff;
+ Object obj, diff, timestamping;
obj.push_back(Pair("version", FormatFullVersion()));
obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
obj.push_back(Pair("newmint", ValueFromAmount(pwalletMain->GetNewMint())));
obj.push_back(Pair("stake", ValueFromAmount(pwalletMain->GetStake())));
obj.push_back(Pair("blocks", (int)nBestHeight));
- obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset()));
+
+ timestamping.push_back(Pair("systemclock", GetTime()));
+ timestamping.push_back(Pair("adjustedtime", GetAdjustedTime()));
+
+ int64_t nNtpOffset = GetNtpOffset(),
+ nP2POffset = GetNodesOffset();
+
+ timestamping.push_back(Pair("ntpoffset", nNtpOffset != INT64_MAX ? nNtpOffset : Value::null));
+ timestamping.push_back(Pair("p2poffset", nP2POffset != INT64_MAX ? nP2POffset : Value::null));
+
+ obj.push_back(Pair("timestamping", timestamping));
+
obj.push_back(Pair("moneysupply", ValueFromAmount(pindexBest->nMoneySupply)));
obj.push_back(Pair("connections", (int)vNodes.size()));
obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string())));
obj.push_back(Pair("difficulty", diff));
obj.push_back(Pair("testnet", fTestNet));
- obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
+ obj.push_back(Pair("keypoololdest", (int64_t)pwalletMain->GetOldestKeyPoolTime()));
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
obj.push_back(Pair("mininput", ValueFromAmount(nMinimumInputValue)));
if (pwalletMain->IsCrypted())
- obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000));
+ obj.push_back(Pair("unlocked_until", (int64_t)nWalletUnlockTime / 1000));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
return obj;
}
"<amount> is resulting inputs sum\n"
"<minvalue> is minimum value of inputs which are used in join process\n"
"<outputvalue> is resulting value of inputs which will be created\n"
- "All values are real and and rounded to the nearest " + FormatMoney(MIN_TXOUT_AMOUNT)
+ "All values are real and and rounded to the nearest " + FormatMoney(nMinimumInputValue)
+ HelpRequiringPassphrase());
if (pwalletMain->IsLocked())
// Output amount
int64_t nOutputValue = AmountFromValue(params[2]);
- if (nAmount < MIN_TXOUT_AMOUNT)
+ if (nAmount < nMinimumInputValue)
throw JSONRPCError(-101, "Send amount too small");
- if (nMinValue < MIN_TXOUT_AMOUNT)
+ if (nMinValue < nMinimumInputValue)
throw JSONRPCError(-101, "Max value too small");
- if (nOutputValue < MIN_TXOUT_AMOUNT)
+ if (nOutputValue < nMinimumInputValue)
throw JSONRPCError(-101, "Output value too small");
if (nOutputValue < nMinValue)
if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error(
"sendtoaddress <novacoinaddress> <amount> [comment] [comment-to]\n"
- "<amount> is a real and is rounded to the nearest " + FormatMoney(MIN_TXOUT_AMOUNT)
+ "<amount> is a real and is rounded to the nearest " + FormatMoney(nMinimumInputValue)
+ HelpRequiringPassphrase());
- CBitcoinAddress address(params[0].get_str());
- if (!address.IsValid())
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
+ // Parse address
+ CScript scriptPubKey;
+ string strAddress = params[0].get_str();
+
+ CBitcoinAddress address(strAddress);
+ if (address.IsValid())
+ scriptPubKey.SetDestination(address.Get());
+ else
+ {
+ CMalleablePubKey mpk(strAddress);
+ if (!mpk.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
+
+ CPubKey R, pubKeyVariant;
+ mpk.GetVariant(R, pubKeyVariant);
+ scriptPubKey.SetDestination(R, pubKeyVariant);
+ }
// Amount
int64_t nAmount = AmountFromValue(params[1]);
- if (nAmount < MIN_TXOUT_AMOUNT)
+ if (nAmount < nMinimumInputValue)
throw JSONRPCError(-101, "Send amount too small");
// Wallet comments
if (pwalletMain->IsLocked())
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
- string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
+ string strError = pwalletMain->SendMoney(scriptPubKey, nAmount, wtx);
if (strError != "")
throw JSONRPCError(RPC_WALLET_ERROR, strError);
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
scriptPubKey.SetDestination(address.Get());
if (!IsMine(*pwalletMain,scriptPubKey))
- return (double)0.0;
+ return 0.0;
// Minimum confirmations
int nMinDepth = 1;
string strTo = AccountFromValue(params[1]);
int64_t nAmount = AmountFromValue(params[2]);
- if (nAmount < MIN_TXOUT_AMOUNT)
+ if (nAmount < nMinimumInputValue)
throw JSONRPCError(-101, "Send amount too small");
if (params.size() > 3)
if (fHelp || params.size() < 3 || params.size() > 6)
throw runtime_error(
"sendfrom <fromaccount> <tonovacoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
- "<amount> is a real and is rounded to the nearest " + FormatMoney(MIN_TXOUT_AMOUNT)
+ "<amount> is a real and is rounded to the nearest " + FormatMoney(nMinimumInputValue)
+ HelpRequiringPassphrase());
string strAccount = AccountFromValue(params[0]);
- CBitcoinAddress address(params[1].get_str());
- if (!address.IsValid())
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
+
+ // Parse address
+ CScript scriptPubKey;
+ string strAddress = params[0].get_str();
+
+ CBitcoinAddress address(strAddress);
+ if (address.IsValid())
+ scriptPubKey.SetDestination(address.Get());
+ else
+ {
+ CMalleablePubKey mpk(strAddress);
+ if (!mpk.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
+
+ CPubKey R, pubKeyVariant;
+ mpk.GetVariant(R, pubKeyVariant);
+ scriptPubKey.SetDestination(R, pubKeyVariant);
+ }
+
int64_t nAmount = AmountFromValue(params[2]);
- if (nAmount < MIN_TXOUT_AMOUNT)
+ if (nAmount < nMinimumInputValue)
throw JSONRPCError(-101, "Send amount too small");
int nMinDepth = 1;
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
// Send
- string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
+ string strError = pwalletMain->SendMoney(scriptPubKey, nAmount, wtx);
if (strError != "")
throw JSONRPCError(RPC_WALLET_ERROR, strError);
{
if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error(
- "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
+ "sendmany <fromaccount> '{address:amount,...}' [minconf=1] [comment]\n"
"amounts are double-precision floating point numbers"
+ HelpRequiringPassphrase());
scriptPubKey.SetDestination(address.Get());
int64_t nAmount = AmountFromValue(s.value_);
- if (nAmount < MIN_TXOUT_AMOUNT)
+ if (nAmount < nMinimumInputValue)
throw JSONRPCError(-101, "Send amount too small");
totalAmount += nAmount;
Object entry;
entry.push_back(Pair("account", acentry.strAccount));
entry.push_back(Pair("category", "move"));
- entry.push_back(Pair("time", (boost::int64_t)acentry.nTime));
+ entry.push_back(Pair("time", (int64_t)acentry.nTime));
entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
entry.push_back(Pair("comment", acentry.strComment));
"should be replaced with the newly generated one."
+ HelpRequiringPassphrase());
- unsigned int nSize = max<unsigned int>(GetArg("-keypool", 100), 0);
+ unsigned int nSize = max<unsigned int>(GetArgUInt("-keypool", 100), 0);
if (params.size() > 0) {
if (params[0].get_int() < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size");
"should be replaced with the newly generated one."
+ HelpRequiringPassphrase());
- unsigned int nSize = max<unsigned int>(GetArg("-keypool", 100), 0);
+ unsigned int nSize = max<unsigned int>(GetArgUInt("-keypool", 100), 0);
if (params.size() > 0) {
if (params[0].get_int() < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size");
nAmount = (nAmount / CENT) * CENT; // round to cent
if (nAmount < 0)
throw runtime_error("amount cannot be negative.\n");
- mapArgs["-reservebalance"] = FormatMoney(nAmount).c_str();
+ mapArgs["-reservebalance"] = FormatMoney(nAmount);
}
else
{
return Value::null;
}
-// ppcoin: make a public-private key pair
+// Make a public-private key pair
Value makekeypair(const Array& params, bool fHelp)
{
- if (fHelp || params.size() > 1)
+ if (fHelp || params.size() > 0)
throw runtime_error(
- "makekeypair [prefix]\n"
- "Make a public/private key pair.\n"
- "[prefix] is optional preferred prefix for the public key.\n");
+ "makekeypair\n"
+ "Make a public/private key pair.\n");
string strPrefix = "";
if (params.size() > 0)
strPrefix = params[0].get_str();
-
+
CKey key;
- key.MakeNewKey(false);
+ key.MakeNewKey(true);
CPrivKey vchPrivKey = key.GetPrivKey();
Object result;
result.push_back(Pair("PrivateKey", HexStr<CPrivKey::iterator>(vchPrivKey.begin(), vchPrivKey.end())));
+
+ bool fCompressed;
+ CSecret vchSecret = key.GetSecret(fCompressed);
+ result.push_back(Pair("Secret", HexStr<CSecret::iterator>(vchSecret.begin(), vchSecret.end())));
result.push_back(Pair("PublicKey", HexStr(key.GetPubKey().Raw())));
return result;
}
+
+Value newmalleablekey(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 0)
+ throw runtime_error(
+ "newmalleablekey\n"
+ "Make a malleable public/private key pair.\n");
+
+ if (!fTestNet && GetTime() < SMALLDATA_SWITCH_TIME)
+ throw runtime_error("This feature has been disabled for mainNet clients");
+
+ CMalleableKeyView keyView = pwalletMain->GenerateNewMalleableKey();
+
+ CMalleableKey mKey;
+ if (!pwalletMain->GetMalleableKey(keyView, mKey))
+ throw runtime_error("Unable to generate new malleable key");
+
+ Object result;
+ result.push_back(Pair("PublicPair", mKey.GetMalleablePubKey().ToString()));
+ result.push_back(Pair("KeyView", keyView.ToString()));
+
+ return result;
+}
+
+Value validatemalleablepubkey(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "validatemalleablekey <Malleable public key data>\n"
+ "Check the validity and ownership for priovided malleable public key.\n");
+
+ CMalleablePubKey mpk;
+ bool isValid = mpk.SetString(params[0].get_str());
+
+ Object result;
+ result.push_back(Pair("isvalid", isValid));
+
+ if (isValid)
+ {
+ CMalleableKeyView view;
+ bool isMine = pwalletMain->GetMalleableView(mpk, view);
+ result.push_back(Pair("ismine", isMine));
+
+ if (isMine)
+ result.push_back(Pair("KeyView", view.ToString()));
+ }
+
+ return result;
+}
+
+Value adjustmalleablekey(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 3)
+ throw runtime_error(
+ "adjustmalleablekey <Malleable key data> <Public key variant data> <R data>\n"
+ "Calculate new private key using provided malleable key, public key and R data.\n");
+
+ CMalleableKey malleableKey;
+ malleableKey.SetString(params[0].get_str());
+
+ CKey privKeyVariant;
+ CPubKey vchPubKeyVariant = CPubKey(ParseHex(params[1].get_str()));
+
+ CPubKey R(ParseHex(params[2].get_str()));
+
+ if (!malleableKey.CheckKeyVariant(R,vchPubKeyVariant, privKeyVariant)) {
+ throw runtime_error("Unable to calculate the private key");
+ }
+
+ Object result;
+ bool fCompressed;
+ CSecret vchPrivKeyVariant = privKeyVariant.GetSecret(fCompressed);
+
+ result.push_back(Pair("PrivateKey", CBitcoinSecret(vchPrivKeyVariant, fCompressed).ToString()));
+
+ return result;
+}
+
+Value adjustmalleablepubkey(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 2 || params.size() == 0)
+ throw runtime_error(
+ "adjustmalleablepubkey <Malleable public key data>\n"
+ "Calculate new public key using provided malleable public key data.\n");
+
+ string pubKeyPair = params[0].get_str();
+ CMalleablePubKey malleablePubKey;
+
+ if (pubKeyPair.size() == 138) {
+ CDataStream ssPublicBytes(ParseHex(pubKeyPair), SER_NETWORK, PROTOCOL_VERSION);
+ ssPublicBytes >> malleablePubKey;
+ } else
+ malleablePubKey.SetString(pubKeyPair);
+
+ CPubKey R, vchPubKeyVariant;
+ malleablePubKey.GetVariant(R, vchPubKeyVariant);
+
+ Object result;
+ result.push_back(Pair("R", HexStr(R.Raw())));
+ result.push_back(Pair("PubkeyVariant", HexStr(vchPubKeyVariant.Raw())));
+ result.push_back(Pair("KeyVariantID", CBitcoinAddress(vchPubKeyVariant.GetID()).ToString()));
+
+ return result;
+}
+
+Value listmalleableviews(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "listmalleableviews\n"
+ "Get list of views for generated malleable keys.\n");
+
+ std::list<CMalleableKeyView> keyViewList;
+ pwalletMain->ListMalleableViews(keyViewList);
+
+ Array result;
+ BOOST_FOREACH(const CMalleableKeyView &keyView, keyViewList)
+ {
+ result.push_back(keyView.ToString());
+ }
+
+ return result;
+}
+