Support BIP173 in addwitnessaddress

pull/476/merge
Pieter Wuille 7 years ago
parent c091b99379
commit e278f12ca7

@ -129,6 +129,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "logging", 0, "include" }, { "logging", 0, "include" },
{ "logging", 1, "exclude" }, { "logging", 1, "exclude" },
{ "disconnectnode", 1, "nodeid" }, { "disconnectnode", 1, "nodeid" },
{ "addwitnessaddress", 1, "p2sh" },
// Echo with conversion (For testing only) // Echo with conversion (For testing only)
{ "echojson", 0, "arg0" }, { "echojson", 0, "arg0" },
{ "echojson", 1, "arg1" }, { "echojson", 1, "arg1" },

@ -1154,9 +1154,10 @@ class Witnessifier : public boost::static_visitor<bool>
{ {
public: public:
CWallet * const pwallet; CWallet * const pwallet;
CScriptID result; CTxDestination result;
bool already_witness;
explicit Witnessifier(CWallet *_pwallet) : pwallet(_pwallet) {} explicit Witnessifier(CWallet *_pwallet) : pwallet(_pwallet), already_witness(false) {}
bool operator()(const CKeyID &keyID) { bool operator()(const CKeyID &keyID) {
if (pwallet) { if (pwallet) {
@ -1170,9 +1171,7 @@ public:
!VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) { !VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) {
return false; return false;
} }
pwallet->AddCScript(witscript); return ExtractDestination(witscript, result);
result = CScriptID(witscript);
return true;
} }
return false; return false;
} }
@ -1183,7 +1182,8 @@ public:
int witnessversion; int witnessversion;
std::vector<unsigned char> witprog; std::vector<unsigned char> witprog;
if (subscript.IsWitnessProgram(witnessversion, witprog)) { if (subscript.IsWitnessProgram(witnessversion, witprog)) {
result = scriptID; ExtractDestination(subscript, result);
already_witness = true;
return true; return true;
} }
CScript witscript = GetScriptForWitness(subscript); CScript witscript = GetScriptForWitness(subscript);
@ -1195,13 +1195,25 @@ public:
!VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) { !VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) {
return false; return false;
} }
pwallet->AddCScript(witscript); return ExtractDestination(witscript, result);
result = CScriptID(witscript);
return true;
} }
return false; return false;
} }
bool operator()(const WitnessV0KeyHash& id)
{
already_witness = true;
result = id;
return true;
}
bool operator()(const WitnessV0ScriptHash& id)
{
already_witness = true;
result = id;
return true;
}
template<typename T> template<typename T>
bool operator()(const T& dest) { return false; } bool operator()(const T& dest) { return false; }
}; };
@ -1213,17 +1225,18 @@ UniValue addwitnessaddress(const JSONRPCRequest& request)
return NullUniValue; return NullUniValue;
} }
if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
{ {
std::string msg = "addwitnessaddress \"address\"\n" std::string msg = "addwitnessaddress \"address\" ( p2sh )\n"
"\nAdd a witness address for a script (with pubkey or redeemscript known).\n" "\nAdd a witness address for a script (with pubkey or redeemscript known).\n"
"It returns the witness script.\n" "It returns the witness script.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"address\" (string, required) An address known to the wallet\n" "1. \"address\" (string, required) An address known to the wallet\n"
"2. p2sh (bool, optional, default=true) Embed inside P2SH\n"
"\nResult:\n" "\nResult:\n"
"\"witnessaddress\", (string) The value of the new address (P2SH of witness script).\n" "\"witnessaddress\", (string) The value of the new address (P2SH or BIP173).\n"
"}\n" "}\n"
; ;
throw std::runtime_error(msg); throw std::runtime_error(msg);
@ -1241,13 +1254,31 @@ UniValue addwitnessaddress(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
} }
bool p2sh = true;
if (!request.params[1].isNull()) {
p2sh = request.params[1].get_bool();
}
Witnessifier w(pwallet); Witnessifier w(pwallet);
bool ret = boost::apply_visitor(w, dest); bool ret = boost::apply_visitor(w, dest);
if (!ret) { if (!ret) {
throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed"); throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed");
} }
pwallet->SetAddressBook(w.result, "", "receive"); CScript witprogram = GetScriptForDestination(w.result);
if (p2sh) {
w.result = CScriptID(witprogram);
}
if (w.already_witness) {
if (!(dest == w.result)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot convert between witness address types");
}
} else {
pwallet->AddCScript(witprogram);
pwallet->SetAddressBook(w.result, "", "receive");
}
return EncodeDestination(w.result); return EncodeDestination(w.result);
} }
@ -3200,7 +3231,7 @@ static const CRPCCommand commands[] =
{ "wallet", "abandontransaction", &abandontransaction, {"txid"} }, { "wallet", "abandontransaction", &abandontransaction, {"txid"} },
{ "wallet", "abortrescan", &abortrescan, {} }, { "wallet", "abortrescan", &abortrescan, {} },
{ "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","account"} }, { "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","account"} },
{ "wallet", "addwitnessaddress", &addwitnessaddress, {"address"} }, { "wallet", "addwitnessaddress", &addwitnessaddress, {"address","p2sh"} },
{ "wallet", "backupwallet", &backupwallet, {"destination"} }, { "wallet", "backupwallet", &backupwallet, {"destination"} },
{ "wallet", "bumpfee", &bumpfee, {"txid", "options"} }, { "wallet", "bumpfee", &bumpfee, {"txid", "options"} },
{ "wallet", "dumpprivkey", &dumpprivkey, {"address"} }, { "wallet", "dumpprivkey", &dumpprivkey, {"address"} },

Loading…
Cancel
Save