Skip to content

account/TokenID.hpp

Fixed-size token identifier wrapper with GNUS compatibility helpers. More...

Namespaces

Name
sgns

Classes

Name
class sgns::TokenID
Represents a 32-byte token identifier while preserving legacy GNUS semantics.

Functions

Name
std::ostream & operator<<(std::ostream & os, const sgns::TokenID & id)
Streams a token identifier as hexadecimal text.

Detailed Description

Fixed-size token identifier wrapper with GNUS compatibility helpers.

Date: 2025-06-19 Henrique A. Klein ([email protected])

Functions Documentation

function operator<<

inline std::ostream & operator<<(
    std::ostream & os,
    const sgns::TokenID & id
)

Streams a token identifier as hexadecimal text.

Parameters:

  • os Output stream to write to.
  • id Token identifier to stream.

Return: Reference to os after writing the token identifier.

Source code

#pragma once

#include <array>
#include <algorithm>
#include <cstdint>
#include <cstring>
#include <iomanip>
#include <string>
#include <sstream>

namespace sgns
{
    class TokenID
    {
    public:
        using ByteArray = std::array<uint8_t, 32>;

        enum class Endianness
        {
            HOST,
            BIG,
            LITTLE
        };

        TokenID() : data_{}, valid_( false ) {}

        TokenID( const TokenID &other ) = default;

        TokenID( TokenID &&other ) = default;

        TokenID &operator=( const TokenID &other ) = default;

        TokenID &operator=( TokenID &&other ) = default;

        static TokenID FromBytes( std::initializer_list<uint8_t> list )
        {
            return FromBytes( list.begin(), list.size() );
        }

        static TokenID FromBytes( const void *data, size_t size )
        {
            TokenID id;
            if ( !data || size == 0 )
            {
                // legacy/invalid case
                return id;
            }

            if ( size <= 32 )
            {
                // size 1–32: left-pad into the 32-byte buffer
                size_t copy_size = std::min( size, id.data_.size() );
                std::memcpy( id.data_.data() + ( id.data_.size() - copy_size ), data, copy_size );
                id.valid_ = true;
            }

            return id;
        }

        template <typename Uint256>
        static TokenID FromUint256( const Uint256 &value, Endianness endianness = Endianness::HOST )
        {
            static_assert( Uint256::num_bits == 256, "FromUint256 requires a 256-bit unsigned integer type" );

            const Endianness resolved_endianness = ResolveEndianness( endianness );

            TokenID id;
            for ( size_t i = 0; i < id.data_.size(); ++i )
            {
                const size_t byte_index = resolved_endianness == Endianness::BIG ? id.data_.size() - 1 - i : i;
                id.data_[i]             = static_cast<uint8_t>( ( value >> ( byte_index * 8 ) ) & 0xFF );
            }

            id.valid_ = true;
            return id;
        }

        const ByteArray &bytes() const
        {
            return data_;
        }

        size_t size() const
        {
            return valid_ ? 32 : 0;
        }

        bool operator==( const TokenID &other ) const
        {
            return valid_ == other.valid_ && data_ == other.data_;
        }

        bool operator!=( const TokenID &other ) const
        {
            return !( *this == other );
        }

        bool operator<( const TokenID &other ) const
        {
            return data_ < other.data_; // lexicographic comparison
        }

        std::string ToHex() const
        {
            std::ostringstream oss;
            for ( uint8_t byte : data_ )
            {
                oss << std::hex << std::setw( 2 ) << std::setfill( '0' ) << (int)byte;
            }
            return oss.str();
        }

        bool IsGNUS() const
        {
            return !valid_ || std::all_of( data_.begin(), data_.end(), []( uint8_t b ) { return b == 0; } );
        }

        bool Equals( const TokenID &other ) const
        {
            if ( *this == other )
            {
                return true;
            }
            return this->IsGNUS() && other.IsGNUS();
        }

    private:
        static Endianness ResolveEndianness( Endianness endianness )
        {
            if ( endianness != Endianness::HOST )
            {
                return endianness;
            }

            const uint16_t value = 0x0001;
            return *reinterpret_cast<const uint8_t *>( &value ) == 0x01 ? Endianness::LITTLE : Endianness::BIG;
        }

        ByteArray data_;  
        bool      valid_; 
    };
}

inline std::ostream &operator<<( std::ostream &os, const sgns::TokenID &id )
{
    return os << id.ToHex();
}

Updated on 2026-06-05 at 17:22:19 -0700