Add p2sh option to importaddress to import redeemScripts
This commit is contained in:
parent
983d2d90af
commit
907a425aa5
3 changed files with 31 additions and 6 deletions
|
@ -93,6 +93,16 @@ class ListTransactionsTest(BitcoinTestFramework):
|
||||||
{"category":"receive","amount":Decimal("0.44")},
|
{"category":"receive","amount":Decimal("0.44")},
|
||||||
{"txid":txid, "account" : "toself"} )
|
{"txid":txid, "account" : "toself"} )
|
||||||
|
|
||||||
|
multisig = self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()])
|
||||||
|
self.nodes[0].importaddress(multisig["redeemScript"], "watchonly", False, True)
|
||||||
|
txid = self.nodes[1].sendtoaddress(multisig["address"], 0.1)
|
||||||
|
self.nodes[1].generate(1)
|
||||||
|
self.sync_all()
|
||||||
|
assert(len(self.nodes[0].listtransactions("watchonly", 100, 0, False)) == 0)
|
||||||
|
check_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True),
|
||||||
|
{"category":"receive","amount":Decimal("0.1")},
|
||||||
|
{"txid":txid, "account" : "watchonly"} )
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
ListTransactionsTest().main()
|
ListTransactionsTest().main()
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||||
{ "lockunspent", 1 },
|
{ "lockunspent", 1 },
|
||||||
{ "importprivkey", 2 },
|
{ "importprivkey", 2 },
|
||||||
{ "importaddress", 2 },
|
{ "importaddress", 2 },
|
||||||
|
{ "importaddress", 3 },
|
||||||
{ "verifychain", 0 },
|
{ "verifychain", 0 },
|
||||||
{ "verifychain", 1 },
|
{ "verifychain", 1 },
|
||||||
{ "keypoolrefill", 0 },
|
{ "keypoolrefill", 0 },
|
||||||
|
|
|
@ -146,21 +146,28 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
|
||||||
return NullUniValue;
|
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");
|
throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
|
||||||
|
|
||||||
pwalletMain->MarkDirty();
|
pwalletMain->MarkDirty();
|
||||||
|
|
||||||
if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script))
|
if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script))
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
|
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)
|
void ImportAddress(const CBitcoinAddress& address, const string& strLabel)
|
||||||
{
|
{
|
||||||
CScript script = GetScriptForDestination(address.Get());
|
CScript script = GetScriptForDestination(address.Get());
|
||||||
ImportScript(script, false);
|
ImportScript(script, strLabel, false);
|
||||||
// add to address book or update label
|
// add to address book or update label
|
||||||
if (address.IsValid())
|
if (address.IsValid())
|
||||||
pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
|
pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
|
||||||
|
@ -171,14 +178,15 @@ UniValue importaddress(const UniValue& params, bool fHelp)
|
||||||
if (!EnsureWalletIsAvailable(fHelp))
|
if (!EnsureWalletIsAvailable(fHelp))
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
|
|
||||||
if (fHelp || params.size() < 1 || params.size() > 3)
|
if (fHelp || params.size() < 1 || params.size() > 4)
|
||||||
throw runtime_error(
|
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"
|
"\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"
|
"\nArguments:\n"
|
||||||
"1. \"address\" (string, required) The address\n"
|
"1. \"address\" (string, required) The address\n"
|
||||||
"2. \"label\" (string, optional, default=\"\") An optional label\n"
|
"2. \"label\" (string, optional, default=\"\") An optional label\n"
|
||||||
"3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\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"
|
"\nNote: This call can take minutes to complete if rescan is true.\n"
|
||||||
"\nExamples:\n"
|
"\nExamples:\n"
|
||||||
"\nImport an address with rescan\n"
|
"\nImport an address with rescan\n"
|
||||||
|
@ -201,15 +209,21 @@ UniValue importaddress(const UniValue& params, bool fHelp)
|
||||||
if (params.size() > 2)
|
if (params.size() > 2)
|
||||||
fRescan = params[2].get_bool();
|
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);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
|
|
||||||
CBitcoinAddress address(params[0].get_str());
|
CBitcoinAddress address(params[0].get_str());
|
||||||
if (address.IsValid()) {
|
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);
|
ImportAddress(address, strLabel);
|
||||||
} else if (IsHex(params[0].get_str())) {
|
} else if (IsHex(params[0].get_str())) {
|
||||||
std::vector<unsigned char> data(ParseHex(params[0].get_str()));
|
std::vector<unsigned char> data(ParseHex(params[0].get_str()));
|
||||||
ImportScript(CScript(data.begin(), data.end()));
|
ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH);
|
||||||
} else {
|
} else {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue