1
// Copyright © 2017-2020 Trust Wallet.
2
//
3
// This file is part of Trust. The full Trust copyright notice, including
4
// terms governing use, modification, and redistribution, is contained in the
5
// file LICENSE at the root of the source code distribution tree.
6

7
#pragma once
8

9
#include "Base58.h"
10
#include "Data.h"
11
#include "PublicKey.h"
12

13
#include <array>
14
#include <string>
15

16
namespace TW {
17

18
template <std::size_t S>
19
class Base58Address {
20
  public:
21
    /// Number of bytes in an address.
22
    static const size_t size = S;
23

24
    /// Address data consisting of a prefix byte followed by the public key
25
    /// hash.
26
    std::array<byte, size> bytes;
27

28
    /// Determines whether a collection of bytes makes a valid  address.
29
    template <typename T>
30 1
    static bool isValid(const T& data) {
31 1
        return data.size() == size;
32
    }
33

34
    /// Determines whether a string makes a valid address.
35 1
    static bool isValid(const std::string& string) {
36 1
        const auto decoded = Base58::bitcoin.decodeCheck(string);
37 1
        if (decoded.size() != Base58Address::size) {
38 1
            return false;
39
        }
40 1
        return true;
41
    }
42

43
    /// Determines whether a string makes a valid address, and the prefix is
44
    /// within the valid set.
45 1
    static bool isValid(const std::string& string, const std::vector<Data>& validPrefixes) {
46 1
        const auto decoded = Base58::bitcoin.decodeCheck(string);
47 1
        if (decoded.size() != Base58Address::size) {
48 1
            return false;
49
        }
50 1
        for (const auto& prefix : validPrefixes) {
51 1
            if (has_prefix(decoded, prefix)) {
52 1
                return true;
53
            }
54
        }
55 1
        return false;
56
    }
57

58
    Base58Address() = default;
59

60
    /// Initializes an address with a string representation.
61 1
    explicit Base58Address(const std::string& string) {
62 1
        const auto decoded = Base58::bitcoin.decodeCheck(string);
63 1
        if (decoded.size() != Base58Address::size) {
64 1
            throw std::invalid_argument("Invalid address string");
65
        }
66

67 1
        std::copy(decoded.begin(), decoded.end(), bytes.begin());
68
    }
69

70
    /// Initializes an address with a collection of bytes.
71 1
    explicit Base58Address(const Data& data) {
72 1
        if (!isValid(data)) {
73 1
            throw std::invalid_argument("Invalid address key data");
74
        }
75 1
        std::copy(data.begin(), data.end(), bytes.begin());
76
    }
77

78
    /// Initializes an address with a public key and a prefix.
79 1
    Base58Address(const PublicKey& publicKey, const Data& prefix) {
80 1
        if (publicKey.type != TWPublicKeyTypeSECP256k1) {
81 1
            throw std::invalid_argument("Bitcoin::Address needs a compressed SECP256k1 public key.");
82
        }
83 1
        const auto data = publicKey.hash(prefix, Hash::sha256ripemd);
84 1
        std::copy(data.begin(), data.end(), bytes.begin());
85
    }
86

87
    /// Returns a string representation of the address.
88 1
    std::string string() const {
89 1
        return Base58::bitcoin.encodeCheck(bytes);
90
    }
91
};
92

93
template <std::size_t S>
94 1
inline bool operator==(const Base58Address<S>& lhs, const Base58Address<S>& rhs) {
95 1
    return lhs.bytes == rhs.bytes;
96
}
97

98
} // namespace TW

Read our documentation on viewing source code .

Loading