@@ -1154,9 +1154,10 @@ class Witnessifier : public boost::static_visitor<bool>
1154
1154
{
1155
1155
public:
1156
1156
CWallet * const pwallet;
1157
- CScriptID result;
1157
+ CTxDestination result;
1158
+ bool already_witness;
1158
1159
1159
- explicit Witnessifier (CWallet *_pwallet) : pwallet(_pwallet) {}
1160
+ explicit Witnessifier (CWallet *_pwallet) : pwallet(_pwallet), already_witness( false ) {}
1160
1161
1161
1162
bool operator ()(const CKeyID &keyID) {
1162
1163
if (pwallet) {
@@ -1170,9 +1171,7 @@ class Witnessifier : public boost::static_visitor<bool>
1170
1171
!VerifyScript (sigs.scriptSig , witscript, &sigs.scriptWitness , MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator (pwallet).Checker ())) {
1171
1172
return false ;
1172
1173
}
1173
- pwallet->AddCScript (witscript);
1174
- result = CScriptID (witscript);
1175
- return true ;
1174
+ return ExtractDestination (witscript, result);
1176
1175
}
1177
1176
return false ;
1178
1177
}
@@ -1183,7 +1182,8 @@ class Witnessifier : public boost::static_visitor<bool>
1183
1182
int witnessversion;
1184
1183
std::vector<unsigned char > witprog;
1185
1184
if (subscript.IsWitnessProgram (witnessversion, witprog)) {
1186
- result = scriptID;
1185
+ ExtractDestination (subscript, result);
1186
+ already_witness = true ;
1187
1187
return true ;
1188
1188
}
1189
1189
CScript witscript = GetScriptForWitness (subscript);
@@ -1195,13 +1195,25 @@ class Witnessifier : public boost::static_visitor<bool>
1195
1195
!VerifyScript (sigs.scriptSig , witscript, &sigs.scriptWitness , MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator (pwallet).Checker ())) {
1196
1196
return false ;
1197
1197
}
1198
- pwallet->AddCScript (witscript);
1199
- result = CScriptID (witscript);
1200
- return true ;
1198
+ return ExtractDestination (witscript, result);
1201
1199
}
1202
1200
return false ;
1203
1201
}
1204
1202
1203
+ bool operator ()(const WitnessV0KeyHash& id)
1204
+ {
1205
+ already_witness = true ;
1206
+ result = id;
1207
+ return true ;
1208
+ }
1209
+
1210
+ bool operator ()(const WitnessV0ScriptHash& id)
1211
+ {
1212
+ already_witness = true ;
1213
+ result = id;
1214
+ return true ;
1215
+ }
1216
+
1205
1217
template <typename T>
1206
1218
bool operator ()(const T& dest) { return false ; }
1207
1219
};
@@ -1213,17 +1225,18 @@ UniValue addwitnessaddress(const JSONRPCRequest& request)
1213
1225
return NullUniValue;
1214
1226
}
1215
1227
1216
- if (request.fHelp || request.params .size () < 1 || request.params .size () > 1 )
1228
+ if (request.fHelp || request.params .size () < 1 || request.params .size () > 2 )
1217
1229
{
1218
- std::string msg = " addwitnessaddress \" address\"\n "
1230
+ std::string msg = " addwitnessaddress \" address\" ( p2sh ) \n "
1219
1231
" \n Add a witness address for a script (with pubkey or redeemscript known).\n "
1220
1232
" It returns the witness script.\n "
1221
1233
1222
1234
" \n Arguments:\n "
1223
1235
" 1. \" address\" (string, required) An address known to the wallet\n "
1236
+ " 2. p2sh (bool, optional, default=true) Embed inside P2SH\n "
1224
1237
1225
1238
" \n Result:\n "
1226
- " \" witnessaddress\" , (string) The value of the new address (P2SH of witness script ).\n "
1239
+ " \" witnessaddress\" , (string) The value of the new address (P2SH or BIP173 ).\n "
1227
1240
" }\n "
1228
1241
;
1229
1242
throw std::runtime_error (msg);
@@ -1241,13 +1254,31 @@ UniValue addwitnessaddress(const JSONRPCRequest& request)
1241
1254
throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, " Invalid Bitcoin address" );
1242
1255
}
1243
1256
1257
+ bool p2sh = true ;
1258
+ if (!request.params [1 ].isNull ()) {
1259
+ p2sh = request.params [1 ].get_bool ();
1260
+ }
1261
+
1244
1262
Witnessifier w (pwallet);
1245
1263
bool ret = boost::apply_visitor (w, dest);
1246
1264
if (!ret) {
1247
1265
throw JSONRPCError (RPC_WALLET_ERROR, " Public key or redeemscript not known to wallet, or the key is uncompressed" );
1248
1266
}
1249
1267
1250
- pwallet->SetAddressBook (w.result , " " , " receive" );
1268
+ CScript witprogram = GetScriptForDestination (w.result );
1269
+
1270
+ if (p2sh) {
1271
+ w.result = CScriptID (witprogram);
1272
+ }
1273
+
1274
+ if (w.already_witness ) {
1275
+ if (!(dest == w.result )) {
1276
+ throw JSONRPCError (RPC_WALLET_ERROR, " Cannot convert between witness address types" );
1277
+ }
1278
+ } else {
1279
+ pwallet->AddCScript (witprogram);
1280
+ pwallet->SetAddressBook (w.result , " " , " receive" );
1281
+ }
1251
1282
1252
1283
return EncodeDestination (w.result );
1253
1284
}
@@ -3200,7 +3231,7 @@ static const CRPCCommand commands[] =
3200
3231
{ " wallet" , " abandontransaction" , &abandontransaction, {" txid" } },
3201
3232
{ " wallet" , " abortrescan" , &abortrescan, {} },
3202
3233
{ " wallet" , " addmultisigaddress" , &addmultisigaddress, {" nrequired" ," keys" ," account" } },
3203
- { " wallet" , " addwitnessaddress" , &addwitnessaddress, {" address" } },
3234
+ { " wallet" , " addwitnessaddress" , &addwitnessaddress, {" address" , " p2sh " } },
3204
3235
{ " wallet" , " backupwallet" , &backupwallet, {" destination" } },
3205
3236
{ " wallet" , " bumpfee" , &bumpfee, {" txid" , " options" } },
3206
3237
{ " wallet" , " dumpprivkey" , &dumpprivkey, {" address" } },
0 commit comments