/tmp/bitcoin/src/uint256.h
Line | Count | Source |
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 <crypto/hex_base.h> |
11 | | #include <span.h> |
12 | | #include <util/strencodings.h> |
13 | | #include <util/string.h> |
14 | | |
15 | | #include <algorithm> |
16 | | #include <array> |
17 | | #include <cassert> |
18 | | #include <cstdint> |
19 | | #include <cstring> |
20 | | #include <optional> |
21 | | #include <string> |
22 | | #include <string_view> |
23 | | |
24 | | /** Template base class for fixed-sized opaque blobs. */ |
25 | | template<unsigned int BITS> |
26 | | class base_blob |
27 | | { |
28 | | protected: |
29 | | static constexpr int WIDTH = BITS / 8; |
30 | | static_assert(BITS % 8 == 0, "base_blob currently only supports whole bytes."); |
31 | | std::array<uint8_t, WIDTH> m_data; |
32 | | static_assert(WIDTH == sizeof(m_data), "Sanity check"); |
33 | | |
34 | | public: |
35 | | /* construct 0 value by default */ |
36 | 1.32G | constexpr base_blob() : m_data() {}base_blob<256u>::base_blob() Line | Count | Source | 36 | 1.32G | constexpr base_blob() : m_data() {} |
base_blob<160u>::base_blob() Line | Count | Source | 36 | 7.57M | constexpr base_blob() : m_data() {} |
|
37 | | |
38 | | /* constructor for constants between 1 and 255 */ |
39 | 532 | constexpr explicit base_blob(uint8_t v) : m_data{v} {} |
40 | | |
41 | | constexpr explicit base_blob(std::span<const unsigned char> vch) |
42 | 2.52M | { |
43 | 2.52M | assert(vch.size() == WIDTH); |
44 | 2.52M | std::copy(vch.begin(), vch.end(), m_data.begin()); |
45 | 2.52M | } base_blob<256u>::base_blob(std::span<unsigned char const, 18446744073709551615ul>) Line | Count | Source | 42 | 2.01M | { | 43 | 2.01M | assert(vch.size() == WIDTH); | 44 | 2.01M | std::copy(vch.begin(), vch.end(), m_data.begin()); | 45 | 2.01M | } |
base_blob<160u>::base_blob(std::span<unsigned char const, 18446744073709551615ul>) Line | Count | Source | 42 | 505k | { | 43 | 505k | assert(vch.size() == WIDTH); | 44 | 505k | std::copy(vch.begin(), vch.end(), m_data.begin()); | 45 | 505k | } |
|
46 | | |
47 | | consteval explicit base_blob(std::string_view hex_str); |
48 | | |
49 | | constexpr bool IsNull() const |
50 | 29.3M | { |
51 | 130M | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { |
52 | 130M | return val == 0; |
53 | 130M | }); base_blob<256u>::IsNull() const::'lambda'(unsigned char)::operator()(unsigned char) const Line | Count | Source | 51 | 130M | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 52 | 130M | return val == 0; | 53 | 130M | }); |
base_blob<160u>::IsNull() const::'lambda'(unsigned char)::operator()(unsigned char) const Line | Count | Source | 51 | 1.53k | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 52 | 1.53k | return val == 0; | 53 | 1.53k | }); |
|
54 | 29.3M | } base_blob<256u>::IsNull() const Line | Count | Source | 50 | 29.3M | { | 51 | 29.3M | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 52 | 29.3M | return val == 0; | 53 | 29.3M | }); | 54 | 29.3M | } |
base_blob<160u>::IsNull() const Line | Count | Source | 50 | 528 | { | 51 | 528 | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 52 | 528 | return val == 0; | 53 | 528 | }); | 54 | 528 | } |
|
55 | | |
56 | | constexpr void SetNull() |
57 | 6.79M | { |
58 | 6.79M | std::fill(m_data.begin(), m_data.end(), 0); |
59 | 6.79M | } base_blob<256u>::SetNull() Line | Count | Source | 57 | 6.79M | { | 58 | 6.79M | std::fill(m_data.begin(), m_data.end(), 0); | 59 | 6.79M | } |
base_blob<160u>::SetNull() Line | Count | Source | 57 | 1.55k | { | 58 | 1.55k | std::fill(m_data.begin(), m_data.end(), 0); | 59 | 1.55k | } |
|
60 | | |
61 | | /** Lexicographic ordering |
62 | | * @note Does NOT match the ordering on the corresponding \ref |
63 | | * base_uint::CompareTo, which starts comparing from the end. |
64 | | */ |
65 | 856M | constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); }base_blob<256u>::Compare(base_blob<256u> const&) const Line | Count | Source | 65 | 844M | constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); } |
base_blob<160u>::Compare(base_blob<160u> const&) const Line | Count | Source | 65 | 12.1M | constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); } |
|
66 | | |
67 | 29.0M | friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; }operator==(base_blob<256u> const&, base_blob<256u> const&) Line | Count | Source | 67 | 28.9M | friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } |
operator==(base_blob<160u> const&, base_blob<160u> const&) Line | Count | Source | 67 | 9.11k | friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } |
|
68 | 54.5M | friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; }operator<(base_blob<256u> const&, base_blob<256u> const&) Line | Count | Source | 68 | 42.3M | friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } |
operator<(base_blob<160u> const&, base_blob<160u> const&) Line | Count | Source | 68 | 12.1M | friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } |
|
69 | | |
70 | | /** @name Hex representation |
71 | | * |
72 | | * The hex representation used by GetHex(), ToString(), and FromHex() |
73 | | * is unusual, since it shows bytes of the base_blob in reverse order. |
74 | | * For example, a 4-byte blob {0x12, 0x34, 0x56, 0x78} is represented |
75 | | * as "78563412" instead of the more typical "12345678" representation |
76 | | * that would be shown in a hex editor or used by typical |
77 | | * byte-array / hex conversion functions like python's bytes.hex() and |
78 | | * bytes.fromhex(). |
79 | | * |
80 | | * The nice thing about the reverse-byte representation, even though it is |
81 | | * unusual, is that if a blob contains an arithmetic number in little endian |
82 | | * format (with least significant bytes first, and most significant bytes |
83 | | * last), the GetHex() output will match the way the number would normally |
84 | | * be written in base-16 (with most significant digits first and least |
85 | | * significant digits last). |
86 | | * |
87 | | * This means, for example, that ArithToUint256(num).GetHex() can be used to |
88 | | * display an arith_uint256 num value as a number, because |
89 | | * ArithToUint256() converts the number to a blob in little-endian format, |
90 | | * so the arith_uint256 class doesn't need to have its own number parsing |
91 | | * and formatting functions. |
92 | | * |
93 | | * @{*/ |
94 | | std::string GetHex() const; |
95 | | std::string ToString() const; |
96 | | /**@}*/ |
97 | | |
98 | 9.03M | constexpr const unsigned char* data() const { return m_data.data(); }base_blob<160u>::data() const Line | Count | Source | 98 | 12.1k | constexpr const unsigned char* data() const { return m_data.data(); } |
base_blob<256u>::data() const Line | Count | Source | 98 | 9.02M | constexpr const unsigned char* data() const { return m_data.data(); } |
|
99 | 11.8M | constexpr unsigned char* data() { return m_data.data(); }Line | Count | Source | 99 | 5.97M | constexpr unsigned char* data() { return m_data.data(); } |
Line | Count | Source | 99 | 5.85M | constexpr unsigned char* data() { return m_data.data(); } |
|
100 | | |
101 | 124M | constexpr unsigned char* begin() { return m_data.data(); }Line | Count | Source | 101 | 3.53M | constexpr unsigned char* begin() { return m_data.data(); } |
Line | Count | Source | 101 | 121M | constexpr unsigned char* begin() { return m_data.data(); } |
|
102 | 42.8k | constexpr unsigned char* end() { return m_data.data() + WIDTH; }Line | Count | Source | 102 | 608 | constexpr unsigned char* end() { return m_data.data() + WIDTH; } |
Line | Count | Source | 102 | 42.2k | constexpr unsigned char* end() { return m_data.data() + WIDTH; } |
|
103 | | |
104 | 322M | constexpr const unsigned char* begin() const { return m_data.data(); }base_blob<160u>::begin() const Line | Count | Source | 104 | 813k | constexpr const unsigned char* begin() const { return m_data.data(); } |
base_blob<256u>::begin() const Line | Count | Source | 104 | 321M | constexpr const unsigned char* begin() const { return m_data.data(); } |
|
105 | 2.56M | constexpr const unsigned char* end() const { return m_data.data() + WIDTH; }base_blob<160u>::end() const Line | Count | Source | 105 | 812k | constexpr const unsigned char* end() const { return m_data.data() + WIDTH; } |
base_blob<256u>::end() const Line | Count | Source | 105 | 1.74M | constexpr const unsigned char* end() const { return m_data.data() + WIDTH; } |
|
106 | | |
107 | 21.3M | static constexpr unsigned int size() { return WIDTH; }Line | Count | Source | 107 | 6.00M | static constexpr unsigned int size() { return WIDTH; } |
Line | Count | Source | 107 | 15.3M | static constexpr unsigned int size() { return WIDTH; } |
|
108 | | |
109 | 1.46G | constexpr uint64_t GetUint64(int pos) const { return ReadLE64(m_data.data() + pos * 8); } |
110 | | |
111 | | template<typename Stream> |
112 | | void Serialize(Stream& s) const |
113 | 109M | { |
114 | 109M | s << std::span(m_data); |
115 | 109M | } void base_blob<256u>::Serialize<DataStream>(DataStream&) const Line | Count | Source | 113 | 8.11M | { | 114 | 8.11M | s << std::span(m_data); | 115 | 8.11M | } |
void base_blob<256u>::Serialize<ParamsStream<SizeComputer&, TransactionSerParams>>(ParamsStream<SizeComputer&, TransactionSerParams>&) const Line | Count | Source | 113 | 4.05M | { | 114 | 4.05M | s << std::span(m_data); | 115 | 4.05M | } |
void base_blob<256u>::Serialize<ParamsStream<DataStream&, TransactionSerParams>>(ParamsStream<DataStream&, TransactionSerParams>&) const Line | Count | Source | 113 | 50.7k | { | 114 | 50.7k | s << std::span(m_data); | 115 | 50.7k | } |
void base_blob<256u>::Serialize<ParamsStream<HashWriter&, TransactionSerParams>>(ParamsStream<HashWriter&, TransactionSerParams>&) const Line | Count | Source | 113 | 1.84M | { | 114 | 1.84M | s << std::span(m_data); | 115 | 1.84M | } |
void base_blob<256u>::Serialize<HashWriter>(HashWriter&) const Line | Count | Source | 113 | 93.4M | { | 114 | 93.4M | s << std::span(m_data); | 115 | 93.4M | } |
void base_blob<256u>::Serialize<SizeComputer>(SizeComputer&) const Line | Count | Source | 113 | 80.2k | { | 114 | 80.2k | s << std::span(m_data); | 115 | 80.2k | } |
void base_blob<160u>::Serialize<SizeComputer>(SizeComputer&) const Line | Count | Source | 113 | 2 | { | 114 | 2 | s << std::span(m_data); | 115 | 2 | } |
void base_blob<160u>::Serialize<DataStream>(DataStream&) const Line | Count | Source | 113 | 3 | { | 114 | 3 | s << std::span(m_data); | 115 | 3 | } |
void base_blob<256u>::Serialize<VectorWriter>(VectorWriter&) const Line | Count | Source | 113 | 178k | { | 114 | 178k | s << std::span(m_data); | 115 | 178k | } |
void base_blob<256u>::Serialize<AutoFile>(AutoFile&) const Line | Count | Source | 113 | 16.4k | { | 114 | 16.4k | s << std::span(m_data); | 115 | 16.4k | } |
void base_blob<256u>::Serialize<ParamsStream<HashedSourceWriter<AutoFile>&, CAddress::SerParams>>(ParamsStream<HashedSourceWriter<AutoFile>&, CAddress::SerParams>&) const Line | Count | Source | 113 | 2.96k | { | 114 | 2.96k | s << std::span(m_data); | 115 | 2.96k | } |
void base_blob<256u>::Serialize<ParamsStream<DataStream&, CAddress::SerParams>>(ParamsStream<DataStream&, CAddress::SerParams>&) const Line | Count | Source | 113 | 14 | { | 114 | 14 | s << std::span(m_data); | 115 | 14 | } |
void base_blob<256u>::Serialize<ParamsStream<VectorWriter&, TransactionSerParams>>(ParamsStream<VectorWriter&, TransactionSerParams>&) const Line | Count | Source | 113 | 1.13M | { | 114 | 1.13M | s << std::span(m_data); | 115 | 1.13M | } |
void base_blob<256u>::Serialize<BufferedWriter<AutoFile>>(BufferedWriter<AutoFile>&) const Line | Count | Source | 113 | 102k | { | 114 | 102k | s << std::span(m_data); | 115 | 102k | } |
void base_blob<256u>::Serialize<ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>>(ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>&) const Line | Count | Source | 113 | 394k | { | 114 | 394k | s << std::span(m_data); | 115 | 394k | } |
void base_blob<256u>::Serialize<ParamsStream<AutoFile&, TransactionSerParams>>(ParamsStream<AutoFile&, TransactionSerParams>&) const Line | Count | Source | 113 | 2.36k | { | 114 | 2.36k | s << std::span(m_data); | 115 | 2.36k | } |
|
116 | | |
117 | | template<typename Stream> |
118 | | void Unserialize(Stream& s) |
119 | 2.95M | { |
120 | 2.95M | s.read(MakeWritableByteSpan(m_data)); |
121 | 2.95M | } void base_blob<256u>::Unserialize<DataStream>(DataStream&) Line | Count | Source | 119 | 1.73M | { | 120 | 1.73M | s.read(MakeWritableByteSpan(m_data)); | 121 | 1.73M | } |
void base_blob<256u>::Unserialize<ParamsStream<DataStream&, TransactionSerParams>>(ParamsStream<DataStream&, TransactionSerParams>&) Line | Count | Source | 119 | 200k | { | 120 | 200k | s.read(MakeWritableByteSpan(m_data)); | 121 | 200k | } |
void base_blob<256u>::Unserialize<SpanReader>(SpanReader&) Line | Count | Source | 119 | 382k | { | 120 | 382k | s.read(MakeWritableByteSpan(m_data)); | 121 | 382k | } |
void base_blob<256u>::Unserialize<ParamsStream<SpanReader&, TransactionSerParams>>(ParamsStream<SpanReader&, TransactionSerParams>&) Line | Count | Source | 119 | 579k | { | 120 | 579k | s.read(MakeWritableByteSpan(m_data)); | 121 | 579k | } |
void base_blob<160u>::Unserialize<DataStream>(DataStream&) Line | Count | Source | 119 | 395 | { | 120 | 395 | s.read(MakeWritableByteSpan(m_data)); | 121 | 395 | } |
void base_blob<256u>::Unserialize<AutoFile>(AutoFile&) Line | Count | Source | 119 | 8.94k | { | 120 | 8.94k | s.read(MakeWritableByteSpan(m_data)); | 121 | 8.94k | } |
Unexecuted instantiation: void base_blob<256u>::Unserialize<ParamsStream<AutoFile&, CAddress::SerParams>>(ParamsStream<AutoFile&, CAddress::SerParams>&) void base_blob<256u>::Unserialize<ParamsStream<HashVerifier<AutoFile>&, CAddress::SerParams>>(ParamsStream<HashVerifier<AutoFile>&, CAddress::SerParams>&) Line | Count | Source | 119 | 1.12k | { | 120 | 1.12k | s.read(MakeWritableByteSpan(m_data)); | 121 | 1.12k | } |
void base_blob<256u>::Unserialize<ParamsStream<DataStream&, CAddress::SerParams>>(ParamsStream<DataStream&, CAddress::SerParams>&) Line | Count | Source | 119 | 13 | { | 120 | 13 | s.read(MakeWritableByteSpan(m_data)); | 121 | 13 | } |
void base_blob<256u>::Unserialize<ParamsStream<HashVerifier<DataStream>&, CAddress::SerParams>>(ParamsStream<HashVerifier<DataStream>&, CAddress::SerParams>&) Line | Count | Source | 119 | 3 | { | 120 | 3 | s.read(MakeWritableByteSpan(m_data)); | 121 | 3 | } |
void base_blob<256u>::Unserialize<ParamsStream<AutoFile&, TransactionSerParams>>(ParamsStream<AutoFile&, TransactionSerParams>&) Line | Count | Source | 119 | 467 | { | 120 | 467 | s.read(MakeWritableByteSpan(m_data)); | 121 | 467 | } |
void base_blob<256u>::Unserialize<BufferedReader<AutoFile>>(BufferedReader<AutoFile>&) Line | Count | Source | 119 | 36.8k | { | 120 | 36.8k | s.read(MakeWritableByteSpan(m_data)); | 121 | 36.8k | } |
void base_blob<256u>::Unserialize<BufferedFile>(BufferedFile&) Line | Count | Source | 119 | 3.93k | { | 120 | 3.93k | s.read(MakeWritableByteSpan(m_data)); | 121 | 3.93k | } |
void base_blob<256u>::Unserialize<ParamsStream<BufferedFile&, TransactionSerParams>>(ParamsStream<BufferedFile&, TransactionSerParams>&) Line | Count | Source | 119 | 5.33k | { | 120 | 5.33k | s.read(MakeWritableByteSpan(m_data)); | 121 | 5.33k | } |
|
122 | | }; |
123 | | |
124 | | template <unsigned int BITS> |
125 | | consteval base_blob<BITS>::base_blob(std::string_view hex_str) |
126 | | { |
127 | | if (hex_str.length() != m_data.size() * 2) throw "Hex string must fit exactly"; |
128 | | auto str_it = hex_str.rbegin(); |
129 | | for (auto& elem : m_data) { |
130 | | auto lo = util::ConstevalHexDigit(*(str_it++)); |
131 | | elem = (util::ConstevalHexDigit(*(str_it++)) << 4) | lo; |
132 | | } |
133 | | } |
134 | | |
135 | | namespace detail { |
136 | | /** |
137 | | * Writes the hex string (in reverse byte order) into a new uintN_t object |
138 | | * and only returns a value iff all of the checks pass: |
139 | | * - Input length is uintN_t::size()*2 |
140 | | * - All characters are hex |
141 | | */ |
142 | | template <class uintN_t> |
143 | | std::optional<uintN_t> FromHex(std::string_view str) |
144 | 31.0k | { |
145 | 31.0k | if (uintN_t::size() * 2 != str.size() || !IsHex(str)) return std::nullopt; |
146 | 30.5k | uintN_t rv; |
147 | 30.5k | unsigned char* p1 = rv.begin(); |
148 | 30.5k | unsigned char* pend = rv.end(); |
149 | 30.5k | size_t digits = str.size(); |
150 | 1.00M | while (digits > 0 && p1 < pend) { |
151 | 978k | *p1 = ::HexDigit(str[--digits]); |
152 | 978k | if (digits > 0) { |
153 | 978k | *p1 |= ((unsigned char)::HexDigit(str[--digits]) << 4); |
154 | 978k | p1++; |
155 | 978k | } |
156 | 978k | } |
157 | 30.5k | return rv; |
158 | 31.0k | } std::optional<uint160> detail::FromHex<uint160>(std::basic_string_view<char, std::char_traits<char>>) Line | Count | Source | 144 | 93 | { | 145 | 93 | if (uintN_t::size() * 2 != str.size() || !IsHex(str)) return std::nullopt; | 146 | 11 | uintN_t rv; | 147 | 11 | unsigned char* p1 = rv.begin(); | 148 | 11 | unsigned char* pend = rv.end(); | 149 | 11 | size_t digits = str.size(); | 150 | 231 | while (digits > 0 && p1 < pend) { | 151 | 220 | *p1 = ::HexDigit(str[--digits]); | 152 | 220 | if (digits > 0) { | 153 | 220 | *p1 |= ((unsigned char)::HexDigit(str[--digits]) << 4); | 154 | 220 | p1++; | 155 | 220 | } | 156 | 220 | } | 157 | 11 | return rv; | 158 | 93 | } |
std::optional<uint256> detail::FromHex<uint256>(std::basic_string_view<char, std::char_traits<char>>) Line | Count | Source | 144 | 30.9k | { | 145 | 30.9k | if (uintN_t::size() * 2 != str.size() || !IsHex(str)) return std::nullopt; | 146 | 30.5k | uintN_t rv; | 147 | 30.5k | unsigned char* p1 = rv.begin(); | 148 | 30.5k | unsigned char* pend = rv.end(); | 149 | 30.5k | size_t digits = str.size(); | 150 | 1.00M | while (digits > 0 && p1 < pend) { | 151 | 978k | *p1 = ::HexDigit(str[--digits]); | 152 | 978k | if (digits > 0) { | 153 | 978k | *p1 |= ((unsigned char)::HexDigit(str[--digits]) << 4); | 154 | 978k | p1++; | 155 | 978k | } | 156 | 978k | } | 157 | 30.5k | return rv; | 158 | 30.9k | } |
|
159 | | /** |
160 | | * @brief Like FromHex(std::string_view str), but allows an "0x" prefix |
161 | | * and pads the input with leading zeroes if it is shorter than |
162 | | * the expected length of uintN_t::size()*2. |
163 | | * |
164 | | * Designed to be used when dealing with user input. |
165 | | */ |
166 | | template <class uintN_t> |
167 | | std::optional<uintN_t> FromUserHex(std::string_view input) |
168 | 64 | { |
169 | 64 | input = util::RemovePrefixView(input, "0x"); |
170 | 64 | constexpr auto expected_size{uintN_t::size() * 2}; |
171 | 64 | if (input.size() < expected_size) { |
172 | 42 | auto padded = std::string(expected_size, '0'); |
173 | 42 | std::copy(input.begin(), input.end(), padded.begin() + expected_size - input.size()); |
174 | 42 | return FromHex<uintN_t>(padded); |
175 | 42 | } |
176 | 22 | return FromHex<uintN_t>(input); |
177 | 64 | } |
178 | | } // namespace detail |
179 | | |
180 | | /** 160-bit opaque blob. |
181 | | * @note This type is called uint160 for historical reasons only. It is an opaque |
182 | | * blob of 160 bits and has no integer operations. |
183 | | */ |
184 | | class uint160 : public base_blob<160> { |
185 | | public: |
186 | 93 | static std::optional<uint160> FromHex(std::string_view str) { return detail::FromHex<uint160>(str); } |
187 | 7.57M | constexpr uint160() = default; |
188 | 505k | constexpr explicit uint160(std::span<const unsigned char> vch) : base_blob<160>(vch) {} |
189 | | }; |
190 | | |
191 | | /** 256-bit opaque blob. |
192 | | * @note This type is called uint256 for historical reasons only. It is an |
193 | | * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if |
194 | | * those are required. |
195 | | */ |
196 | | class uint256 : public base_blob<256> { |
197 | | public: |
198 | 30.9k | static std::optional<uint256> FromHex(std::string_view str) { return detail::FromHex<uint256>(str); } |
199 | 64 | static std::optional<uint256> FromUserHex(std::string_view str) { return detail::FromUserHex<uint256>(str); } |
200 | 1.32G | constexpr uint256() = default; |
201 | 0 | consteval explicit uint256(std::string_view hex_str) : base_blob<256>(hex_str) {} |
202 | 532 | constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {} |
203 | 2.01M | constexpr explicit uint256(std::span<const unsigned char> vch) : base_blob<256>(vch) {} |
204 | | static const uint256 ZERO; |
205 | | static const uint256 ONE; |
206 | | }; |
207 | | |
208 | | #endif // BITCOIN_UINT256_H |