Bitcoin Core  0.19.99
P2P Digital Currency
outputtype.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2019 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 
23 
24 bool ParseOutputType(const std::string& type, OutputType& output_type)
25 {
26  if (type == OUTPUT_TYPE_STRING_LEGACY) {
27  output_type = OutputType::LEGACY;
28  return true;
29  } else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) {
30  output_type = OutputType::P2SH_SEGWIT;
31  return true;
32  } else if (type == OUTPUT_TYPE_STRING_BECH32) {
33  output_type = OutputType::BECH32;
34  return true;
35  }
36  return false;
37 }
38 
39 const std::string& FormatOutputType(OutputType type)
40 {
41  switch (type) {
45  default: assert(false);
46  }
47 }
48 
50 {
51  switch (type) {
52  case OutputType::LEGACY: return PKHash(key);
54  case OutputType::BECH32: {
55  if (!key.IsCompressed()) return PKHash(key);
56  CTxDestination witdest = WitnessV0KeyHash(PKHash(key));
57  CScript witprog = GetScriptForDestination(witdest);
58  if (type == OutputType::P2SH_SEGWIT) {
59  return ScriptHash(witprog);
60  } else {
61  return witdest;
62  }
63  }
64  default: assert(false);
65  }
66 }
67 
68 std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key)
69 {
70  PKHash keyid(key);
71  CTxDestination p2pkh{keyid};
72  if (key.IsCompressed()) {
73  CTxDestination segwit = WitnessV0KeyHash(keyid);
75  return Vector(std::move(p2pkh), std::move(p2sh), std::move(segwit));
76  } else {
77  return Vector(std::move(p2pkh));
78  }
79 }
80 
82 {
83  // Add script to keystore
84  keystore.AddCScript(script);
85  ScriptHash sh(script);
86  // Note that scripts over 520 bytes are not yet supported.
87  switch (type) {
88  case OutputType::LEGACY:
89  keystore.AddCScript(GetScriptForDestination(sh));
90  return sh;
92  case OutputType::BECH32: {
93  CTxDestination witdest = WitnessV0ScriptHash(script);
94  CScript witprog = GetScriptForDestination(witdest);
95  // Check if the resulting program is solvable (i.e. doesn't use an uncompressed key)
96  if (!IsSolvable(keystore, witprog)) {
97  // Since the wsh is invalid, add and return the sh instead.
98  keystore.AddCScript(GetScriptForDestination(sh));
99  return sh;
100  }
101  // Add the redeemscript, so that P2WSH and P2SH-P2WSH outputs are recognized as ours.
102  keystore.AddCScript(witprog);
103  if (type == OutputType::BECH32) {
104  return witdest;
105  } else {
106  ScriptHash sh_w = ScriptHash(witprog);
107  keystore.AddCScript(GetScriptForDestination(sh_w));
108  return sh_w;
109  }
110  }
111  default: assert(false);
112  }
113 }
virtual bool AddCScript(const CScript &redeemScript)
OutputType
Definition: outputtype.h:17
const std::array< OutputType, 3 > OUTPUT_TYPES
Definition: outputtype.cpp:22
std::vector< CTxDestination > GetAllDestinationsForKey(const CPubKey &key)
Get all destinations (potentially) supported by the wallet for the given key.
Definition: outputtype.cpp:68
std::vector< typename std::common_type< Args... >::type > Vector(Args &&... args)
Construct a vector with the specified elements.
Definition: vector.h:20
static const std::string OUTPUT_TYPE_STRING_P2SH_SEGWIT
Definition: outputtype.cpp:19
An encapsulated public key.
Definition: pubkey.h:30
Fillable signing provider that keeps keys in an address->secret map.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:289
CTxDestination AddAndGetDestinationForScript(FillableSigningProvider &keystore, const CScript &script, OutputType type)
Get a destination of the requested type (if possible) to the specified script.
Definition: outputtype.cpp:81
bool IsSolvable(const SigningProvider &provider, const CScript &script)
Definition: sign.cpp:434
const std::string & FormatOutputType(OutputType type)
Definition: outputtype.cpp:39
static const std::string OUTPUT_TYPE_STRING_LEGACY
Definition: outputtype.cpp:18
static const std::string OUTPUT_TYPE_STRING_BECH32
Definition: outputtype.cpp:20
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:390
CTxDestination GetDestinationForKey(const CPubKey &key, OutputType type)
Get a destination of the requested type (if possible) to the specified key.
Definition: outputtype.cpp:49
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:143
bool ParseOutputType(const std::string &type, OutputType &output_type)
Definition: outputtype.cpp:24
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:180