XYHASH

Overview

XYXYX introduces a built-in hash function called XYHASH, which provides uniqueness to each XYXYX visual output.

XYHASH, instead of using numbers and characters to create an encoded hash, employs Hex colors as output. Simple and robust, the input that generates each XYHASH is the tokenId of each XYXYX. For each combination of numbers that represents a tokenId, an one-of-a-kind combination of two Hex colors is produced by the XYXYX contract.

Uniqueness

The XYHASH function guarantees the uniqueness of each 1 full XYXYX by generating distinct hashes for every token. This ensures that no two XYXYX will ever duplicate. By capitalizing on the ERC-404's inherent characteristic of non-repeating token IDs, XYHASH uses each tokenId as the input to create a unique output.

This method leverages the non-rollup feature of token IDs within the ERC-404, ensuring that each 1 full XYXYX retains a one-of-a-kind identity through a specifically generated hash, thereby maintaining the uniqueness of each token.


XYHASH

Unlike traditional hash functions that output a string of numbers and characters, XYHASH generates outputs in the form of Hex color codes. This method is both straightforward and effective, utilizing the tokenId of each XYXYX as the input variable.

Consequently, for every unique tokenId, the XYXYX contract produces a specific pair of Hex colors. This mechanism ensures that each 1 full XYXYX visual output is uniquely identifiable and linked directly to its corresponding tokenId through a visually intuitive and cryptographically robust process.

function getColorComponentRed(uint256 value)    
    internal
    pure
    returns (uint16)
{
    return uint16((value >> 8) & 0xf);
}

function getColorComponentGreen(uint256 value)
    internal
    pure
    returns (uint16)
{
    return uint16((value >> 4) & 0xf);
}

function getColorComponentBlue(uint256 value)
    internal
    pure
    returns (uint16)
{
    return uint16(value & 0xf);
}

bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

function getColorHexCode(uint256 value)
    internal
    pure
    returns (string memory)
{
    uint16 red = getColorComponentRed(value);
    uint16 green = getColorComponentGreen(value);
    uint16 blue = getColorComponentBlue(value);

    bytes memory buffer = new bytes(7);

    buffer[0] = "#";
    buffer[1] = _HEX_SYMBOLS[red];
    buffer[2] = _HEX_SYMBOLS[red];
    buffer[3] = _HEX_SYMBOLS[green];
    buffer[4] = _HEX_SYMBOLS[green];
    buffer[5] = _HEX_SYMBOLS[blue];
    buffer[6] = _HEX_SYMBOLS[blue];

    return string(buffer);
}

function xyHash(string memory prefix, uint256 tokenId)
    private
    pure
    returns (uint256)
{
    return uint256(keccak256(abi.encodePacked(prefix, tokenId))) % 4096;
}

function getColor1(uint256 tokenId) public pure returns (uint256) {
    return xyHash("1", tokenId);
}

function getColor2(uint256 tokenId) public pure returns (uint256) {
    return xyHash("2", tokenId);
}

The Solidity code snippet above defines a set of functions within a smart contract that works together to generate hexadecimal color codes based on a given numeric value and to create unique hashes for token IDs which are then used to determine colors.


How does it work

Find below a breakdown of XYHASH components and functionality:

  1. getColorComponentRed, getColorComponentGreen, getColorComponentBlue: These three functions extract the red, green, and blue components of a color from a uint256 value. This is achieved by bit-shifting the value to the right (>>) and applying a bitwise, and operation (&) with 0xf (hexadecimal for 15) to isolate the last four bits. The bit-shifting distances (8 for red, 4 for green, and 0 for blue) position the bits of interest in the rightmost position to apply the mask (0xf). The result is cast to uint16 and represents the color component value in the range of 0 to 15.

    • Red Component: Extracted by shifting the value 8 bits to the right and isolating the last four bits.

    • Green Component: Extracted by shifting the value 4 bits to the right and isolating the last four bits.

    • Blue Component: Extracted by directly isolating the last four bits of the value.

  2. _HEX_SYMBOLS: A private constant byte array containing the hexadecimal symbols '0' to 'f'. This is used to map the numeric color component values (0-15) to their hexadecimal character representations.

  3. getColorHexCode: This function uses the three color component functions to obtain the red, green, and blue values of a color, maps these values to their hexadecimal characters using the _HEX_SYMBOLS array, and constructs a hexadecimal color code string. The color code string starts with a "#" followed by two characters for each color component, doubling each character for simplicity (e.g., if the red component is 0xf, it will be represented as "ff" in the string).

  4. xyHash: A function that generates a hash value based on a given string prefix and a uint256 tokenId. It uses the keccak256 hash function on the concatenated string and tokenId, then takes the result modulo 4096 (refers to the mathematical operation known as the "modulo" operation, which finds the remainder when one number is divided by another. In this context, after computing the hash function (likely producing a large integer as a result), the modulo operation is applied with 4096 as the divisor.). This ensures a fixed range of possible outcomes, which is useful for generating predictable yet unique values for color determination.

  5. getColor1 and getColor2: These public functions generate color values by calling xyHash with different string prefixes ("1" and "2", respectively), and the given tokenId. The resultant hash values can then be used to determine unique colors for each, potentially for use in generating or coloring tokens.

Last updated