outputtype.cpp raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-present 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  
  13  #include <cassert>
  14  #include <optional>
  15  #include <string>
  16  
  17  static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy";
  18  static const std::string OUTPUT_TYPE_STRING_P2SH_SEGWIT = "p2sh-segwit";
  19  static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32";
  20  static const std::string OUTPUT_TYPE_STRING_BECH32M = "bech32m";
  21  static const std::string OUTPUT_TYPE_STRING_UNKNOWN = "unknown";
  22  
  23  std::optional<OutputType> ParseOutputType(std::string_view type)
  24  {
  25      if (type == OUTPUT_TYPE_STRING_LEGACY) {
  26          return OutputType::LEGACY;
  27      } else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) {
  28          return OutputType::P2SH_SEGWIT;
  29      } else if (type == OUTPUT_TYPE_STRING_BECH32) {
  30          return OutputType::BECH32;
  31      } else if (type == OUTPUT_TYPE_STRING_BECH32M) {
  32          return OutputType::BECH32M;
  33      }
  34      return std::nullopt;
  35  }
  36  
  37  const std::string& FormatOutputType(OutputType type)
  38  {
  39      switch (type) {
  40      case OutputType::LEGACY: return OUTPUT_TYPE_STRING_LEGACY;
  41      case OutputType::P2SH_SEGWIT: return OUTPUT_TYPE_STRING_P2SH_SEGWIT;
  42      case OutputType::BECH32: return OUTPUT_TYPE_STRING_BECH32;
  43      case OutputType::BECH32M: return OUTPUT_TYPE_STRING_BECH32M;
  44      case OutputType::UNKNOWN: return OUTPUT_TYPE_STRING_UNKNOWN;
  45      } // no default case, so the compiler can warn about missing cases
  46      assert(false);
  47  }
  48  
  49  std::string FormatAllOutputTypes()
  50  {
  51      return util::Join(OUTPUT_TYPES, ", ", [](const auto& i) { return "\"" + FormatOutputType(i) + "\""; });
  52  }
  53  
  54  CTxDestination AddAndGetDestinationForScript(FlatSigningProvider& keystore, const CScript& script, OutputType type)
  55  {
  56      // Add script to keystore
  57      keystore.scripts.emplace(CScriptID(script), script);
  58  
  59      switch (type) {
  60      case OutputType::LEGACY:
  61          return ScriptHash(script);
  62      case OutputType::P2SH_SEGWIT:
  63      case OutputType::BECH32: {
  64          CTxDestination witdest = WitnessV0ScriptHash(script);
  65          CScript witprog = GetScriptForDestination(witdest);
  66          // Add the redeemscript, so that P2WSH and P2SH-P2WSH outputs are recognized as ours.
  67          keystore.scripts.emplace(CScriptID(witprog), witprog);
  68          if (type == OutputType::BECH32) {
  69              return witdest;
  70          } else {
  71              return ScriptHash(witprog);
  72          }
  73      }
  74      case OutputType::BECH32M:
  75      case OutputType::UNKNOWN: {} // This function should not be used for BECH32M or UNKNOWN, so let it assert
  76      } // no default case, so the compiler can warn about missing cases
  77      assert(false);
  78  }
  79  
  80  std::optional<OutputType> OutputTypeFromDestination(const CTxDestination& dest) {
  81      if (std::holds_alternative<PKHash>(dest) ||
  82          std::holds_alternative<ScriptHash>(dest)) {
  83          return OutputType::LEGACY;
  84      }
  85      if (std::holds_alternative<WitnessV0KeyHash>(dest) ||
  86          std::holds_alternative<WitnessV0ScriptHash>(dest)) {
  87          return OutputType::BECH32;
  88      }
  89      if (std::holds_alternative<WitnessV1Taproot>(dest) ||
  90          std::holds_alternative<WitnessUnknown>(dest)) {
  91          return OutputType::BECH32M;
  92      }
  93      return std::nullopt;
  94  }
  95