1 // Copyright (c) 2009-2010 Satoshi Nakamoto 2 // Copyright (c) 2009-2020 The Bitcoin Core developers 3 // Distributed under the MIT software license, see the accompanying 4 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 6 #include <outputtype.h> 7 8 #include <pubkey.h> 9 #include <script/script.h> 10 #include <script/sign.h> 11 #include <script/signingprovider.h> 12 #include <script/standard.h> 13 #include <util/vector.h> 14 15 #include <assert.h> 16 #include <string> 17 18 static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy"; 19 static const std::string OUTPUT_TYPE_STRING_P2SH_SEGWIT = "p2sh-segwit"; 20 static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32"; 21 static const std::string OUTPUT_TYPE_STRING_BECH32M = "bech32m"; 22 23 bool ParseOutputType(const std::string& type, OutputType& output_type) 24 { 25 if (type == OUTPUT_TYPE_STRING_LEGACY) { 26 output_type = OutputType::LEGACY; 27 return true; 28 } else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) { 29 output_type = OutputType::P2SH_SEGWIT; 30 return true; 31 } else if (type == OUTPUT_TYPE_STRING_BECH32) { 32 output_type = OutputType::BECH32; 33 return true; 34 } else if (type == OUTPUT_TYPE_STRING_BECH32M) { 35 output_type = OutputType::BECH32M; 36 return true; 37 } 38 return false; 39 } 40 41 const std::string& FormatOutputType(OutputType type) 42 { 43 switch (type) { 44 case OutputType::LEGACY: return OUTPUT_TYPE_STRING_LEGACY; 45 case OutputType::P2SH_SEGWIT: return OUTPUT_TYPE_STRING_P2SH_SEGWIT; 46 case OutputType::BECH32: return OUTPUT_TYPE_STRING_BECH32; 47 case OutputType::BECH32M: return OUTPUT_TYPE_STRING_BECH32M; 48 } // no default case, so the compiler can warn about missing cases 49 assert(false); 50 } 51 52 CTxDestination GetDestinationForKey(const CPubKey& key, OutputType type) 53 { 54 switch (type) { 55 case OutputType::LEGACY: return PKHash(key); 56 case OutputType::P2SH_SEGWIT: 57 case OutputType::BECH32: { 58 if (!key.IsCompressed()) return PKHash(key); 59 CTxDestination witdest = WitnessV0KeyHash(key); 60 CScript witprog = GetScriptForDestination(witdest); 61 if (type == OutputType::P2SH_SEGWIT) { 62 return ScriptHash(witprog); 63 } else { 64 return witdest; 65 } 66 } 67 case OutputType::BECH32M: {} // This function should never be used with BECH32M, so let it assert 68 } // no default case, so the compiler can warn about missing cases 69 assert(false); 70 } 71 72 std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key) 73 { 74 PKHash keyid(key); 75 CTxDestination p2pkh{keyid}; 76 if (key.IsCompressed()) { 77 CTxDestination segwit = WitnessV0KeyHash(keyid); 78 CTxDestination p2sh = ScriptHash(GetScriptForDestination(segwit)); 79 return Vector(std::move(p2pkh), std::move(p2sh), std::move(segwit)); 80 } else { 81 return Vector(std::move(p2pkh)); 82 } 83 } 84 85 CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore, const CScript& script, OutputType type) 86 { 87 // Add script to keystore 88 keystore.AddCScript(script); 89 // Note that scripts over 520 bytes are not yet supported. 90 switch (type) { 91 case OutputType::LEGACY: 92 return ScriptHash(script); 93 case OutputType::P2SH_SEGWIT: 94 case OutputType::BECH32: { 95 CTxDestination witdest = WitnessV0ScriptHash(script); 96 CScript witprog = GetScriptForDestination(witdest); 97 // Check if the resulting program is solvable (i.e. doesn't use an uncompressed key) 98 if (!IsSolvable(keystore, witprog)) return ScriptHash(script); 99 // Add the redeemscript, so that P2WSH and P2SH-P2WSH outputs are recognized as ours. 100 keystore.AddCScript(witprog); 101 if (type == OutputType::BECH32) { 102 return witdest; 103 } else { 104 return ScriptHash(witprog); 105 } 106 } 107 case OutputType::BECH32M: {} // This function should not be used for BECH32M, so let it assert 108 } // no default case, so the compiler can warn about missing cases 109 assert(false); 110 } 111 112 std::optional<OutputType> OutputTypeFromDestination(const CTxDestination& dest) { 113 if (std::holds_alternative<PKHash>(dest) || 114 std::holds_alternative<ScriptHash>(dest)) { 115 return OutputType::LEGACY; 116 } 117 if (std::holds_alternative<WitnessV0KeyHash>(dest) || 118 std::holds_alternative<WitnessV0ScriptHash>(dest)) { 119 return OutputType::BECH32; 120 } 121 if (std::holds_alternative<WitnessV1Taproot>(dest) || 122 std::holds_alternative<WitnessUnknown>(dest)) { 123 return OutputType::BECH32M; 124 } 125 return std::nullopt; 126 } 127