PageRenderTime 58ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/outputtype.cpp

https://github.com/denis2342/bitcoin
C++ | 123 lines | 105 code | 10 blank | 8 comment | 27 complexity | cf83c858ed279a770e6f4d9c5ce00fc9 MD5 | raw file
  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. #include <outputtype.h>
  6. #include <pubkey.h>
  7. #include <script/script.h>
  8. #include <script/sign.h>
  9. #include <script/signingprovider.h>
  10. #include <script/standard.h>
  11. #include <util/vector.h>
  12. #include <assert.h>
  13. #include <optional>
  14. #include <string>
  15. static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy";
  16. static const std::string OUTPUT_TYPE_STRING_P2SH_SEGWIT = "p2sh-segwit";
  17. static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32";
  18. static const std::string OUTPUT_TYPE_STRING_BECH32M = "bech32m";
  19. std::optional<OutputType> ParseOutputType(const std::string& type)
  20. {
  21. if (type == OUTPUT_TYPE_STRING_LEGACY) {
  22. return OutputType::LEGACY;
  23. } else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) {
  24. return OutputType::P2SH_SEGWIT;
  25. } else if (type == OUTPUT_TYPE_STRING_BECH32) {
  26. return OutputType::BECH32;
  27. } else if (type == OUTPUT_TYPE_STRING_BECH32M) {
  28. return OutputType::BECH32M;
  29. }
  30. return std::nullopt;
  31. }
  32. const std::string& FormatOutputType(OutputType type)
  33. {
  34. switch (type) {
  35. case OutputType::LEGACY: return OUTPUT_TYPE_STRING_LEGACY;
  36. case OutputType::P2SH_SEGWIT: return OUTPUT_TYPE_STRING_P2SH_SEGWIT;
  37. case OutputType::BECH32: return OUTPUT_TYPE_STRING_BECH32;
  38. case OutputType::BECH32M: return OUTPUT_TYPE_STRING_BECH32M;
  39. } // no default case, so the compiler can warn about missing cases
  40. assert(false);
  41. }
  42. CTxDestination GetDestinationForKey(const CPubKey& key, OutputType type)
  43. {
  44. switch (type) {
  45. case OutputType::LEGACY: return PKHash(key);
  46. case OutputType::P2SH_SEGWIT:
  47. case OutputType::BECH32: {
  48. if (!key.IsCompressed()) return PKHash(key);
  49. CTxDestination witdest = WitnessV0KeyHash(key);
  50. CScript witprog = GetScriptForDestination(witdest);
  51. if (type == OutputType::P2SH_SEGWIT) {
  52. return ScriptHash(witprog);
  53. } else {
  54. return witdest;
  55. }
  56. }
  57. case OutputType::BECH32M: {} // This function should never be used with BECH32M, so let it assert
  58. } // no default case, so the compiler can warn about missing cases
  59. assert(false);
  60. }
  61. std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key)
  62. {
  63. PKHash keyid(key);
  64. CTxDestination p2pkh{keyid};
  65. if (key.IsCompressed()) {
  66. CTxDestination segwit = WitnessV0KeyHash(keyid);
  67. CTxDestination p2sh = ScriptHash(GetScriptForDestination(segwit));
  68. return Vector(std::move(p2pkh), std::move(p2sh), std::move(segwit));
  69. } else {
  70. return Vector(std::move(p2pkh));
  71. }
  72. }
  73. CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore, const CScript& script, OutputType type)
  74. {
  75. // Add script to keystore
  76. keystore.AddCScript(script);
  77. // Note that scripts over 520 bytes are not yet supported.
  78. switch (type) {
  79. case OutputType::LEGACY:
  80. return ScriptHash(script);
  81. case OutputType::P2SH_SEGWIT:
  82. case OutputType::BECH32: {
  83. CTxDestination witdest = WitnessV0ScriptHash(script);
  84. CScript witprog = GetScriptForDestination(witdest);
  85. // Check if the resulting program is solvable (i.e. doesn't use an uncompressed key)
  86. if (!IsSolvable(keystore, witprog)) return ScriptHash(script);
  87. // Add the redeemscript, so that P2WSH and P2SH-P2WSH outputs are recognized as ours.
  88. keystore.AddCScript(witprog);
  89. if (type == OutputType::BECH32) {
  90. return witdest;
  91. } else {
  92. return ScriptHash(witprog);
  93. }
  94. }
  95. case OutputType::BECH32M: {} // This function should not be used for BECH32M, so let it assert
  96. } // no default case, so the compiler can warn about missing cases
  97. assert(false);
  98. }
  99. std::optional<OutputType> OutputTypeFromDestination(const CTxDestination& dest) {
  100. if (std::holds_alternative<PKHash>(dest) ||
  101. std::holds_alternative<ScriptHash>(dest)) {
  102. return OutputType::LEGACY;
  103. }
  104. if (std::holds_alternative<WitnessV0KeyHash>(dest) ||
  105. std::holds_alternative<WitnessV0ScriptHash>(dest)) {
  106. return OutputType::BECH32;
  107. }
  108. if (std::holds_alternative<WitnessV1Taproot>(dest) ||
  109. std::holds_alternative<WitnessUnknown>(dest)) {
  110. return OutputType::BECH32M;
  111. }
  112. return std::nullopt;
  113. }