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