Merge pull request #3412
c3a7f51
Move `verifymessage` from rpcwallet to rpcmisc (Wladimir J. van der Laan)723a03d
Move `createmultisig` from rpcwallet to rpcmisc (Wladimir J. van der Laan)452955f
Move `validateaddress` from rpcwallet to rpcmisc (Wladimir J. van der Laan)cd7fa8b
Move `nTransactionFee` from main.cpp to wallet.cpp (Wladimir J. van der Laan)a943bde
Move `settxfee` from rpcblockchain to rpcwallet (Wladimir J. van der Laan)16bc9aa
Move `getinfo` from rpcnet to rpcmisc (Wladimir J. van der Laan)652e156
add new RPC implementation file `rpcmisc.cpp` (Wladimir J. van der Laan)
This commit is contained in:
commit
285cf7a1a6
13 changed files with 366 additions and 329 deletions
|
@ -53,6 +53,7 @@ libbitcoin_server_a_SOURCES = \
|
|||
noui.cpp \
|
||||
rpcblockchain.cpp \
|
||||
rpcmining.cpp \
|
||||
rpcmisc.cpp \
|
||||
rpcnet.cpp \
|
||||
rpcrawtransaction.cpp \
|
||||
txdb.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
|
||||
|
|
|
@ -67,9 +67,6 @@ CScript COINBASE_FLAGS;
|
|||
|
||||
const string strMessageMagic = "Bitcoin Signed Message:\n";
|
||||
|
||||
// Settings
|
||||
int64_t nTransactionFee = 0;
|
||||
|
||||
// Internal stuff
|
||||
namespace {
|
||||
struct CBlockIndexWorkComparator
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "main.h"
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
#include "wallet.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "init.h"
|
||||
#include "main.h"
|
||||
#include "net.h"
|
||||
#include "wallet.h"
|
||||
#include "walletdb.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
|
|
@ -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)
|
||||
|
|
326
src/rpcmisc.cpp
Normal file
326
src/rpcmisc.cpp
Normal file
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
// Settings
|
||||
int64_t nTransactionFee = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// Settings
|
||||
extern int64_t nTransactionFee;
|
||||
|
||||
class CAccountingEntry;
|
||||
class CCoinControl;
|
||||
class COutput;
|
||||
|
|
Loading…
Reference in a new issue