9 #include <validation.h> 24 #include <boost/algorithm/string.hpp> 25 #include <boost/date_time/posix_time/posix_time.hpp> 30 std::string
static EncodeDumpTime(int64_t nTime) {
34 int64_t
static DecodeDumpTime(
const std::string &str) {
35 static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0);
36 static const std::locale loc(std::locale::classic(),
37 new boost::posix_time::time_input_facet(
"%Y-%m-%dT%H:%M:%SZ"));
38 std::istringstream iss(str);
40 boost::posix_time::ptime ptime(boost::date_time::not_a_date_time);
42 if (ptime.is_not_a_date_time())
44 return (ptime - epoch).total_seconds();
47 std::string
static EncodeDumpString(
const std::string &str) {
48 std::stringstream ret;
49 for (
unsigned char c : str) {
50 if (c <= 32 || c >= 128 ||
c ==
'%') {
60 std::stringstream ret;
61 for (
unsigned int pos = 0; pos < str.length(); pos++) {
62 unsigned char c = str[pos];
63 if (c ==
'%' && pos+2 < str.length()) {
64 c = (((str[pos+1]>>6)*9+((str[pos+1]-
'0')&15)) << 4) |
65 ((str[pos+2]>>6)*9+((str[pos+2]-
'0')&15));
81 throw std::runtime_error(
82 "importprivkey \"privkey\" ( \"label\" ) ( rescan )\n" 83 "\nAdds a private key (as returned by dumpprivkey) to your wallet.\n" 85 "1. \"privkey\" (string, required) The private key (see dumpprivkey)\n" 86 "2. \"label\" (string, optional, default=\"\") An optional label\n" 87 "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" 88 "\nNote: This call can take minutes to complete if rescan is true.\n" 90 "\nDump a private key\n" 92 "\nImport the private key with rescan\n" 94 "\nImport using a label and without rescan\n" 96 "\nImport using default blank label and without rescan\n" 98 "\nAs a JSON-RPC call\n" 108 std::string strLabel =
"";
121 bool fGood = vchSecret.
SetString(strSecret);
136 if (pwallet->
HaveKey(vchAddress)) {
165 throw std::runtime_error(
167 "\nStops current wallet rescan triggered e.g. by an importprivkey call.\n" 169 "\nImport a private key\n" 171 "\nAbort the running wallet rescan\n" 173 "\nAs a JSON-RPC call\n" 195 if (isRedeemScript) {
225 throw std::runtime_error(
226 "importaddress \"address\" ( \"label\" rescan p2sh )\n" 227 "\nAdds a script (in hex) or address that can be watched as if it were in your wallet but cannot be used to spend.\n" 229 "1. \"script\" (string, required) The hex-encoded script (or address)\n" 230 "2. \"label\" (string, optional, default=\"\") An optional label\n" 231 "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" 232 "4. p2sh (boolean, optional, default=false) Add the P2SH version of the script as well\n" 233 "\nNote: This call can take minutes to complete if rescan is true.\n" 234 "If you have the full public key, you should call importpubkey instead of this.\n" 235 "\nNote: If you import a non-standard raw script in hex form, outputs sending to it will be treated\n" 236 "as change, and not show up in many RPCs.\n" 238 "\nImport a script with rescan\n" 240 "\nImport using a label without rescan\n" 241 +
HelpExampleCli(
"importaddress",
"\"myscript\" \"testing\" false") +
242 "\nAs a JSON-RPC call\n" 243 +
HelpExampleRpc(
"importaddress",
"\"myscript\", \"testing\", false")
247 std::string strLabel =
"";
295 throw std::runtime_error(
296 "importprunedfunds\n" 297 "\nImports funds without rescan. Corresponding address or script must previously be included in wallet. Aimed towards pruned wallets. The end-user is responsible to import additional transactions that subsequently spend the imported outputs or rescan after the point in the blockchain the transaction is included.\n" 299 "1. \"rawtransaction\" (string, required) A raw transaction in hex funding an already-existing address in wallet\n" 300 "2. \"txoutproof\" (string, required) The hex output from gettxoutproof that contains the transaction\n" 307 CWalletTx wtx(pwallet, MakeTransactionRef(std::move(tx)));
314 std::vector<uint256> vMatch;
315 std::vector<unsigned int> vIndex;
316 unsigned int txnIndex = 0;
317 if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) == merkleBlock.header.hashMerkleRoot) {
324 std::vector<uint256>::const_iterator it;
325 if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx))==vMatch.end()) {
329 txnIndex = vIndex[it - vMatch.begin()];
336 wtx.
hashBlock = merkleBlock.header.GetHash();
340 if (pwallet->
IsMine(wtx)) {
356 throw std::runtime_error(
357 "removeprunedfunds \"txid\"\n" 358 "\nDeletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will affect wallet balances.\n" 360 "1. \"txid\" (string, required) The hex-encoded id of the transaction you are deleting\n" 362 +
HelpExampleCli(
"removeprunedfunds",
"\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") +
363 "\nAs a JSON-RPC call\n" 364 +
HelpExampleRpc(
"removeprunedfunds",
"\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"")
371 std::vector<uint256> vHash;
372 vHash.push_back(hash);
373 std::vector<uint256> vHashOut;
379 if(vHashOut.empty()) {
394 throw std::runtime_error(
395 "importpubkey \"pubkey\" ( \"label\" rescan )\n" 396 "\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n" 398 "1. \"pubkey\" (string, required) The hex-encoded public key\n" 399 "2. \"label\" (string, optional, default=\"\") An optional label\n" 400 "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" 401 "\nNote: This call can take minutes to complete if rescan is true.\n" 403 "\nImport a public key with rescan\n" 405 "\nImport using a label without rescan\n" 406 +
HelpExampleCli(
"importpubkey",
"\"mypubkey\" \"testing\" false") +
407 "\nAs a JSON-RPC call\n" 408 +
HelpExampleRpc(
"importpubkey",
"\"mypubkey\", \"testing\", false")
412 std::string strLabel =
"";
427 CPubKey pubKey(data.begin(), data.end());
428 if (!pubKey.IsFullyValid())
454 throw std::runtime_error(
455 "importwallet \"filename\"\n" 456 "\nImports keys from a wallet dump file (see dumpwallet).\n" 458 "1. \"filename\" (string, required) The wallet file\n" 460 "\nDump the wallet\n" 462 "\nImport the wallet\n" 464 "\nImport using the json rpc call\n" 476 file.open(request.
params[0].
get_str().c_str(), std::ios::in | std::ios::ate);
484 int64_t nFilesize =
std::max((int64_t)1, (int64_t)file.tellg());
485 file.seekg(0, file.beg);
488 while (file.good()) {
491 std::getline(file, line);
492 if (line.empty() || line[0] ==
'#')
495 std::vector<std::string> vstr;
496 boost::split(vstr, line, boost::is_any_of(
" "));
510 int64_t nTime = DecodeDumpTime(vstr[1]);
511 std::string strLabel;
513 for (
unsigned int nStr = 2; nStr < vstr.size(); nStr++) {
514 if (boost::algorithm::starts_with(vstr[nStr],
"#"))
516 if (vstr[nStr] ==
"change=1")
518 if (vstr[nStr] ==
"reserve=1")
520 if (boost::algorithm::starts_with(vstr[nStr],
"label=")) {
533 nTimeBegin =
std::min(nTimeBegin, nTime);
555 throw std::runtime_error(
556 "dumpprivkey \"address\"\n" 557 "\nReveals the private key corresponding to 'address'.\n" 558 "Then the importprivkey can be used with this output\n" 560 "1. \"address\" (string, required) The fabcoin address for the private key\n" 562 "\"key\" (string) The private key\n" 581 if (!pwallet->
GetKey(keyID, vchSecret)) {
596 throw std::runtime_error(
597 "dumpwallet \"filename\"\n" 598 "\nDumps all wallet keys in a human-readable format to a server-side file. This does not allow overwriting existing files.\n" 600 "1. \"filename\" (string, required) The filename with path (either absolute or relative to fabcoind)\n" 603 " \"filename\" : { (string) The filename with full absolute path\n" 614 boost::filesystem::path filepath = request.
params[0].
get_str();
615 filepath = boost::filesystem::absolute(filepath);
622 if (boost::filesystem::exists(filepath)) {
627 file.open(filepath.string().c_str());
631 std::map<CTxDestination, int64_t> mapKeyBirth;
636 std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
637 for (
const auto& entry : mapKeyBirth) {
638 if (
const CKeyID* keyID = boost::get<CKeyID>(&entry.first)) {
639 vKeyBirth.push_back(std::make_pair(entry.second, *keyID));
643 std::sort(vKeyBirth.begin(), vKeyBirth.end());
654 if (!masterKeyID.
IsNull())
657 if (pwallet->
GetKey(masterKeyID, key)) {
662 b58extkey.
SetKey(masterKey);
664 file <<
"# extended private masterkey: " << b58extkey.
ToString() <<
"\n\n";
667 for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) {
668 const CKeyID &keyid = it->second;
669 std::string strTime = EncodeDumpTime(it->first);
672 if (pwallet->
GetKey(keyid, key)) {
676 }
else if (keyid == masterKeyID) {
677 file <<
"hdmaster=1";
678 }
else if (mapKeyPool.count(keyid)) {
681 file <<
"inactivehdmaster=1";
689 file <<
"# End of dump\n";
702 bool success =
false;
705 const UniValue& scriptPubKey = data[
"scriptPubKey"];
713 const std::string& strRedeemScript = data.
exists(
"redeemscript") ? data[
"redeemscript"].
get_str() :
"";
716 const bool&
internal = data.
exists(
"internal") ? data[
"internal"].
get_bool() :
false;
717 const bool& watchOnly = data.
exists(
"watchonly") ? data[
"watchonly"].
get_bool() :
false;
718 const std::string& label = data.
exists(
"label") && !
internal ? data[
"label"].
get_str() :
"";
721 bool isP2SH = strRedeemScript.length() > 0;
722 const std::string& output = isScript ? scriptPubKey.
get_str() : scriptPubKey[
"address"].
get_str();
735 if (!
IsHex(output)) {
739 std::vector<unsigned char> vData(
ParseHex(output));
740 script =
CScript(vData.begin(), vData.end());
744 if (watchOnly && keys.
size()) {
749 if (
internal && data.
exists(
"label")) {
754 if (!
internal && isScript) {
759 if (!isP2SH && (keys.
size() > 1 || pubKeys.
size() > 1)) {
764 if (isP2SH && !
IsHex(strRedeemScript)) {
773 std::vector<unsigned char> vData(
ParseHex(strRedeemScript));
800 if (!pwallet->
AddWatchOnly(redeemDestination, timestamp)) {
811 for (
size_t i = 0; i < keys.
size(); i++) {
812 const std::string& privkey = keys[i].
get_str();
815 bool fGood = vchSecret.
SetString(privkey);
834 if (pwallet->
HaveKey(vchAddress)) {
851 if (pubKeys.
size() && keys.
size() == 0) {
852 const std::string& strPubKey = pubKeys[0].
get_str();
854 if (!
IsHex(strPubKey)) {
858 std::vector<unsigned char> vData(
ParseHex(strPubKey));
859 CPubKey pubKey(vData.begin(), vData.end());
861 if (!pubKey.IsFullyValid()) {
868 if (!isScript && !(pubKeyAddress.
Get() == address.
Get())) {
879 if (!(scriptAddress.
Get() == pubKeyAddress.
Get())) {
911 if (!pwallet->
AddWatchOnly(scriptRawPubKey, timestamp)) {
920 const std::string& strPrivkey = keys[0].
get_str();
924 bool fGood = vchSecret.
SetString(strPrivkey);
941 if (!isScript && !(pubKeyAddress.Get() == address.
Get())) {
952 if (!(scriptAddress.
Get() == pubKeyAddress.Get())) {
962 if (pwallet->
HaveKey(vchAddress)) {
978 if (pubKeys.
size() == 0 && keys.
size() == 0) {
1006 result.
pushKV(
"error", e);
1018 if (data.
exists(
"timestamp")) {
1019 const UniValue& timestamp = data[
"timestamp"];
1020 if (timestamp.
isNum()) {
1022 }
else if (timestamp.
isStr() && timestamp.
get_str() ==
"now") {
1039 throw std::runtime_error(
1040 "importmulti \"requests\" ( \"options\" )\n\n" 1041 "Import addresses/scripts (with private or public keys, redeem script (P2SH)), rescanning all addresses in one-shot-only (rescan can be disabled via options).\n\n" 1043 "1. requests (array, required) Data to be imported\n" 1044 " [ (array of json objects)\n" 1046 " \"scriptPubKey\": \"<script>\" | { \"address\":\"<address>\" }, (string / json, required) Type of scriptPubKey (string for script, json for address)\n" 1047 " \"timestamp\": timestamp | \"now\" , (integer / string, required) Creation time of the key in seconds since epoch (Jan 1 1970 GMT),\n" 1048 " or the string \"now\" to substitute the current synced blockchain time. The timestamp of the oldest\n" 1049 " key will determine how far back blockchain rescans need to begin for missing wallet transactions.\n" 1050 " \"now\" can be specified to bypass scanning, for keys which are known to never have been used, and\n" 1051 " 0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest key\n" 1052 " creation time of all keys being imported by the importmulti call will be scanned.\n" 1053 " \"redeemscript\": \"<script>\" , (string, optional) Allowed only if the scriptPubKey is a P2SH address or a P2SH scriptPubKey\n" 1054 " \"pubkeys\": [\"<pubKey>\", ... ] , (array, optional) Array of strings giving pubkeys that must occur in the output or redeemscript\n" 1055 " \"keys\": [\"<key>\", ... ] , (array, optional) Array of strings giving private keys whose corresponding public keys must occur in the output or redeemscript\n" 1056 " \"internal\": <true> , (boolean, optional, default: false) Stating whether matching outputs should be treated as not incoming payments\n" 1057 " \"watchonly\": <true> , (boolean, optional, default: false) Stating whether matching outputs should be considered watched even when they're not spendable, only allowed if keys are empty\n" 1058 " \"label\": <label> , (string, optional, default: '') Label to assign to the address (aka account name, for now), only allowed with internal=false\n" 1062 "2. options (json, optional)\n" 1064 " \"rescan\": <false>, (boolean, optional, default: true) Stating if should rescan the blockchain after all imports\n" 1067 HelpExampleCli(
"importmulti",
"'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, \"timestamp\":1455191478 }, " 1068 "{ \"scriptPubKey\": { \"address\": \"<my 2nd address>\" }, \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") +
1069 HelpExampleCli(
"importmulti",
"'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, \"timestamp\":1455191478 }]' '{ \"rescan\": false}'") +
1071 "\nResponse is an array with the same size as the input that has the execution result :\n" 1072 " [{ \"success\": true } , { \"success\": false, \"error\": { \"code\": -1, \"message\": \"Internal Server Error\"} }, ... ]\n");
1081 bool fRescan =
true;
1086 if (options.
exists(
"rescan")) {
1087 fRescan = options[
"rescan"].
get_bool();
1100 bool fRunScan =
false;
1101 const int64_t minimumTimestamp = 1;
1102 int64_t nLowestTimestamp = 0;
1122 if (result[
"success"].get_bool()) {
1127 if (timestamp < nLowestTimestamp) {
1128 nLowestTimestamp = timestamp;
1132 if (fRescan && fRunScan && requests.
size()) {
1133 int64_t scannedTime = pwallet->
RescanFromTime(nLowestTimestamp,
true );
1136 if (scannedTime > nLowestTimestamp) {
1137 std::vector<UniValue> results = response.
getValues();
1146 if (scannedTime <=
GetImportTimestamp(request, now) || results.at(i).exists(
"error")) {
1155 strprintf(
"Rescan failed for key with creation timestamp %d. There was an error reading a " 1156 "block from time %d, which is after or within %d seconds of key creation, and " 1157 "could contain transactions pertaining to the key. As a result, transactions " 1158 "and coins using this key may not appear in the wallet. This error could be " 1159 "caused by pruning or data corruption (see fabcoind log for details) and could " 1160 "be dealt with by downloading and rescanning the relevant blocks (see -reindex " 1161 "and -rescan options).",
1162 GetImportTimestamp(request, now), scannedTime - TIMESTAMP_WINDOW - 1, TIMESTAMP_WINDOW)));
A base58-encoded secret key.
std::string DecodeDumpString(const std::string &str)
UniValue abortrescan(const JSONRPCRequest &request)
const std::string & get_str() const
CKeyID masterKeyID
master key hash160
bool SetString(const char *pszSecret)
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
bool fPruneMode
True if we're running in -prune mode.
const unsigned char * begin() const
bool HaveKey(const CKeyID &address) const override
Check whether a key corresponding to a given address is present in the store.
UniValue dumpprivkey(const JSONRPCRequest &request)
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
std::map< CTxDestination, CAddressBookData > mapAddressBook
CCriticalSection cs_wallet
UniValue importmulti(const JSONRPCRequest &mainRequest)
bool IsPayToScriptHash() const
bool EnsureWalletIsAvailable(CWallet *const pwallet, bool avoidException)
virtual bool HaveCScript(const CScriptID &hash) const override
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Adds a key to the store, and saves it to disk.
const std::vector< UniValue > & getValues() const
void ReacceptWalletTransactions()
base58-encoded Fabcoin addresses.
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
UniValue dumpwallet(const JSONRPCRequest &request)
isminetype IsMine(const CKeyStore &keystore, const CScript &scriptPubKey, SigVersion sigversion)
void GetKeyBirthTimes(std::map< CTxDestination, int64_t > &mapKeyBirth) const
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
assert(len-trim+(2 *lenIndices)<=WIDTH)
Double ended buffer combining vector and stream-like interfaces.
std::map< CTxDestination, CKeyMetadata > mapKeyMetadata
bool AddWatchOnly(const CScript &dest) override
Private version of AddWatchOnly method which does not accept a timestamp, and which will reset the wa...
void RPCTypeCheck(const UniValue ¶ms, const std::list< UniValue::VType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Invalid, missing or duplicate parameter.
std::string ToString() const
bool IsValid() const
Check whether this private key is valid.
enum VType getType() const
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
const char * uvTypeName(UniValue::VType t)
int Height() const
Return the maximal height in the chain.
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
int64_t get_int64() const
bool push_back(const UniValue &val)
void ImportAddress(CWallet *, const CFabcoinAddress &address, const std::string &strLabel)
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/fabcoin/bips/blob/master/bip-0013.mediawiki.
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx, bool fTryNoWitness=false)
CPubKey GetPubKey() const
Compute the public key from a private key.
void ImportScript(CWallet *const pwallet, const CScript &script, const std::string &strLabel, bool isRedeemScript)
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet, txnouttype *typeRet)
UniValue removeprunedfunds(const JSONRPCRequest &request)
An encapsulated public key.
bool IsHex(const std::string &str)
Unexpected type was passed as parameter.
void UpdateTimeFirstKey(int64_t nCreateTime)
Update wallet first key creation time.
std::string ToString() const
General application defined errors.
bool pushKV(const std::string &key, const UniValue &val)
const CHDChain & GetHDChain() const
UniValue ProcessImport(CWallet *const pwallet, const UniValue &data, const int64_t timestamp)
bool GetKey(const CKeyID &address, CKey &keyOut) const override
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
CScript GetScriptForDestination(const CTxDestination &dest)
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
CTxDestination Get() const
void SetKey(const K &key)
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
bool AddToWallet(const CWalletTx &wtxIn, bool fFlushOnClose=true)
bool SetString(const char *psz, unsigned int nVersionBytes=1)
A transaction with a bunch of additional info that only the owner cares about.
std::vector< unsigned char > ParseHexV(const UniValue &v, std::string strName)
const std::map< CKeyID, int64_t > & GetAllReserveKeys() const
int64_t RescanFromTime(int64_t startTime, bool update)
Scan active chain for relevant transactions after importing keys.
int64_t GetImportTimestamp(const UniValue &data, int64_t now)
bool GetKeyID(CKeyID &keyID) const
const UniValue & get_array() const
Serialized script, used inside transaction inputs and outputs.
UniValue importpubkey(const JSONRPCRequest &request)
A reference to a CKey: the Hash160 of its serialized public key.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
const UniValue NullUniValue
CWallet * GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
UniValue importprivkey(const JSONRPCRequest &request)
void SetMaster(const unsigned char *seed, unsigned int nSeedLen)
UniValue importwallet(const JSONRPCRequest &request)
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
A reference to a CScript: the Hash160 of its serialization (see script.h)
UniValue importaddress(const JSONRPCRequest &request)
A mutable version of CTransaction.
isminetype IsMine(const CTxIn &txin) const
UniValue JSONRPCError(int code, const std::string &message)
bool exists(const std::string &key) const
dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b)
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
struct evm_uint160be address(struct evm_env *env)
An encapsulated private key.
virtual bool HaveWatchOnly(const CScript &dest) const override
int64_t GetBlockTime() const
unsigned int size() const
Simple read-only vector-like interface.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
void SetHex(const char *psz)
int64_t GetMedianTimePast() const
const std::string CLIENT_BUILD
UniValue importprunedfunds(const JSONRPCRequest &request)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
Error parsing or validating structure in raw format.
uint256 GetBlockHash() const
void EnsureWalletIsUnlocked()
std::vector< unsigned char > ParseHex(const char *psz)