Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2009-2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#ifndef BITCOIN_UINT256_H7#define BITCOIN_UINT256_H9#include <crypto/common.h>10#include <crypto/hex_base.h>11#include <span.h>12#include <util/strencodings.h>13#include <util/string.h>15#include <algorithm>16#include <array>17#include <cassert>18#include <compare>19#include <cstdint>20#include <cstring>21#include <optional>22#include <string>23#include <string_view>25/** Template base class for fixed-sized opaque blobs. */26template<unsigned int BITS>27class base_blob28{29protected:30static constexpr int WIDTH = BITS / 8;31static_assert(BITS % 8 == 0, "base_blob currently only supports whole bytes.");32std::array<uint8_t, WIDTH> m_data;33static_assert(WIDTH == sizeof(m_data), "Sanity check");35public:36/* construct 0 value by default */37constexpr base_blob() : m_data() {}39/* constructor for constants between 1 and 255 */40constexpr explicit base_blob(uint8_t v) : m_data{v} {}42constexpr explicit base_blob(std::span<const unsigned char> vch)43{44assert(vch.size() == WIDTH);45std::copy(vch.begin(), vch.end(), m_data.begin());46}48consteval explicit base_blob(std::string_view hex_str);50constexpr bool IsNull() const51{52return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) {53return val == 0;54});55}57constexpr void SetNull()58{59std::fill(m_data.begin(), m_data.end(), 0);60}62constexpr bool operator==(const base_blob&) const = default;64/** Lexicographic ordering65* @note Does NOT match the ordering on the corresponding \ref66* base_uint::CompareTo, which starts comparing from the end.67*/68constexpr std::strong_ordering operator<=>(const base_blob& other) const = default;70/** @name Hex representation71*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 represented75* as "78563412" instead of the more typical "12345678" representation76* that would be shown in a hex editor or used by typical77* byte-array / hex conversion functions like python's bytes.hex() and78* bytes.fromhex().79*80* The nice thing about the reverse-byte representation, even though it is81* unusual, is that if a blob contains an arithmetic number in little endian82* format (with least significant bytes first, and most significant bytes83* last), the GetHex() output will match the way the number would normally84* be written in base-16 (with most significant digits first and least85* significant digits last).86*87* This means, for example, that ArithToUint256(num).GetHex() can be used to88* display an arith_uint256 num value as a number, because89* 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 parsing91* and formatting functions.92*93* @{*/94std::string GetHex() const;95std::string ToString() const;96/**@}*/98constexpr const unsigned char* data() const { return m_data.data(); }99constexpr unsigned char* data() { return m_data.data(); }101constexpr unsigned char* begin() { return m_data.data(); }102constexpr unsigned char* end() { return m_data.data() + WIDTH; }104constexpr const unsigned char* begin() const { return m_data.data(); }105constexpr const unsigned char* end() const { return m_data.data() + WIDTH; }107static constexpr unsigned int size() { return WIDTH; }109constexpr uint64_t GetUint64(int pos) const { return ReadLE64(m_data.data() + pos * 8); }111template<typename Stream>112void Serialize(Stream& s) const113{114s << std::span(m_data);115}117template<typename Stream>118void Unserialize(Stream& s)119{120s.read(MakeWritableByteSpan(m_data));121}122};124template <unsigned int BITS>125consteval base_blob<BITS>::base_blob(std::string_view hex_str)126{127if (hex_str.length() != m_data.size() * 2) throw "Hex string must fit exactly";128auto str_it = hex_str.rbegin();129for (auto& elem : m_data) {130auto lo = util::ConstevalHexDigit(*(str_it++));131elem = (util::ConstevalHexDigit(*(str_it++)) << 4) | lo;132}133}135namespace detail {136/**137* Writes the hex string (in reverse byte order) into a new uintN_t object138* and only returns a value iff all of the checks pass:139* - Input length is uintN_t::size()*2140* - All characters are hex141*/142template <class uintN_t>143std::optional<uintN_t> FromHex(std::string_view str)144{145if (uintN_t::size() * 2 != str.size() || !IsHex(str)) return std::nullopt;146uintN_t rv;147unsigned char* p1 = rv.begin();148unsigned char* pend = rv.end();149size_t digits = str.size();150while (digits > 0 && p1 < pend) {151*p1 = ::HexDigit(str[--digits]);152if (digits > 0) {153*p1 |= ((unsigned char)::HexDigit(str[--digits]) << 4);154p1++;155}156}157return rv;158}159/**160* @brief Like FromHex(std::string_view str), but allows an "0x" prefix161* and pads the input with leading zeroes if it is shorter than162* the expected length of uintN_t::size()*2.163*164* Designed to be used when dealing with user input.165*/166template <class uintN_t>167std::optional<uintN_t> FromUserHex(std::string_view input)168{169input = util::RemovePrefixView(input, "0x");170constexpr auto expected_size{uintN_t::size() * 2};171if (input.size() < expected_size) {172auto padded = std::string(expected_size, '0');173std::copy(input.begin(), input.end(), padded.begin() + expected_size - input.size());174return FromHex<uintN_t>(padded);175}176return FromHex<uintN_t>(input);177}178} // namespace detail180/** 160-bit opaque blob.181* @note This type is called uint160 for historical reasons only. It is an opaque182* blob of 160 bits and has no integer operations.183*/184class uint160 : public base_blob<160> {185public:186static std::optional<uint160> FromHex(std::string_view str) { return detail::FromHex<uint160>(str); }187constexpr uint160() = default;188constexpr explicit uint160(std::span<const unsigned char> vch) : base_blob<160>(vch) {}189};191/** 256-bit opaque blob.192* @note This type is called uint256 for historical reasons only. It is an193* opaque blob of 256 bits and has no integer operations. Use arith_uint256 if194* those are required.195*/196class uint256 : public base_blob<256> {197public:198static std::optional<uint256> FromHex(std::string_view str) { return detail::FromHex<uint256>(str); }199static std::optional<uint256> FromUserHex(std::string_view str) { return detail::FromUserHex<uint256>(str); }200constexpr uint256() = default;201consteval explicit uint256(std::string_view hex_str) : base_blob<256>(hex_str) {}202constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {}203constexpr explicit uint256(std::span<const unsigned char> vch) : base_blob<256>(vch) {}204static const uint256 ZERO;205static const uint256 ONE;206};208#endif // BITCOIN_UINT256_H