aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/rpcdump.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2015-08-14 12:04:47 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2015-08-14 16:28:37 +0200
commitddd8d80c63182aefea56abf743bb9199d9602544 (patch)
tree4cb40e3bc509c433388bf8c58dee9e3f6b86c046 /src/wallet/rpcdump.cpp
parent87f37e259d6deb52ee464edde7aece687eea97a5 (diff)
parentd04285430d1b54b3ce3d50ffa67b6098157e7c14 (diff)
Merge pull request #6415
d042854 SQUASH "Implement watchonly support in fundrawtransaction" (Matt Corallo) 428a898 SQUASH "Add have-pubkey distinction to ISMINE flags" (Matt Corallo) 6bdb474 Implement watchonly support in fundrawtransaction (Matt Corallo) f5813bd Add logic to track pubkeys as watch-only, not just scripts (Matt Corallo) d3354c5 Add have-pubkey distinction to ISMINE flags (Matt Corallo) 5c17059 Update importaddress help to push its use to script-only (Matt Corallo) a1d7df3 Add importpubkey method to import a watch-only pubkey (Matt Corallo) 907a425 Add p2sh option to importaddress to import redeemScripts (Matt Corallo) 983d2d9 Split up importaddress into helper functions (Matt Corallo) cfc3dd3 Also remove pay-2-pubkey from watch when adding a priv key (Matt Corallo)
Diffstat (limited to 'src/wallet/rpcdump.cpp')
-rw-r--r--src/wallet/rpcdump.cpp135
1 files changed, 104 insertions, 31 deletions
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index dbe36a2be1..8d557979c0 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -149,46 +149,124 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
return NullUniValue;
}
+void ImportAddress(const CBitcoinAddress& address, const string& strLabel);
+void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript)
+{
+ if (!isRedeemScript && ::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE)
+ throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
+
+ pwalletMain->MarkDirty();
+
+ if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
+
+ if (isRedeemScript) {
+ if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet");
+ ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel);
+ }
+}
+
+void ImportAddress(const CBitcoinAddress& address, const string& strLabel)
+{
+ CScript script = GetScriptForDestination(address.Get());
+ ImportScript(script, strLabel, false);
+ // add to address book or update label
+ if (address.IsValid())
+ pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
+}
+
UniValue importaddress(const UniValue& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))
return NullUniValue;
- if (fHelp || params.size() < 1 || params.size() > 3)
+ if (fHelp || params.size() < 1 || params.size() > 4)
throw runtime_error(
- "importaddress \"address\" ( \"label\" rescan )\n"
- "\nAdds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n"
+ "importaddress \"address\" ( \"label\" rescan p2sh )\n"
+ "\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"
"\nArguments:\n"
- "1. \"address\" (string, required) The address\n"
+ "1. \"script\" (string, required) The hex-encoded script (or address)\n"
"2. \"label\" (string, optional, default=\"\") An optional label\n"
"3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n"
+ "4. p2sh (boolean, optional, default=false) Add the P2SH version of the script as well\n"
"\nNote: This call can take minutes to complete if rescan is true.\n"
+ "If you have the full public key, you should call importpublickey instead of this.\n"
"\nExamples:\n"
- "\nImport an address with rescan\n"
- + HelpExampleCli("importaddress", "\"myaddress\"") +
+ "\nImport a script with rescan\n"
+ + HelpExampleCli("importaddress", "\"myscript\"") +
"\nImport using a label without rescan\n"
- + HelpExampleCli("importaddress", "\"myaddress\" \"testing\" false") +
+ + HelpExampleCli("importaddress", "\"myscript\" \"testing\" false") +
"\nAs a JSON-RPC call\n"
- + HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false")
+ + HelpExampleRpc("importaddress", "\"myscript\", \"testing\", false")
);
if (fPruneMode)
throw JSONRPCError(RPC_WALLET_ERROR, "Importing addresses is disabled in pruned mode");
- LOCK2(cs_main, pwalletMain->cs_wallet);
+ string strLabel = "";
+ if (params.size() > 1)
+ strLabel = params[1].get_str();
+
+ // Whether to perform rescan after import
+ bool fRescan = true;
+ if (params.size() > 2)
+ fRescan = params[2].get_bool();
- CScript script;
+ // Whether to import a p2sh version, too
+ bool fP2SH = false;
+ if (params.size() > 3)
+ fP2SH = params[3].get_bool();
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (address.IsValid()) {
- script = GetScriptForDestination(address.Get());
+ if (fP2SH)
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead");
+ ImportAddress(address, strLabel);
} else if (IsHex(params[0].get_str())) {
std::vector<unsigned char> data(ParseHex(params[0].get_str()));
- script = CScript(data.begin(), data.end());
+ ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH);
} else {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script");
}
+ if (fRescan)
+ {
+ pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
+ pwalletMain->ReacceptWalletTransactions();
+ }
+
+ return NullUniValue;
+}
+
+UniValue importpubkey(const UniValue& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return NullUniValue;
+
+ if (fHelp || params.size() < 1 || params.size() > 4)
+ throw runtime_error(
+ "importpubkey \"pubkey\" ( \"label\" rescan )\n"
+ "\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n"
+ "\nArguments:\n"
+ "1. \"pubkey\" (string, required) The hex-encoded public key\n"
+ "2. \"label\" (string, optional, default=\"\") An optional label\n"
+ "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n"
+ "\nNote: This call can take minutes to complete if rescan is true.\n"
+ "\nExamples:\n"
+ "\nImport a public key with rescan\n"
+ + HelpExampleCli("importpubkey", "\"mypubkey\"") +
+ "\nImport using a label without rescan\n"
+ + HelpExampleCli("importpubkey", "\"mypubkey\" \"testing\" false") +
+ "\nAs a JSON-RPC call\n"
+ + HelpExampleRpc("importpubkey", "\"mypubkey\", \"testing\", false")
+ );
+
+ if (fPruneMode)
+ throw JSONRPCError(RPC_WALLET_ERROR, "Importing public keys is disabled in pruned mode");
+
string strLabel = "";
if (params.size() > 1)
strLabel = params[1].get_str();
@@ -198,33 +276,28 @@ UniValue importaddress(const UniValue& params, bool fHelp)
if (params.size() > 2)
fRescan = params[2].get_bool();
- {
- if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE)
- throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
-
- // add to address book or update label
- if (address.IsValid())
- pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
-
- // Don't throw error in case an address is already there
- if (pwalletMain->HaveWatchOnly(script))
- return NullUniValue;
+ if (!IsHex(params[0].get_str()))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string");
+ std::vector<unsigned char> data(ParseHex(params[0].get_str()));
+ CPubKey pubKey(data.begin(), data.end());
+ if (!pubKey.IsFullyValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key");
- pwalletMain->MarkDirty();
+ LOCK2(cs_main, pwalletMain->cs_wallet);
- if (!pwalletMain->AddWatchOnly(script))
- throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
+ ImportAddress(CBitcoinAddress(pubKey.GetID()), strLabel);
+ ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false);
- if (fRescan)
- {
- pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
- pwalletMain->ReacceptWalletTransactions();
- }
+ if (fRescan)
+ {
+ pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
+ pwalletMain->ReacceptWalletTransactions();
}
return NullUniValue;
}
+
UniValue importwallet(const UniValue& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))