aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am1
-rw-r--r--src/init.cpp2
-rw-r--r--src/main.cpp3
-rw-r--r--src/main.h3
-rw-r--r--src/qt/bitcoin.cpp1
-rw-r--r--src/qt/optionsmodel.cpp1
-rw-r--r--src/rpcblockchain.cpp24
-rw-r--r--src/rpcmisc.cpp326
-rw-r--r--src/rpcnet.cpp62
-rw-r--r--src/rpcserver.cpp8
-rw-r--r--src/rpcwallet.cpp259
-rw-r--r--src/wallet.cpp2
-rw-r--r--src/wallet.h3
13 files changed, 366 insertions, 329 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 62dd63abef..5ce1c8e1b6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,6 +53,7 @@ libbitcoin_server_a_SOURCES = \
noui.cpp \
rpcblockchain.cpp \
rpcmining.cpp \
+ rpcmisc.cpp \
rpcnet.cpp \
rpcrawtransaction.cpp \
txdb.cpp \
diff --git a/src/init.cpp b/src/init.cpp
index 22ee0cfc08..a0b9f89f23 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -535,6 +535,7 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"].c_str()));
}
+#ifdef ENABLE_WALLET
if (mapArgs.count("-paytxfee"))
{
if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
@@ -543,7 +544,6 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
}
-#ifdef ENABLE_WALLET
strWalletFile = GetArg("-wallet", "wallet.dat");
#endif
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
diff --git a/src/main.cpp b/src/main.cpp
index d130e9705e..e3f9fdd843 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -67,9 +67,6 @@ CScript COINBASE_FLAGS;
const string strMessageMagic = "Bitcoin Signed Message:\n";
-// Settings
-int64_t nTransactionFee = 0;
-
// Internal stuff
namespace {
struct CBlockIndexWorkComparator
diff --git a/src/main.h b/src/main.h
index fd5e352cb6..f3f9acb639 100644
--- a/src/main.h
+++ b/src/main.h
@@ -96,9 +96,6 @@ extern bool fTxIndex;
extern unsigned int nCoinCacheSize;
extern bool fHaveGUI;
-// Settings
-extern int64_t nTransactionFee;
-
// Minimum disk space required - used in CheckDiskSpace()
static const uint64_t nMinDiskSpace = 52428800;
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index b74452d4c6..2f04a71ec0 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -17,6 +17,7 @@
#include "main.h"
#include "ui_interface.h"
#include "util.h"
+#include "wallet.h"
#include <stdint.h>
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index 15a873d2bd..363f432d62 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -14,6 +14,7 @@
#include "init.h"
#include "main.h"
#include "net.h"
+#include "wallet.h"
#include "walletdb.h"
#include <QSettings>
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index 34ae6e0543..661deffb19 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -127,30 +127,6 @@ Value getdifficulty(const Array& params, bool fHelp)
}
-Value settxfee(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() < 1 || params.size() > 1)
- throw runtime_error(
- "settxfee amount\n"
- "\nSet the transaction fee. 'amount' is a real and is rounded to the nearest 0.00000001\n"
- "\nArguments:\n"
- "1. amount (numeric, required) The transaction fee in btc rounded to the nearest 0.00000001\n"
- "\nResult\n"
- "true|false (boolean) Returns true if successful\n"
- "\nExamples:\n"
- + HelpExampleCli("settxfee", "0.00001")
- + HelpExampleRpc("settxfee", "0.00001")
- );
-
- // Amount
- int64_t nAmount = 0;
- if (params[0].get_real() != 0.0)
- nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts
-
- nTransactionFee = nAmount;
- return true;
-}
-
Value getrawmempool(const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp
new file mode 100644
index 0000000000..c61cc4192b
--- /dev/null
+++ b/src/rpcmisc.cpp
@@ -0,0 +1,326 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "base58.h"
+#include "rpcserver.h"
+#include "init.h"
+#include "main.h"
+#include "net.h"
+#include "netbase.h"
+#include "util.h"
+#ifdef ENABLE_WALLET
+#include "wallet.h"
+#include "walletdb.h"
+#endif
+
+#include <stdint.h>
+
+#include <boost/assign/list_of.hpp>
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_value.h"
+
+using namespace std;
+using namespace boost;
+using namespace boost::assign;
+using namespace json_spirit;
+
+Value getinfo(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getinfo\n"
+ "Returns an object containing various state info.\n"
+ "\nResult:\n"
+ "{\n"
+ " \"version\": xxxxx, (numeric) the server version\n"
+ " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
+ " \"walletversion\": xxxxx, (numeric) the wallet version\n"
+ " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
+ " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
+ " \"timeoffset\": xxxxx, (numeric) the time offset\n"
+ " \"connections\": xxxxx, (numeric) the number of connections\n"
+ " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
+ " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
+ " \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
+ " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
+ " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
+ " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc\n"
+ " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
+ " \"errors\": \"...\" (string) any error messages\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getinfo", "")
+ + HelpExampleRpc("getinfo", "")
+ );
+
+ proxyType proxy;
+ GetProxy(NET_IPV4, proxy);
+
+ Object obj;
+ obj.push_back(Pair("version", (int)CLIENT_VERSION));
+ obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
+#ifdef ENABLE_WALLET
+ if (pwalletMain) {
+ obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
+ obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
+ }
+#endif
+ obj.push_back(Pair("blocks", (int)chainActive.Height()));
+ obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset()));
+ 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", (double)GetDifficulty()));
+ obj.push_back(Pair("testnet", TestNet()));
+#ifdef ENABLE_WALLET
+ if (pwalletMain) {
+ obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
+ obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
+ }
+ obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
+ if (pwalletMain && pwalletMain->IsCrypted())
+ obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
+#endif
+ obj.push_back(Pair("errors", GetWarnings("statusbar")));
+ return obj;
+}
+
+#ifdef ENABLE_WALLET
+class DescribeAddressVisitor : public boost::static_visitor<Object>
+{
+public:
+ Object operator()(const CNoDestination &dest) const { return Object(); }
+
+ Object operator()(const CKeyID &keyID) const {
+ Object obj;
+ CPubKey vchPubKey;
+ pwalletMain->GetPubKey(keyID, vchPubKey);
+ obj.push_back(Pair("isscript", false));
+ obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
+ obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
+ return obj;
+ }
+
+ Object operator()(const CScriptID &scriptID) const {
+ Object obj;
+ obj.push_back(Pair("isscript", true));
+ CScript subscript;
+ pwalletMain->GetCScript(scriptID, subscript);
+ std::vector<CTxDestination> addresses;
+ txnouttype whichType;
+ int nRequired;
+ ExtractDestinations(subscript, whichType, addresses, nRequired);
+ obj.push_back(Pair("script", GetTxnOutputType(whichType)));
+ obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
+ Array a;
+ BOOST_FOREACH(const CTxDestination& addr, addresses)
+ a.push_back(CBitcoinAddress(addr).ToString());
+ obj.push_back(Pair("addresses", a));
+ if (whichType == TX_MULTISIG)
+ obj.push_back(Pair("sigsrequired", nRequired));
+ return obj;
+ }
+};
+#endif
+
+Value validateaddress(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "validateaddress \"bitcoinaddress\"\n"
+ "\nReturn information about the given bitcoin address.\n"
+ "\nArguments:\n"
+ "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
+ "\nResult:\n"
+ "{\n"
+ " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
+ " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
+ " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
+ " \"isscript\" : true|false, (boolean) If the key is a script\n"
+ " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
+ " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
+ " \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
+ + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
+ );
+
+ CBitcoinAddress address(params[0].get_str());
+ bool isValid = address.IsValid();
+
+ Object ret;
+ ret.push_back(Pair("isvalid", isValid));
+ if (isValid)
+ {
+ CTxDestination dest = address.Get();
+ string currentAddress = address.ToString();
+ ret.push_back(Pair("address", currentAddress));
+#ifdef ENABLE_WALLET
+ bool fMine = pwalletMain ? IsMine(*pwalletMain, dest) : false;
+ ret.push_back(Pair("ismine", fMine));
+ if (fMine) {
+ Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
+ ret.insert(ret.end(), detail.begin(), detail.end());
+ }
+ if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
+ ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
+#endif
+ }
+ return ret;
+}
+
+//
+// Used by addmultisigaddress / createmultisig:
+//
+CScript _createmultisig(const Array& params)
+{
+ int nRequired = params[0].get_int();
+ const Array& keys = params[1].get_array();
+
+ // Gather public keys
+ if (nRequired < 1)
+ throw runtime_error("a multisignature address must require at least one key to redeem");
+ if ((int)keys.size() < nRequired)
+ throw runtime_error(
+ strprintf("not enough keys supplied "
+ "(got %"PRIszu" keys, but need at least %d to redeem)", keys.size(), nRequired));
+ std::vector<CPubKey> pubkeys;
+ pubkeys.resize(keys.size());
+ for (unsigned int i = 0; i < keys.size(); i++)
+ {
+ const std::string& ks = keys[i].get_str();
+#ifdef ENABLE_WALLET
+ // Case 1: Bitcoin address and we have full public key:
+ CBitcoinAddress address(ks);
+ if (pwalletMain && address.IsValid())
+ {
+ CKeyID keyID;
+ if (!address.GetKeyID(keyID))
+ throw runtime_error(
+ strprintf("%s does not refer to a key",ks.c_str()));
+ CPubKey vchPubKey;
+ if (!pwalletMain->GetPubKey(keyID, vchPubKey))
+ throw runtime_error(
+ strprintf("no full public key for address %s",ks.c_str()));
+ if (!vchPubKey.IsFullyValid())
+ throw runtime_error(" Invalid public key: "+ks);
+ pubkeys[i] = vchPubKey;
+ }
+
+ // Case 2: hex public key
+ else
+#endif
+ if (IsHex(ks))
+ {
+ CPubKey vchPubKey(ParseHex(ks));
+ if (!vchPubKey.IsFullyValid())
+ throw runtime_error(" Invalid public key: "+ks);
+ pubkeys[i] = vchPubKey;
+ }
+ else
+ {
+ throw runtime_error(" Invalid public key: "+ks);
+ }
+ }
+ CScript result;
+ result.SetMultisig(nRequired, pubkeys);
+ return result;
+}
+
+Value createmultisig(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 2 || params.size() > 2)
+ {
+ string msg = "createmultisig nrequired [\"key\",...]\n"
+ "\nCreates a multi-signature address with n signature of m keys required.\n"
+ "It returns a json object with the address and redeemScript.\n"
+
+ "\nArguments:\n"
+ "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
+ "2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n"
+ " [\n"
+ " \"key\" (string) bitcoin address or hex-encoded public key\n"
+ " ,...\n"
+ " ]\n"
+
+ "\nResult:\n"
+ "{\n"
+ " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
+ " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
+ "}\n"
+
+ "\nExamples:\n"
+ "\nCreate a multisig address from 2 addresses\n"
+ + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("icreatemultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
+ ;
+ throw runtime_error(msg);
+ }
+
+ // Construct using pay-to-script-hash:
+ CScript inner = _createmultisig(params);
+ CScriptID innerID = inner.GetID();
+ CBitcoinAddress address(innerID);
+
+ Object result;
+ result.push_back(Pair("address", address.ToString()));
+ result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
+
+ return result;
+}
+
+Value verifymessage(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 3)
+ throw runtime_error(
+ "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
+ "\nVerify a signed message\n"
+ "\nArguments:\n"
+ "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n"
+ "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
+ "3. \"message\" (string, required) The message that was signed.\n"
+ "\nResult:\n"
+ "true|false (boolean) If the signature is verified or not.\n"
+ "\nExamples:\n"
+ "\nUnlock the wallet for 30 seconds\n"
+ + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
+ "\nCreate the signature\n"
+ + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
+ "\nVerify the signature\n"
+ + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
+ "\nAs json rpc\n"
+ + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
+ );
+
+ string strAddress = params[0].get_str();
+ string strSign = params[1].get_str();
+ string strMessage = params[2].get_str();
+
+ CBitcoinAddress addr(strAddress);
+ if (!addr.IsValid())
+ throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
+
+ CKeyID keyID;
+ if (!addr.GetKeyID(keyID))
+ throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
+
+ bool fInvalid = false;
+ vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
+
+ if (fInvalid)
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
+
+ CHashWriter ss(SER_GETHASH, 0);
+ ss << strMessageMagic;
+ ss << strMessage;
+
+ CPubKey pubkey;
+ if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
+ return false;
+
+ return (pubkey.GetID() == keyID);
+}
+
diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp
index fd72fe6386..06ae7070c3 100644
--- a/src/rpcnet.cpp
+++ b/src/rpcnet.cpp
@@ -338,65 +338,3 @@ Value getnettotals(const Array& params, bool fHelp)
obj.push_back(Pair("timemillis", static_cast<boost::int64_t>(GetTimeMillis())));
return obj;
}
-
-Value getinfo(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "getinfo\n"
- "Returns an object containing various state info.\n"
- "\nResult:\n"
- "{\n"
- " \"version\": xxxxx, (numeric) the server version\n"
- " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
- " \"walletversion\": xxxxx, (numeric) the wallet version\n"
- " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
- " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
- " \"timeoffset\": xxxxx, (numeric) the time offset\n"
- " \"connections\": xxxxx, (numeric) the number of connections\n"
- " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
- " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
- " \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
- " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
- " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
- " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc\n"
- " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
- " \"errors\": \"...\" (string) any error messages\n"
- "}\n"
- "\nExamples:\n"
- + HelpExampleCli("getinfo", "")
- + HelpExampleRpc("getinfo", "")
- );
-
- proxyType proxy;
- GetProxy(NET_IPV4, proxy);
-
- Object obj;
- obj.push_back(Pair("version", (int)CLIENT_VERSION));
- obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
-#ifdef ENABLE_WALLET
- if (pwalletMain) {
- obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
- obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
- }
-#endif
- obj.push_back(Pair("blocks", (int)chainActive.Height()));
- obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset()));
- 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", (double)GetDifficulty()));
- obj.push_back(Pair("testnet", TestNet()));
-#ifdef ENABLE_WALLET
- if (pwalletMain) {
- obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
- obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
- }
-#endif
- obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
-#ifdef ENABLE_WALLET
- if (pwalletMain && pwalletMain->IsCrypted())
- obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
-#endif
- obj.push_back(Pair("errors", GetWarnings("statusbar")));
- return obj;
-}
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index c95f450c82..d1fa81628c 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -237,7 +237,6 @@ static const CRPCCommand vRPCCommands[] =
{ "getrawmempool", &getrawmempool, true, false, false },
{ "getblock", &getblock, false, false, false },
{ "getblockhash", &getblockhash, false, false, false },
- { "settxfee", &settxfee, false, false, true },
{ "getrawtransaction", &getrawtransaction, false, false, false },
{ "createrawtransaction", &createrawtransaction, false, false, false },
{ "decoderawtransaction", &decoderawtransaction, false, false, false },
@@ -253,6 +252,9 @@ static const CRPCCommand vRPCCommands[] =
{ "getmininginfo", &getmininginfo, true, false, false },
{ "getblocktemplate", &getblocktemplate, true, false, false },
{ "submitblock", &submitblock, false, false, false },
+ { "validateaddress", &validateaddress, true, false, false },
+ { "createmultisig", &createmultisig, true, true , false },
+ { "verifymessage", &verifymessage, false, false, false },
#ifdef ENABLE_WALLET
/* Wallet */
@@ -273,18 +275,15 @@ static const CRPCCommand vRPCCommands[] =
{ "walletpassphrasechange", &walletpassphrasechange, false, false, true },
{ "walletlock", &walletlock, true, false, true },
{ "encryptwallet", &encryptwallet, false, false, true },
- { "validateaddress", &validateaddress, true, false, false },
{ "getbalance", &getbalance, false, false, true },
{ "move", &movecmd, false, false, true },
{ "sendfrom", &sendfrom, false, false, true },
{ "sendmany", &sendmany, false, false, true },
{ "addmultisigaddress", &addmultisigaddress, false, false, true },
- { "createmultisig", &createmultisig, true, true , false },
{ "gettransaction", &gettransaction, false, false, true },
{ "listtransactions", &listtransactions, false, false, true },
{ "listaddressgroupings", &listaddressgroupings, false, false, true },
{ "signmessage", &signmessage, false, false, true },
- { "verifymessage", &verifymessage, false, false, false },
{ "listaccounts", &listaccounts, false, false, true },
{ "listsinceblock", &listsinceblock, false, false, true },
{ "dumpprivkey", &dumpprivkey, true, false, true },
@@ -294,6 +293,7 @@ static const CRPCCommand vRPCCommands[] =
{ "listunspent", &listunspent, false, false, true },
{ "lockunspent", &lockunspent, false, false, true },
{ "listlockunspent", &listlockunspent, false, false, true },
+ { "settxfee", &settxfee, false, false, true },
/* Wallet-enabled mining */
{ "getgenerate", &getgenerate, true, false, false },
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 82fa9d88c5..32db0b46aa 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -441,59 +441,6 @@ Value signmessage(const Array& params, bool fHelp)
return EncodeBase64(&vchSig[0], vchSig.size());
}
-Value verifymessage(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 3)
- throw runtime_error(
- "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
- "\nVerify a signed message\n"
- "\nArguments:\n"
- "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n"
- "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
- "3. \"message\" (string, required) The message that was signed.\n"
- "\nResult:\n"
- "true|false (boolean) If the signature is verified or not.\n"
- "\nExamples:\n"
- "\nUnlock the wallet for 30 seconds\n"
- + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
- "\nCreate the signature\n"
- + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
- "\nVerify the signature\n"
- + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
- "\nAs json rpc\n"
- + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
- );
-
- string strAddress = params[0].get_str();
- string strSign = params[1].get_str();
- string strMessage = params[2].get_str();
-
- CBitcoinAddress addr(strAddress);
- if (!addr.IsValid())
- throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
-
- CKeyID keyID;
- if (!addr.GetKeyID(keyID))
- throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
-
- bool fInvalid = false;
- vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
-
- if (fInvalid)
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
-
- CHashWriter ss(SER_GETHASH, 0);
- ss << strMessageMagic;
- ss << strMessage;
-
- CPubKey pubkey;
- if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
- return false;
-
- return (pubkey.GetID() == keyID);
-}
-
-
Value getreceivedbyaddress(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
@@ -907,61 +854,8 @@ Value sendmany(const Array& params, bool fHelp)
return wtx.GetHash().GetHex();
}
-//
-// Used by addmultisigaddress / createmultisig:
-//
-static CScript _createmultisig(const Array& params)
-{
- int nRequired = params[0].get_int();
- const Array& keys = params[1].get_array();
-
- // Gather public keys
- if (nRequired < 1)
- throw runtime_error("a multisignature address must require at least one key to redeem");
- if ((int)keys.size() < nRequired)
- throw runtime_error(
- strprintf("not enough keys supplied "
- "(got %"PRIszu" keys, but need at least %d to redeem)", keys.size(), nRequired));
- std::vector<CPubKey> pubkeys;
- pubkeys.resize(keys.size());
- for (unsigned int i = 0; i < keys.size(); i++)
- {
- const std::string& ks = keys[i].get_str();
-
- // Case 1: Bitcoin address and we have full public key:
- CBitcoinAddress address(ks);
- if (pwalletMain && address.IsValid())
- {
- CKeyID keyID;
- if (!address.GetKeyID(keyID))
- throw runtime_error(
- strprintf("%s does not refer to a key",ks.c_str()));
- CPubKey vchPubKey;
- if (!pwalletMain->GetPubKey(keyID, vchPubKey))
- throw runtime_error(
- strprintf("no full public key for address %s",ks.c_str()));
- if (!vchPubKey.IsFullyValid())
- throw runtime_error(" Invalid public key: "+ks);
- pubkeys[i] = vchPubKey;
- }
-
- // Case 2: hex public key
- else if (IsHex(ks))
- {
- CPubKey vchPubKey(ParseHex(ks));
- if (!vchPubKey.IsFullyValid())
- throw runtime_error(" Invalid public key: "+ks);
- pubkeys[i] = vchPubKey;
- }
- else
- {
- throw runtime_error(" Invalid public key: "+ks);
- }
- }
- CScript result;
- result.SetMultisig(nRequired, pubkeys);
- return result;
-}
+// Defined in rpcmisc.cpp
+extern CScript _createmultisig(const Array& params);
Value addmultisigaddress(const Array& params, bool fHelp)
{
@@ -1006,49 +900,6 @@ Value addmultisigaddress(const Array& params, bool fHelp)
return CBitcoinAddress(innerID).ToString();
}
-Value createmultisig(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() < 2 || params.size() > 2)
- {
- string msg = "createmultisig nrequired [\"key\",...]\n"
- "\nCreates a multi-signature address with n signature of m keys required.\n"
- "It returns a json object with the address and redeemScript.\n"
-
- "\nArguments:\n"
- "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
- "2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n"
- " [\n"
- " \"key\" (string) bitcoin address or hex-encoded public key\n"
- " ,...\n"
- " ]\n"
-
- "\nResult:\n"
- "{\n"
- " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
- " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
- "}\n"
-
- "\nExamples:\n"
- "\nCreate a multisig address from 2 addresses\n"
- + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
- "\nAs a json rpc call\n"
- + HelpExampleRpc("icreatemultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
- ;
- throw runtime_error(msg);
- }
-
- // Construct using pay-to-script-hash:
- CScript inner = _createmultisig(params);
- CScriptID innerID = inner.GetID();
- CBitcoinAddress address(innerID);
-
- Object result;
- result.push_back(Pair("address", address.ToString()));
- result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
-
- return result;
-}
-
struct tallyitem
{
@@ -1862,87 +1713,6 @@ Value encryptwallet(const Array& params, bool fHelp)
return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.";
}
-class DescribeAddressVisitor : public boost::static_visitor<Object>
-{
-public:
- Object operator()(const CNoDestination &dest) const { return Object(); }
-
- Object operator()(const CKeyID &keyID) const {
- Object obj;
- CPubKey vchPubKey;
- pwalletMain->GetPubKey(keyID, vchPubKey);
- obj.push_back(Pair("isscript", false));
- obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
- obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
- return obj;
- }
-
- Object operator()(const CScriptID &scriptID) const {
- Object obj;
- obj.push_back(Pair("isscript", true));
- CScript subscript;
- pwalletMain->GetCScript(scriptID, subscript);
- std::vector<CTxDestination> addresses;
- txnouttype whichType;
- int nRequired;
- ExtractDestinations(subscript, whichType, addresses, nRequired);
- obj.push_back(Pair("script", GetTxnOutputType(whichType)));
- obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
- Array a;
- BOOST_FOREACH(const CTxDestination& addr, addresses)
- a.push_back(CBitcoinAddress(addr).ToString());
- obj.push_back(Pair("addresses", a));
- if (whichType == TX_MULTISIG)
- obj.push_back(Pair("sigsrequired", nRequired));
- return obj;
- }
-};
-
-Value validateaddress(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 1)
- throw runtime_error(
- "validateaddress \"bitcoinaddress\"\n"
- "\nReturn information about the given bitcoin address.\n"
- "\nArguments:\n"
- "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
- "\nResult:\n"
- "{\n"
- " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
- " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
- " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
- " \"isscript\" : true|false, (boolean) If the key is a script\n"
- " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
- " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
- " \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n"
- "}\n"
- "\nExamples:\n"
- + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
- + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
- );
-
- CBitcoinAddress address(params[0].get_str());
- bool isValid = address.IsValid();
-
- Object ret;
- ret.push_back(Pair("isvalid", isValid));
- if (isValid)
- {
- CTxDestination dest = address.Get();
- string currentAddress = address.ToString();
- ret.push_back(Pair("address", currentAddress));
- bool fMine = pwalletMain ? IsMine(*pwalletMain, dest) : false;
- ret.push_back(Pair("ismine", fMine));
- if (fMine) {
- Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
- ret.insert(ret.end(), detail.begin(), detail.end());
- }
- if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
- ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
- }
- return ret;
-}
-
Value lockunspent(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
@@ -2066,3 +1836,28 @@ Value listlockunspent(const Array& params, bool fHelp)
return ret;
}
+Value settxfee(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 1)
+ throw runtime_error(
+ "settxfee amount\n"
+ "\nSet the transaction fee. 'amount' is a real and is rounded to the nearest 0.00000001\n"
+ "\nArguments:\n"
+ "1. amount (numeric, required) The transaction fee in btc rounded to the nearest 0.00000001\n"
+ "\nResult\n"
+ "true|false (boolean) Returns true if successful\n"
+ "\nExamples:\n"
+ + HelpExampleCli("settxfee", "0.00001")
+ + HelpExampleRpc("settxfee", "0.00001")
+ );
+
+ // Amount
+ int64_t nAmount = 0;
+ if (params[0].get_real() != 0.0)
+ nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts
+
+ nTransactionFee = nAmount;
+ return true;
+}
+
+
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 3c3d890e2e..76a83082ae 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -16,6 +16,8 @@
using namespace std;
+// Settings
+int64_t nTransactionFee = 0;
//////////////////////////////////////////////////////////////////////////////
//
diff --git a/src/wallet.h b/src/wallet.h
index 8e879c5e1a..99f6293b1e 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -23,6 +23,9 @@
#include <utility>
#include <vector>
+// Settings
+extern int64_t nTransactionFee;
+
class CAccountingEntry;
class CCoinControl;
class COutput;