Bitcoin Core  28.1.0
P2P Digital Currency
uint256.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-present 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 #ifndef BITCOIN_UINT256_H
7 #define BITCOIN_UINT256_H
8 
9 #include <crypto/common.h>
10 #include <span.h>
11 #include <util/strencodings.h>
12 
13 #include <algorithm>
14 #include <array>
15 #include <cassert>
16 #include <cstdint>
17 #include <cstring>
18 #include <optional>
19 #include <string>
20 
22 template<unsigned int BITS>
23 class base_blob
24 {
25 protected:
26  static constexpr int WIDTH = BITS / 8;
27  static_assert(BITS % 8 == 0, "base_blob currently only supports whole bytes.");
28  std::array<uint8_t, WIDTH> m_data;
29  static_assert(WIDTH == sizeof(m_data), "Sanity check");
30 
31 public:
32  /* construct 0 value by default */
33  constexpr base_blob() : m_data() {}
34 
35  /* constructor for constants between 1 and 255 */
36  constexpr explicit base_blob(uint8_t v) : m_data{v} {}
37 
38  constexpr explicit base_blob(Span<const unsigned char> vch)
39  {
40  assert(vch.size() == WIDTH);
41  std::copy(vch.begin(), vch.end(), m_data.begin());
42  }
43 
44  consteval explicit base_blob(std::string_view hex_str);
45 
46  constexpr bool IsNull() const
47  {
48  return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) {
49  return val == 0;
50  });
51  }
52 
53  constexpr void SetNull()
54  {
55  std::fill(m_data.begin(), m_data.end(), 0);
56  }
57 
62  constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); }
63 
64  friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; }
65  friend constexpr bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; }
66  friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; }
67 
81  std::string GetHex() const;
95  void SetHexDeprecated(std::string_view str);
96  std::string ToString() const;
99  constexpr const unsigned char* data() const { return m_data.data(); }
100  constexpr unsigned char* data() { return m_data.data(); }
101 
102  constexpr unsigned char* begin() { return m_data.data(); }
103  constexpr unsigned char* end() { return m_data.data() + WIDTH; }
104 
105  constexpr const unsigned char* begin() const { return m_data.data(); }
106  constexpr const unsigned char* end() const { return m_data.data() + WIDTH; }
107 
108  static constexpr unsigned int size() { return WIDTH; }
109 
110  constexpr uint64_t GetUint64(int pos) const { return ReadLE64(m_data.data() + pos * 8); }
111 
112  template<typename Stream>
113  void Serialize(Stream& s) const
114  {
115  s << Span(m_data);
116  }
117 
118  template<typename Stream>
119  void Unserialize(Stream& s)
120  {
121  s.read(MakeWritableByteSpan(m_data));
122  }
123 };
124 
125 template <unsigned int BITS>
126 consteval base_blob<BITS>::base_blob(std::string_view hex_str)
127 {
128  // Non-lookup table version of HexDigit().
129  auto from_hex = [](const char c) -> int8_t {
130  if (c >= '0' && c <= '9') return c - '0';
131  if (c >= 'a' && c <= 'f') return c - 'a' + 0xA;
132  if (c >= 'A' && c <= 'F') return c - 'A' + 0xA;
133 
134  assert(false); // Reached if ctor is called with an invalid hex digit.
135  };
136 
137  assert(hex_str.length() == m_data.size() * 2); // 2 hex digits per byte.
138  auto str_it = hex_str.rbegin();
139  for (auto& elem : m_data) {
140  auto lo = from_hex(*(str_it++));
141  elem = (from_hex(*(str_it++)) << 4) | lo;
142  }
143 }
144 
145 namespace detail {
152 template <class uintN_t>
153 std::optional<uintN_t> FromHex(std::string_view str)
154 {
155  if (uintN_t::size() * 2 != str.size() || !IsHex(str)) return std::nullopt;
156  uintN_t rv;
157  rv.SetHexDeprecated(str);
158  return rv;
159 }
160 } // namespace detail
161 
166 class uint160 : public base_blob<160> {
167 public:
168  static std::optional<uint160> FromHex(std::string_view str) { return detail::FromHex<uint160>(str); }
169  constexpr uint160() = default;
170  constexpr explicit uint160(Span<const unsigned char> vch) : base_blob<160>(vch) {}
171 };
172 
178 class uint256 : public base_blob<256> {
179 public:
180  static std::optional<uint256> FromHex(std::string_view str) { return detail::FromHex<uint256>(str); }
181  constexpr uint256() = default;
182  consteval explicit uint256(std::string_view hex_str) : base_blob<256>(hex_str) {}
183  constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {}
184  constexpr explicit uint256(Span<const unsigned char> vch) : base_blob<256>(vch) {}
185  static const uint256 ZERO;
186  static const uint256 ONE;
187 };
188 
189 /* uint256 from std::string_view, containing byte-reversed hex encoding.
190  * DEPRECATED. Unlike FromHex this accepts any invalid input, thus it is fragile and deprecated!
191  */
192 inline uint256 uint256S(std::string_view str)
193 {
194  uint256 rv;
195  rv.SetHexDeprecated(str);
196  return rv;
197 }
198 
199 #endif // BITCOIN_UINT256_H
consteval uint256(std::string_view hex_str)
Definition: uint256.h:182
static const uint256 ONE
Definition: uint256.h:186
assert(!tx.IsCoinBase())
constexpr C * end() const noexcept
Definition: span.h:176
static constexpr unsigned int size()
Definition: uint256.h:108
Span< std::byte > MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:282
bool IsHex(std::string_view str)
constexpr std::size_t size() const noexcept
Definition: span.h:187
void Serialize(Stream &s) const
Definition: uint256.h:113
constexpr uint256(uint8_t v)
Definition: uint256.h:183
static void from_hex(unsigned char *data, int len, const char *hex)
Definition: test.c:41
constexpr unsigned char * data()
Definition: uint256.h:100
friend constexpr bool operator<(const base_blob &a, const base_blob &b)
Definition: uint256.h:66
constexpr uint160(Span< const unsigned char > vch)
Definition: uint256.h:170
std::array< uint8_t, WIDTH > m_data
Definition: uint256.h:27
constexpr unsigned char * begin()
Definition: uint256.h:102
friend constexpr bool operator==(const base_blob &a, const base_blob &b)
Definition: uint256.h:64
void SetHexDeprecated(std::string_view str)
Unlike FromHex this accepts any invalid input, thus it is fragile and deprecated! ...
Definition: uint256.cpp:21
void Unserialize(Stream &s)
Definition: uint256.h:119
friend constexpr bool operator!=(const base_blob &a, const base_blob &b)
Definition: uint256.h:65
constexpr base_blob()
Definition: uint256.h:33
std::optional< uintN_t > FromHex(std::string_view str)
Writes the hex string (in reverse byte order) into a new uintN_t object and only returns a value iff ...
Definition: uint256.h:153
static std::optional< uint256 > FromHex(std::string_view str)
Definition: uint256.h:180
static const uint256 ZERO
Definition: uint256.h:185
constexpr uint160()=default
std::string ToString() const
Definition: uint256.cpp:47
constexpr bool IsNull() const
Definition: uint256.h:46
static uint64_t ReadLE64(const unsigned char *ptr)
Definition: common.h:27
constexpr int Compare(const base_blob &other) const
Lexicographic ordering.
Definition: uint256.h:62
constexpr C * begin() const noexcept
Definition: span.h:175
Template base class for fixed-sized opaque blobs.
Definition: uint256.h:23
256-bit opaque blob.
Definition: uint256.h:178
constexpr const unsigned char * data() const
Definition: uint256.h:99
constexpr void SetNull()
Definition: uint256.h:53
static std::optional< uint160 > FromHex(std::string_view str)
Definition: uint256.h:168
static constexpr int WIDTH
Definition: uint256.h:26
constexpr unsigned char * end()
Definition: uint256.h:103
constexpr uint64_t GetUint64(int pos) const
Definition: uint256.h:110
std::string GetHex() const
Definition: uint256.cpp:11
160-bit opaque blob.
Definition: uint256.h:166
uint256 uint256S(std::string_view str)
Definition: uint256.h:192
constexpr const unsigned char * begin() const
Definition: uint256.h:105
constexpr const unsigned char * end() const
Definition: uint256.h:106
constexpr base_blob(Span< const unsigned char > vch)
Definition: uint256.h:38
Span(T *, EndOrSize) -> Span< T >
constexpr uint256(Span< const unsigned char > vch)
Definition: uint256.h:184
constexpr uint256()=default
constexpr base_blob(uint8_t v)
Definition: uint256.h:36