From 4f933b3d23010d3b03998460290faed97cd6f236 Mon Sep 17 00:00:00 2001 From: fivepiece Date: Thu, 1 Feb 2018 02:40:47 +0200 Subject: p2wpkh, p2wsh and p2sh-nested scripts in decodescript plus tests --- src/rpc/rawtransaction.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/rpc/rawtransaction.cpp') diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 803cd28649..b99906edf4 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -563,6 +563,38 @@ UniValue decodescript(const JSONRPCRequest& request) // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH, // don't return the address for a P2SH of the P2SH. r.pushKV("p2sh", EncodeDestination(CScriptID(script))); + // P2SH and witness programs cannot be wrapped in P2WSH, if this script + // is a witness program, don't return addresses for a segwit programs. + if (type.get_str().find("witness") == std::string::npos) { + txnouttype which_type; + std::vector> solutions_data; + Solver(script, which_type, solutions_data); + // Uncompressed pubkeys cannot be used with segwit checksigs. + // If the script contains an uncompressed pubkey, skip encoding of a segwit program. + if ((which_type == TX_PUBKEY) || (which_type == TX_MULTISIG)) { + for (const auto& solution : solutions_data) { + if ((solution.size() != 1) && !CPubKey(solution).IsCompressed()) { + return r; + } + } + } + UniValue sr(UniValue::VOBJ); + CScript segwitScr; + if (which_type == TX_PUBKEY) { + segwitScr = GetScriptForDestination(WitnessV0KeyHash(Hash160(solutions_data[0].begin(), solutions_data[0].end()))); + } else if (which_type == TX_PUBKEYHASH) { + segwitScr = GetScriptForDestination(WitnessV0KeyHash(solutions_data[0])); + } else { + // Scripts that are not fit for P2WPKH are encoded as P2WSH. + // Newer segwit program versions should be considered when then become available. + uint256 scriptHash; + CSHA256().Write(script.data(), script.size()).Finalize(scriptHash.begin()); + segwitScr = GetScriptForDestination(WitnessV0ScriptHash(scriptHash)); + } + ScriptPubKeyToUniv(segwitScr, sr, true); + sr.pushKV("p2sh-segwit", EncodeDestination(CScriptID(segwitScr))); + r.pushKV("segwit", sr); + } } return r; -- cgit v1.2.3 From 41ff9675a92f6c080a4bb171e286060ef864a803 Mon Sep 17 00:00:00 2001 From: fivepiece Date: Sun, 8 Apr 2018 00:03:04 +0300 Subject: list the types of scripts we should consider for a witness program --- src/rpc/rawtransaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpc/rawtransaction.cpp') diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index b99906edf4..4897a2d972 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -565,7 +565,7 @@ UniValue decodescript(const JSONRPCRequest& request) r.pushKV("p2sh", EncodeDestination(CScriptID(script))); // P2SH and witness programs cannot be wrapped in P2WSH, if this script // is a witness program, don't return addresses for a segwit programs. - if (type.get_str().find("witness") == std::string::npos) { + if (type.get_str() == "pubkey" || type.get_str() == "pubkeyhash" || type.get_str() == "multisig" || type.get_str() == "nonstandard") { txnouttype which_type; std::vector> solutions_data; Solver(script, which_type, solutions_data); -- cgit v1.2.3