Skip to content

Commit 907a425

Browse files
committed
Add p2sh option to importaddress to import redeemScripts
1 parent 983d2d9 commit 907a425

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

qa/rpc-tests/listtransactions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ def run_test(self):
9393
{"category":"receive","amount":Decimal("0.44")},
9494
{"txid":txid, "account" : "toself"} )
9595

96+
multisig = self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()])
97+
self.nodes[0].importaddress(multisig["redeemScript"], "watchonly", False, True)
98+
txid = self.nodes[1].sendtoaddress(multisig["address"], 0.1)
99+
self.nodes[1].generate(1)
100+
self.sync_all()
101+
assert(len(self.nodes[0].listtransactions("watchonly", 100, 0, False)) == 0)
102+
check_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True),
103+
{"category":"receive","amount":Decimal("0.1")},
104+
{"txid":txid, "account" : "watchonly"} )
105+
96106
if __name__ == '__main__':
97107
ListTransactionsTest().main()
98108

src/rpcclient.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
8787
{ "lockunspent", 1 },
8888
{ "importprivkey", 2 },
8989
{ "importaddress", 2 },
90+
{ "importaddress", 3 },
9091
{ "verifychain", 0 },
9192
{ "verifychain", 1 },
9293
{ "keypoolrefill", 0 },

src/wallet/rpcdump.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,21 +146,28 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
146146
return NullUniValue;
147147
}
148148

149-
void ImportScript(const CScript& script)
149+
void ImportAddress(const CBitcoinAddress& address, const string& strLabel);
150+
void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript)
150151
{
151-
if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE)
152+
if (!isRedeemScript && ::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE)
152153
throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
153154

154155
pwalletMain->MarkDirty();
155156

156157
if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script))
157158
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
159+
160+
if (isRedeemScript) {
161+
if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script))
162+
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet");
163+
ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel);
164+
}
158165
}
159166

160167
void ImportAddress(const CBitcoinAddress& address, const string& strLabel)
161168
{
162169
CScript script = GetScriptForDestination(address.Get());
163-
ImportScript(script, false);
170+
ImportScript(script, strLabel, false);
164171
// add to address book or update label
165172
if (address.IsValid())
166173
pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
@@ -171,14 +178,15 @@ UniValue importaddress(const UniValue& params, bool fHelp)
171178
if (!EnsureWalletIsAvailable(fHelp))
172179
return NullUniValue;
173180

174-
if (fHelp || params.size() < 1 || params.size() > 3)
181+
if (fHelp || params.size() < 1 || params.size() > 4)
175182
throw runtime_error(
176-
"importaddress \"address\" ( \"label\" rescan )\n"
183+
"importaddress \"address\" ( \"label\" rescan p2sh )\n"
177184
"\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"
178185
"\nArguments:\n"
179186
"1. \"address\" (string, required) The address\n"
180187
"2. \"label\" (string, optional, default=\"\") An optional label\n"
181188
"3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n"
189+
"4. p2sh (boolean, optional, default=false) Add the P2SH version of the script as well\n"
182190
"\nNote: This call can take minutes to complete if rescan is true.\n"
183191
"\nExamples:\n"
184192
"\nImport an address with rescan\n"
@@ -201,15 +209,21 @@ UniValue importaddress(const UniValue& params, bool fHelp)
201209
if (params.size() > 2)
202210
fRescan = params[2].get_bool();
203211

212+
// Whether to import a p2sh version, too
213+
bool fP2SH = false;
214+
if (params.size() > 3)
215+
fP2SH = params[3].get_bool();
204216

205217
LOCK2(cs_main, pwalletMain->cs_wallet);
206218

207219
CBitcoinAddress address(params[0].get_str());
208220
if (address.IsValid()) {
221+
if (fP2SH)
222+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead");
209223
ImportAddress(address, strLabel);
210224
} else if (IsHex(params[0].get_str())) {
211225
std::vector<unsigned char> data(ParseHex(params[0].get_str()));
212-
ImportScript(CScript(data.begin(), data.end()));
226+
ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH);
213227
} else {
214228
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script");
215229
}

0 commit comments

Comments
 (0)