Branch data Line data Source code
# 1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto # 2 : : // Copyright (c) 2009-2021 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 <optional> # 17 : : #include <string> # 18 : : # 19 : : static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy"; # 20 : : static const std::string OUTPUT_TYPE_STRING_P2SH_SEGWIT = "p2sh-segwit"; # 21 : : static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32"; # 22 : : static const std::string OUTPUT_TYPE_STRING_BECH32M = "bech32m"; # 23 : : # 24 : : std::optional<OutputType> ParseOutputType(const std::string& type) # 25 : 2555 : { # 26 [ + + ]: 2555 : if (type == OUTPUT_TYPE_STRING_LEGACY) { # 27 : 462 : return OutputType::LEGACY; # 28 [ + + ]: 2093 : } else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) { # 29 : 455 : return OutputType::P2SH_SEGWIT; # 30 [ + + ]: 1638 : } else if (type == OUTPUT_TYPE_STRING_BECH32) { # 31 : 1430 : return OutputType::BECH32; # 32 [ + + ]: 1430 : } else if (type == OUTPUT_TYPE_STRING_BECH32M) { # 33 : 198 : return OutputType::BECH32M; # 34 : 198 : } # 35 : 10 : return std::nullopt; # 36 : 2555 : } # 37 : : # 38 : : const std::string& FormatOutputType(OutputType type) # 39 : 1674 : { # 40 [ - + ]: 1674 : switch (type) { # 41 [ - + ]: 0 : case OutputType::LEGACY: return OUTPUT_TYPE_STRING_LEGACY; # 42 [ - + ]: 0 : case OutputType::P2SH_SEGWIT: return OUTPUT_TYPE_STRING_P2SH_SEGWIT; # 43 [ + - ]: 1674 : case OutputType::BECH32: return OUTPUT_TYPE_STRING_BECH32; # 44 [ - + ]: 0 : case OutputType::BECH32M: return OUTPUT_TYPE_STRING_BECH32M; # 45 : 1674 : } // no default case, so the compiler can warn about missing cases # 46 : 0 : assert(false); # 47 : 0 : } # 48 : : # 49 : : CTxDestination GetDestinationForKey(const CPubKey& key, OutputType type) # 50 : 13986 : { # 51 [ - + ]: 13986 : switch (type) { # 52 [ + + ]: 1518 : case OutputType::LEGACY: return PKHash(key); # 53 [ + + ]: 707 : case OutputType::P2SH_SEGWIT: # 54 [ + + ]: 12468 : case OutputType::BECH32: { # 55 [ - + ]: 12468 : if (!key.IsCompressed()) return PKHash(key); # 56 : 12468 : CTxDestination witdest = WitnessV0KeyHash(key); # 57 : 12468 : CScript witprog = GetScriptForDestination(witdest); # 58 [ + + ]: 12468 : if (type == OutputType::P2SH_SEGWIT) { # 59 : 707 : return ScriptHash(witprog); # 60 : 11761 : } else { # 61 : 11761 : return witdest; # 62 : 11761 : } # 63 : 12468 : } # 64 [ - + ]: 0 : case OutputType::BECH32M: {} // This function should never be used with BECH32M, so let it assert # 65 : 13986 : } // no default case, so the compiler can warn about missing cases # 66 : 0 : assert(false); # 67 : 0 : } # 68 : : # 69 : : std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key) # 70 : 1662 : { # 71 : 1662 : PKHash keyid(key); # 72 : 1662 : CTxDestination p2pkh{keyid}; # 73 [ + + ]: 1662 : if (key.IsCompressed()) { # 74 : 1657 : CTxDestination segwit = WitnessV0KeyHash(keyid); # 75 : 1657 : CTxDestination p2sh = ScriptHash(GetScriptForDestination(segwit)); # 76 : 1657 : return Vector(std::move(p2pkh), std::move(p2sh), std::move(segwit)); # 77 : 1657 : } else { # 78 : 5 : return Vector(std::move(p2pkh)); # 79 : 5 : } # 80 : 1662 : } # 81 : : # 82 : : CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore, const CScript& script, OutputType type) # 83 : 162 : { # 84 : : // Add script to keystore # 85 : 162 : keystore.AddCScript(script); # 86 : : // Note that scripts over 520 bytes are not yet supported. # 87 [ - + ]: 162 : switch (type) { # 88 [ + + ]: 89 : case OutputType::LEGACY: # 89 : 89 : return ScriptHash(script); # 90 [ + + ]: 38 : case OutputType::P2SH_SEGWIT: # 91 [ + + ]: 73 : case OutputType::BECH32: { # 92 : 73 : CTxDestination witdest = WitnessV0ScriptHash(script); # 93 : 73 : CScript witprog = GetScriptForDestination(witdest); # 94 : : // Check if the resulting program is solvable (i.e. doesn't use an uncompressed key) # 95 [ - + ]: 73 : if (!IsSolvable(keystore, witprog)) return ScriptHash(script); # 96 : : // Add the redeemscript, so that P2WSH and P2SH-P2WSH outputs are recognized as ours. # 97 : 73 : keystore.AddCScript(witprog); # 98 [ + + ]: 73 : if (type == OutputType::BECH32) { # 99 : 35 : return witdest; # 100 : 38 : } else { # 101 : 38 : return ScriptHash(witprog); # 102 : 38 : } # 103 : 73 : } # 104 [ - + ]: 0 : case OutputType::BECH32M: {} // This function should not be used for BECH32M, so let it assert # 105 : 162 : } // no default case, so the compiler can warn about missing cases # 106 : 0 : assert(false); # 107 : 0 : } # 108 : : # 109 : 225 : std::optional<OutputType> OutputTypeFromDestination(const CTxDestination& dest) { # 110 [ + + ]: 225 : if (std::holds_alternative<PKHash>(dest) || # 111 [ + + ]: 225 : std::holds_alternative<ScriptHash>(dest)) { # 112 : 140 : return OutputType::LEGACY; # 113 : 140 : } # 114 [ + + ]: 85 : if (std::holds_alternative<WitnessV0KeyHash>(dest) || # 115 [ + + ]: 85 : std::holds_alternative<WitnessV0ScriptHash>(dest)) { # 116 : 75 : return OutputType::BECH32; # 117 : 75 : } # 118 [ + + ]: 10 : if (std::holds_alternative<WitnessV1Taproot>(dest) || # 119 [ + - ]: 10 : std::holds_alternative<WitnessUnknown>(dest)) { # 120 : 10 : return OutputType::BECH32M; # 121 : 10 : } # 122 : 0 : return std::nullopt; # 123 : 10 : }