git / moonbite-core / src/outputtype.cpp · raw

// Copyright (c) 2009-2010 Satoshi Nakamoto// Copyright (c) 2009-2020 The Bitcoin Core developers// Distributed under the MIT software license, see the accompanying// file COPYING or http://www.opensource.org/licenses/mit-license.php.#include <outputtype.h>#include <pubkey.h>#include <script/script.h>#include <script/sign.h>#include <script/signingprovider.h>#include <script/standard.h>#include <util/vector.h>#include <assert.h>#include <string>static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy";static const std::string OUTPUT_TYPE_STRING_P2SH_SEGWIT = "p2sh-segwit";static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32";static const std::string OUTPUT_TYPE_STRING_MWEB = "mweb";const std::array<OutputType, 4> OUTPUT_TYPES = {OutputType::LEGACY, OutputType::P2SH_SEGWIT, OutputType::BECH32, OutputType::MWEB};bool ParseOutputType(const std::string& type, OutputType& output_type){    if (type == OUTPUT_TYPE_STRING_LEGACY) {        output_type = OutputType::LEGACY;        return true;    } else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) {        output_type = OutputType::P2SH_SEGWIT;        return true;    } else if (type == OUTPUT_TYPE_STRING_BECH32) {        output_type = OutputType::BECH32;        return true;    } else if (type == OUTPUT_TYPE_STRING_MWEB) {        output_type = OutputType::MWEB;        return true;    }    return false;}const std::string& FormatOutputType(OutputType type){    switch (type) {    case OutputType::LEGACY: return OUTPUT_TYPE_STRING_LEGACY;    case OutputType::P2SH_SEGWIT: return OUTPUT_TYPE_STRING_P2SH_SEGWIT;    case OutputType::BECH32: return OUTPUT_TYPE_STRING_BECH32;    case OutputType::MWEB: return OUTPUT_TYPE_STRING_MWEB;    } // no default case, so the compiler can warn about missing cases    assert(false);}CTxDestination GetDestinationForKey(const CPubKey& key, OutputType type, const SecretKey& scan_secret){    assert(type != OutputType::MWEB || !scan_secret.IsNull());    switch (type) {    case OutputType::LEGACY: return PKHash(key);    case OutputType::P2SH_SEGWIT:    case OutputType::BECH32: {        if (!key.IsCompressed()) return PKHash(key);        CTxDestination witdest = WitnessV0KeyHash(key);        CScript witprog = GetScriptForDestination(witdest);        if (type == OutputType::P2SH_SEGWIT) {            return ScriptHash(witprog);        } else {            return witdest;        }    }    case OutputType::MWEB: {        PublicKey spend_pubkey(key.data());        return StealthAddress(spend_pubkey.Mul(scan_secret), spend_pubkey);    }    } // no default case, so the compiler can warn about missing cases    assert(false);}std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key, const SecretKey& scan_secret){    PKHash keyid(key);    CTxDestination p2pkh{keyid};    if (key.IsCompressed()) {        CTxDestination segwit = WitnessV0KeyHash(keyid);        CTxDestination p2sh = ScriptHash(GetScriptForDestination(segwit));        if (!scan_secret.IsNull()) {            CTxDestination stealth = GetDestinationForKey(key, OutputType::MWEB, scan_secret);            return Vector(std::move(p2pkh), std::move(p2sh), std::move(segwit), std::move(stealth));        } else {            return Vector(std::move(p2pkh), std::move(p2sh), std::move(segwit));        }    } else {        return Vector(std::move(p2pkh));    }}CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore, const CScript& script, OutputType type){    // Add script to keystore    keystore.AddCScript(script);    // Note that scripts over 520 bytes are not yet supported.    switch (type) {    case OutputType::LEGACY:        return ScriptHash(script);    case OutputType::P2SH_SEGWIT:    case OutputType::BECH32: {        CTxDestination witdest = WitnessV0ScriptHash(script);        CScript witprog = GetScriptForDestination(witdest);        // Check if the resulting program is solvable (i.e. doesn't use an uncompressed key)        if (!IsSolvable(keystore, witprog)) return ScriptHash(script);        // Add the redeemscript, so that P2WSH and P2SH-P2WSH outputs are recognized as ours.        keystore.AddCScript(witprog);        if (type == OutputType::BECH32) {            return witdest;        } else {            return ScriptHash(witprog);        }    }    case OutputType::MWEB:        assert(false);    } // no default case, so the compiler can warn about missing cases    assert(false);}