LCOV - code coverage report
Current view: top level - src - key_io.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 96 107 89.7 %
Date: 2025-02-23 09:33:43 Functions: 13 16 81.2 %

          Line data    Source code
       1             : // Copyright (c) 2014-2019 The Bitcoin Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include "key_io.h"
       6             : 
       7             : #include "base58.h"
       8             : #include "script/script.h"
       9             : #include <boost/variant/apply_visitor.hpp>
      10             : #include <boost/variant/static_visitor.hpp>
      11             : 
      12             : #include <assert.h>
      13             : #include <string.h>
      14             : #include <algorithm>
      15             : 
      16             : namespace
      17             : {
      18             :     class DestinationEncoder : public boost::static_visitor<std::string>
      19             :     {
      20             :     private:
      21             :         const CChainParams& m_params;
      22             :         const CChainParams::Base58Type m_addrType;
      23             : 
      24             :     public:
      25     1990161 :         explicit DestinationEncoder(const CChainParams& params, const CChainParams::Base58Type _addrType = CChainParams::PUBKEY_ADDRESS) : m_params(params), m_addrType(_addrType) {}
      26             : 
      27     1990068 :         std::string operator()(const CKeyID& id) const
      28             :         {
      29     1990068 :             std::vector<unsigned char> data = m_params.Base58Prefix(m_addrType);
      30     1990068 :             data.insert(data.end(), id.begin(), id.end());
      31     3980136 :             return EncodeBase58Check(data);
      32             :         }
      33             : 
      34           0 :         std::string operator()(const CExchangeKeyID& id) const
      35             :         {
      36           0 :             std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::EXCHANGE_ADDRESS);
      37           0 :             data.insert(data.end(), id.begin(), id.end());
      38           0 :             return EncodeBase58Check(data);
      39             :         }
      40             : 
      41          93 :         std::string operator()(const CScriptID& id) const
      42             :         {
      43          93 :             std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
      44          93 :             data.insert(data.end(), id.begin(), id.end());
      45         186 :             return EncodeBase58Check(data);
      46             :         }
      47             : 
      48           0 :         std::string operator()(const CNoDestination& no) const { return ""; }
      49             :     };
      50             : 
      51        9813 :     CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, bool& isStaking, bool& isExchange)
      52             :     {
      53       19626 :         std::vector<unsigned char> data;
      54        9813 :         uint160 hash;
      55        9813 :         if (DecodeBase58Check(str, data, 23)) {
      56             :             // base58-encoded PIVX addresses.
      57             :             // Public-key-hash-addresses have version 30 (or 139 testnet).
      58             :             // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
      59        8397 :             const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
      60        8397 :             if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
      61        8225 :                 std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
      62        8225 :                 return CKeyID(hash);
      63             :             }
      64             :             // Exchange Transparent addresses have version 31
      65         172 :             const std::vector<unsigned char>& exchange_pubkey_prefix = params.Base58Prefix(CChainParams::EXCHANGE_ADDRESS);
      66         172 :             if (data.size() == hash.size() + exchange_pubkey_prefix.size() && std::equal(exchange_pubkey_prefix.begin(), exchange_pubkey_prefix.end(), data.begin())) {
      67           5 :                 isExchange = true;
      68           5 :                 std::copy(data.begin() + exchange_pubkey_prefix.size(), data.end(), hash.begin());
      69           5 :                 return CExchangeKeyID(hash);
      70             :             }
      71             :             // Public-key-hash-coldstaking-addresses have version 63 (or 73 testnet).
      72         167 :             const std::vector<unsigned char>& staking_prefix = params.Base58Prefix(CChainParams::STAKING_ADDRESS);
      73         167 :             if (data.size() == hash.size() + staking_prefix.size() && std::equal(staking_prefix.begin(), staking_prefix.end(), data.begin())) {
      74          97 :                 isStaking = true;
      75          97 :                 std::copy(data.begin() + staking_prefix.size(), data.end(), hash.begin());
      76          97 :                 return CKeyID(hash);
      77             :             }
      78             :             // Script-hash-addresses have version 13 (or 19 testnet).
      79             :             // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
      80          70 :             const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
      81          70 :             if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
      82          62 :                 std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
      83          62 :                 return CScriptID(hash);
      84             :             }
      85             :         }
      86        1424 :         return CNoDestination();
      87             :     }
      88             : 
      89             : } // anon namespace
      90             : 
      91         257 : std::string EncodeDestination(const CTxDestination& dest, bool isStaking, bool isExchange)
      92             : {
      93         257 :     return isExchange ? EncodeDestination(dest, CChainParams::EXCHANGE_ADDRESS) : (isStaking ? EncodeDestination(dest, CChainParams::STAKING_ADDRESS) : EncodeDestination(dest, CChainParams::PUBKEY_ADDRESS));
      94             : }
      95             : 
      96     1990161 : std::string EncodeDestination(const CTxDestination& dest, const CChainParams::Base58Type addrType)
      97             : {
      98     1990161 :     return boost::apply_visitor(DestinationEncoder(Params(), addrType), dest);
      99             : }
     100             : 
     101        7968 : CTxDestination DecodeDestination(const std::string& str)
     102             : {
     103        7968 :     bool isStaking;
     104        7968 :     bool isExchange;
     105        7968 :     return DecodeDestination(str, Params(), isStaking, isExchange);
     106             : }
     107             : 
     108        1845 : CTxDestination DecodeDestination(const std::string& str, bool& isStaking, bool& isExchange)
     109             : {
     110        1845 :     return DecodeDestination(str, Params(), isStaking, isExchange);
     111             : }
     112             : 
     113           0 : bool IsValidDestinationString(const std::string& str, bool fStaking, const CChainParams& params)
     114             : {
     115           0 :     bool isStaking = false;
     116           0 :     bool isExchange = false;
     117           0 :     return IsValidDestination(DecodeDestination(str, params, isStaking, isExchange)) && (isStaking == fStaking);
     118             : }
     119             : 
     120           0 : bool IsValidDestinationString(const std::string& str, bool isStaking)
     121             : {
     122           0 :     return IsValidDestinationString(str, isStaking, Params());
     123             : }
     124             : 
     125             : namespace KeyIO {
     126             : 
     127        1243 :     CKey DecodeSecret(const std::string &str) {
     128        1243 :         CKey key;
     129        1243 :         std::vector<unsigned char> data;
     130        1243 :         if (DecodeBase58Check(str, data, 34)) {
     131        1205 :             const std::vector<unsigned char> &privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
     132        1205 :             if ((data.size() == 32 + privkey_prefix.size() ||
     133        1205 :                  (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
     134        1171 :                 std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
     135        1165 :                 bool compressed = data.size() == 33 + privkey_prefix.size();
     136        1165 :                 key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
     137             :             }
     138             :         }
     139        1243 :         if (!data.empty()) {
     140        1205 :             memory_cleanse(data.data(), data.size());
     141             :         }
     142        2458 :         return key;
     143             :     }
     144             : 
     145        2047 :     std::string EncodeSecret(const CKey &key) {
     146        2047 :         assert(key.IsValid());
     147        2047 :         std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
     148        4094 :         data.insert(data.end(), key.begin(), key.end());
     149        2047 :         if (key.IsCompressed()) {
     150        2035 :             data.push_back(1);
     151             :         }
     152        2047 :         std::string ret = EncodeBase58Check(data);
     153        2047 :         memory_cleanse(data.data(), data.size());
     154        4094 :         return ret;
     155             :     }
     156             : 
     157          39 :     CExtKey DecodeExtKey(const std::string &str) {
     158          39 :         CExtKey key;
     159          39 :         std::vector<unsigned char> data;
     160          39 :         if (DecodeBase58Check(str, data, 78)) {
     161          39 :             const std::vector<unsigned char> &prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
     162          39 :             if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() &&
     163          39 :                 std::equal(prefix.begin(), prefix.end(), data.begin())) {
     164          34 :                 key.Decode(data.data() + prefix.size());
     165             :             }
     166             :         }
     167          78 :         return key;
     168             :     }
     169             : 
     170          20 :     std::string EncodeExtKey(const CExtKey &key) {
     171          20 :         std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
     172          20 :         size_t size = data.size();
     173          20 :         data.resize(size + BIP32_EXTKEY_SIZE);
     174          20 :         key.Encode(data.data() + size);
     175          20 :         std::string ret = EncodeBase58Check(data);
     176          20 :         memory_cleanse(data.data(), data.size());
     177          40 :         return ret;
     178             :     }
     179             : 
     180          39 :     CExtPubKey DecodeExtPubKey(const std::string& str)
     181             :     {
     182          39 :         CExtPubKey key;
     183          39 :         std::vector<unsigned char> data;
     184          39 :         if (DecodeBase58Check(str, data, 78)) {
     185          39 :             const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
     186          39 :             if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
     187          19 :                 key.Decode(data.data() + prefix.size());
     188             :             }
     189             :         }
     190          78 :         return key;
     191             :     }
     192             : 
     193          14 :     std::string EncodeExtPubKey(const CExtPubKey& key)
     194             :     {
     195          14 :         std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
     196          14 :         size_t size = data.size();
     197          14 :         data.resize(size + BIP32_EXTKEY_SIZE);
     198          14 :         key.Encode(data.data() + size);
     199          14 :         std::string ret = EncodeBase58Check(data);
     200          28 :         return ret;
     201             :     }
     202             : 
     203             : }// namespace

Generated by: LCOV version 1.14