From 983d2d90af1b517bee51170d2ea059e68d09be35 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 11 Jun 2015 00:57:26 -0700 Subject: Split up importaddress into helper functions --- src/wallet/rpcdump.cpp | 67 +++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 33 deletions(-) (limited to 'src/wallet/rpcdump.cpp') diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 5f800474a..f56ff65f8 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -146,6 +146,26 @@ UniValue importprivkey(const UniValue& params, bool fHelp) return NullUniValue; } +void ImportScript(const CScript& script) +{ + if (::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"); +} + +void ImportAddress(const CBitcoinAddress& address, const string& strLabel) +{ + CScript script = GetScriptForDestination(address.Get()); + ImportScript(script, 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)) @@ -172,20 +192,6 @@ UniValue importaddress(const UniValue& params, bool fHelp) if (fPruneMode) throw JSONRPCError(RPC_WALLET_ERROR, "Importing addresses is disabled in pruned mode"); - LOCK2(cs_main, pwalletMain->cs_wallet); - - CScript script; - - CBitcoinAddress address(params[0].get_str()); - if (address.IsValid()) { - script = GetScriptForDestination(address.Get()); - } else if (IsHex(params[0].get_str())) { - std::vector data(ParseHex(params[0].get_str())); - script = CScript(data.begin(), data.end()); - } else { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); - } - string strLabel = ""; if (params.size() > 1) strLabel = params[1].get_str(); @@ -195,28 +201,23 @@ 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; - - pwalletMain->MarkDirty(); + LOCK2(cs_main, pwalletMain->cs_wallet); - if (!pwalletMain->AddWatchOnly(script)) - throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + CBitcoinAddress address(params[0].get_str()); + if (address.IsValid()) { + ImportAddress(address, strLabel); + } else if (IsHex(params[0].get_str())) { + std::vector data(ParseHex(params[0].get_str())); + ImportScript(CScript(data.begin(), data.end())); + } else { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); + } - if (fRescan) - { - pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); - pwalletMain->ReacceptWalletTransactions(); - } + if (fRescan) + { + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + pwalletMain->ReacceptWalletTransactions(); } return NullUniValue; -- cgit v1.2.3 From 907a425aa5b8fd90cf1d28215712a309e934b364 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 11 Jun 2015 00:57:50 -0700 Subject: Add p2sh option to importaddress to import redeemScripts --- src/wallet/rpcdump.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src/wallet/rpcdump.cpp') diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index f56ff65f8..3493efc8f 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -146,21 +146,28 @@ UniValue importprivkey(const UniValue& params, bool fHelp) return NullUniValue; } -void ImportScript(const CScript& script) +void ImportAddress(const CBitcoinAddress& address, const string& strLabel); +void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript) { - if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) + 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, false); + ImportScript(script, strLabel, false); // add to address book or update label if (address.IsValid()) pwalletMain->SetAddressBook(address.Get(), strLabel, "receive"); @@ -171,14 +178,15 @@ 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" + "importaddress \"address\" ( \"label\" rescan p2sh )\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" "\nArguments:\n" "1. \"address\" (string, required) The 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" "\nExamples:\n" "\nImport an address with rescan\n" @@ -201,15 +209,21 @@ UniValue importaddress(const UniValue& params, bool fHelp) if (params.size() > 2) fRescan = params[2].get_bool(); + // 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()) { + 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 data(ParseHex(params[0].get_str())); - ImportScript(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"); } -- cgit v1.2.3 From a1d7df32360605724d8f0ea4b7aebfa7aea24c97 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 9 Jul 2015 22:47:36 -0700 Subject: Add importpubkey method to import a watch-only pubkey --- src/wallet/rpcdump.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'src/wallet/rpcdump.cpp') diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 3493efc8f..7efabbfeb 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -237,6 +237,63 @@ UniValue importaddress(const UniValue& params, bool fHelp) 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(); + + // Whether to perform rescan after import + bool fRescan = true; + if (params.size() > 2) + fRescan = params[2].get_bool(); + + if (!IsHex(params[0].get_str())) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string"); + std::vector 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"); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + ImportAddress(CBitcoinAddress(pubKey.GetID()), strLabel); + ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false); + + if (fRescan) + { + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + pwalletMain->ReacceptWalletTransactions(); + } + + return NullUniValue; +} + + UniValue importwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) -- cgit v1.2.3 From 5c17059872c9b63a1e05c7aa8aea32a03c3ec73a Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 9 Jul 2015 22:47:47 -0700 Subject: Update importaddress help to push its use to script-only --- src/wallet/rpcdump.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/wallet/rpcdump.cpp') diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 7efabbfeb..2c4f1f243 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -181,20 +181,21 @@ UniValue importaddress(const UniValue& params, bool fHelp) if (fHelp || params.size() < 1 || params.size() > 4) throw runtime_error( "importaddress \"address\" ( \"label\" rescan p2sh )\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" + "\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) -- cgit v1.2.3