Only this pageAll pages
Powered by GitBook
1 of 78

fxhash docs

Loading...

Loading...

FXH

Loading...

Loading...

Loading...

Loading...

Creating on fxhash

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Collecting on fxhash

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Knowledge Base

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Find us on Social Media

Docs Overview

Welcome to the fxhash documentation, here you can find everything that you need to know to get started on the open generative art platform!

Quickstart Guide

Learn about the fxhash platform and how to get started.

Creating on fxhash

Technical resources for those who want to create and sell generative art on fxhash

Collecting on fxhash

Guides for those interested to collect generative art on fxhash.

Knowledge Base

Over of the fxhash eco-system & additional resources.

Protocol Overview

The $FXH protocol is a powerful foundation for creating, collecting, and evolving generative art in ways that push artistic potential to new levels.

The protocol powers art coins: art-driven currencies that unlock a new medium called open-form generative art.

A new era for generative art

We’ve had long-form. We’ve had short-form.

Now, fxhash introduces open-form: a dynamic, evolving, participatory medium where the artwork is shaped in real time—by both artists and collectors.

This isn’t just a feature. It’s a new medium.

Core actions

→ MINT — generate a new edition

→ RE-ROLL — burn and mint again

→ LOCK — freezing an edition locks in traits + turns it into a seed

Seed evolution explained

Every locked edition becomes a seed—a source from which others can evolve. Evolutions generate mint fees shared across the lineage.

Great seeds earn. The better your curation, the more others build on it.

👇 Try out the for yourself to see how it works.

Art-driven Currencies

Each open-form collection runs on an art coin—an ERC20 cryptocurrency that can represent a project, a series, or your entire body of work. Art coins are not memecoins, shitcoins, or content coins.

Unlike other coins, art coins are intrinsically connected to the artwork at a contract level. They are meaningful forms of currency for art collections that blur the lines between art, finance, and utility.

Use one art coin across the years, or launch a fresh art coin with each idea. Projects launched with art coins can evolve, their codebases can be updated, and they can stay open indefinitely.

Art coins are built for how artists actually work. They enable interaction at scale, unlock new value around your work, and grow with your practice.

How value flows around the art coin system

Art coins turn interaction into income—for artists, collectors, and traders alike. When your art moves people, it moves coins.

When people engage

  • mint fees go to the artist

  • evolutions pay fees to the seed lineage

This means

  • artists earn from mints, evolutions, and coin trading activity

  • collectors earn by locking seeds others want to evolve from

Why art coins matter for…

– Collectors: re-roll, lock, evolve—every choice can shape the art and move the market

– Artists: release systems, not static drops—and earn from every layer of interaction

– Traders: speculate on coins tied to projects with real usage and visibility

– Everyone: a market shaped by creative action—not gatekeeping

$FXH has a supply of 1bn tokens—learn more about earning $FXH through our community incentives .


The structure of art coin sales has been developed with the assistance of legal counsel operating predominantly in the crypto-assets industry, with due care taken to align with applicable regulatory frameworks including the MiCA Regulation.

Quickstart Guide

Welcome to the fxhash Quickstart Guide! This guide will walk you through setting up your wallet, adding funds, and connecting to fxhash so you can start collecting and/or publish your own projects. We'll link to the relevant sections of the docs throughout the guide, but if you don't find something you're looking for make sure to check the search box in the top right corner, or reach out to us over on discord.

1

Install & Setup your Wallet(s)

A crypto wallet is your identity on the blockchain. To interact with fxhash you need a wallet that is compatible with one of the chains that fxhash integrates with. Popular choices for this purpose are Temple for Tezos and Metamask for mainnet Eth and the Base L2, if you already have one of them you can get started straight away, otherwise .

Maybe you already have a favorite chain, but in case you don't know which one to get started with, here's an explainer on their differences and the rationale behind fxhash's adoption. If you're completely new to blockchain tech, we've also put together a section that explains the fxhash ecosystem where you can .

2

Add Funds to your Wallet(s)

To interact with the blockchain, for the purpose of creating and collecting tokens on fxhash, you'll need to add some funds to your wallet. This can be a bit tricky as a newcommer, since there's several steps involved. There's multiple ways to go about it, we provide a .

3

Connect your Wallet(s) to (make an account on) fxhash

Once you've set up your wallet and added some funds to it you'll want to connect it to fxhash and . Creating an account on fxhash basically means that you'll link your wallet to our platform—since fxhash supports several chains there a system in place to handle that, so there's some nuance to setting up an account.

4

Read the Code of Conduct & Safety Notes

Before you start collecting or creating on fxhash make sure to read through the so that you're on your best behavior, as well as the on navigating the Web3 space.

5

Start collecting on fxhash

Once you've completed all of the previous steps you can get started collecting generative art on fxhash. There's two parts to the fxhash marketplace, the Primary, and the Secondary Market.

On the you can collect generative artworks directly from the artists. Unlike regular NFTs, collecting an edition of a generative artwork creates a new, unique, and randomly generated token. Learn more about how this works here. On the you can buy and sell already collected generative artworks with other collectors, there's a number of different ways in which you can acquire tokens from other collectors.

Besides that, fxhash also allows artists to create custom minting experiences that are sold in a bit of a different manner than you would collect a regular project. In this scenario you can be involved as a sort of collaborator in creating the artwork—you can

6

Publish your own Project on fxhash

If you're a programmer and a generative artist and want to create your own project on fxhash, we recommend checking out the section for a detailed explanation of how to setup up your development environment and how to build an fxhash compatible generative artwork. These artist focused docs are made out of 4 sections:

If you need assistance with any part of the process, come join the discord, we'll be more than happy to assist you. Here's a page that explain our Discord structure and all of the different channels that you might find in there.

.
: this section shows how to structure your project so that it's compatible with fxhash, and explains the tools that fxhash provides to build your project.
  • fxhash API: the API that you need to incorporate within your project to communicate with the fxhash platform once it's published.

  • Genart in the Browser: useful guides for making responsive and deterministic browser based generative art.

  • Releasing your Project: a run-down of the steps to publish your project on fxhash.

  • learn how to set up your wallet here
    learn more about blockchain technology and how fxhash leverages it for the purpose of generative art
    run-down in the Adding Funds to your Wallet(s) section of the docs
    create an account
    Code of Conduct
    Safety Notes
    Primary Market
    Secondary Market
    Creating on fxhash
    learn more about fx(params) and mint tickets here
    Project Setup and Development

    fxhash API

    fxhash & Web3

    At fxhash, we build tools that allow artists and collectors to pursue their passion for generative art. Our platform provides an intuitive and secure environment for artists, collectors, and curators to create generative art projects, buy, sell, and collect art — and share their collections with the world.

    Digital artists have have faced challenging in securing a living from their art during the last twenty years. However, this paradigm is shifting gradually with the advent of blockchain and Non-Fungible Tokens (NFTs).

    Our mission is to accelerate this change by building fxhash into the world’s foremost generative art hub. In this place, the entire artistic community — including artists, collectors, curators, institutions— can access to meaningful tools to realise and share their art projects.

    Our vision for fxhash is a place where global artists earn a living from their digital works of art, regardless of their geographic location, while using our tools that assist them to learn, grow, and excel in their generative art practice.

    In our ecosystem, collectors, curators, galleries, and museums hold an equivalent status with artists in that their support, network effects, and feedback are vital to the artist’s success.

    This is the reason we place equal importance on developing marketplace features, curation tools, and live minting implementations. So that collectors, curators, galleries, and museums can not only showcase but also elevate the generative art movement.

    Onboarding

    Cross-chain Referencing

    Onchfs provides a specification for turning directories and files into inscriptions, following a process suited for any blockchain, as the file abstraction layer is high enough so that blockchain-implementation specifics can't intefere with it.

    Due to files & directories being fully content-addressed, a same set of files/directories will end up having a same set of pointers regardless of the blockchain on which they're stored. This is particularly usefull when looking at cross-chain compatibility of the protocol, because it means that one asset may reference a resource on another blockchain, even though such resource may not currently exist on the former blockchain. Onchfs proxies will be responsible for handling requests to fetch corresponding files if needed, but eventually such files can be moved to the blockchain on which the original asset exist for ensuring it will be stored in perpetuity.

    This can become useful if there is a need to use a cheaper blockchain for storing bigger chunks of data to be accessed more expensive blockchain. While not a typical scenario, it's worth noting the built-in onchfs support for such cases.

    → EVOLVE — generate new editions from a locked seed

    locked seeds burn coins, decreasing supply

  • coin trades generate fees—shared with the artist

  • traders speculate on art coins tied to active, growing collections

    open-form simulator
    here
    755KB
    fxhash - TCs Art Coins .pdf
    PDF
    Open

    Project Setup & Development

    References

    • RFC 3986 / Uniform Resource Identifier (URI): Generic Syntax

    • RFC 1738 / Uniform Resource Locators (URL)

    • RFC 5234 / Augmented BNF for Syntax Specifications: ABNF

    • RFC 2718 / Guidelines for new URL Schemes

    Platform Overview

    Overview of the different parts of the UI to collect on fxhash's primary and secondary market, as well as a explanation of some of fxhash’s special features.

    Over the next two chapters of the collectors docs we’ll provide you with everything required to get started on fxhash as a collector. In the first part we detail how to navigate the fxhash platform for acquiring tokens and adding them to your collection, whereas in the second part we go over some more advanced notions required for growing a collection and some of the notions of being a collector.

    Testing Browser Compatibility

    A note on testing your fxhash project and ensuring that it is compatible with most modern browsers.

    One thing that you want to do often and frequently while developing your fxhash project, is testing it across different browsers and different devices. Because different browsers are developed by different organisations and may be built in a way such that they interpret web standards differently, there can be variations in how a website or web application is displayed and behaves across different browsers.

    Browser compatibility is particularly important for web developers and designers because it ensures that users have a consistent and reliable experience regardless of the browser they choose to use. This is also important in the case of an fxhash project, we want the code that generates our artwork to run consistently on every browser with no variance.

    What is Browser compatibility?

    Refers to the ability of a website or web application to function correctly and consistently across different web browsers.

    Limitations

    Content Availability

    In contrast to other on-chain on-demand storage solutions, onchfs requires an http proxy to display the content of a resource, as it cannot reliably serve files directly from on-chain read calls. In essence, we consider this limitation to be fairly acceptable as this in-between http-proxy layer is very straightforward and can easily be ran by anyone with an internet connection, without even having to rely on a 3rd party service.

    Read more

    More infos about the .

    Collector Tips

    This Chapter covers some of the important aspects of being a collector, some best practices for collecting on fxhash and elsewhere, and the intricacies of the Secondary Market.

    Collector's Code of Conduct

    Code of Conduct for collectors on fxhash

    Advantaged Buying

    Advantaged buyers are considered those who have tools they have built themselves, or purchased from others, that give them an algorithmic advantage and automated buying capabilities from primary markets or secondary markets. This is colloquially referred to as botting and like in many communities, is considered taboo.

    At fxhash, there is inbuilt anti-botting mechanisms included in the contracts to combat this behaviour. Small scale botting is allowed but is highly discouraged.

    Collectors that are caught botting will be outed where possible, have their verification removed (with their chances of re-verification drastically reduced) and in extreme cases, a server-wide announcement made about their activities if we deem it a risk to our collectors.

    Market Manipulation

    Attempts at market manipulation are taken extremely seriously and will not be accepted. Due to the nature of the blockchain, and methods and tools developed by the team, it is possible for us to thread together transactions (even across marketplaces) in order to create a strong, evidence based, case against a user.

    Users which do try to manipulate the market will be made aware to the community, moderate and lose their reputation.

    Project Structure

    Project Template

    CLI Setup

    CLI Reference

    fxlens

    RFC 3628 / UTF-8
    IPFS - Content Addressed, Versioned, P2P File System

    Primary Market

    Secondary Market

    fxparams & the Ticketing System

    Allow Lists & Reserves

    Redeemables

    Getting Started as a Collector

    Token Discovery Tools

    Towards Curation

    Market Analysis & Dynamics

    Policies & Guidelines

    Ecosystem integration

    While ipfs is fairly supported on most platforms nowadays, onchfs is not. As such, platforms will not be capable of reliably displaying onchfs absolute URIs found on-chain due to the infancy of the protocol.

    However, some solutions exist to get around this temporary problem. Smart Contract can store updateable base URIs to onchfs assets, initially configured to a valid http proxy, later updated to the onchfs:// schema string:

    onchfs http proxy here
    onchfsCid = 3d767a081f6d...
    baseUri = https://onchfs.proxy.com/
    tokenUri = {baseUri}{onchfsCid}
    
    at first ->
    baseUri = https://onchfs.proxy.com/3d767a081f6d...
    
    then when onchfs gets adopted ->
    baseUri = onchfs://
    tokenUri = onchfs://3d767a081f6d...
    Some newer features of Javascript, CSS, and HTML might not be implemented or supported yet in certain browsers, if your code happens to use one of these features and is run in a browser that doesn’t support them, it is likely that your generative artwork will not display correctly or not display at all.

    Since it is not possible to anticipate what browser your collectors/audience may be using, you should make sure that your project is compatible with at least the popular modern browsers. Although you can indicate that your project might not work on specific browsers, it is good practice to make the project compatible across all browsers.

    One useful resource for this purpose are the MDN web docs which we have already mentioned a couple times throughout the docs. When looking up a specific function, scrolling down towards the bottom of the documentations page will reveal a compatibility table that shows if different browsers support that feature:

    Not all browsers are created equal, for instance, although the canvas element is supported by all browsers, not all functions provided by the rendering context are. Hence, you should always test your project in different browser, as well as on different devices, as that may cause additional problems. It is better to catch bugs and errors early on, rather than after having minted the project.

    Genart in the Browser

    An overview of the different methods with which graphics can be rendered to the browser.

    fxhash projects are web based generative artworks that display graphics in the browser. We’ve now had a look at all of the tools that fxhash provides to facilitate this endeavour, and also had a look at the fxhash API that provides helper functions to create a compatible generative artwork. Now we still need to discuss some notions that are related to developing a robust generative artwork, that displays itself properly in the canvas, works across different browsers, and implements some user friendly features. These things aren’t directly related to fxhash, but are quite important to get right.

    In the following sections we will discuss some of the important notions involved in the creation of a generative artwork for fxhash:

    There are primarily two technologies to create graphics in the browser, they are:

    • The HTML Canvas: the html canvas element is a rectangular bitmap area (essentially a raster/grid of pixels) that can be displayed within an HTML page, and allows the control over individual pixels via javascript. It comes with an attached rendering context that provides several useful functions for drawing to that canvas. Most modern generative art makes use of this canvas element and its associated API. Furthermore, many libraries are built on top of this Canvas API that further facilitate the creation of graphics. We will talk in detail about this canvas element in the coming sections.

    • SVGs - Scalable Vector Graphics: in contrast to the pixel based canvas element, scalable vector graphics are a resolution independent alternative to creating graphics in the browser. SVGs are based on XML and describes 2D graphics in a vector format. An SVG is essentially a document of shapes and paths that can be drawn, and the browser renders it as needed. There are also javascript libraries that facilitate the creation of these SVGs, and make it possible to make art with them, but it is overall a bit trickier than making art with the canvas element.

    Towards Curation

    In this page we explain the differences between collectors and curators, elaborate on the goals of creating curations, and give a run-down of some of the different tools that allow for the creation of

    While for collectors the focus lies on ownership, curators are more concerned with the presentation of their collection. Curators aim to elevate the individual works they’ve added to their collection beyond their simple existence as “acquisitions” and leveraging them as vehicles to paint and present different narratives:

    What is Art Curation? Art curation involves the selection, organization, and presentation of artworks in a way that creates a meaningful and cohesive experience for viewers. Curators are individuals or professionals responsible for managing and arranging art collections, whether in museums, galleries, exhibitions, or other public spaces. Their role is to create a narrative or theme that ties the artworks together, creating a cohesive narrative, and making the individual works more accessible and engaging for the audience.

    In this manner, art curators strive to tell stories, provoke thought, and spark dialogue through the careful presentation of art. This is often achieved by highlighting connections between works, contextualize the artworks within historical, cultural, or thematic frameworks, or by providing further context on the creation of the pieces and offering new perspectives on their interpretation. Additionally, curators play a vital role in preserving and promoting the artistic heritage that goes into making of individual artworks - which is crucial factor in the fast paced and ever-evolving NFT landscape.

    In this sense, Web3 tech not only makes it much easier to be involved in the NFT art scene as a collector, but also creates new curatorial affordances. Hobbyist collectors can try their hand at art curation, while experts from the traditional art scene can exercise and leverage their experience in a digital framework. In what follows we will discuss what it means to be a curator in the Web3 setting and provide some guidance on getting started with this endeavor on your own.

    Curatorial Approaches

    In the NFT setting, the distinction between collectors and curators becomes blurred: NFT collectors, just like traditional art collectors, may be motivated by financial incentives or personal interest. Due to the digital nature of NFTs, collectors can also easily showcase and present their collections online, further simplified by many of the collection management platforms already having built-in curation features.

    There’s a number of different approaches for creating groupings of distinct pieces in your collection, both in the traditional and digital Web3 setting, some common methods towards that end are:

    • Thematic Curation: Selecting artworks based on a specific theme, idea, or concept. In generative art this could be based on a similarity in visual aesthetics, similarity in underlying algorithmic principles that bring the generative outputs to life, or even similarity in the non-code concepts behind the artwork.

    • Comparative Curation: Juxtaposing artworks from different artists, can highlight their similarities and/or differences. Again, this can be from an aesthetic or conceptual point of view.

    • Collaborative Curation: Sometimes collectors, curators, artists, and/or community members band together to create a shared vision for an exhibition or collection, pitching pieces from their own collections. Curating an artwork doesn’t necessarily mean that you need to own it - you can still emotionally and intellectually engage with an artwork even if it is not part of your collection.

    Naturally, there’s more to creating a curation than just grouping different artworks together and calling it a day, the accompanying context, story, and narrative is of equal importance.

    Tools for Creating NFT Curations

    There are quite a few tools out there that allow you to create digital galleries, showcase the pieces in your collection, and create curations with ease:

    1. : Deca is arguably the most popular tool for curation purposes. It covers both ETH and Tezos NFTs. It allows you to create a number of different types of digital galleries; essentially represented as different kinds of canvas-like boards on which you can position the artworks in your collection in arbitrary manners, and further supplement them with written information of your own.

      It also provides advanced filtering tools to search your collection for particular pieces to include in these galleries. Deca also provides social features, allowing you to follow your favorite artists/collectors/curators, and also has some mechanics that game-ify the curation experience. As a dApp you can simply connect your wallet to the platform and get started creating your digital galleries.

    2. : Gallery is another popular curation tool - covering several blockchains other than ETH and Tezos as well it’s also quickly become a community favorite. It functions similarly to Deca in that it allows you to group specific pieces in your collection and display them in form of a board. Furthermore, Gallery is currently also compatible with Farcaster - meaning that you can simply login to it via your Farcaster account. Beyond that Gallery also provides a convenient companion mobile app in which you can view your collection on the go.

    Beyond this we also encourage you to write about your curatorial efforts with the fx(text) feature, allowing you to mint your writing as semi-fungible tokens, in which you can natively link/showcase fxhash pieces in your collection. You can learn more about fx(text) here.

    NFTs & Smart Contracts

    An introduction to Non-Fungible Tokens (NFTs) and their transformative impact on digital art, including generative art on platforms like fxhash.

    What are NFTs?

    Imagine NFTs as digital certificates of authenticity and ownership for unique items. They're akin to virtual collectibles, each with its own special story and intrinsic value.

    What are NFTs?

    A Non-Fungible Token (NFT) represents a unique digital asset, recorded and stored on a blockchain, and signifies the ownership and authenticity of specific items, such as digital artwork.

    Non-fungibility in this setting means uniqueness. Each NFT is distinct and cannot be replaced or exchanged on a one-to-one basis with another token.

    An NFT is like a one-of-a-kind painting. Just as no two paintings are exactly alike, each NFT is distinct and irreplaceable. This is in contrast to cryptocurrencies that are fungible tokens:

    • Fungible Tokens: Regular money is fungible. One $10 bill can be swapped for another, retaining the same value. The same principle applies to cryptocurrency, which is a fungible token on the blockchain.

    • Non-Fungible Tokens: A unique painting or a signed first-edition book can't be swapped for just anything else. They are valuable because of their uniqueness – this is what an NFT represents. It is a unique digital token that has unique properties making it distinct from any other token, such as a unique ID and metadata.

    By virtue of blockchains being digital ledgers that have an immutable record of transactions, ownership of these Non-Fungible Tokens can be associated with specific wallet addresses. This also has the consequence that NFTs are financial assets:

    • Ownership: NFTs affirm digital ownership, akin to holding a rare, collectible item.

    • NFTs can be sold and traded: This ownership is recorded on the blockchain, allowing for transparent and verifiable transfer, exchanged for cryptocurrency or traded for another NFT via smart contracts.

    • Authenticity and Provenance: The blockchain ensures each NFT's authenticity and provides a traceable history.

    What are Smart Contracts?

    Whereas blockchain technology provides the infrastructure to store and immutably record transactions, there needs to be a protocol for how these transactions are effectuated.

    These protocols are called smart contracts, as their name suggests, are agreements executed between two parties on a blockchain. They typically dictate the rules for transaction execution, doing so in a transparent and secure manner.

    What are smart contracts?

    In essence, smart contracts are small pieces of code that represent the rules and conditions of a contract. Moreover, since they run on a decentralized blockchain, they are not controlled by any single entity, thus ensuring transparency and security.

    Smart contracts self-execute when both parties agree to the contract conditions, making the process trustless – neither party needs to trust the other, as the smart contract ensures each party receives what has been agreed upon.

    Smart contracts, which come in various forms, are essentially the code that makes blockchain transactions possible. Most of the operations that you will effectuate on fxhash have some sort of smart contract running in the background. For instance, purchasing a GENTK from fxhash triggers a smart contract upon transaction confirmation in your wallet. This action records the transaction on the blockchain, transferring the cost of the GENTK to the artist and delivering the purchased GENTK to you.

    NFTs in Generative Art

    Smart Contracts and blockchain technology are crucial in enabling code-generated blockchain art and facilitate the ownership of these code-generated tokens. It is an innovative piece of technology which fxhash builds upon for the distribution of generative artworks.

    When collectors acquire an iteration from a project on fxhash, this action generates a new Non-Fungible Token on the blockchain, representing the acquired asset. We cover how this works in more detail in the section.

    Project Template

    An introduction to the fx(hash) boilerplate, a starting template to kickstart new projects.

    The boilerplate is essentially a minimal, self-contained starting template that serves as a simple starting point for creating an fx(hash) project. It comes out of the box with all of the required files, and you|d just have to fill in the blanks to create an fx(hash) compatible generative artwork. You can download the starting template from this Github repository:

    What's a Boilerplate?

    In the context of software development the term "boilerplate" often refers to a template or starting point for a project that includes a set of standardised code or files. These templates are designed to provide a foundation for building software applications quickly and efficiently.

    Boilerplates help developers avoid starting from scratch and ensure that best practices and common functionality are already in place. For instance, a web development boilerplate might include a basic HTML structure, CSS styles, and JavaScript libraries to kickstart the development of a website. In the case of the fx(hash) boilerplate, it additionally includes the fxhash.js script file.

    In the early days of fx(hash), artists needed to include a short snippet of code in their projects for them to be compatible with fx(hash) and function properly once uploaded. This snippet could be found on the fx(hash) site and had to be manually copy-pasted into the artist's project.

    With fx(hash) evolving as a platform, and new features being added on a regular basis, this snippet quickly grew in size and had to be frequently updated to account for these changes. For the convenience of the artist, fx(hash) made a boilerplate available - a starter kit that already included this code snippet, becoming the go to method for kickstarting new projects.

    Cloning the boilerplate from Github will download a zip file onto your machine - unzipping it will produce a folder with the following content:

    This directory essentially contains the necessary files for creating a simple web page, just as we described in the previous section. It contains:

    • An index.html file that will act as the project entry point.

    • An index.js file ****that will contain the artist’s code that powers the generative artwork. This file should be completed by you, the artist, and should contain the code that creates the generative artwork displayed by the index.html. Right now, the boilerplate contains a bunch of code that produces the screen that we've shown above, you don't have to worry about what this information is at this point - it’ll make more sense after reading the Artist Tools section.

    • An additional javascript file titled fxhash.js that contains the helper functions provided by fxhash. A standalone script provided by fx(hash) that exposes several functions required for creating platform compatible projects. The contents of this script file and its purpose are discussed in more detail in the section.

    You can actually go ahead and open the index.html in your browser now - although it won't much sense at this point, the page shown below is an indication that the boilerplate is working correctly:

    But make sure to read the rest of the Artist Tools chapter first before you start building your generative token—there are actually a couple of different types of generative tokens for which it is recommended to use some of the more advanced artist tools instead of the simple boilerplate.

    ONCHFS

    Welcome to the On-Chain for Http File System (ONCHFS) main documentation. ONCHFS is a permissionless unix-like content-addressable file system fully stored on-chain designed to be delivered through the http protocol, with cross-blockchain compatibility in mind.

    ONCHFS is inspired by ethfs, ipfs, bitcoin ordinals recursive inscriptions, Unix filesystem, and aims at providing a general framework for working with files stored on-chain, following modern standards & practices.

    Redeemables

    An overview of the redeemables feature on fxhash, that enables artists to distribute and send out physical representations of the minted iterations from their fxhash projects.

    Generative art doesn’t only exist on the digital canvas, but can often also take on a physical existence under the form of fine art prints, pen plots, 3D prints, laser cuts, and several other creative mediums.

    With NFTs becoming a more popular medium for distributing generative art in a digital manner, there has naturally also been an increasing desire from artists, and collectors alike, to bridge between the digital and the physical and provide physical counterparts to the individually minted iterations for the generative projects on fxhash. Previously this had to be done manually through the artists’ website or an online form where collectors needed to enter their details and provide proof of payment in one way or another for the artist to prepare and send out the physical item.

    An early example of this is the fxhash project Plottable Era by Greweb, where collectors could sign up to receiving a plotted version of the minted artwork through a form:

    This process is however a hassle for both the collectors and the artists, as it requires a number of extra steps. This is where fxhash redeemables come into play. To address the needs of artists and collectors, fxhash created an extension that can be attached onto any existing project, to facilitate the distribution of physical counterparts for the minted iterations of a generative project.

    Redeemables are a feature that can be toggled on fxhash projects, that enables artists to distribute digital counterparts for their generative collections, and provides the necessary interface as well as smart contract tech to make it possible.

    In essence, redeemables provide a secure on-chain method for artists to distribute physical counterparts to their generative artworks. Redeemable projects can be identified by the “This project can be redeemed” subheading underneath its title:

    Clicking on see more opesn a new page where the artist can provide additional information about the physical item:

    The price of the redeemable is sometimes already included in the cost of the initial collect transaction, but can also be offered in exchange for an up-price when the token is redeemed. Sometimes it is the case that not every collector is interested in obtaining what the redeemable offers (or might in some case not be eligible for it due to their geographical location).

    Redeeming a token executes a smart-contract and triggers an on-chain redeem event. Redeeming a token does not destroy it, nor does it remove the token from your wallet or ownership (it’s not like using up a ticket). The token remains a digital collectible just as before, and remains trade-able, saleable, and transferable in its own right.

    Are redeemables an open feature? Redeemables are rather complex and, for now, can only be created via our internal admin dashboard. Before releasing the feature to the public, we want to test it carefully and ensure we cover the basic use cases. We are open to receiving requests if you want to experiment with redeemables.

    Interested in creating your own redeemable, or have a cool idea for the feature? You can ping us on discord (@fxhash team) or send a mail at

    Redeemables were introduced to fxhash on the 20th June, 2023

    Web3 Storage

    An overview of the different storage solutions that fxhash integrates to make available the projects uploaded to fxhash and their associated outputs.

    One of the core principles of Web3 is decentralization: a paradigm that introduces many benefits over the previous iteration of the web, such as a censorship resistant environment without central authorities that users have to rely on, trustless environments with improved security, and the provision of users with greater control and ownership over their data.

    In other words, Web3 envisions a more decentralized and user-centric internet, leveraging blockchain and decentralized technologies to empower individuals with control over their digital assets, including data.

    What is Decentralization?

    Decentralization in the context of Web3 means distributing control and authority across a network of participants rather than relying on a single central authority, like a traditional server or company.

    In a decentralized system, data and processes are spread out among many nodes or computers, making the network more resilient, resistant to censorship, and less dependent on any single point of failure.

    This shift toward decentralization in Web3 aims to empower individuals, giving them greater control over their data, identities, and interactions online, and reducing the dominance of centralized entities in the digital landscape.

    In this setting, it doesn’t make sense anymore to have data stored on a central server owned by an entity or company. Centralized storage solutions need to be replaced by a different decentralized method.

    Because Data cannot exist in vacuum and actually still needs to be physically stored somewhere, several solutions have been devised for this purpose. fxhash leverages IPFS and ONCHFS.

    Trading $FXH & Art Coins

    Everything you need to know about trading $FXH and art coins

    When does $FXH go live for trading?

    $FXH trading goes live this Wednesday July 2 at approximately 5PM CET

    Releasing your Project

    Everything you need to know to properly release your project on fxhash

    After you’ve created a beautiful piece of generative art, tested it extensively, and made sure that it works properly, it is now time to release your project on fxhash and get it into your collectors' wallets.

    Whether it's your first time, or you've already got a dozen projects under your belt, this is always a daunting step of the process; it takes careful preparation as there are many things that we need to consider. Here are some of the things that should be considered prior to releasing your project.

    Assessing if your Project is Ready

    Generative artworks are every changing beasts - sometimes it can be difficult to decide on a clear cutoff point. A quote from Zach Liebermann captures this very beautifully:

    Token Discovery Tools

    An overview of some of the different tools and methods that can be leveraged for the discovery of new and old works on fxhash.

    On fxhash there’s a constant influx of new works, as well as a varied catalogue of already created projects that might still be up for grabs - all that’s left to do is finding them. There’s a number of tools and resources to assist you in that regard, in no particular order:

    1. The fxhash Marketplace: fxhash’s native marketplace allows you to browse listings and sort them by different criterias allowing you to discover some of the most sought after works throughout the history of fxhash, some of the recent smash hits, as well as recent listings:

    2. fxhash discord

    Account Verification

    Details about the verification badge on fxhash and how to apply for verification.

    Verification systems and verification badges displayed next to users profiles on various platforms have established themselves as an important feature, they serve several purposes:

    • Authenticity and Trust: They confirm that an account/profile belongs to the real person, brand, or organization it claims to represent. This helps to build trust and credibility with users, as they know they are interacting with a legitimate source.

    • Combatting Impersonation: Verification badges can help to prevent impersonation and fraud, as it becomes more difficult for someone to create a fake account and pretend to be someone they are not.

    On fxhash the verification system is put in place to indicate the legitimacy of artist profiles on the platform, which is crucial for collectors to verify prior to purchasing a token. Being verified on fxhash has two benefits:

    Decentralization & Blockchain Tech

    An introduction to Web3, the concept of decentralization, as well as a brief primer on blockchain technology and how fxhash builds on top of it.

    fxhash is a platform that builds on top of Web3 principles and blockchain technology for the distribution of digital code generated artworks. To understand how fxhash makes this possible it is important to have a general idea of what the term Web3 means and how blockchains power this new era of the internet.

    What is Web3?

    With the terms Web1, Web2, and Web3, we are essentially referring to different phases of the World Wide Web - they are different paradigms in which people interact with the internet, and with each other via the internet.

    Web3 refers to the newest of these paradigms: it is focused on decentralization, blockchain technology, and user empowerment. Here it is beneficial to briefly tackle the previous iterations of the internet to get a better understanding:

    Artists' Code of Conduct

    Code of Conduct for artists on fxhash

    Art and artistic expression is at the core of our fxhash. We believe that each artist has the potential to contribute unique and inspiring generative artworks to the collective body of work on fxhash. By putting forth your best effort and committing to excellence in your craft, you not only elevate your individual skills but also enrich the entire community. Here's what this commitment entails.

    Your creative output has the power to influence and inspire others. By putting in the effort to create meaningful and impactful generative artworks, you contribute positively to the overall atmosphere of the community. Your work can serve as a source of inspiration and encouragement for fellow artists.

    Criticism vs Feedback

    Encourage and support your fellow artists in their creative endeavors. While constructive feedback is valuable, it's essential to communicate criticism with sensitivity and respect. Refrain from providing unsolicited or overly negative criticism. Instead, foster an environment where artists feel supported and encouraged. If you have feedback, offer it constructively and be receptive to others' perspectives. A supportive and collaborative community fosters growth and creates a more enriching environment for everyone.

    IPFS

    An primer on IPFS: the Inter-Planetary File System.

    What is IPFS?

    IPFS is an abbreviation for Inter Planetary File System. In essence, as the name suggests, IPFS is a file system designed for the storage of various types of files. It functions vastly differently from the regular file systems that one might be used to.

    Here, the phrase "Inter Planetary" is a play on words that symbolises the decentralised character of this file system. Decentralization being a core value of Web3 technology makes IPFS a good fit and has therefore received wide adoption.

    A good introduction to IPFS in video format can be found here:

    I feel like I am a wildlife photographer trying to capture the best moments of some wild thing that keeps changing / evolving (that I created)

    Some strategies and ideas for deciding if your project is ready:

    • Asking other artists for feedback and their opinions

    • Generating mock collections to assess if the project has enough variety

    • It is also a good idea to set personal deadlines

    • Taking a break from and returning with fresh eyes. It can happen

    A stellar resource for this is Bruce Studio Yorktown's article on the topic in which he condenses his invaluable knowledge in written form, illuminating several aspect

    Creative Considerations For Generative Art Collections

    A Note on Sharing WIPs

    Throughout the process of developing your project it is always a good idea to share WIP posts on your socials, short for Work in Progress it is a good way to build anticipation and excitement for your project. Sharing WIP posts has several benefits:

    • It's a great way to visually document the development process of your project.

    • It shows your collectors and followers that you're dedicating time to your art practice and continuously aiming to improve

    • It informs social media algorithms that you're active and helps you reach new audiences

    • Your social following can provide early and important feedback on your ideas, which in turn can help nudge the artwork towards its final form

    <aside> <img src="https://prod-files-secure.s3.us-west-2.amazonaws.com/f9d1e984-50ed-4650-a543-95d2b6c0ba90/a3295794-cd95-4ae1-b59f-975456aac3c3/fx_doc-icon_info_001.png" alt="https://prod-files-secure.s3.us-west-2.amazonaws.com/f9d1e984-50ed-4650-a543-95d2b6c0ba90/a3295794-cd95-4ae1-b59f-975456aac3c3/fx_doc-icon_info_001.png" width="40px" /> How often and how frequently should you share WIPs?

    There really aren't strict guidelines as to how many WIPs you should share, it's better to share more than to not share any WIPs at all. As a rule of thumb, it's a good idea to check in once a day, put on the content creator pants and share something you've been working on. It tells the algorithm that you're maintaining forward momentum and helps maintain your social outreach.

    </aside>

    Consistency is key here, and building a strong social profile is not something that should be neglected as a digital artist.

    Announcement and Release Timing

    Announcing your project prior to release is always a good idea. Informing your followers on your socials, and letting your past collectors and potential future collectors know about a potential release frame in advance is usually a good idea. Ideally you schedule a release and share a link to your GENTK's project page ahead of time.

    Some things to consider here:

    • The date and time of day can play a huge factor on how many of your collectors can be digitally present to participate in the mint.

    • Other events that might be happening at the same time can also affect the initial minting period of your project.

    Creating a Write-up

    Creating a write-up that details the motivations, inspirations and technical aspects of your project can be very valuable to collectors and other artists. You'd be surprised how many of your ideas might resonate with others.

    Telling the story of how your piece came together from initial conception to final implementation helps your collectors connect with your art on an emotional level. From a technical point of view, explaining some parts of the code that are involved in the creation of your piece can provide great educational value for those interested in learning more, especially to generative art enthusiasts that don't necessarily come from a programming background.

    Detailing some of the technical aspects can also be of value to other artists that are searching for new inspirations and techniques to implement in their own projects. And besides being a vehicle for keeping the conversation going over longer periods of time, it can also serve as a good reference point for your future self, that you can look back to, allowing you to see how you've progressed since then.

    The best way for creating such a write-up/article/post is fx(text), where you can natively showcase GENTKs and even mint the text itself as a collectible digital token.

    fx(params)

    Determinism

    At fxhash we apply a broader definition to generative work to encompass any and all procedural, parametric and generative work which uses fxrand() at its core. This saves philosophical arguments about taxonomy.

    Ideally, all work released on FXHash should adhere to the spirit of the platform in that it should be generative and use a deterministic approach to randomness. Ideally, work should produce the same result given the same transaction hash. This means ensuring that you’re using fxrand() for random number generation and that you’re careful to use the same set of random numbers when the artwork is redrawn.

    If a Generative Token produces different results given the same hash then it is considered in opposition to this principle and will be moderated.

    Imitations, Impersonation and Inspiration.

    Ideally, every project on fxhash should be unique in design and code - if you find yourself inspired by someone else’s work and want to create something similar, ensure that your work transformative enough and evolves the inspiring concept into something new.

    If an artwork is too similar to already existing (and well known) artworks, the fxhash team may moderate it on account of it being misleading towards collectors. If you are uncertain about your project, reach out on discord.

    There is a great deal of nuance to this and artworks, with their code and descriptions, will be taken into consideration before action is taken.

    Images and Layered PNG Artworks (PFP)

    Generative projects can use textures and images in a number of different ways, the simplest of these being layering randomly selected PNGs on top of each other, most commonly seen in PFP projects. These projects are acceptable and welcomed on fxhash but some communication guidelines must be followed to ensure that collectors know what they’re getting when they collect your token.

    • What is acceptable:

      • Projects where javascript is used to layer multiple static images on top of each other or as a collage (ie. illustrations, pfps, etc.).

      • Projects where javascript is used to manipulate or draw on top of a static image.

    • What is NOT acceptable:

      • Projects that simply display a randomly selected image as output from a set of images included in the project directory.

      • Projects that are layered multiple static images on top of each other but not described as such in the project description.

      • Projects that involve static images with javascript being used to manipulate the image further but not described as such in the project description.

    In case you are uncertain about your project, reach out on discord to the fxhash team.

    Project Descriptions

    The methods used to generate these projects must be described thoroughly in the description section of the project and the appropriate tags must be used (ex. PNG, layered PNG, etc.). Labeling them simply as “generative” or “created with p5js/js/etc.” is not acceptable and will be considered misleading language. The language for these projects must include a reference to them being “generative layered pngs” or something similar.

    A good rule of thumb when putting together a description of your token is that there is no such thing as too much communication of the core ideas and methodologies involved in your token. The more a collector knows about the underlying principles of your token the more comfortable they’re going to feel collecting it.

    Make sure to use the tagging system at upload time. It allows you to to add layered / static PNG as tags to clearly communicate the nature of your token making it clearly visible to collectors. You should however still communicate this in the description of your project.

    If you’re struggling with how to describe your artwork, the bare minimum you need to include, if your artwork is made of layered PNGs chosen at random is: This artwork is made by layering PNGs chosen at random.

    Rescheduling

    The scheduling feature is provided as a means to refresh your project's settings and have it appear back at the top of the list. Resheduling should only be used under the following circumstances:

    • Something has gone wrong with your launch - a mistake or issue with the drop that caused the launch to be broken; or

    • A significant change to the allow list; and

    • You have not rescheduled this token already.

    If you're unsure of whether you meet these requirements and want to reschedule your token, please reach out to @fxhash team on Discord.

    Abuse of the rescheduling system will result in the moderation of your token, repeated abuses will result in your profile being moderated.

    Canvas Element & API

    The canvas API and the function that it exposes.

    How to use Libraries

    Including and working with 3rd party libraries.

    Responsive Browser Projects

    Approaches for creating responsive and resizeable art in the browser.

    Deterministic Randomness

    Using PRNGs correctly and pitfalls to avoid.

    User Input & Media Export

    Handling user inputs and how to export your art in various formats.

    Testing Browser Compatibility

    Testing your code's compatibility with the different modern browsers.

    Introduction to Generative Tokens
    IPFS
    ONCHFS
    [email protected]
    Link to Project

    Experimental Curation: Exploring new and unconventional ways of presenting art, often involving multimedia or interactive elements.

    VR Exhibitions: there’s a bunch of other tools that allow you to hang your digital collectibles in 3D VR spaces that users can visit and explore by traversing them like you would explore a video game.

  • Objkt Curations: is a Tezos only marketplace that also offers a curation tool. It is not as advanced as the other two on this list, as it only lets you make sub-groupings of your collected pieces:

  • Physical Exhibitions: If you have a physical location that allows for screens and displays, you could equivalently also host your very own physical exhibition.

  • Deca
    Gallery

    A styles.css file for styling purposes. The styles.css in the boilerplate is empty - meaning that it applies no styling to the HTML. This file isn’t necessary, but often used for the purpose of displaying tokens correctly within the browser window, we address this in more detail in the Responsive Projects page.

  • A LICENSE file in which you should declare usage rights of your code. This file should contain the License that you wish to apply to your project. Because files that are uplaoded to IPFS or OCNCHFS can be viewed an accessed by anyone, it is important to include a legal document that can help protect your intellectual property. A License is essentially a document that details the usage rights for the code and the generated artworks; whether the code can be used and modified by others or not, and the specifics of it. You can read more about it and find suggestion for some common licenses in the Licensing page of the docs.

  • A README.MD file, which can safely be ignored. It's simply the file that provides the description of the boilerplate on its Github page.

  • fxhash API
    Where can I buy $FXH?

    You can buy $FXH directly on the fxhash—once the protocol goes live you'll find a convenient drop-down Buy/Sell widget in the navigation bar (right next to where you connect your wallet) 👇

    There you can swap your ETH for FXH, and vice-versa. This widget will also let you trade other pairs, and customize the trade settings. Of course you can also use your favorite decentralized exchange for swapping FXH ( Uniswap, Aerodrome, etc).

    What's the $FXH contract address?

    This is only official $FXH token:

    0x5fc2843838e65eb0b5d33654628f446d54602791

    Link to the contract address on basescan.

    How do I see the $FXH token in my wallet?

    To view your $FXH holdings in your wallet's token list, you can import the token contract 0x5Fc2843838e65eb0B5d33654628F446d54602791 as follows:

    Where can I track the price of $FXH?

    You can track the price of fxhash directly on Coinbase: https://www.coinbase.com/price/fxhash

    But also on other token indexers like CoinMarketCap, CoinGecko, DexScreener, and other websites.

    What can I do with my $FXH?

    FXH is used to back the value of art coins on the FXH Protocol, and lets you mint, collect, and evolve open-form generative art collections.

    Soon after launch, you will also be able to stake FXH to earn more + govern the FXH Protocol.

    : discord is a popular messaging app where communities can create their own servers around a specific topic. Currently the fxhash discord has hundreds of engaged members as is one of the best ways to interact with the community, to exchange ideas, discuss generative art and discover new projects.

    Discord is a great way to interact with the fxhash community
    • Announcement channels: in these two channels the fxhash team will announce all important things concerning the platform, such as upcoming events and new features when they become available.

    • fx(fam): fx(fam) is a special community event that is held every so often, where collectors and artists can flock together around particular themes, such as hackathon workshops.

    • Artist Studio Channel: this channel is a special forum where artists can create their own threads and share their works in progress, make announcements and give each other feedback. Check in and see if your favorite artist has their own channel.

  • Social Media: most artists have their own social media accounts, on popular platforms like TwitterX, Instagram, most recently also Farcaster, and to some lesser extent on other platforms like Mastodon. Artist will often share their WIPs (works in progress) as social media posts and make announcements about regarding the release of these projects.

  • TwitterX Spaces: For special events fxhash will often also hold TwitterX Spaces; essentially a live audio stream for the purpose of announcements or discussing matters with guests and partners.

  • Third Party Marketplaces: there are other marketplaces that integrate the fxhash smart-contracts and in that manner enable the collecting and trading of fxhash projects. Some of them are:

    1. Opensea: opensea is the largest NFT marketplace that aggregates tokens from many blockchains and platforms. Ethereum projects minted on fxhash (mainnet and the Base L2) can be found on OpenSea. It does not currently have support for the Tezos blockchain.

    2. Objkt.com: similarly to opensea, objkt.com is a marketplace dedicated to the Tezos blockchain aggregating Tezos tokens from various different Tezos marketplaces. Tezos projects minted on fxhash can be found on Objkt.

  • Deca Galleries: Deca is a platform where users can create custom galleries to showcase NFTs from generative art platforms like fxhash, Art Blocks, etc. It is one of the best ways to curate your collection and group related pieces (conceptually or aesthetically). It also has social features where you can follow other collectors as well as your favorite artists, and keep others up to date with upcoming releases.

    1. Independent Tools: some creators build their own exploratory tools, some of them:

      • such as NFT Biker who’s created a number of tools to keep tract and interact with Tezos NFTs. One part of the toolkit is dedicated towards fxhash:

      • The (art) Collector’s Corner by FluffHeadChaser where upcoming releases are continuously curated in form of a nice calendar:

  • Podcasts and Newsletters: with the vibrant community around fxhash many content creators began making fxhash related content, such as interviews with artists, discussions about features of the platform, coverage of events. Some content creators in that regard are the Waiting to Be Signed podcast, the Arbitrarily Deterministic podcast, Kaloh’s Newsletter, as well as many others.

  • Tender Lists: Tender is a curatorial platform that highlights iconic fxhash projects and creates curated drops with prolific artists in the space.

    1. Verified artists automatically bypass the 3 hour safety lock that’s imposed on projects set with an immediate release. As the name suggests, the three hour lock prevents projects from being collected in the initial three hours of their release where projects that are set to release immediately are disabled for the initial three hours to prevent them from being collected. (such that they can’t be collected in this 3 hour time span) between submitting a project, and the project becoming live (if it is set to release immediately).

    2. A badge next to the artist’s name/profile picture on the platform to reflect the verification status.

    At this point in time, there are no other benefits to verification. Verification essentially signals the moderation team that they can trust that your work is yours, follows the CoC and that the intentions of the work are sound. That's it. Those simple measures help in preventing scammers from reaching the front-end of the application.

    Verification on the fxhash platform and Discord are manually applied to applicable applicants, public figures and companies that are at risk of being impersonated.

    Verification is not a right, and the lack of verification does not limit the chances of your work being minted.

    Verification Criteria

    Since verification is a manual process, whose main goal is to prove authenticity of the account, there are a few things which greatly help us to easily and quickly verify you. These are:

    • Correctly linked fxhash account, wallet address, and Discord

    • Proof of existence and work outside of fxhash. This means a twitter account that has some history, instagram etc.

    • A history of work, either on fxhash or another platform - that makes sense in context (e.g. a history of generative/code based practice)

    • A personal website with extra information about you, or an active GitHub, codepen, openprocessing or equivalent.

    • No history of shady activity (e.g. previous moderations or unverification)

    Having multiple minted works, being an active member of the community, having a strong body of work external to fxhash, being a model community member and having socials linked to your account all strongly aid a successful verification.

    If you believe that you're applicable for verification, but do not wish to share any of the above - it makes it very hard for us to spend time on your case. If you want to share extra details with a moderator regarding verification, please DM them

    How to get Verified

    Getting verified simply boils down to filling out the following form: fx(hash) verification application

    NOTE: this form DOES NOT require an email address, and we WILL NOT be able to see your email address if you are signed into google.

    If you have already requested verification, but feel like you have been overlooked, missed, or otherwise haven't received verification as of yet, feel free to fill it in again. Make sure you have an fxhash account before verifying, if your address results in a 404, we cannot verify you.

    The verification process

    Once you have submitted your verification a moderator needs to review your account to see if your profile is in line with our criteria. We check these once per week and process the approved accounts in batches. Due to the number of applications we will not notify you individually if you are approved or not. But feel free to reach out in the Discord and a moderator or community support member may be able to give you an explanation.

    If you are told that you have failed, or after a week have not been verified, you are free to try again.

    Losing your verification

    If you act in a way which is against the CoC, do harm to the community, or become untrustworthy, the moderation team reserves the right to revoke your verification. Since the verification is essentially a way for the community to instantly know who is and isn't trustworthy in the eyes of the moderation team, we cannot allow untrustworthy members the privilege of verified status.

    Before you lose your verification we will likely reach out to you in case we have come to the wrong conclusion surrounding your status - it is unlikely that you will randomly lose your verification without priorly being made aware of it. In some rare instances you may have been verified without actually meeting the correct criteria, much like before we will reach out to you to let you know.

    Collector Verification

    Verification is mainly for the purpose of preventing bad actors from creating works that don’t comply with fxhash’s Code of Conduct. Therefore collector verification is not commonplace yet, but might be subject to change in the future. If you are a prominent large collector with an extensive collection you can however still fill out the form or reach out to moderators for verification purposes.

    Web1 (The Static Web): This was the early stage of the internet, where websites were mostly static and read-only. Users could view information, but there wasn't much interactivity. Content was created by a limited number of entities for users, but users themselves couldn't directly create content.

  • Web2 (The Social Web): This is the current version of the internet that most people are familiar with. It's characterized by social media platforms, interactive websites, and user-generated content. Examples include Facebook, TwitterX, YouTube, etc. Web2 essentially focuses on the participation of users to generate content for each other.

  • Although Web2 mainly revolves around user participation, the created user content/data is handled, controlled, and stored by centralized authorities, such as social media platforms and search engines. In this setting, users are reliant on these intermediaries to interact with and view the content. Web3 is an attempt at moving away from such centralized authorities and making the internet more user-centric. This version of the internet places an emphasis on user ownership, digital identity, transparency and security, as well as interoperability of applications.

    In essence, Web3 aims to make the internet more decentralized.

    What is Decentralization?

    Decentralization in the context of Web3 means distributing control and authority across a network of participants rather than relying on a single central authority, like a traditional server or company.

    In a decentralized system, data and processes are spread out among many nodes or computers, making the network more resilient, resistant to censorship, and less dependent on any single point of failure.

    This shift toward decentralization in Web3 aims to empower individuals, giving them greater control over their data, identities, and interactions online, and reducing the dominance of centralized entities in the digital landscape.

    What is a Blockchain?

    Blockchains are the underlying technology that makes decentralization in Web3 possible. They serve as the technological backbone of Web3 and enable digital ownership, a crucial notion in the context of fxhash.

    What is a blockchain?

    A blockchain is a decentralized and distributed digital ledger technology that securely records transactions across a network of computers. Each transaction is grouped into a block, and these blocks are linked together in a chronological chain using cryptographic hashes.

    The decentralized nature of blockchains ensures that no single entity has control over the entire system, reducing the risk of tampering and enhancing trust.

    Initially, blockchains were conceived as alternative financial systems, and to create decentralized and tamper-resistant systems for conducting and recording transactions without the need for a central authority such as a bank. The technology has evolved significantly since then, opening up many other use cases. One of which is digital ownership.

    These immutable and tamper-proof digital ledgers make it possible to tie specific digital tokens to transactions, and the ability to unambiguously trace back to whomever effectuated a transaction makes it possible to attribute ownership of these digital tokens. This is explained in greater detail in the sections NFTs and Smart Contracts.

    A great introduction to how blockchains work is the seminal video by 3Blue1Brown, although it focuses on the bitcoin blockchain as an example, the concepts introduced can be extrapolated to other chains as well:

    A Decentralized Peer-to-Peer Network

    Traditionally, in Web2.0, files are stored on centralized servers, centralized in this setting means that these servers are owned by specific entities, companies and individuals. Although users can view and interact with that data via the web, they are always reliant on this central authority to serve that data.

    Instead of relying on such a centralized approach to file storage, IPFS uses a decentralized approach that distributes files over a network of nodes - where these nodes are simply the machines of the users that choose to participate in the network.

    Moreover, in this setting, each user's device on the network is both a client and a server. This is in contrast to the client-server model where users connect to a central server to request data. With IPFS, users can request and share data directly with each other. Peers on the network collaborate to share and distribute files, creating a more resilient and scalable system.

    Content Based Addressing

    Traditionally, when requesting a file from a server we are essentially asking the server to retrieve his file from a certain location by means of an address (urls basically), this is known as location based addressing.

    Instead of location based addressing, IPFS makes use of content based addressing. This is because the same file could be stored on several nodes throughout the network, hence we would simply need to retrieve that file from one of these nodes. In this case it doesn't matter where the file comes from, simply that the correct file is requested. This can be done by assigning a unique identifier (a hash essentially) to each file on the network.

    Files and all of their versions are uniquely identified using content-addressed hyperlinks, meaning that the content of a file is used to generate its unique identifier (hash). This hash is then used to locate the file on the IPFS network. This hash isn't generated at random, but rather is derived from the data itself, meaning that the data predicates what this hash will look like, making it such that there is a 1-to-1 mapping between the hashes and the files.

    Having the hash derived from the data itself has several inbuilt advantages:

    1. Security: when requesting a file by its hash, the data needs to match the hash otherwise it is not valid. This makes it such that Files can't be tampered with by actors on the network.

    2. Deduplication: If two files are identical, they will produce the same hash, meaning that there is no reason to store the file a second time.

    3. Immutability: Once a file is added to IPFS and given a hash, the content cannot be changed. If you modify the file, you create a new hash. This ensures data integrity and allows anyone to verify that the content they retrieve matches the expected hash.

    4. Versioning: The technical details of how this is implemented are beyond the scope of this resource, but IPFS also makes it easy to update files by providing a versioning system. Every change to a file results in a new identifier, allowing for easy versioning and tracking of changes, where the new file adds a pointer to the previous one.

    Downsides of IPFS

    While IPFS has many advantages and innovative features, it's important to be aware of some potential downsides and challenges associated with the technology. Some of them are:

    1. Content Availability: most notably the biggest flaw of IPFS, for files to be available on the network, there needs to be at least a single node hosting that file and making it available. If this node for some reason goes offline, as a consequence, the files that are only hosted by this node also become unavailable.

    2. Speed: The speed at which you can retrieve content from IPFS depends on the popularity of the content and the number of nodes (peers) hosting it. Less popular content might take longer to retrieve, and some content may not be available if there are not enough nodes hosting it.

    One countermeasure to content becoming unavailable is "pinning" (from the verb to pin), where the IPFS network is explicitely instructed to retain a specific piece of content regardless of it being accessed by nodes or not. There are certain dedicated services for this purpose than can automate this pinning process, such as ClubNFT, but can equivalently be done from your own local machine, which would require a little setup however.

    How does IPFS integrate into fxhash?

    IPFS is often used for various applications, including decentralized websites, file sharing, and data distribution. It aims to create a more resilient and censorship-resistant internet by changing the way data is stored and retrieved, making it less dependent on centralized servers, thus making it a popular solution in that regard.

    What is ONCHFS?

    An overview of ONCHFS

    Motivations

    Rationale behind our Onchain File Storage

    System Overview

    Cross-chain Referencing

    Limitations

    References

    Licensing your Project

    An over of Licenses, what they are, and some of the popular types of licenses that can be used for fxhash projects.

    If you want to learn more about a particular license, here’s a useful lookup tool that explains licenses in plain English.

    What is a license?

    A license allows someone else to use, modify, or share software or creative works, under certain conditions set by the owner. It outlines how the work can be used, distributed, modified, and under what conditions. Licenses are crucial for defining terms of use and interaction with intellectual property. Essentially, a license specifies:

    1. Permissions and Restrictions: A license details what you can and can’t do with the work, like using, changing, or sharing it.

    2. Attribution: Many licenses require that the original author or copyright holder be given credit for their work. This is often referred to as attribution.

    3. Distribution: Some licenses set rules for how you can share the work with others.This may include whether the source code must be made available, whether modifications can be distributed, and if there are any restrictions on distribution methods.

    In this sense licensing your fxhash projects is incredibly important, since they are essentially pieces of software, and at the same time publicly visible and accessible once uploaded to IPFS or minted on ONCHFS. A clear license informs others how they can use your code and the project's outputs, and legally protects you against misuse of your work.

    Types of Creative Commons Licenses

    Creative Commons (CC) licenses allow creators to share some rights with the public while retaining others. These licenses provide a flexible range of permissions for authors, artists, and other creators. Here's a quick list of some of the most popular CC licenses that have different degrees of restrictions on reuse of your project:

    1. CC BY (Attribution):

      • Allows others to copy, distribute, display, and perform the work and derivative works based upon it, but only if they give the author or licensor the credits in the manner specified by these.

      • This is the most permissive CC license in terms of what others can do with the works.

    2. CC BY-SA (Attribution-ShareAlike):

    It's important to choose the Creative Commons license that aligns with how you want others to use your work. The licenses are designed to be easy to understand and use, promoting a balance between sharing and protecting the rights of the original creator.

    You can . The page also provides a useful license chooser tool that helps you determine which license could be a good fit by answering a set of questions.

    Other Permissible Licenses

    CC licenses are generally used for a wide range of creative works, including images, music, literature, and other artistic expressions. Whereas CC licenses are more flexible and adaptable to different types of content and creative endeavours, there are other popular permissible licenses that are frequently used for software:

    • GNU General Public License (GPL): GPL is a widely used open-source license that allows users to use, modify, and distribute the software freely. Any derivative work must also be distributed under the GPL.

    • MIT License: The MIT License is a permissive open-source license that allows users to do anything they want with the software as long as they provide proper attribution and don't hold the developers liable.

    • Apache License: The Apache License is a permissive open-source license that allows users to use the software for any purpose, to distribute it, to modify it, and to distribute modified versions under the terms of the license.

    About Modifying Licenses

    Should you modify standard licenses? In general, it is not recommended to modify existing licenses on your own, especially when dealing with standard licenses like Creative Commons licenses or open-source software licenses. These licenses are legally crafted documents that have been carefully designed to balance the interests of creators and users, and modifying them can lead to legal uncertainties.

    If you need specific terms that are not covered by existing licenses, it's usually better to choose a license that aligns closely with your intentions and then supplement it with additional terms or permissions outside of the license itself. You can include a separate document or agreement that outlines any additional conditions or permissions.

    For critical modifications or if your needs are not met by existing licenses, you may want to seek legal advice to draft a custom license or to explore alternative licensing options. Creating a new license or modifying an existing one requires a deep understanding of intellectual property law to ensure that the resulting license is legally enforceable and achieves your desired goals.

    Overall, these are just some considerations, depending on your needs, requirements and restrictions that you would like to impose, and depending on what libraries you include in your project you might need to use a different license.

    API Overview

    Overview of the fxhash project SDK and API

    In the previous sections we've had a look at the structure of an fxhash project, introduced the boilerplate as a minimal starting point for new projects and also had a first look at the CLI as an alternative method to setting up blank projects.

    Both the boilerplate and the CLI are a part of the fxhash Project SDK—essentially a number of resources that fxhash provides, with the aim of facilitating the development and creation of projects for the platform. This encompasses this documentation, the CLI, the Boilerplate, and most importantly the fxhash.js script. This script file is also referred to as an API.

    In other words, the fxhash API is simply a fancy term to refer to the functions that the fxhash.js script exposes within the scope of an fxhash project. These functions provide useful functionality for artists to build deterministic generative artworks that work properly and are platform compatible once uploaded to fx(hash).

    What is an SDK?

    SDK is an abbreviation for the term Software Development Kit, an SDK usually represents a bundle of code, tools, and documentation provided by the creators of a platform for third party developers, and is aimed at aiding them in creating software that is compatible with the platform.

    What is an API?

    The abbreviation API stands for Application Programming Interface, and refers to the code part of an SDK. It's a software-to-software interface that allows developers to build platform specific software. APIs usually provide numerous functionalities that are useful and sometimes necessary for the purpose of compatibility.

    How does this API work? Why do we need to use it? And moreover, how do we use it? All of these questions should be answered by the end of this page. If you’re more experienced, know what an API is, and simply want to have an overview of the different functions it provides you can jump to the following , and .

    Why do we need to use the API?

    The fxhash API is a code library designed for developing deterministic generative systems. It provides a pseudo random number generator (PRNG) that can be used as the primary source of randomness throughout a generative token's code. Moreover, it automatically seeds this pseudo random number generator with the hash that is injected into the code.

    Furthermore, depending on what kind of token you want to develop, and depending on how the randomness should behave, the SDK provides a couple of options for that as well. It provides a number of functions to generate different kinds of random numbers and/or make random decisions throughout the code.

    Technically, the PRNG provided by the API isn't mandatory - as an artist you can also equivalently implement your own PRNG function, under the condition that it is seeded correctly with the hash that the API script injects into your code. The hash is therefore the only part of the API that is required. We strongly recommended to use the API however, in this manner you can focus on building your generative artwork rather than spending time on programming a PRNG.

    What does the fxhash.js script file do?

    When we had a look at and introduced , we’ve seen that the index.html should reference the fxhash.js script within it’s head tag. By doing so the fxhash.js script is run when the webpage is viewed in a browser. Although there is a lot of code inside of the fx(hash) script file, the main purpose of it is the creation an $fx object and attaching it to the window object as a property.

    What is the window Object?

    In JavaScript, the window object represents the global context for a web page or a browser environment. It is the top-level object that contains global variables and functions accessible throughout the entire JavaScript runtime in a web page. Attaching new properties/variables makes them accessible throughout the scope of all scripts, which is why the $fx API object is attached as such a property.

    This $fx object is essentially a container for the functions of the fxhash project API, making them available for usage in the artist script, namely the index.js file.

    What is this $fx object?

    If you’ve already installed the CLI and created a new blank fxhash project, we can see for ourselves what this $fx object is. While keeping all of the files unchanged, we’ll only delete the contents of the index.js file, and replace it with a single line of code that logs this $fx object to the console:

    If we now open the index.html in our browser, we'll get a blank, white browser window (because we deleted the previous code), but if we check the console however, we'll see that something has been logged:

    This is the content of the $fx object created by the fxhash.js script. There's a bunch of stuff inside of it: a number of properties, functions, and other objects. All of these are now accessible in the artist script and available for our convenience to build a generative artwork with.

    What is an Object in programming?

    Objects in programming are usually containers for variables and functions. The contained variables and functions are referred to as member variables and methods respectively. They can be accessed and invoked using the dot notation, for example $fx.rand() invokes the rand() function contained inside the $fx object.

    One last note here, it is not recommended to change the code inside of the fxhash.js script for your generative token to work properly:

    You should not change or edit the code inside of fxhash.js for your GENTK to function properly.

    A complete run-down of all API functions can be found in the A detailed explanation of these functions can be found in the .

    Project Structure

    This page explains the structure of an fxhash project, providing an overview of the individual files and their purpose.

    Generative artworks on fxhash are self-contained web projects that run in the browser. In other words, fxhash projects are mini web pages that display generative graphics, which are served inside an iframe whenever they are requested by a user in the interface.

    If your project is not working in the sandbox or the mint preview, the most common reason is that you are likely trying to make networked requests or load in external script files. All assets required for your project need to be contained within the source directory.

    An fxhash project needs to follow a specific structure—at the bare minimum it needs to consist out of:

    CLI Setup

    This page provides an introduction to the fx(hash) CLI - Command Line Interface - a helper tool that simplifies the development process of an fx(hash) project.

    Whereas the Starting Template provided a simple and minimal starting point for creating new projects, the CLI will allow us to get a bit more hands on and provides a number of useful functionalities for the purpose of developing a project, running it locally, as well as testing it.

    If you’re relatively new to programming, the learning curve of what follows might be a bit steep, as there's a number of new notions that we'll have to familiarise ourselves with, and will have to set up a couple of things on our machines. But we'll tackle one thing at a time. To provide a quick overview, in this section we will:

    • Learn about Command Line Interfaces (CLIs)

    • Learn a little about Node.js and the Node Package Manager (NPM) with which we’ll install the fx(hash) CLI

    Secondary Market

    An overview of the necessary interfaces for collecting on fxhash’s Secondary Market, outlining the different trading mechanisms and collecting methods that make it possible to exchange existing GENTKs

    The Secondary Market refers to the fxhash marketplace where collectors can buy, sell, and trade already minted iterations amongst themselves.

    Once a an edition of a project is minted, it can commence its lifecycle on the secondary market. Minted editions become their own standalone NFTs, tradeable just like any other non-fungible token on the blockchain. This allows fxhash to provide a secondary marketplace in which collectors can trade among each other, resell their acquisitions, or acquire desired pieces from other collectors.

    In this way collectors to expand their collections in a targeted manner, hunt down specific artworks that they’d like to own, or scour for select pieces that align with pre-defined collection themes or desired aesthetic qualities. In certain cases, some collectors collect exclusively on the secondary market. fxhash provides the necessary interfaces to facilitate these transactions. In this section we provide an overview of the relevant UI elements, and explain the different methods to sell and acquire tokens on the secondary market.

    User Input & Media Exports

    An overview of handling user input, listening to key presses, exporting the artwork at different resolutions and passing in values as URL parameters.

    Artists often choose to add additional user interaction options to their generative artworks, for instance the option to export the artwork in various formats by means of a key press, the ability to switch between different resolutions, toggling on a debug mode, as well as all kinds of other experimental user interactions. These are often nice features to have and can greatly elevate the project.

    In this section we will discuss some of the methods for exporting the canvas as an image via a key press as well as other interaction options.

    Exporting the Canvas

    Although the canvas can be saved as an image through the right click menu in the browser, it's a good idea to add in a dedicated key for that purpose. Just like we previously resized the canvas with an event listener, we can also use event listeners to detect key presses:

    Including Libraries

    An overview of some of the popular libraries for creating generative art on fxhash.

    While the Canvas API is already quite versatile, it can at the same time be a little clunky and hard to work with. In this section, we'd like to introduce some of the popular libraries that can be used to create various kinds of graphics in the browser and streamline certain approaches for making generative art.

    Including Libraries in your Project

    Withdrawing Earnings on ETH/Base via splits

    This section provides an overview of how to withdraw earnings received from ETH & Base fxhash projects, as well as an overview of the Splits smart contract app that’s used for this purpose.

    With the integration of mainnet ETH and the Base L2, fxhash started using a solution call Splits to optimize the fund distribution. TLDR: To receive your project earnings, log into with the wallet that is supposed to receive the funds.

    About & Withdrawing Funds on ETH

    When publishing a project on mainnet ETH or the Base L2 network, funds received from the sale of the project’s editions do not directly/automatically get sent to your wallet, as you might be used to from releasing your projects on the Tezos side of fxhash - but rather get sent to a special contract that pools these funds from which they have to be manually withdrawn.

    fx(params) & the Ticketing System

    An overview of collector customizable fx(params) projects and the associated ticketing system for minting these projects.

    fx(params) was introduced by fxhash on March 20, 2023. It is currently a feature exclusive to the Tezos blockchain.

    fx(params) is a different way for collecting GENTKs on fxhash, where the collector plays an active role in the configuration of the GENTKs appearance. fx(params) is the name of the module that enables artists to relinquish control over certain variables in their code and exposing them to the collector at mint time, such that collectors can modify and customise the artwork to their liking before collecting their unique iteration.

    This customization process happens through a special minting interface, where collectors can modulate toggles and sliders to vary the values of those code variables to shape the artwork to their liking.

    However, fxhash also allows artists to create their own custom minting interfaces with code driven parameters, which greatly extends the possibilities of fx(params). Overall, fx(params) is intended to amplify artistic powers of expression and enables collectors to become co-creators of the art.

    Platform Moderation

    An overview of fxhash's moderation system, guidelines, and procdeures

    While fxhash embraces an open model, this open nature also makes it a perfect target for malicious individuals and bad actors. Back in 2021 when fxhash was still at the start of its journey, copyminters took advantage of the momentum and the good energy in the community to scam enthusiastic collectors.

    What is a Copymint? A copymint is a project published by someone other than its original author, that doesn't have the right. This is done with the malicious intent of profiting from someone else’s work.

    Because of the open nature of fxhash, no curation of the content is made prior to projects being minted. Regulating such malicious behaviour becomes difficult. And although verification is a first step in the prevention of malicious mints, more tools have been deployed since - one of them being the “Report and Moderation System". A set of features added to the front-end to protect collectors from malicious projects.

    Allow Lists & Reserves

    In this section we provide an overview of Reserves and Allows Lists, tools that allows artists to control the minting access to their projects on fxhash

    Allow Lists and reserves provide artists with a general-purpose framework for controlling the overall mint access to their generative projects:

    Allow List / Access List: A list of artist approved wallet addresses that have exclusive access to a number of reserved editions/iterations from a generative project.

    While the two terms “Allow List” and “Reserve” are frequently used interchangeably to refer to the same feature, they are actually not the same thing. As stated, an allow list refers to the actual list of wallet addresses that are eligible for minting from a reserve - where this reserve refers to the number of editions/iterations from the generative project that have been set aside, and can only exclusively be minted by the addresses on the allow list:

    Derivative Works: Licenses can state if you’re allowed to make and share new creations based on the original work. Some licenses, like the GPL (GNU General Public License), require that derivative works also be released under the same license.
  • Commercial Use: Licenses may say whether you can use the work for profit or only for non-commercial purposes.

  • Allows others to remix, tweak, and build upon the work even for commercial purposes, as long as they credit the author and license their new creations under the identical terms.

  • This license is often compared to open source software licenses.

  • CC BY-NC (Attribution-NonCommercial):

    • Allows others to remix, tweak, and build upon the work non-commercially, and although their new works must also acknowledge the author and be non-commercial, they don't have to license their derivative works on the same terms.

  • CC BY-ND (Attribution-NoDerivs):

    • Allows others to download the works and share them with others as long as they credit the author, but they can't change them in any way or use them commercially.

  • CC BY-NC-SA (Attribution-NonCommercial-ShareAlike):

    • Allows others to remix, tweak, and build upon the work non-commercially, as long as they credit the author and license their new creations under the identical terms.

  • CC BY-NC-ND (Attribution-NonCommercial-NoDerivs):

    • The most restrictive of the six main licenses, only allowing others to download the works and share them with others as long as they credit the author, but they can't change them in any way or use them commercially.

  • CC0 (Public Domain Dedication):

    • Allows creators to waive all their copyright and related rights, effectively placing their work in the public domain.

    • The most permissive option, as it allows for the broadest use without any restrictions.

  • BSD Licenses (Berkeley Software Distribution): BSD licenses are a family of permissive free software licenses that allow users to do anything they want with the software, as long as they include the original copyright and license notice in any copy or substantial portion of the software.

    find a list of these creative commons licenses here
    Some of NFTBiker’s tools help you keep track of the releases during specific events.
    (art) Collector's Corner
    page
    for an reference of the general API
    this page for a reference of the fxparams module of the API
    Projects on fxhash are deterministic generative artworks that can reliably re-generate the same output when the same input hash is used injected into their code.
    the structure of an fx(hash) project
    the boilerplate
    API Overview
    API Reference
    The $fx object that is instantiated by the fxhash.js script, logged to the browser console.
    Libraries cannot be linked as scripts that fetch an external URL. Any library that you might use for your project needs to be included as standalone file inside of your project.

    Projects on fxhash cannot make any network requests. This means that they cannot communicate with a server, nor send or fetch data over the internet. For example, we cannot fetch a library from a CDN like cdnjs or jsdelivr:

    The reasons why this is not allowed:

    • It ensures the longevity of fxhash projects: projects should be self contained bundles of code that can run independently of external resources.

    • A measure against malicious intent: It prevents bad actors actors from building malicious fxhash projects intending to preform certain malicious actions on your device.

    It is necessary that any libraries used in the project is included as standalone script file within the project's directory, and referenced correctly via its relative path.

    The proper way to use a library is thus simply by downloading it from its official website, then moving/pasting it in the project's directory. In our index.html file we then reference the library (generally in the head tag before your artwork script runs) such that the library's functions are available in our own script:

    If you're using node.js to develop your project, you can also download libraries via npm, and them simply bundle your project for fxhash.

    A Note on Library Licenses

    When using a library, it's crucial to ensure it's distributed under a permissible license that allows for derivative commercial use. Licensing can be complex; some licenses grant full open-source rights, allowing you to use the code however you like, and even modify it for your own purposes, whereas others impose restrictions on derivative work and how the library can be redistributed.

    We discuss these concepts in more detail on our Licensing page.

    What is a permissible license? A "permissible license" is a software license that allows specific activities without infringing on the granted rights. This term often applies to open-source software licenses, which clearly outline the permissions and restrictions for using, modifying, and distributing the software.

    Reusing Libraries stored with ONCHFS

    In case you are intending to store your project onchain via ONCHFS, then storage costs are something to be considered as they might get pricey

    P5

    Built on top of the canvas API, P5 is the spiritual successor to the Processing language. It powers creative coding in the browser, and is by far the most popular library for making generative art on fxhash, many projects make use of it.

    The main strength of P5 is that it is very easy to get into, and makes coding accessible to a large group of people. Moreover, it is an open-source library, which allows you to freely use and include it in your projects. It also has a flourishing community around it and there's a plethora of resources out there specifically for making visuals with code.

    Here's a simple example of what the code for a P5 sketch looks like:

    P5 has two integral functions setup() and draw() - and as their name suggests, the setup function should contain all of the code that you want to run before drawing things to the canvas, whereas the draw function usually contains the code that draws things to the canvas.

    One immediate useful thing about P5 is that you don't even have to create a canvas element manually, it provides a function that does this for you. By invoking the createCanvas() function P5 will create a canvas element and insert into the html of the page that it is run in. You should also specify the dimensions of the canvas as input parameters to that function. Then all of the p5 drawing functions will automatically draw to that canvas. P5 is very versatile, so there's a lot more that can be done here.

    The advantage of using P5 in this scenario is that it adds a layer of abstraction on top of we don't have to write as much code as we would have to with pure CSS and Javascript.

    A note on running P5 in global mode with fxlens (and in other bundlers)

    When using P5 with a bundler—like when you do when using fxlens—you will find that the setup and draw functions won't trigger when using P5's global mode. For example, placing this code in the index.js file will not render a canvas to your html page using fxlens:

    In global mode, p5.js relies on attaching its functions (like setup(), draw(), ellipse(), etc.) to the global window object so they can be accessed without a prefix.

    Bundlers however encapsulate modules in local scopes to avoid polluting the global namespace. As a result, p5 can't find those functions on the global window object and won't automatically run setup() or draw(). To work around this, you could use P5's instance mode:

    Or explicitly bind your functions to the window object as such:

    Alternatively, if you run P5 in global mode from another file—that's not named index.js—or runn it directly inside a script tag in your html, the P5 functions might end up on window, triggering global mode behavior. But to reliably use global mode in a bundler, you have to either attach your p5 functions to window manually, or use instance mode to avoid scope issues altogether.

    Other popular libraries

    There are other popular libraries that are also used for the purpose of making generative art on fxhash, some of them aren’t directly libraries that draw graphics to the canvas, but rather in some cases act as auxiliary helper functions for making certain tasks easier. Some popular ones are:

    • Paper.js

    • chroma.js

    • Spectral.js

    • p5.brush

    • More added soon

    There are many more libraries that can be used.

    console.log($fx) // logging the $fx object to the console
    <!-- this is not allowed -->
    <script src="<https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.8.0/p5.js>"></script>
    <!-- The p5 script is inside a folder called 'libraries' -->
    <script src="./libraries/p5.min.js"></script>
    function setup(){
    	createCanvas(400, 400)
    }
    
    function draw(){
    	ellipse(200, 200, 200)
    }
    function setup(){
        createCanvas(400, 400);
        background(220);
    }
    
    function draw(){
        ellipse(p.mouseX, p.mouseY, 50, 50);
    }
    const sketch = (p) => {
      p.setup = () => {
        p.createCanvas(400, 400);
        p.background(220);
      };
    
      p.draw = () => {
        p.ellipse(p.mouseX, p.mouseY, 50, 50);
      };
    };
    
    new p5(sketch);
    window.setup = function () {
      createCanvas(400, 400);
      background(220);
    };
    
    window.draw = function () {
      ellipse(mouseX, mouseY, 50, 50);
    };
    An index.html file that the browser uses to display the artwork.
  • A styles.css stylesheet that helps display the HTML file properly.

  • And a script.js JavaScript file that contains the artist's code and is responsible for generating the artwork/graphcis.

  • Additionally, fxhash provides a script file fxhash.js (or fxhash.min.js as a minified version) that provides the functionality to make the project compatible with the platform.

    If you're familiar with these technologies, here's a quick example of what each file should contain:

    Every web project typically has a primary HTML entry point, also known as the index file. This file usually represents the initial view of a webpage, and in the case of generative art project on fxhash is the page that will display your generative artwork. In essence it's the page that fxhash serves to the client whenever a project is viewed.

    Here is an example of what a minimal index.html page looks like:

    <!DOCTYPE html>
    <html>
    	<head>
    		<title>Title of the Project</title>
    		<meta charset="utf-8" />
    		<script src="./fxhash.min.js"></
    

    It is necessary that every fxhash project has this index.html file. And it needs to be titled index.html . This HTML file will either contain all of the necessary code, including the CSS and the JavaScript, or reference them as other files in the same directory.

    This JavaScript file contains the artist written code that makes the generative artwork happen. Most, if not all of your code should go here.

    It actually doesn't matter what this file is called, it just needs to be referenced correctly within the index.html file. Alternatively, the script could also be placed directly inside the index.html within a <script></script> tag.

    Moreover, it is often the case that larger projects split their code over several script files, which is also perfectly fine. In that scenario the index.html file just needs to reference all of these files.

    The stylesheet will generally only contain a few styling instructions for the purpose of correctly displaying the generative artwork in the browser. In that sense, this file is optional, but is useful for centering and containing the artwork within the browser window responsively, or resize the artwork when the dimensions of the browser window change, if it is meant to be a dynamic piece.

    In the scenario of centering a static artwork within the browser window, the content of the stylesheet would look something like what follows:

    We talk in more detail about what these CSS rules do in the Responsive Webpages Section.

    A necessary script file provided by fxhash - every project needs to include this file. This script exposes a number of functions that make your project compatible with the fx(hash) platform.

    These functions are geared towards aiding artists in turning their generative artworks into deterministic generators - we will have a detailed look at the contents of this file in the Project SDK & API section, where it'll be properly introduced

    If you're not familiar with the general structure of a webpage, here's additional information to get you up to speed:

    HTML

    The three core technologies that generally make up a webpage are:

    HTML (Hypertext Markup Language): This is the backbone of nearly every webpage and the standard markup language of the internet. A markup language uses symbols inserted in a text document to control its structure, formatting, or the relationships between its parts. HTML's primary purpose is to structure content on a web page.

    HTML primarily functions on a basis of tags that define and structure the content of the web page. These tags come in the form of specific keywords that are enclosed in angle brackets <> . Tags usually come in pairs: an opening tag and a closing tag containing some text, or other tags in between. The opening tag indicates the beginning of an element, and the closing tag indicates the end of that element. These tags are then used as instructions by the web browser to structure the content between these tags.

    In the case of fx(hash) projects we're usually not going to write much HTML code, usually none at all - except maybe in a scenario in which the artist is creating a generative artwork with HTML and CSS. The index.html that comes with the boilerplate is a very simple web page that references the two js files, the fxhash.js file and index.js file, that are also found in the boilerplate folder.

    Why is the fxhash.js script referenced in the head tag, whereas the artist's index.js script is included in the body tag?

    It is common practice to include important scripts required for the proper execution of a web page in the head tag - scripts referenced in the head tag are loaded in before the page is actually run by the browser - this makes sure the fx(hash) functions are available when the time comes to execute the artist script. If you include third party libraries in your project, you should also reference them in this head tag.

    A few other tags that also exist in the index’s head are:

    • title: the title tag is the title of the webpage, and should contain the name of your project. When your artwork is opened in live view, this title will appear as the title of the tab it is open in.

    • meta: some metadata information about the document, this is a standard tag that is included in every webpage. Usually it is left as is.

    • stylesheet: a reference to the css stylesheet that takes care of formatting the html document. This will simply bring in the styling instructions, if any.

    Additionally, you can include a special tag in the head of your project in case you'd like the page to display a favicon when it is opened in live view - you'd simply drop the favicon file (a PNG or SVG file) in the project directory alongside the other files and link it as such:

    A good example for this are loackme's projects—that always include a custom favicon:

    CSS

    CSS (Cascading Style Sheets): This style sheet language describes the presentation of documents written in markup languages. Used with HTML, CSS makes webpages visually appealing. It controls page layout, visual properties of elements, typography, and more. In essence, CSS gives webpages their visual aesthetics.

    JavaScript

    JavaScript (JS): Now arguably the most popular programming language, JavaScript is the primary language used on the Web. It adds functionality and interactivity to webpages. JavaScript can also generate graphics in the browser, making it increasingly popular for creating generative art. It's commonly used in fxhash projects.

    Although these are the main 3 technologies that you need to have a grasp of for making a project on fxhash, there are other approaches that you can

    In the next section we'll have a look at the fxhash boilerplate - a starting template that already includes all of these files and essentially constitutes the quickest way to get started building a generative token for fxhash, without you having to manually create these files.

    Subsequently install the fx(hash) CLI

  • Use the fx(hash) CLI to set up a blank fx(hash) project

  • Using the fx(hash) CLI is completely optional. It is simply intended for streamlining the development process of a project by providing all of the fx(hash) artist tools in a single place. You should however still give this page a read and decide for yourself if the functionality it provides might be useful for your own workflow.

    What is a CLI?

    A Command Line Interface (CLI) is a text-based interface for interacting with a computer via text commands. A CLI is also often referred to with the following terms: console, terminal, command line, command prompt. These terms can be used interchangeably.

    CLIs stand in contrast to graphical user interfaces (GUIs) that most are familiar with, where we navigate and interact with the computer through visual elements like icons and buttons. A CLI relies on text-based commands and responses to do so.

    What’s the difference between a CLI and a GUI?

    The abbreviations CLI and GUI stand for the terms Command Line Interface and Graphical User Interface respectively. Modern operating systems generally make use of GUIs to allow users to navigate directories, manipulate files, and interact with applications in a visual manner.

    Operating systems also come equipped with a CLI that lets you perform all of these tasks via text based commands. CLIs are often preferred by developers and power users for several reasons, including efficiency, automation, and the ability to perform advanced tasks, where certain tasks can only be performed via terminal commands.

    Here's an example of what the terminal looks like on a Mac:

    The terminal on Mac OS

    You can often also find a terminal integrated within certain code editors like VSCode:

    Terminal inside the VSCode editor

    Within CLIs you can write specific commands to navigate directories, manipulate folders and execute certain programs:

    For example, here we navigated to the Desktop directory via the cd command, and then returned back to the parent user directory with cd .. . These commands vary between different operating systems.

    In this section we'll have a look at the fx(hash) CLI, a tool that provides a number of commands to help with the creation and development of fx(hash) projects - we'll cover how to install this CLI, explain some of the required tech that it needs to function, as well as how to get a project started with it.

    What’s the difference between a Command Line Interface and a Command Line Tool?

    The term Command Line Interface is often used interchangeably with the term Command Line Tool.

    Whereas a CLI is the overall environment or interface that allows users to interact with a computer or software via text-based commands (the text box into which you type the commands), a command line tool is a specific software application that can be executed from the CLI to perform particular tasks.

    Node.js and the Node Package Manager

    To use the fxhash CLI we need to have node.js and the node package manager installed on our machine. If you're familiar with these tools and have used them before, you can skip to the next section for the installation instructions, if not, read on.

    Why do we need Node.js and the Node Package Manager?

    The fx(hash) command line tool comes in the form of a node package, which can be installed with the node package manager. We're actually not going to use node except for the purpose of installing the fx(hash) CLI. Hence you don't have to worry about learning Node.js - we'll just give a brief overview before we guide you through the installation steps.

    If this is your first encounter with node, here's a brief overview.

    Node.js not a programming language, and it's also not a framework or library - but rather it's a runtime environment that allows you to run Javascript code outside of the browser. It is usually used to run Javascript code on backend servers to run javascript code server-side. Over the years it has become a popular and established tool for building various types of web applications.

    NPM, is short for node package manager, and as the name suggests is used to install node packages made by third parties. These packages are bundles of Javascript code that solve specific problems or accomplish particular tasks - they're generally intended for reuse in other projects; you can think of them as lego blocks. The node package manager takes care of the distribution of these packages, and we’ll be using it to install the fx(hash) CLI that is itself a node package.

    What's cool about npm is that it also takes care of version control - if the fx(hash) team pushes an update to the CLI, you can simply check for this update with a simple command from your terminal.

    Overall, it's definitely a more advanced tool - it introduces a lot of new things that might take some practice to get used to. Although you don't actually need to know that much about Node to use the fxhash CLI (you can simply skip to the next section at this point) - if you want to learn more about what Node is and how it functions, the official node docs provide a slightly technical starting point:

    If you want an alternative more lighthearted introduction to node in video format, we recommend this video by Fireship:

    A quick guide to installing Node & NPM

    Let's start with installing Node - there's a number of different ways to do so, the easiest of them being through the main website with an installer, you can find the official page here

    Otherwise you can install node via the terminal - the instructions for this can differ depending on what operating system you're working on. Since most users are probably running Windows or macOS, we'll cover these two scenarios. Instructions for installing Node on other types of operating systems can be found here

    Installing Node on Windows

    Installing Node on macOS

    Here we've got a couple of options, either via a curl command:

    Or with via homebrew:

    In both cases simply copy paste the command to your command line and hit enter.

    Checking your Install

    To check if node has been installed correctly, run the following command from your terminal:

    If it prints a number such as 21.0.0 to the console then you're good to go. If it tells you that the node command is not recognized, then something went awry.

    You're always more than welcome to consult the fxhash discord - the team members and community are always more than happy to help your troubleshoot any issues that you might be running into. Also make sure to consult the FAQ page to check if you’re running into a common issue.

    Node & NPM Version Requirements

    On last thing here, for the the fxhash CLI make sure that you have a node version higher or equal than 18.0.0 and and npm version higher or equal than 9.0.0. You can check this via node -v and npm -v.

    Installing node also automatically installs npm on your machine.

    Setting up the fx(hash) CLI

    If you’ve completed the previous steps, it means that you’re all set and you've successfully installed node.js and npm on your machine. We can now proceed to install the fx(hash) CLI with npm. This can be done with the following command:

    The letter i here simply stands for install, and you could also equivalently write npm install -g fxhash. Moreover, the -g flag stands for global, meaning that the package is installed globally on your system, making it such that the fx(hash) CLI tool can be run from anywhere on your system, without you having to reinstall the package every time you start a new project.

    The terminal might throw an EACCES error when you run this command, which is related to permissions issues and is typically triggered when you're trying to install things with the global flag. Running the command again with with admin rights by prepending sudo to the command should fix this. This will prompt you to enter your password.

    If you've completed the above steps you're done setting up - the fx(hash) CLI should now be installed on your machine and ready for you to use. In the next page we'll talk in more detail about using the fx(hash) CLI, use it to create a new project, and have a look at the other terminal commands it provides.

    Running CLI commands with NPX

    One last thing to point out here, is that once you've installed node.js you also get access to the npx command. In contrast to npm that installs packages on your system, npx lets you execute node packages directly without having to install them - meaning that you can directly set up a new fxhash project with:

    By prepending the npx command you can now run the the fx(hash) CLI command without having to install it with the npm i -g fxhash command first, but this is simply a matter of preference.

    The Main Marketplace Page

    The main entry point to fxhash’s secondary market is the general Marketplace page - it can be accessed from the homepage:

    It provides a leader-board of projects that have had sales activity within a recent time-frame. Which can be further filter via the drop down menu. The numbers indicated on the leaderboard here refer to the sales volume a project has received:

    Trading Volume: The term volume is one of the key metrics used to gauge the activity for a given NFT marketplace or a specific NFT project. It indicates how frequently tokens are being bought and sold, and represents the total value traded within a specific time-frame.

    Scrolling down a more detailed view of the different iterations that have been sold and/or been listed recently across the entirety of the fxhash platform can be seen:

    Individual Marketplace Pages

    Each project on fxhash also has its own individual marketplace page from which all of its secondary activity can be tracked. These individual marketplace pages, just like the main marketplace page, aggregate sales and trading statistics at the very top:

    A project’s marketplace page can be accessed via the ‘open marketplace’ button on a project’s main page. Returning to the main minting page of a project can be done via the ‘open project page’ button.

    Scrolling down, below these statistics you will find a number of tabs that let you explore other secondary market functionalities for a particular collection. On fxhash the word collection is a grouping term that indicates the entirety of all editions that are minted from a single project.

    The first tab titled “listed” shows all iterations that are currently listed for sale by holders. The indicated price on the listings is the asking price that collectors are willing to sell it for immediately - if you find an iteration that you would like to acquire for your own collection, make sure to compare its listing price with the current floor price in the above statistics to get a feel for where it falls compared to the average asking price.

    You can also sort the listed iterations by different criteria from the drop-down list.

    If that price seems reasonable, you can then click on the desired Edition/Iteration which will navigate you to it’s individual token page - yes, fxhash also creates individual pages for each edition of a project. Here you would then simply click “purchase token”, which will then trigger a transaction that you’ll have to confirm to finalize the purchase:

    The stats and activity tabs are two other useful views. The stats tab for example, visualises the cummulative trading activity of a project over a given period of time, filterable by different metrics. This can provide an indicator if there is ongoing interest in a particular project:

    In contrast, the ‘activity’ tab simply shows the most recent trades that have been effectuated on some of the project’s iterations:

    Collection and Iteration Offers

    The Offers tab is a bit more involved. If you find a particular artwork that you would like to have in your collection, but isn’t actually listed on the secondary market by its current holder - or for a price that you might consider too high - fxhash also lets you make a direct offer:

    Offers: On fxhash collectors can propose a price for purchasing iterations that are not listed on the secondary market. fxhash then relays this Offer to the current holder(s) who can decide if they want to sell for that price or just ignore the offer.

    There’s two types of offers that can be made on fxhash:

    1. Iteration Offers: interested collectors can propose a purchasing price for an individual iteration. The interface for this can be found on the individual iteration’s page. This will require you to input a price before clicking on the ‘make offer’ button and confirming the transaction from your connected wallet:

    2. Collection Offer: an offer made for the entire collection, where any one of the holders of a project’s iterations can accept the offer - in this scenario the collector that makes the offer doesn’t care about which iteration they could possibly receive from the collection. Collection offers are made from the marketplace page of an project.

    Here you simply indicate how many editions you want to collect and what price you’d like to offer for collecting an iteration - here you can conveniently select a percentage of the Floor price.

    The lowest price at which an NFT can currently be purchased from a specific collection on a marketplace. This price point changes dynamically based on the listings and sales activity within the collection.

    If you have collected pieces on fxhash, you might also receive offers yourself. You can view these under the dashboard tab of your profile that displays all of your inbound and outgoing offers - there is also a slider that lets you filter offers that lie beneath a certain percentage of the floor price:

    Viewing your Collection and Listing Iterations on the Secondary

    Similarly to viewing your offers, you can view your collection under the ‘collection’ tab of your profile:

    Clicking on any of your collected pieces here will take you to a new page where it will reveal a button labeled list for trade via which you can list the GENTK on the secondary market. This requires you to input a price and confirm a transaction in your wallet as well:

    Addendum

    fxhash’s secondary market does not only have a transactional function, but also fosters a sense of community amongst the collectors, and generative art enthusiasts in general; token holders can engage in dialogue with one another, fostering a shared appreciation for generative art, and discussing the different aspects that make or break different generative tokens.

    If you’re planning on engaging with the secondary market, make sure to check out the other documentations pages on this topic:

    • The Value of Generative Art

    • Market Analysis and Dynamics

    Exporting a canvas element as an image file (PNG/JPEG) can be done with the following piece of code:

    The canvas API provides a function called toDataURL() that converts it canvas bitmap to an image file.

    Downloading this image involves temporarily creating a link to which it gets attached, and then simulating a click that triggers this link. We often tie this event to the s key (s as in saving) on our keyboard:

    P5 makes this is as straightforward as using the inbuilt keyPressed() and save() functions:

    You can find more information about this function in the P5 reference.

    Different Resolution Export

    Sometimes we want to provide this exported image at different resolutions, this is useful if collectors want to make their own prints of the artwork or use it as a wallpaper for their devices. For this purpose we need to build a way into our GENTK to be able to generate the artwork at different resolution. There's multiple solutions to this.

    Rather than multiplying/dividing all of the individual variables in our code by specific amount, it makes more sense to simply scale the dimensions of the canvas:

    The rendering context provides a useful function called scale() that scales the dimensions of all the drawn graphics by the parameters that we pass into it. Before that we also need to multiply the canvas dimensions by this scale. For a scale of 2, the canvas would end up being 1800x2400 instead of 900x1200.

    We also want to be able to regenerate the artwork at the new given scale with a key press, for instance if the user presses the ‘2’ key we want to double the dimensions of the canvas, if they press the ‘1’ key we want to revert back to the original dimensions.

    To this end we can wrap the graphics generating code inside of a function that we can call to redraw the canvas at a different resolution when these keys are pressed:

    Here we don’t need to manually clear the canvas, it is done automatically when the width or height of the canvas is modified. Then we can simply draw the graphics as before and they will end up with the correct resolution. Notice how all of this is independent from the fxhash PRNG, and will not affect the deterministic output of the GENTK. Here’s an example of this in action:

    As for P5, its default behaviour is a little different from working with the regular HTML canvas.

    It scales the P5 created canvas automatically to match the device's pixel density. The pixel density essentially just indicates how many pixels there are in a given screen, for instance retina displays (as well as many modern displays) usually have a pixel density of two. If you tried to export your artwork earlier with P5 you'll have noticed that it is exported at twice the actual dimensions that we specified in the createCanvas() function, so 1800x2400 instead of 900x1200. This is done to achieve smoother graphics on higher resolution displays.

    P5 provides control over this pixelDensity parameter and we can override it with the inbuilt pixelDensity() function. Furthermore, we can leverage this function to export outputs at different resolutions. We can simply set the canvas' and secondary graphics buffer pixel densities to a higher value to scale the graphics without a loss of resolution:

    We could also alternatively just set the secondary graphics buffer to a higher pixel density while keeping the display canvas at the same resolution, then simply exporting the secondary graphics buffer when the user wants to export the graphics. Then you can simply export the graphics as detailed earlier. You might want to even go the extra mile and add in touch support for mobile devices.

    URL Parameters

    Another alternative method to allow for user interaction is passing variables into the javascript code via URL parameters.

    URL parameters: (also known as query parameters or query strings) are a way to include additional information in the URL of a web page. They are typically used to pass data from one page to another or to configure the behavior of a web application. URL parameters are appended to the end of a URL and are separated from the base URL by a question mark (?). Multiple parameters are separated by ampersands (&).

    For example we could allow users to query a specific resolution by inputting it as a URL parameter:

    In the code we can check if this URL parameter exists:

    If it doesn’t we can simply fall back to a default value.

    fxhash leverages Splits.app as an out-of-the-box solution to this end: Splits is a smart contract suite that provides all of the necessary functionality to optimize fund distribution on Ethereum based networks:

    About the Split Contracts: Split acts as an equity instrument by letting you define the percent of future value each recipient will earn. It's a payable smart contract that distributes all ETH & ERC20 tokens it receives among recipients according to pre-set ownership percentages.

    If you’re curious to learn more about the technical details of these smart contracts work, you can explore the official docs here.

    If you have an fxhash project on ETH/Base, your fxhash profile should show you a button under your connected Eth wallet address, from which you can withdraw the received funds:

    I should also show up in the your Splits Dashboard when you sync with the same wallet that you released the project under, where you can initiate the same withdrawal action.

    Splits for Collaborative Projects

    Splits is also very convenient for collaborative projects, as it essentially streamlines the distribution of earnings between the involved parties - here’s an example for this, the project Week after Week, a collaboration between the WTBS team and the generative artist Alessandro Fiore:

    Each collaborative fxhash project on Eth will have its own page/view over on the Splits app that visualizes how the funds are distributed among the recipients, and wether or not there currently are funds to be withdrawn.

    The same is true for royalties generated from secondary sales of the minted editions, they are pooled under their own Split and can be viewed separately:

    Clicking on the “Distribute Balance” will then prompt if you want to send the pooled funds to the involved parties, and optionally if you want to also directly withdraw them:

    Some noteworthy points about the Split contract here:

    • Withdrawal of the funds can be initiated by any party. It can be either one of the involved creators, or even another third party [is this accurate?]. Naturally, the funds will always only be sent to the addresses that are stored by the smart contract.

    • Splits are payable contracts. This means that splits ****can received funds and tokens similar to how a regular wallet can receive assets. Withdrawing them is optional.

    Always be cautious when handling unknown assets, the sale thereof might be malicious. Check the Safety and Security section of the docs for more info.

    Manually Withdrawing from Splits

    In the case of an outage of some sort, it is also possible to withdraw the funds manually from the contract, which has to be effectuated from the Etherscan.io website (Etherscan is the primary blockchain explorer for ethereum).

    The steps for this on mainnet ETH are the following:

    1. Navigate to Etherscan.io

    2. In the search bar paste one of the following fxhash minter contract addresses - depending on which sales method you have used:

      1. dutch_auction_minter_v1: 0x1bC736a2b144096a4752534C557D7E6C311CcAF1

      2. fixed_price_minter_v1: 0xB645cFfD9bFB93c2c181d5Be0D6a8C1d81C2aEf3

    3. It will show you a dedicated page for the contract address, under which you should see a number of actions.

    4. Click on the “Contract” button.

    5. You should a new view that has an option called “Write Contract”

    6. This will reveal a list of actions that you can perform - in this case we care about the very last one #12, titled “withdraw”

    7. Clicking on withdraw will then reveal a field into which you need to paste the token address of the project’s funds that you want to withdraw:

    8. You can find your token’s address over on its fxhash page - example:

    9. You also need to sync your wallet with before you can effectuate the withdraw action - there’s a little button titled “Connect to Web3” that lets you do this:

    For tokens on the Base L2 you need to do these same steps, but via the [Basescan.io](http://basescan.io/) website rather than Etherscan. The contract addresses for the fxhash minters are different in this case:

    • dutch_auction_minter_v1: 0x9667a1Cf26223c9de22207DD93cfEEc9237b8f4E

    • fixed_price_minter_v1: 0x4bDcaC532143d8d35ed759189EE22E3704580b9D

    the splits app
    Splits.app

    The Ticketing System

    Collecting a regular Generative Token that doesn't make use of fx(params), is simply done by clicking the mint button on the respective project page. Once the transaction is confirmed in the collector's wallet fxhash takes care of the rest and the collector receives their GENTK.

    On fx(hash) things can get a bit hectic sometimes, when a popular artist publishes a project that is highly sought after, it can often happen that all editions of the Generative Token mint out in a matter of minutes or seconds. And this is perfectly fine for regular projects, but when it comes to Generative Tokens that make use of fx(params) this doesn't make sense.

    Collectors would have to rush through the minting interface and throw together an output that they're only partially happy with if they want to get a chance at minting before all editions of a Generative Token mint out. This would sully the collectors' and artist's experience: collectors would not obtain outputs that they are happy with, and the collection would not come to life as it otherwise would have. On fxhash we collectors to be able to fully explore the parameter space of the project.

    For this reason, a ticketing system is introduced. When you collect an edition of an fx(params) project, you obtain a mint ticket instead of having to immediately create the final output. This mint ticket can later be exchanged for your final GENTK after you’ve dialed in the parameters to your liking.

    Delaying the actual creation of the GENTK until a later moment, while reserving claim to an output makes it such that collectors have ample time to explore the entire output space of the Generative Token, and allows them to carefully craft their desired output.

    In this manner, the ticketing system solves the problem of minting races for fx(params) projects. However, at the same time introduces a different issue: what if collectors indefinitely hold tickets and never exchange them for their final GENTKs?

    This is problematic because some collectors might forget about their tickets, or for whatever reason not use their tickets - which would lead to collections never fully minting out. To create a fair environment for both parties, a couple of new dynamics are introduced to protect both artist and collector.

    Holding a Mint Ticket

    After an artist-defined grace period (X days), tickets become subject to a Harberger tax system. This tax mechanism requires ticket holders to pay a daily tax to maintain ownership of an un-exchanged ticket after the grace period has elapsed. If the collector chooses to not pay this tax, tickets are listed for sale on the fxhash marketplace.

    In other words, once outside of the grace period, ticket holders have two options: pay a daily tax or exchange the ticket for an artwork. This means there is no option to keep the ticket off the market and that, as a ticket holder, you should constantly reassess the ticket’s market value to avoid paying a higher daily proportional tax than necessary.

    With this tax system in place, we can facilitate and incentivize several important factors at once, such as maximizing the amount of tickets exchanged for artworks, the proper assessment of mint ticket value by collectors, and ensuring artists are compensated for collectors holding un-exchanged tickets.

    Grace period

    The grace period is a duration of time defined by the artist wherein ticket holders can explore the generative algorithm and play with parameters without paying tax on the unexchanged ticket. Defining the length of the grace period allows artists to further refine and influence the collector’s exploratory process, giving them more or less time to exchange their ticket for an artwork before the daily proportional tax applies.

    Grace periods can be as short as one day or longer than multiple lifetimes — it’s entirely up to the artist. When the grace period ends, the tax mechanism kicks in, requiring tickets to be listed on the market and subject to tax for as long as they remain unexchanged.

    Daily proportional tax

    Once an unexchanged ticket falls outside of the grace period, a new set of requirements should be met by the ticket holder to maintain ownership of the ticket.

    1. The ticket holder defines a price for the ticket (mint price by default), thereby listing it on the secondary market

    2. A daily tax proportional to the ticket’s list price must be paid to retain ownership

    These requirements entail that unexchanged tickets are always for sale and collectable by anyone — and that any salable ticket is subject to the daily tax. If the ticket tax is not paid, ownership is forfeited by the owner and the ticket is entered into foreclosure.

    The yearly tax is roughly 51% of the ticket price defined by its owner. Moreover, all taxes collected from fx(params) projects are sent to their respective creators.

    Ticket foreclosure

    When a ticket holder fails to pay the daily proportional tax, their ticket is forfeited and entered into foreclosure. During this process, the ticket is auctioned off beginning from its list price and decreases linearly over a 24hr period until it reaches a 0.1 XTZ resting price. Anyone can buy a ticket in foreclosure, including its previous owner.

    When a ticket is claimed, either during the auction in its foreclosure or at the price defined by the previous owner, the full amount paid by the buyer is transferred to the previous owner. Only taxes are paid to the artists.

    Additional Information

    Mint tickets are NFTs: they will appear in your wallet alongside your other NFTs, and you will be able to transfer them. However, mint tickets cannot be traded on other marketplaces: that's because the marketplace is written into the mint tickets Smart Contract.

    If a ticket is transferred to another account, the recipient will be responsible for either paying the tax to keep ownership or exchanging the ticket for an iteration.

    Link to Discord Message about the Ticket Tax System

    The panel on the left side of the artwork is the fx(params) interface, where interaction with the sliders changes the appearance of the artwork. You can then lock in your final choices via the mint button on the bottom, with which the final GENTK is then created.
    22MB
    Screen_Recording_2023-04-21_at_11_06_10_AM_AdobeExpress.mp4
    Open
    The Report System

    Members of the community can report suspicious projects on their respective pages:

    The three dots next to the project number reveal a report button.

    Note: You need to be connected with a wallet to report a project.

    Reporting a project in this manner is considered a “vote” for the moderation of this project. This vote from a member will only count if it meets certain criteria:

    • The reporting member posted at least one Generative Token OR owns at least one GENTK

    • Only one report/account/project was made

    • The project was not flagged as CLEAR by a moderator

    The report is sent to a Smart Contract which is indexed by fxhash, and the reports are processed when they reach the blockchain. If 10 votes are counted in the span of one hour, the project will be flagged as REPORTED by the indexer.

    Once a Generative Token is flagged as reported, it will be hidden from the main, explore, and user creations pages. It will then enter a moderation stage, during which only trusted community members will have the authority to decide if the Generative Token can remain on the platform.

    The Moderation System

    When a Generative Token is flagged as “REPORTED”, it will appear in the /community/reports page. On this page, moderators will have the ability to update the flag of the token to:

    • CLEAN

    • MALICIOUS

    If a token is moderated as CLEAN, it will become accessible again, and reports will no longer be counted. It will never be flagged as REPORTED by the system again.

    If a token is moderated as MALICIOUS, then it will remain inaccessible on the main, explore, and user creations pages. If some Gentk were already generated using the Generated Token, they will be flagged as “undesirable content”.

    The moderation system does not set a finite flag on a Generative Token. A manual operation can update the state manually. Also, if a moderator sees an undesirable Generative Token, they can remove it from the UI manually, and so by calling a Smart Contract.

    3-Hour Lock

    One issue remains with the system described above. There is no way to establish if a Generative Token can be minted safely in the moments following its release. If no moderator is present, at least 10 reports are required for the token to be flagged, and it can take some time. This next feature helps in that regard.

    The mint button of a Token will appear as locked for three hours after the project is published on fxhash. This lock acts as a reminder for the collectors to assert the validity of a project before minting from it.

    The lock can be removed by clicking on it, and by doing so acknowledging the risks of minting from a recent token which did not go through the community/moderators approval.

    Warnings on flagged Projects

    Finally, a warning will appear at the top of all the Generative Tokens flagged. It will also appear at the top of GENTKS minted from flagged projects. It acts as a last-resort warning to inform members.

    On the marketplace (and anywhere a Project Card is displayed) a warning will be displayed.

    Purpose of the Moderation System

    This system was designed to meet certain criteria:

    • Protect collectors from collecting copymints or otherwise malicious projects

    • Keep the platform open to all artists

    • Give the community the ability to self-moderate Generative Tokens

    • Aid the moderation team to quickly identify malicious projects

    fxhash is a constantly evolving platform, this system can potentially change in the future to best adapt to the community’s needs. We are always more than happy to hear your feedback in the discord.

    Reserve: A number of editions/iterations from the generative project that are set aside and only mintable by the wallet addresses on the allow list(s) set for the project.

    The status bar that visualizes the minting progress on fxhash projects generally indicates whether a project has a reserve or not:

    The interface will usually also display if you’re eligible for an iteration from the reserve. A more detailed view of the allow list(s) and the included wallet addresses can be found after the projects description:

    Allow lists have some intricacies to them, that we'll address and discuss in this section.

    If you’re an artist looking to set up allow lists and reserves for your project: you can find the information for it here. We recommend that you read through this section first however.

    There’s currently two ways that artists can enable a reserve on their projects: Access Lists and Mint Passes. Here’s what this looks like from the minting interface when artists prepare their projects for publishing:

    • Access List: with the term access list we’re essentially referring to an allow list, and as stated this is simply a list of wallet addresses that the artists can put together on their own. The fxhash interface makes it easy for the artist to either import this list from and external csv file, or fetch a list of holders of previous project. Only wallet addresses included on this access list can mint from the reserve.

    • Mint Pass: often also referred to as a “token gate”, only holders of this mint pass have access to the reserve of the project. A mint pass usually comes in the form of a token/NFT minted on another platform.

    New types and other forms of reserves will be added depending on the needs of artists and collectors. The interface also allows artists to set an arbitrary number of allows list in combination with mint passes for any given project.

    Understanding Reserves

    The important thing to understand about reserves, is that they don’t necessarily guarantee a mint from a project for each address that’s included in an attached allow list, or alternatively a mint pass that grants mint access to a project - although it can be set up in that each collector has claim to one edition, most commonly there are less reserve slots than there are eligible addresses on the allow list and/or mint pass holders. In this scenario, reserve slots are consumed in a First Come-First Served order.

    Additionally, another important point to consider os that artists can assign a varying number of slots for each wallet address on the allow list, besides configuring the total number of reserves. In the interface this is done simply by indicating the number of eligible slots next to the wallet address of the collector:

    In this particular example, the overall edition size is 128, out of which 10 editions are reserved for wallet addresses on the allow list - moreover, some addresses on the allow list have more than one reserve slot - this means that the total number of reserves can be consumed without each address on the allow list obtaining an edition.

    In a nutshell, there can be more eligible wallet addresses than there reserve slots.

    Reserves can thus be configured primarily in 2 ways:

    • One reserve slot for each eligible address, where each address has claim to one edition: every allow listed user is guaranteed to mint an edition from the project.

    • Less reserve slots than eligible addresses and/or the total number of slot for each allow-listed address sums up to more than the overall number of reserve slots: not every address is guaranteed to have access to an edition.

    The second case gives rise to a number of different scenarios that we’ll have a look at now. Here’s a demonstration of the concept with an access list for 2 users, A and B:

    In this first case, the number of total reserve slots is equal to the total number of eligible slots for the allow-listed users. Both users A and B are guaranteed to get their 5 editions.

    In this second case, the number of slots of the reserve is smaller than the total number of slots given to the users in the access list. It means that neither A nor B are guaranteed to get their 5 editions. If User A mints 5 editions from the reserve first, user B will only be left with 2 editions. If we had set the number of reserve slots to 1, only A or B would have been able to get an edition from the reserve. Users that don’t manage to consume their reserve list spots can however always also mint from the publicly available editions, if any remain.

    Reserves are very permissive (at least when created), and it's up to the artist to configure them properly accordingly.

    Reserves can be Stacked

    As mentioned earlier, multiple reserves can be added to a project. Each reserve will save its slots for the eligible users–here is an example where multiple access lists are stacked to dictate how the final reserve of the project will be distributed among eligible users:

    Notice that the access lists conveniently don’t affect each other and remain self contained. Providing artists with the ability to define multiple reserves allows for fine-grained control over the final distribution of the project.

    Capture Contexts & Preview Settings

    An overview of the different capture contexts and capture settings

    The fxhash API exposes a $fx.context flag—a string value that specifies in which execution context fxhash is running your code. The $fx.context variable can currently assume one of four values:

    $fx.context
    description

    standalone

    When fxhash runs your project's code directly in the browser—"live mode".

    capture

    When fxhash runs your code on the backend to generate an image/GIF preview to display on the frontend.

    How to use $fx.context in your project code

    Since the $fx.context property is a flag that indicates the context in which the code is executed—in most cases you will want to have a conditional block in your code that checks for the different contexts and then renders the artwork according to the use-case:

    This is useful when you want to display your artwork differently in each context. If your artwork display the same everywhere, you can simply not use $fx.context at all, and invoke the preview when the artwork has finished rendering.

    Capture contexts work the same way in both long-form and open-form projects—during the check-files step of the creation flow you can toggle between the different contexts to check that they are working properly and the way you have intended with your code.

    fxlens will also let you set this execution context to verify that your code is working properly.

    Capture & Preview Settings

    In the configure-capture step of the creation flow, you will set up how fxhash creates the preview images of the artworks that your code generates, whenever a collectors mints or evolves a new edition:

    There’s two different methods for triggering the capture module:

    • Programmatically with $fx.preview(): The capture module will wait until your code calls the fxpreview() function. As soon as it is invoked, the capture will be triggered. The placement of this function in your code is up to you, but usually it should be placed towards the end of your code, when all of the graphics have been rendered. If the piece is animated you might want to trigger it after the initial frame has been drawn.

      If your project is loading asynchronous requests from the project's folder, always consider that these resources may be slow to load—please always use fxpreview() to trigger the capture in this case.

    The capture module will automatically take a capture after 300 seconds have passed after your project was loaded in the browser. Hence it is important that the rendering of your graphics completes within this timeframe, otherwise it might lead to undesirable preview images.

    In the case of our example token we’re using the programmatic trigger since it is a static artwork where we want to trigger the capture after all shapes have been rendered to the canvas. After setting the capture trigger we also need to indicate the target of this capture; this can be a canvas element, or the entire viewport.

    In this example we only want to capture the canvas element, and not the entire viewport—selecting the From <canvas> option will reveal a third input field that lets us point the capture module to the HTML canvas element we want to capture:

    Otherwise, if you choose to capture the entire viewport, you can specifiy the dimensions of the viewport at the time of capture (the size of the browser window essentially, in which your code runs):

    Using GPU accelerated captures

    If your project requires a GPU to render, you should use enable GPU-supported rendering for your capture.

    Booting up the GPU capture can be slow however, and can take up to a couple of minutes to finish rendering.

    GIF captures

    We now also support GIF preview captures, that enable animated thumbnails for collected editions of your project. Currently GIF captures are limited in that fxhash will simply record your selected target or viewport for a set number of frames and at a specified interval—rather than programmatically triggering individual frame captures from your code (but this is in the works!)

    When toggling on GIF capture for your project, you don't need to trigger $fx.preview(), it will simply start recording from when your code runs.

    In other settings where GIF previews are not available, the middle frame of the GIF will be used a thumbnail. For example, if the GIF has 20 frames, it will use the 10th frame as a thumbnail.

    Notes about the fast-capture context

    There are a few limitations to the fast-capture context:

    • The GPU is disabled during fast-captures

    • GIF captures are not available as fast-captures

    This is simply because both of these capture methods can not be generated very quickly—if this doesn't suit your project, you can either ignore the fast-capture context or build a creative intermediary preview into your artwork that reveals something about the artwork before the actual preview is rendered.

    Additionaly, the fast-capture will also be taken according to the capture trigger method you have selected for your project:

    • If you're using $fx.preview() as a trigger method, simply call $fx.preview() when you want the fast capture to be taken—preferably as early as possible—in a fast-capture clause in your code.

    • If you're taking the capture after a timed delay, the fast capture will trigger when the selected delay has elapsed, or at a maximum of 1 second.

    And in case you are using the GIF capture for your previews, you still need to call $fx.preview() as a fast-capture trigger.

    fxlens

    A closer look at the fx(lens) interactive project viewer.

    fx(lens) is a web page designed to load and allow the interaction with fx(hash) projects in your local development environment. In a nutshell, fx(lens) is an interactive fx(hash) project viewer. Via a minimalistic user interface it provides a number of controls, toggles, sliders, and buttons that make it possible to interact with, tweak, and test a generative token while it is being developed.

    Building a generative token for fx(hash) is often a big and complicated undertaking. Prior to fx(lens), artists would often create their own testing interfaces for the purpose of making sure that all aspects of the project’s code are functioning as intended.

    Example of a project running in fx(lens)

    fx(lens) also helps artists get a feel for the breadth of the parameter and output space of a generative token.

    Running fx(lens) via the CLI

    If you’ve already installed , you can launch fx(lens) with the fxhash dev command. This command needs to be executed from within your project directory and requires an index.html file to run.

    Running this command will automatically open up a new tab in your default browser, showing a control panel on the left-hand side of the browser window, with the generative token next to it on the right. Depending on whether you’ve already written some code for your generative artwork or not, this new tab will display the default generative token that the boilerplate comes with out of the box, or your own artwork:

    Using the fxhash dev command also automatically checks for updates, if you get an error you might have to prepend this command with `sudo`. fx(lens) will still work nevertheless, it is merely indicating that it couldn't check for the update.

    Again, you can also achieve this with npx.

    Standalone fx(lens) via npx

    You can also run a standalone version of fx(lens) without installing the CLI, also through npx. This would still require Node.js to be installed (refer to the section for installation instructions) for us to run fx(lens). The only difference here is that we can now manually run fx(lens) without using the fxhash dev command.

    We can get fx(lens) with the following npx command:

    Make sure to give your project a meaningful name by replacing your_project_name with a title of your choice. After that, navigate into the newly created directory and run:

    This will install all of the necessary modules required for running fx(lens). Installing these dependencies finalizes the setup of the standalone version of fx(lens), and it can now be run with:

    This will open up a browser tab with fx(lens) running inside of it just like before.

    How does fx(lens) work?

    Booting up fx(lens) runs not one, but two local servers on your machine: one that serves your generative project, and another one that serves fx(lens) itself.

    What is a Local Server? A local server refers to a server that runs on the same machine or device where the programming code is being developed and tested. This local server is often used during software development to test and debug code before it is released.

    After running fx(lens), open another tab in your browser, and in your search box paste in this address http://localhost:3301. This will open a page that simply runs your generative artwork by itself. If you enter the following address http://localhost:3300 it should show you fx(lens), with a blank screen instead of the artwork next to it. This is because we didn't indicate where the project should be fetched from. We actually need to point the local fx(lens) server to the server on which the project is running.

    This is done by passing in the generative token's server address as a URL parameter:

    Overview of the fx(lens) Interface

    What can we do with fx(lens)?

    Not only does fx(lens) let us run our code, it also lets us pretend as if these tokens were running on fx(hash) in different contexts. This means that fx(lens) exposes certain parameters inside our code that would otherwise only be available once uploaded to fx(hash). All of these input parameters can be configured via the left-side UI:

    Moreover, we can tweak and control these parameters - let's have a brief look at the different sections of this interface.

    Current Seed

    With the current seed we refer to the hash that fx(hash) injects into project’s code for it to generate a specific output. In fx(lens) we can simulate and control this exact seed via the current seed field, where we can manually input specific alphanumeric strings, or generate new ones at random:

    This is very useful when testing the determinism of the generative artwork since the randomness in the generative artwork should be derived from that hash, and given the same hash/seed, your code should always generate the same output. Hence, while testing your artwork and rerunning your code in fx(lens), it should generate the exact same output when this hash/seed is fixed. If not, you need to revise your code and figure out which parts of it are introducing variance in this behaviour. You can read more about this in the section.

    Minter Address

    The minter address simulates a wallet address, as if the currently displayed output has been collected by a collector. Some of the randomness in the project can also be derived off of the collector’s wallet address (via it’s own PRNG), which makes it handy to be able to fix and regenerate this simulated address, just like the hash.

    Execution Context

    The execution context is a flag that is passed into the code as a URL parameter and indicates in which context it is run, there are three possible values for this context:

    • standalone: (default) when the final output should be displayed, on the main project page for instance

    • capture: when the code is executed in the capture environment, to get an image preview of an iteration

    • minting: when the code is executed during the minting flow of the collector

    Sometimes it can be useful to run special parts of the code only in a specific context, for instance if we want to configure the image previews in a certain way and execute a function only during the image capture.

    Params

    fx(params) is a large topic, we cover it in the section of the docs.

    Params, short for parameters, are essentially certain variables in the code that the artist chooses to expose for the collectors to tweak at mint time, giving them the ability to modulate certain aspects of the generative token and create custom iterations completely to their liking. All of these exposed parameters will appear under this section, and will look differently from project to project:

    Iteration

    The iteration number is a special value that is unique for each collected iteration of a project, and as its name suggests, indicates the index of the collected output relative to the entire collection. For example, the iteration number for the very first collected iteration of a project will be 0, the second will be 1, and so on. If any parts of the code take this value into consideration, we can tweak and test this behaviour with this field.

    Features

    Features are special, artist chosen attributes that describe the randomly chosen qualities of a collected iteration. They are entirely optional, and have to be declared from within the code. If the artist chooses to use features, the will appear in this bracket of the interface:

    Live Reload

    Last but not least, the interface also provides a way to automatically update and refresh the generative artwork displayed on the right-hand side whenever any other controller/value in the fx(lens) interface changes:

    Responsive Browser Projects

    Methods for displaying your projects responsively in the browser.

    It is not possible to anticipate what kind of displays or browsers your audience on fxhash may be using to view your art, they might be browsing collections on small smartphone screens or on large high resolution retina screens - it is crucial that your code always displays the generative artwork properly within any given browser window, no matter how large or small.

    Moreover, your project should also be responsive and resize themselves automatically when the browser window's dimensions change.

    fxhash projects primarily fall into two categories: dynamic generative artworks that span and take up the entirety of the browser window, and artworks that have fixed dimensions with a specific aspect ratio. In this page, we'll discuss some of the methods with which we can display them properly.

    Centering and Scaling a fixed aspect ratio Canvas

    Projects that aim to generate outputs with a fixed aspect ratio are the more common of the two, and the more popular type of generative token. A fixed aspect ratio means that the canvas has a specific width and height. In this setting:

    • The artwork should always be neatly centred within the browser window without any part of it being cut off or extending beyond the browser window.

    • The artwork should maintain its aspect ratio and not be stretched along either of its axes.

    • The artwork should scale with the browser window when it is resized while maintaining its aspect ratio.

    CSS is an elegant and lightweight solution to centring a canvas element within the browser window. Given the following HTML body structure:

    We will handle the positioning of the canvas element with the following CSS rules:

    The above CSS should be the content of the styles.css file in your project's directory.

    Here we're mainly considering three elements: the body of the webpage that the generative artwork is displayed in, a container element that is used as a wrapper for the canvas element, and the canvas element itself.

    One preliminary thing that we need to do is to remove the default margins that the <body> tag comes with. Having done so, we will set the canvas container to fill the entirety of the web page by setting its height and width to a 100vh (view height) and 100vw (view width) respectively.

    We will indicate that this container div is a flexbox by setting its display property to flex. The CSS Flexbox, or Flexible Box Layout, is a popular oCSS layout model. It is designed for the arrangement of items within a container, providing a more efficient and predictable way to distribute space and align content.

    This flexbox layout unlocks two further properties, namely: align-items and justify-content. These two CSS rules allow us to control the positioning of elements along the two axes of the container. By setting both of them to center, the canvas container taking up the entirety of the webpage, AND the canvas element being the only item inside of this flexbox, this will result in the canvas element being positioned exactly at the center of the browser window.

    Now we also want the canvas element to not be cut off when the window gets smaller than the actual maximum dimensions of the canvas. This can be remedied by setting the canvas' max-width and max-height to a 100%, indicating that we want it to stay contained within its container.

    And in action this would look as follows:

    Here we also reintroduce a small margin between the canvas and the container with the following CSS rules (added to the container element):

    This margin is entirely up to personal preference.

    The only drawback of this CSS approach is that the canvas element will not expand beyond its maximum dimensions when the browser window grows exceedingly large, there is unfortunately no straightforward pure CSS solution to this that doesn't require a lot of additional rules. If your GENTK has large enough dimensions this shouldn't be noticeable, except on very large screens or when you modify the zoom of the browser window.

    A solution to this is with some additional Javascript Code - we can scales the canvas to the size of its container with the following code:

    Here we create a function resizeCanvas() to handle this.

    The original dimensions of the canvas are constant values and entirely up to the artist, and depend on the desired aspect ratio of the output. We need them to calculate how the canvas should be scaled to fit the browser window.

    We also require the dimensions of the browser window. We can fetch these via the window object's innerWidth and innerHeight properties. These are always equal to the browser window's current effective width and height respectively, and are updated automatically when the window is resized.

    The next step is a little convoluted. To explain it intuitively, we are trying to determine if the canvas should be scaled horizontally or vertically, depending on which axis allows for more space. We do so by comparing the horizontal canvas width to window width ratio with the vertical canvas height to window height ratio, subsequently using the correct one to scale the dimensions of the canvas by setting its CSS width and height through Javascript.

    We run this function once at the very start when the artwork is displayed and then also pass it to a Javascript event listener that triggers whenever the browser window is resized, ensuring that the canvas is scaled when this happens.

    What is an event listener?

    In JavaScript, an event listener is a function or piece of code that waits for a specific type of event to occur and then responds to that event by executing some predefined logic. Events can be user actions, like clicking a button, pressing a key, or resizing a window, as well as other things like data being loaded or a timer reaching a specified interval.

    And in action this will work with any aspect ratio, here’s an example of a portrait aspect ratio canvas:

    Naturally, this is not the only possible solution to this end, there are numerous other methods with which you can scale the canvas.

    When you're using a library to create the canvas element, you might have to slightly modify this CSS depending on how the library inserts the canvas element into the webpage and if it wraps the canvas inside other divs.

    Dynamic Fullscreen Projects

    Generative graphics are not always simply static canvases with a fixed aspect ratio, sometimes they're interactive experiences or display animated visuals. In these scenarios it makes more sense to display things fullscreen and cover the entirety of the browser window.

    Here's one solution that makes the canvas as large as the browser window without scaling or stretching the graphics:

    The graphics here don’t scale because we redraw them whenever the window is resized - in this manner we can consistently keep graphics at their respective coordinates without stretching or scaling them.

    Here the canvas resizing code is even simpler:

    We simply set the width and height of the canvas to the width and height of the window object. Here we can also do without any of the CSS as we're manually setting the dimensions of the canvas. The same would be true in the case of animated graphics.

    Library specific solutions

    If you're using a library like p5, it might already have some native methods out of the box to adjust the dimensions of the corresponding canvas element. In p5 a popular method to scale an artwork is by drawing the graphics to a separate graphics buffer, and then displaying this graphics buffer like an image in the webpage.

    Libraries sometimes already have native, out of the box methods for the purpose of scaling the dimensions of the canvas element. P5 for instance has a method called windowResized() that automatically triggers whenever the browser is resized, inside of it we can call resizeCanvas() with the new window dimensions as parameters:

    This makes it very straightforward to create a fullscreen sketch:

    In the same manner, this function is also handy for displaying artworks with a fixed aspect ratio. Especially when used in conjunction with P5's createGraphics() function that allows us to create a secondary canvas. Here's an example of this:

    The code that achieves this is a little more involved than before, but conceptually it's very simple.

    We create a secondary canvas - a graphics buffer - with a fixed size aspect ratio that will serve as the canvas onto which we draw our graphics. This secondary buffer will not be directly scaled or resized, we will actually treat like an image that will be drawn onto the original canvas. This original canvas will then be resized neatly while maintaining its aspect ratio.

    Safety Notes

    A run-down of best practices to stay safe while collecting on fxhash, and while navigating the Web3 eco-system in general.

    While the fxhash team does their utmost to provide a platform and community that is both safe and enjoyable, there is no guarantee that there will not be malicious actors trying to scam you out of your funds or crypto assets - it is important that you stay vigilant and exert scrutiny when you collect projects on fxhash and interact w dapps and other platforms in Web3.

    Not Financial Advice

    It is important to note here that none of the information here is meant to recommend or dissuade you from collecting specific projects on fxhash or interacting with certain dapps/platforms/tokens in the Web3 eco-system. Those decisions are entirely yours.

    All we aim to provide is an overview of how this subject area can be used by scammers to steal your funds.

    Verify before Collecting: Artists and Tokens

    Before purchasing an edition from a project on fxhash’s primary market, always make sure that the artist is actually the creator of the project. Likewise, always make sure that projects you collect are actually original works and not stolen code repackaged as a generative artwork.

    While for some of the bigger artists, that are household names on fxhash, it is pretty straightforward to tell, it might sometimes be a bit more difficult for new and emerging artists. If you are not entirely certain about the originality or legitimacy of a project, this is why fxhash has put in place a verification system, that artists can apply to, to obtain a checkmark badge next to their profile picture on fxhash.

    Verification System A checkmark badge next to an artist’s profile picture on fxhash indicates that they have been vetted by the mod team with a proven track record of works on and off fxhash. While it is a strong indicator that the artist is trustworthy, we still recommend exerting due diligence and verifying that the originality of their work.

    Not all artists on fxhash are verified however, in that case some of the other methods to verify the legitimacy of a project are:

    • Track Record and previous projects: Checking out an artist's previous projects gives a strong indicator of their track record.

    • The artist’s Social Media Profiles: checking the artist’s social media and whether or not they have talked and mentioned the project in the past

    • Artist’s Portfolio/Website/Blog: The artist’s personal pages and blog can also be an indicator if you want to collect their project. These pages might also be indicators about the artist’s persona informing you if they share similar values as you.

    We recommend also applying these same principles when collecting on other platforms and not just fxhash.

    Before purchasing mints from any artist (including any fxhash verified user) offered on the site or marketplace, you are advised to verify the artist verification independently.

    Although we may choose in our sole discretion to intervene or attempt to resolve a dispute between you and other fxhash users or Third Party Sites, you agree that we have no obligation to do so and that all transactions are ultimately solely between you and the applicable fxhash users or Third-Party Tools. The verification badge provided shall help collectors but is no substitute for doing your diligence.

    Separation of Concerns: Hot vs. Cold Wallet

    Besides being careful on what you collect, you can even go a step further and set up two separate wallets: a hot wallet that is used on a daily basis for effectuating transactions and interacting with dapps, and a cold wallet that is used as a vault for storing your assets. Here’s more information about the difference between the two:

    • Hot Wallet: A hot wallet is a cryptocurrency wallet that is connected to the internet. These are ideal for daily transactions and interacting with NFT marketplaces because they offer ease of access and convenience. Browser extension and software wallets like MetaMask, Temple, and the Coinbase wallet are essentially hot wallets. However, hot wallets are more vulnerable to online threats due to their constant internet connection and their interaction with various platforms and tokens. Still haven’t set up your software wallet? Here’s how to get started.

    • Cold Wallet: A cold wallet, on the other hand, is an offline wallet that provides enhanced security by being disconnected from the internet. This makes it an ideal choice for long-term storage of valuable NFTs and other cryptocurrencies. With cold wallets we usually refer to hardware wallets like Ledger and Trezor which are popular options. By using a cold wallet, you significantly reduce the risk of your assets being compromised through online attacks.

      A good guide on getting started with a hardware wallet can be found over in the metamask docs:

    The metamask docs are also generally a great resource for learning about all sorts of scams and how to protect yourself against them.

    Wallet Safety Tips

    We’ve already mentioned this when in the resource that tackles setting up your software wallets, however, we’d like to reiterate this information as it is highly important:

    • Never share your private keys and seed phrases with anyone: treat your private keys and seed phrases as highly confidential information. If anyone ever ask you for this information, assume that they are trying to steal your funds and assets.

    • Avoid storing your private keys and seed phrases digitally: Is it not advised to store this information in digital formats such as on your phone, computer, or online cloud services where they can be vulnerable to hacks or leaks. Also don’t store your private keys on compromisable devices, but rather, use physical backups for storing them - either on a notebook that is stored somewhere safe, or as some recommend, engraved on a metal plate (or other durable material).

    If you ever lose access to your wallet, this information is the only way to restore access. Otherwise your funds and crypto assets are lost forever.

    Interacting with dApps and miscellaneous Tokens

    Whenever you effectuate a transaction via your wallet, it is important that you are careful while doing so. Depending on what kind of transaction different kinds of code (smart contract or other) is run in the background - some transactions can therefore be malicious.

    In Web3 there’s many different decentralized applications, many of them will require you to connect your wallet for you to make use of the functionalities they provide, like the Objkt and OpenSea marketplaces that let you primarily trade your tokens, or other collection management and token curation tools like Deca for instance.

    While it is safe to connect to some dApps, others might be malicious and connecting to them could potentially be very dangerous, as connecting to them will instantly execute some code that will drain your assets to another wallet. For this reason we urge that you:

    1. Never connect your wallet to an unkown platform: don’t only judge platforms based on their looks, it is relatively simple to spin up a website that looks professional. Verify that the dApp is trustworthy, and that you are connecting to the correct domain (as indicated by the URL in your browser)

    2. Never confirm unknown transactions that you have not manually instigated: Never confirm a transaction when your wallet randomly prompts you with one. In case of doubt always reject the transaction. Even when you effectuate a transaction manually, still make sure what the transaction is actually prompting you to confirm.

    Furthermore, it can also be dangerous to interact with tokens that have been airdropped to you - selling them on a DEX (swapping them for another token) can be used to execute some malicious code. It is best to ignore unknown/unidentified airdrops. Same goes for airdropped NFTs as well as other assets.

    Interacting with Others

    There are many malicious actors, not just in Web3 where there’s many financial incentives for scamming others, but also on the internet in general. Scams might not necessarily be done via a decentralized platform or some elaborate token schemes, but can equivalently be done via phishing scams or malicious links sent to you. Here’s some thing to always keep in mind when interacting with others on the internet:

    • Avoid Links: Be cautious of links sent via email or social media; when someone sends you a link, never immediately click on it. Always access fxhash and other marketplaces through the official links/socials. Try to avoid clicking links in general and double-check URLs. Verify the domain first, and ensure it is a legitimate URL to avoid phishing scams.

    • Beware of “Too Good to Be True” Deals: If a deal seems too good to be true, it probably is. Exercise skepticism and do your own thorough research. When something seems suspicious or feels off, it is often better to be safe than sorry.

    • Staying informed and asking others: engaging with others and staying up to date with the space can help you identify potential scams early on.

    In conclusion, navigating the Web3 landscape safely and successfully requires a good amount of personal vigilance. While fxhash is committed to fostering a secure environment, the ultimate responsibility for protecting your assets rests with you. By adopting the best practices outlined here – verifying artists and projects, employing a dual wallet strategy, staying alert online, and meticulously reviewing transactions and interactions – you empower yourself to fully enjoy fxhash and the Web3 eco-system in general, while minimizing the risks involved.

    ONCHFS

    What is ONCHFS?

    ONCHFS stands for On-Chain File System. ONCHFS is a permissionless unix-like content-addressable file system fully stored on-chain designed to be delivered through the http protocol, with cross-blockchain compatibility and extensibility in mind.

    That's a lot to take in at once, let's address each point individually:

    1. Permissionless: Anyone can write data, create files & directories, & reference files stored on the file system.

    2. Unix-like: this simply means that onchfs is inspired by the unix-file system, where data is organized in a hierarchical tree-like structure of directories and files.

    3. Content Addressable: content is addressed by unique identifiers derived from the data itself.

    4. On-Chain: files are entirely stored on the blockchain, making them immutable and persistent as long as the respective blockchain is alive.

    5. Designed for the http protocol: the ONCHFS protocol makes it possible to address and retrieve the stored assets with the http protocol that powers the modern web.

    6. Cross-Blockchain: ONCHFS works on any chain, and files stored on one chain can reference files stored on other chains.

    7. Extensibility: ONCHFS is built in such a manner that it can easily be extended and other technologies to be built on top of it.

    ONCHFS is inspired by , , , , and aims at providing a general framework for working with files stored on-chain, following modern standards & practices.

    Link to revdancatt’s vid

    Why store files on-chain?

    Before we dive into the specifics: why would we want to store files fully on-chain?

    Ever since NFTs have become more popular, the on-chain vs. off-chain discussion has become more and more heated. One cherished aspect of blockchain technology is longevity, security, and immutability, especially when it comes to transactions which play a big role in making generative art as collectible digital tokens possible. In the previous page, we’ve covered the IPFS storage solution, which has characteristics that closely align with Web3 technology, in turn making it a popular solution for storing content and data in the setting of NFTs. Towards the end, we learn that it also introduces an element of impermanence, which requires additional effort from artists, collectors, and platforms to ensure the availability of the content.

    This could in theory all be solved by storing files directly on-chain. But there are two problems that come in tandem with this approach, firstly, the high cost of uploading and eternalizing large data loads on digital ledgers, and secondly, the absence of a good system or protocol for this purpose.

    In the setting of generative art, the first problem solves itself - the actual image data (that represents the art) doesn’t need to be stored directly on the blockchain, merely the code that can generate the art. Code being simply a bunch of alphanumeric symbols, is highly compressible and can be shortened enough to not introduce exorbitant minting costs. The second problem is addressed by ONCHFS which is introduced in greater detail in what follows.

    Overall, storing files on-chain is preferred by many because it is considered a purer and more persistent method for storing files that ensures the existence thereof for as long as the blockchain exists. And for the popular blockchains there is no worry for them to simply disappear overnight.

    What problems does ONCHFS solve?

    Previous attempts at on-chain storage solutions have had some inherent problems that ONCHFS tries to address. For instance, in the context of generative art projects that come in the form of self-contained web projects which the browsers can run, existing solutions don't actually fully store the entirety of the projects on the blockchain, but rather only a part of them - generally the code that creates the artwork. Generally, this code is minified and compressed into a string for it to be efficiently stored on the blockchain.

    This is problematic however, because it makes it such that platforms often need to implement an additional off-chain step to reconstruct the project as a whole for it to actually run in the browser. The javascript code that generates the artwork can't run in a vacuum and needs additional files to be complete, such as an html document that serves as an entry point, a stylesheet to specify its appearance in the browser, and additional other javascript libraries that it makes use of and builds upon.

    Recreating this project structure is referred to as html-reconstruction where the platform creates the index entry point that serves and displays the project in the browser. Additionally the platform needs to provide and host a specific list of dependencies that the project requires to function properly, this doesn't align with the decentralised ethos of Web3.0.

    ONCHFS solves both of these issues, projects are entirely stored on-chain such that no html reconstruction step is required. Additionally libraries, dependencies, and other assets can also be freely created by users, making it possible for anyone to reference them. In this manner, it liberates code artists in their creative endeavours, ensures longevitiy of projects stored with ONCHFS, and opens the door for interesting and creative projects that make use of this on-chain file storage paradigm.

    How does ONCHFS work?

    ONCHFS is designed for the purpose of preserving the integrity and longevity of generative art projects, making it excel in that regard. The ONCHFS protocol ensures that uploaded projects are delivered in a 1:1 format, without requiring any additional steps to reconstruct the original project.

    It also handles project dependencies in an elegant manner. Storing files in a content addressable manner, where each file has a unique identifier derived from the data itself (we cover this in a bit more detailed manner in the page on IPFS), makes it possible to detect if a library already exists on-chain. In this case, the library doesn't need to be re-uploaded a second time, and it will automatically link the already existing stored version. ONCHFS handles this by creating the content ids at upload time.

    This introduces a paradigm of trustless and fully open resources sharing, as no one has to rely on a centralized platform to provide a library, or a set of personal tools they keep reusing over time; if they upload it once, it will become available forever for free for everyone using onchfs.

    What's more, is that the resources stored with ONCHFS are http compliant.

    <aside> <img src="" alt="" width="40px" /> What is http?

    HTTP, or Hypertext Transfer Protocol, is the foundation of data communication on the World Wide Web. HTTP facilitates the transmission of various types of data, including text, images, and multimedia, using a request-response model. When a user enters a web address or clicks on a link, the browser sends an HTTP request to the server, specifying the desired resource. The server then processes the request and returns an HTTP response, containing the requested data or an error message.

    </aside>

    This means that when files are uploaded to ONCHFS, they are also formatted in an http compliant format that can be transferred by means of the protocol. Naturally, the artist/user uploading to ONCHFS doesn't need to worry about any of this, it is automatically handled ia the fxhash minting interface. It is possible however to also manually interact with ONCHFS.

    A complete documentation of ONCHFS can be found here:

    Chain Agnostic

    One innovative aspect of ONCHFS is that it can be used to store files on any blockchain, without having their existence isolated and restricted to that particular chain. This means that a file on the one chain can reference files stored on other chains.

    This can become useful if there is a need to use a cheaper blockchain for storing bigger chunks of data to be accessed more expensive blockchain. While not a typical scenario, it's worth noting the built-in onchfs support for such cases.

    Limitations

    The main limitation of ONCHFS is that it is a relatively new method for storing files on-chain, meaning that it isn't as widely adopted as other decentralized storage solutions such as IPFS. With fxhash growing as a platform and community and with more files being stored with ONCHFS it is likely to become adopted by other platforms that would like to display these generative art projects

    Creating an Account

    How to connect your wallets to fxhash and setup your profile information

    Because fxhash supports both the Tezos and Ethereum chain, it needs to support wallets that can connect and interact with those chains. For this purpose a system has been created where users can link two wallets at the same time - a primary and secondary wallet:

    What is a wallet?

    A cryptocurrency wallet, often simply referred to as a wallet, is a digital tool that allows users to store and manage their cryptocurrency holdings as well as their digital tokens that exist on the blockchain.

    Essentially, a wallet is a software (often in the form of a browser extension) that stores the cryptographic keys (private and public keys) needed to access and manage the owned assets on the blockchain. Usually it also provides useful functionality to create multiple addresses and to manage their corresponding keys.

    If you don’t have a wallet yet, you can find a detailed guide to setting one up for each chain here:

    Once you’ve set up one or both wallets for the chains that you’d like to create or collect art on, come back here to set up your fxhash account and profile.

    Creating an Account

    Creating an account on fxhash requires an Ethereum or Tezos wallet. When navigating to the fxhash website, you will see a large ‘Connect’ button in the upper right corner next to the other navigation items:

    Pressing that button should reveal a drop down list with two options:

    There you can then choose which wallet you would like to connect. If you have both an Ethereum and Tezos wallet, the one that you choose at this point will become your primary wallet.

    Primary Wallet: If it’s the first time connecting to fxhash make sure to connect with the wallet that you intend to use most often, from which you want to create your main projects or hold your main collection - the first connected wallet will become your primary wallet.

    Pressing the Connect button will open a new view showing all supported wallets, choose the one that you would like to connect with:

    Selecting your desired wallet will then trigger it, requiring you to verify this operation through a number of steps:

    1. Make sure to select the appropriate wallet address that you want to connect with.

    2. Approve the connection request.

    3. Approve the signature of the request - this only has to be done the very first time.

    After completing and verifying the required steps from your wallet you can already notice a change in the interface, where the connect button has changed into a circle - in the future you will see your profile picture here once you update your profile settings.

    Clicking your profile circle will reveal a drop down list of link to pages from which you can manage your creations and collection, and all of the other features that fxhash provides. At the very bottom it also shows the connected wallet - here we connected with a Tezos wallet, we could now additionally connect an ethereum wallet.

    We can now navigate to our profile (via the profile button) where we can see your connected wallets, and also equivalently connect a wallet for the other chain.

    Linking a Secondary Wallet

    Besides the primary wallet that has been connected, we can now also link a wallet for the other chain, Ethereum or Tezos depending on which one was connected first. In this example we connected a Tezos wallet first and an Ethereum wallet second:

    Linking a secondary wallet for the other respective chain is important if you want to interact, create, or collect with projects minted on that chain.

    Wallet Management

    There is two operations for each wallet. For the Primary wallet:

    • Disconnecting your primary wallet: this is equivalent to logging out of your account. Reconnecting your primary wallet will grant you access to your profile again.

    • Deleting your account: this essentially deletes all off-chain information associated with your account. The respective projects created with this wallet address are not deleted, they will always stay linked to that wallet address. Deleting the account simply means that the fxhash profile of this account is deleted.

    For the Secondary wallet:

    • Disconnecting your Secondary Wallet: logs out of your secondary wallet, but doesn’t log you out of your profile. It makes the secondary wallet unavailable for usage, and you would have to reconnect it to use it.

    • Unlinking your secondary Wallet: essentially removes this secondary wallet, which would also remove all project created and collected with this wallet from your profile. You can always re-link it as well.

    Linking an Existing Wallet

    If you are trying to link a wallet as a secondary wallet, while this wallet is already connected or linked as a primary or secondary wallet in another account, you will obtain the following warning:

    If this is the case you will have to unlink the wallet (if it is linked as a secondary wallet) or delete the account associated with that wallet (if it is connected as a primary wallet) to make it available for linking.

    Editing your Profile

    Editing your profile is simply done by clicking the edit profiel button, that will take you to another view where you can enter all of your details:

    Temporarily linking social media profiles is disabled due to the migration that fxhash is currently undergoing.

    Canvas element & API

    An explanation of the HTML canvas element and the Canvas API

    The canvas element was first introduced by Apple in 2004 and was later standardised across various web browsers with HTML5. Today, the HTML5 canvas element is widely considered the go-to choice for rendering graphics in modern web browsers. One key reason for this is its built-in Canvas API: a set of functions designed for the purpose of drawing to this digital drawing surface.

    What is the HTML <canvas> element?

    The <canvas> element is a special HTML element that makes it possibly to dynamically draw graphics, animations, and interactive content on a web page using JavaScript. In essence it is a a rectangular bitmap, a grid of pixels, that allows the creation and manipulation of graphics within a web browser.

    Creating a Wallet

    A brief overview of cryptocurrency wallets and step-by-step guides to setting up the Metamask and Temple wallets for the Ethereum and Tezos blockchains respectively.

    Wallets and Browser Extensions

    Wallets are the primary tool with which users interact with the blockchain, they come in the form of small software, usually in the form of browser extensions, that let us connect to different pages and apps that make use of blockchain technology and interact with them. fxhash requires its users to connect with such a wallet to start using its features.

    **What is a Crypto Wallet?**

    In the world of cryptocurrencies, a wallet is a secure place where you can store, send, and receive digital currencies and tokens. It's an app or a software program that helps you interact with the blockchain, which is the technology behind cryptocurrencies. Just like you need a bank account to use regular money online, you need a cryptocurrency wallet to use digital currencies. This wallet has a special address that others can use to send you cryptocurrencies, and it keeps your digital money safe.

    What is Generative Art?

    In his seminal essay ‘Why Love Generative Art?’ Artnome explains the artform and elucidates the importance of generative art:

    What is Generative Art? The modern definition:

    Generative art, an artistic practice, commonly involves using computer code and random processes to create a wide range of media artifacts.

    However, art historians tend to define generative art more broadly as art produced with the assistance of a system or process. By that definition, there are examples of generative art dating back eons, including grids carved into stone by ancient peoples using a systematic approach:

    What’s important to note is that generative art goes beyond strict imagery. Numerous examples exist where nature serves as the ultimate source of randomness to produce unique art, including in music, as exemplified by Aeolian wind harps and wind chimes.

    curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg</a>.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/"
    brew install node
    node -v
    npm i -g fxhash
    npx fxhash create
    // Listen for a key press event
    document.addEventListener('keydown', function(event) {
      // Check if the pressed key is the 'e' key (you can change this to any key you want)
      if (event.key === 's') {
    	// Call the function to export the canvas as a PNG image
    	exportCanvasAsPNG(canvas);
      }
    });
    function exportCanvasAsPNG(canvas) {
      // Create an "a" element to trigger the download
      const link = document.createElement('a');
    
      // Convert the canvas to a data URL
      const dataURL = canvas.toDataURL('image/png');
    
      // Set the href attribute of the "a" element to the data URL
      link.href = dataURL;
    
      // Set the download attribute to specify the file name
      link.download = 'canvas-export.png';
    
      // Simulate a click on the "a" element to trigger the download
      link.click();
    }
    
    function keyPressed() {
    	// keyCodes map to specific keys on the keyboard
    	// 83 maps to the 's' key
    	if (keyCode === 83) {
    	  // the save function exports the canvas as a PNG file
    	  save();
    	}
    }
    const canvasWidth = 900;
    const canvasHeight = 1200;
    
    const scale = 2
    
    // Multiply the canvas dimensions with the desired pixel density
    canvas.width = canvasWidth * scale;
    canvas.height = canvasHeight * scale;
    
    // Scale the canvas appropriately
    ctx.scale(scale, scale)
    function redrawGraphics(scale){
      // Set the canvas dimensions multiplied by the ratio
      canvas.width = canvasWidth * scale;
      canvas.height = canvasHeight * scale;
    
      ctx.scale(scale, scale)
    
    	/*
    	
    		Your code goes here
    	
    	*/
    }
    
    originalScale = 1
    redrawGraphics(originalScale)
    createCanvas(canvasWidth, canvasHeight);
    secondaryCanvas = createGraphics(canvasWidth, canvasHeight)
    
    // setting the pixel density of the canvas and graphics buffer to 4
    pixelDensity(4)
    secondaryCanvas.pixelDensity(4)
    <https://example.com/page?scale=2>
    var urlParams = new URLSearchParams(window.location.search);
    var scale = urlParams.get('scale');
    
    // Check if the 'name' parameter exists
    if (scale === null) {
    	scale = 1
    }
    
    /*
    	Rest of the code as before
    */

    **What is a Browser Extension?**

    A browser extension is a small software module that adds functionality to a web browser. It typically extends the capabilities of the browser and allows users to customize their browsing experience by adding new features or modifying existing ones. In most browsers these extensions appear in a drop down list at the top right corner.

    In this page we’ll walk you through installing Metamask for Ethereum, and Temple for Tezos.

    Creating an Ethereum Wallet

    1. Download and Install MetaMask:

      • Go to the MetaMask website or your browser's web store: https://metamask.io/

      • Download and install the MetaMask extension for your browser.

    2. Create a New Wallet:

      • After installation, click on the MetaMask extension icon in your browser.

      • Select "Create a Wallet" to start setting up a new wallet.

    3. Set a Password:

      • Create a strong password for your MetaMask account.

      • This password is used to access your MetaMask extension on your browser. We recommend storing this password in a password vault.

    4. Secure Your Secret Recovery Phrase:

      • MetaMask will generate a secret recovery phrase (also known as a seed phrase).

      • Write down this phrase and keep it in a secure place. It's crucial for recovering your wallet if you forget your password or change devices. This secure place can either be on a physical piece of paper, and stored somewhere secure like a safe, or in a password vault.

      • NEVER share this with anyone. There is no good reason that anyone will ask you for this phrase.

    5. Confirm Your Secret Recovery Phrase:

      • To ensure you've correctly noted your recovery phrase, MetaMask will ask you to confirm it.

      • Select the words in the correct order as given in your secret phrase.

    6. Wallet Created:

      • Once you’ve confirmed your secret recovery phrase, your wallet is created.

      • You can now use your MetaMask wallet to store Ethereum and other ERC-20 tokens.

    Remember, it’s essential to keep your secret recovery phrase secure and never share it with anyone. Losing this phrase or sharing it with others can result in the loss of your funds.

    Metamask should now appear in your extension list:

    If you need more help setting up metamask you can consult this resource:

    Support

    Temple Wallet for Tezos

    1. Download and Install Temple:

      • Navigate to the temple wallet’s official page here: https://templewallet.com/.

      • Download and Install Temple on your the browser/device you intend to use for creating/collecting generative art.

      • In this demonstration we'll install Temple on Brave

    https://gateway.fxhash2.xyz/ipfs/QmbF8vRfAC3wNMUeqo6VWeQfiDtNsMgNvRS8uP9RkrrBqL

    Since Brave is also chromium based (it uses the same tech as chrome under the hood), it'll also take you to the chrome web store where you'll simply click on Add to Brave:

    Click the ‘Add to Brave’ button to add the extension to your browser.

    Click the ‘Add to Brave’ button to add the extension to your browser.

    You'll also have to allow the extension from the pop-up.

    You'll also have to allow the extension from the pop-up.

    1. Create a New Wallet:

      • After installation, a new tab should open up and you'll be greeted by the following screen.

      • Select "Create a Wallet" to start setting up a new wallet.

    Hit Create a new Wallet now. If you already have a Tezos wallet on some other devices you alternatively import it now. The steps for importing an existing wallet are different than setting up a new one.

    Hit Create a new Wallet now. If you already have a Tezos wallet on some other devices you alternatively import it now. The steps for importing an existing wallet are different than setting up a new one.

    Now when you check your extensions list you should also see Temple show up there, you can go ahead and pin it so that you can quickly access it in the future:

    https://gateway.fxhash2.xyz/ipfs/QmQYKvQVX2AHXVNK59c7uioT2pDcJtugmNMpxcMhbhC4oj

    1. Securing the wallet Seed Phrase:

      • To create a new wallet Temple will prompt us to secure and backup the seed phrase - the private key to the wallet.

      • Temple will ask you to confirm it by filling out some blanks.

    Make sure to complete this step carefully and store your seed phrase in a secure location - ideally somewhere offline as well.

    Make sure to complete this step carefully and store your seed phrase in a secure location - ideally somewhere offline as well.

    This seed phrase is basically the master key that gives you access to your wallet in the future. As indicated in the screenshot, this seed phrase should be stored somewhere safe, ideally somewhere offline, and not be shared with anyone else. If for any reason your device breaks, and you want to import your wallet on a new device, then you will require this seed phrase.

    Seed phrases are usually made out of 12 random words - in the next screen you'll be asked to verify that you've made a backup by filling in some of the words:

    https://gateway.fxhash2.xyz/ipfs/QmZGyrdH7Bn8bir8LoTJujbsNu3nKoKFmXNsbHywXEVhTu

    1. Setting your password:

      • Enter a strong password that you can easily remember

    Also make sure to not check the Skip Onboarding

    Also make sure to not check the Skip Onboarding

    Once you've backed up your seed phrase you’ll also have to set up a password. You're not actually going to use the seed phrase to log into your wallet each and every time you want to use it, but rather you'll be using a regular password just like for other accounts on the internet - this password essentially unlocks your wallet whenever you want to use it for a transaction:

    Next it'll take you through a number of onboarding steps - read those carefully! And we're already good to go actually!

    https://gateway.fxhash2.xyz/ipfs/QmWq7VhkkmryHT4fxVsAufFEtCHMidfYAKpd4xrgPWjqhT

    You can now get started with creating and collecting on the Tezos blockchain.

    Getting Funds in your Wallets

    There's multiple ways to get some Tez in your wallet. The most convenient method is probably by directly purchasing some Tez through the Temple wallet. Simply click the buy button in the wallet and it'll offer a couple of methods to do so, either by exchanging a different currency or directly via debit/credit card.

    Alternatively you can also purchase Tez via an cryptocurrency exchange platform and then sending it to your wallet address from there. This might be more or less difficult depending on your country of residence where there might restrictions on those exchanges, for instance, you might have to get verified by providing legal documents, to subsequently be able to send funds to your browser wallets.

    Thirdly there's also the option of hustling for your funds by creating your own projects on fxhash or other platforms. You'll need someone to initially help you out to cover transaction costs and gas fees to create your projects, and you might be surprised how many artists and collectors would be willing to help kickstart your endeavors in this regard. Once someone collects your art you'll have more funds to create more artworks and support other artists as well.

    A note on Safety

    In the future your wallet will likely contain value in the form of various cryptocurrencies and digital tokens. If unauthorized individuals gain access to your wallet, they could potentially transfer tokens and withdraw funds, leading to financial losses. Once your digital assets are lost or stolen, they are often irrecoverable. Unlike traditional banking systems, there is typically no recourse for retrieving lost or stolen assets on the blockchain. Hence it is of crucial importance to keep your wallets safe.

    Users on Web3 are often targeted by phishing scams, where malicious actors attempt to trick individuals into revealing their wallet credentials or private keys, or alternatively try to gain access to the device a wallet is being used on. By keeping your wallet secure and navigating the web responsibly, you reduce the risk of falling victim to such scams. If your wallet is used for interacting with decentralized applications (DApps) or executing smart contracts, a compromised wallet could lead to unintended and irreversible consequences in these applications.

    Hence, keep these things in mind when you have a wallet installed on your device:

    • Never reveal your private keys to anyone.

    • Don’t store them in an obvious manner on your device.

    • Only interact with reputable platforms that you trust.

    • Don’t confirm or authenticate wallet transactions if you don’t know what they are for.

    • Don’t press on links that you don’t know the origin of.

    • Don’t download files or software that you can’t trust.

    Directly reaching out: Sometimes the best way to verify a work on fxhash is by reaching out to the artist directly and inquiring with them.
  • Inquiring with other collectors: If the previous proves to be difficult, then you can also reach out to other collectors and ask them for their opinion.

  • User Guide: How to use a Hardware Wallet | MetaMask Help Center 🦊♥️
    ethfs
    ipfs
    bitcoin ordinals recursive inscriptions
    Unix filesystem
    https://prod-files-secure.s3.us-west-2.amazonaws.com/f9d1e984-50ed-4650-a543-95d2b6c0ba90/015a834d-6092-42a9-a3c6-6ede37149fdd/fx_doc-icon_info_001.png
    https://prod-files-secure.s3.us-west-2.amazonaws.com/f9d1e984-50ed-4650-a543-95d2b6c0ba90/015a834d-6092-42a9-a3c6-6ede37149fdd/fx_doc-icon_info_001.png
    Hello from ONCHFS — On-Chain for Http File System | ONCHFS — On-Chain for Http File System
    The Marketplace
    Etherscan.io
    Splits
    Creating a Wallet
    the fx(hash) CLI
    CLI Setup
    Using Randomness Correctly
    fx(params) module
    npx degit fxhash/params-boilerplate your_project_name
    npm install
    npm start
    http://localhost:3300/?target=http://localhost:3301
    Automatically after a fixed delay: a fixed time delay indicates that the capture module should trigger automatically after a certain amount of time after the project is loaded. Selecting this option will make a slider appear where you can set how many seconds the capture should wait before triggering, up to 300 seconds.

    fast-capture

    A new context that lets you generate a preliminary preview to display before the actual preview image is generated—useful for intensive projects that require a couple of seconds to render. In essence this can be your custom "waiting to be signed" preview image.

    minting

    When fxhash runs your project's code in the fxparams minting interface.

    For this project we are using the $fx.preview() function
    script
    >
    <link rel="stylesheet" href="./styles.css" />
    </head>
    <body>
    <script src="./index.js"></script>
    </body>
    </html>

    It’s not only a powerful tool for the creation of generative art but also web-based games, data visualisations, charts, drawings, and other interactive multimedia content in the browser.

    The canvas element comes with its own associated canvas API, which provides convenience functions that make the creation of graphics on this bitmap much easier, rather than requiring the artist to manually update individual pixels to create certain shapes, it handles this for us. The most comprehensive resource for this canvas element can be found over on the MDN web docs:

    What's more is that over the years numerous libraries have been developed on top of this canvas API to further simplify writing graphics generating code. For the purpose of making generative art, some of these libraries have become increasingly popular in recent years; they are frequently used to build fxhash projects and we will have a look at some of them throughout the next sections.

    In this section, we'll mainly talk about how to create a canvas element in a web page and how to use the functions that the canvas API provides to draw to it.

    The Canvas Element

    A canvas element can simply be created by using the <canvas> tag in our HTML document:

    The canvas element comes at a default width of 300 pixels and default height of 150 pixels. We can however specify our own dimensions through the width and height HTML attributes - here we set them to 400 pixels each, resulting in a square aspect ratio canvas.

    A minimal webpage with a canvas element would look as follows:

    And here's what this would look like:

    The canvas element is transparent by default. Here we're colouring it in a dark grey with some inline CSS to differentiate it from the background and make it visible:

    This doesn’t look like much yet, but it is the foundation for drawing graphics into the browser.

    The different Rendering Contexts

    Drawing to the canvas element doesn't happen directly via the canvas API per se, but rather via a rendering context that this canvas API exposes. Rendering contexts are essentially different drawing modes in which we can manipulate graphics on an HTML5 <canvas> element.

    Each type of rendering context provides specific capabilities and methods for working with graphics in different ways. Selecting which one is more suitable for your purposes entirely depends on the generative artwork you’d like to create.

    What is a rendering context?

    A rendering context in the context of the HTML canvas element refers to the object that provides methods and properties for drawing on the canvas. The rendering context is an interface to a drawing surface and is obtained from the canvas element.

    The Canvas API mainly provides two rendering contexts, the 2D context and the WebGL context:

    • The 2D Rendering Context (2D Context): is the more commonly used rendering context. It provides methods and properties for creating and manipulating 2D graphics on the canvas. It allows us to draw shapes, text, images, apply styles, create animations, and more. Reference for the 2D rendering context.

    • The WebGL Rendering Context: short for Web Graphics Library, is a JavaScript API that is more commonly used for rendering 3D graphics within a <canvas> element using the power of hardware acceleration. Based on OpenGL, it provides a more advanced and complex way to create interactive 3D graphics and high-performance visualizations on the web. This rendering context comes in two flavors WebGL and WebGL2, where the latter is an updated version of the former that provides more features. Reference for the WebGL rendering context.

    In other words, if you want to display 2D graphics go for the 2D context, and for 3D stuff the WebGL rendering context is more suitable.

    Drawing to the Canvas

    Having created the canvas element we can now make use of one of these rendering contexts to draw some graphics to it. To this end, we first need to fetch the canvas element from the DOM of our webpage. This can be done as follows:

    When we created the canvas element, we conveniently gave it an id attribute allowing us to now fetch a reference to it from the DOM with the document.getElementById() function.

    What is the DOM?

    The DOM, or Document Object Model, is a programming interface for web documents. It represents the structure of a document as a tree of objects, where each object corresponds to a part of the document, such as elements, attributes, text, etc. The DOM provides a way for programs (typically scripts written in languages like JavaScript) to manipulate the structure, style, and content of web documents dynamically.

    Now we can select which rendering context we’d like to use:

    For now we'll make use of the 2d rendering context, otherwise we could also specify ‘webgl’ here. We can now use this rendering context's functions to draw to the canvas:

    And here's what this would look like:

    All of this can be done within a <script> tag inside the same HTML document directly underneath our <canvas> tag:

    But alternatively we could also place this graphics drawing code in it’s own individual JS file and reference it.

    Animated Graphics

    Static graphics are only the tip of the ice-berg however, we can also display animated graphics on this canvas element. This can be achieved via the requestAnimationFrame() function—here’s an example:

    And the code that powers this animation, looks as follows:

    We created a function called draw() that creates a spinning circle of rectangles. Within it we draw a white rectangle that spans the entire canvas (as a background), as well as a loop that uses trigonometry to draw a number of black rectangles around the circumference of a circle. The white rectangle is used to reset the canvas and cover the previous graphics that have already been drawn in previous invocations of the draw() function.

    Towards the end of it we invoke the requestAnimationFrame() function and pass in the draw() function itself as an argument. By doing so, the requestAnimationFrame() function will execute the draw function again once it has completed, this causes the draw() function to run continuously and make the spinning circle move forward by means of a variable called counter, that is incremented each time the draw() function is executed. A note here, is that this function doesn’t necessarily need to be named draw(), it can have a different signature as well. You can find more explanations and examples of animations here.

    This concludes this short primer on the HTML canvas element. In the next sections we will discuss some of the important aspects that come into play when we try to build a generative token with this canvas element, such as positioning it neatly in the browser window, handling user input as well as using some of the libraries that are built around the canvas element.

    By observing examples like that of the wind playing over the Aeolian harp in the above snippet, we see that the foundations for randomness in art have been laid since the earliest days and find inspiration in nature.

    More recently, Dadaists and Surrealists began to experiment with chance in art, utilizing poetry, collage, and other mediums to embrace unpredictability and create unique pieces.

    Later, the role of chance in art was taken to new levels with the invention of the computer, resulting in machine-co-created artworks that were algorithm dependent. Pioneers of this era, the 1960s, include Vera Molnár, Frieder Nake, and Georg Nees..

    Generative Art History so far

    1960s to 1990s: Early Experiments

    Generative art as we know it today finds its roots in the 1960s when artists and computer scientists began experimenting with computer-generated visuals. Pioneers like Vera Molnár, Harold Cohen, and Manfred Mohr used algorithms to create geometric shapes, patterns, and abstract compositions.

    2000s: Processing and OpenFrameworks

    In the 2000s, the development of open-source programming platforms like Processing and OpenFrameworks played a key role in democratizing generative art. These tools allowed artists with little programming experience to learn from others and let experienced generative artists start sharing their works with the world more freely.

    A comprehensive timeline on generative art history can be found in this archival and exploratory resource by Le Random:

    Long-form Generative Art

    All outputs of a long-form collection as seen together

    In his seminal essay, THE RISE OF LONG-FORM GENERATIVE ART, Tyler Hobbs clearly outlined a definition for this new form of generative art. Some modifications have been made to make this definition accurate for Tezos and fxhash.

    The artist creates a generative script (e.g. Fidenza) that is written to a blockchain or IPFS (as is the case on fxhash) Next, the artist specifies how many iterations will be available to be minted by the script. A typical choice is in the 100 to 1000 range. When a collector mints an iteration (i.e. they make a purchase), the script is run to generate a new output, and that output is wrapped in an NFT and transferred directly to the collector. Nobody, including the collector, the platform, or the artist, knows precisely what will be generated when the script is run, so the full range of outputs is a surprise to everyone.

    Note the two key differences from earlier forms of generative art. First, the script output goes directly into the hands of the collector, with no opportunity for intervention or curation by the artist. Second, the generative algorithms are expected to create roughly 100x more iterations than before. Both of these have massive implications for the artist. They should also have massive implications for how collectors and critics evaluate the quality of a generative art algorithm

    This new kind of artform marked a pivot point in how code artists approached generative art, especially in the advent of blockchain technology that made the distribution of generative art in a completely digital manner possible.

    What is long-form generative art?

    A long-form generative artwork is a system that has the ability to generate a large variety of visually/aesthetically distinct, but stylistically coherent outputs.

    Modern Generative Art

    With many modern tools at the artists’ disposal, generative art has become a very multifaceted and nuanced artform that lies at the intersection of art and technology, drawing notions from the two fields for new kinds of artworks and experiences.

    The role of the Artist

    In generative art, the role of the artist extends beyond traditional methods. The artist designs the rules or systems that dictate the creation of the artwork. This requires a combination of creativity, programming skills, and a deep understanding of the algorithms and processes that will shape the final vision of the piece.

    Collaborating with Technology

    In the same manner that the artist doesn’t directly create the final artwork but rather constructs a framework for that purpose, it becomes a collaboration with the machine - a dialogue and ongoing conversation with technology. As much as it relies on building systems, it also embraces the unpredictability and emergent properties of the algorithms that bring these generative systems to life. This partnership allows for unique and unexpected results, which can challenge conventional notions of art and authorship.

    Interactive Art

    Generative art can be interactive, allowing viewers to participate and influence the artwork. By introducing user input, such as in fx(params) for instance, artists can create dynamic and ever-changing pieces that respond to the audience in real-time and let the collector determine the final result. The audience in this manner becomes a part of the artwork because they essentially bring it to life.

    Immersive Experiences

    Generative art can also be utilized to create immersive experiences in metaverse/VR/AR environments — for example, THE PASSAGE by H&N.

    Inside THE PASSAGE, your actions determine the artistic output you receive. By combining generative techniques with these technologies, artists can develop rich, engaging worlds that blur the lines between art, entertainment, and storytelling.

    Collectors as Co-Creators

    Modern blockchain technology and the tools offered by fxhash transform the collector into a co-creator who actively participates in the artwork's creation process. In this manner artists not only build generative systems, but also interfaces that incorporate the decisions of their audience for the creation of the final artwork. More on this when we talk in more detail about fx(params)

    In this manner artistic collaboration is reimagined and transformed.

    When you're part of the creative process, it's only natural that you'll feel a deeper emotional and personal connection to the artwork. Your actions directly shape the final piece, potentially deepening your sense of ownership and pride in this new treasure. This connection can make the artwork more valuable and meaningful to a collector, both emotionally and financially.

    The idea of collectors as co-creators in long-form generative art shakes up the traditional concept of artistic collaboration. It turns passive observers into active participants, and that's a game-changer. This collaborative approach adds a fresh layer of complexity and depth to the generative art experience, making it an exciting and engaging form of artistic expression.

    Cultural Impact and the Art Market

    Democratising art creation

    Digital art on the blockchain has unarguably had a transformative effect on the art market. In particular generative art has helped democratize art creation, by enabling a wider range of individuals to participate in the process. Open-source tools, coding platforms, and online resources have made it easier for people to learn, experiment, and share their creations.

    Generative Art and NFTs

    The rise of NFTs and web3 platforms has had a significant impact on the generative art landscape. NFTs have given generative artists a new way to monetize their work, while collectors and enthusiasts can now own, trade, and invest in unique digital art pieces with unquestionable provenance. With fxhash it has never been easier to turn generative art into a career.

    Getting Started as a Collector

    A discussion of best practices for collecting NFTs on fxhash and elsewhere, the role of the collector in shaping a complete NFT eco-system, and strategies for acquiring a meaningful body of varied pie

    Blockchain technology has made it much more accessible to become an art collector today. Decentralized sales mechanisms have not only streamlined the distribution of digital art, they’ve also democratized the participation in a global art movement, making it possible for anyone to take part either as a creator, a collector, or both at the same time. In this resource we’ll tackle the role of the collector in the dynamic Web3 setting - collectors are in many ways vital to forming a complete NFT eco-system:

    (NFT) Collector: An individual or entity that actively acquires and holds non-fungible tokens (NFTs) for various reasons, including personal enjoyment, investment potential, community engagement, or support for digital artists and creators. They play a crucial role in the NFT ecosystem by shaping market demand, influencing trends, and supporting the development of digital art and culture.

    While collecting NFTs is in many ways easier and more accessible than being a collector in the traditional art world, this modern practice does however come with its own set of difficulties. In what follows we outline some guidelines and best practices for getting started as a new collector, and also provide some strategies for growing and accruing a meaningful collection of different works over time.

    Motivations for Collecting Art

    Before providing advice on how to get started as a collector - it is also meaningful to assess one’s own internal motivations and desire for art ownership:

    Why do collectors collect Art? Why be a collector?

    While the answer to these questions can be highly individual, the practice of collecting art is important for multiple reasons:

    • Supporting the Artists You Admire: The simplest reason for collecting artworks, is that it financially supports the artists that have poured countless hours into honing their craft and creating unique pieces of expression.

    • Furthering a Cultural Dialogue and Exchange: By purchasing works from living artists and by endorsing their endeavors, collectors can directly contribute to the dynamic evolution of art and culture, providing essential financial support that allows for experimentation and innovation. This fuels an evolving cultural landscape where new ideas and perspectives challenge and enrich existing norms.

    • Collecting is a Form of Expression in of Itself: Collecting and building a collection of works can be a fulfilling personal endeavor in of itself. Not only to express a genuine appreciation for the art-form (when it comes to generative art on fxhash), but also because the act of collecting works can in itself be a form of expression - through which one can convey their own personal unique tastes and interests. Expressing interest in certain artworks, by certain artists, can often constitute a

    And these are just a few reasons why it can be a fulfilling endeavor to collect art. Pivoting off of the last point though, what makes collecting digitally native tokens special and what’s the difference when compared to collecting art in a traditional setting?

    Why collect NFTs? What is the difference between holding a digital token vs. owning a physical artwork?

    Beyond the aforementioned reasons, collecting in the NFT setting furthers the ongoing dialogue around this new digital medium and encourages the exploration of new technological ideas. We’ve already witnessed a number of breakthroughs through some innovative explorations of the artists - which would not have been possible without the ongoing support from collectors of all kind.

    Whether you simply want to become a collector to show support to the creators that you admire, or have a firm belief in the future financial value of these digital tokens, is ultimately up to you - you might even have other personal motivations.

    Best Practices for Collecting on fxhash

    Taking your first steps as a collector can be a daunting endeavor when you don’t know how and where to get started. Collecting doesn’t mean that you just blindly acquire different tokens on fxhash and other platforms, but rather involves doing your research and making informed decisions on which pieces you’d like to add to your growing collection - and in that regard there’s quite a few things that need to be considered.

    We found that one of the best primers for collectors aiming to dive into fxhash, is the article by Lil Saturn titled .** The author adequately describes it as “the article I wish I had when I first started collecting on fxhash”. While the landscape has changed quite a bit in the past years since the article was published, most of the information that’s presented still holds true today:

    I believe long-form generative art is the biggest shift in the art space of this generation. And we have the rare opportunity to be living while it blossoms, we can take part in it, help shape it, and participate in the financial (yes, I said it) upside of this movement.

    The article references another meaningful resource, and highlights a talk given by Jason Bailey, aka Artnome - one of the original enthusiasts, that recognized the value of NFTs early on, and has shown a long standing interest in generative art. Over the years he’s become a critically acclaimed writer and respect voice in the generative art space.

    In one part of his presentations he breaks down collecting NFTs into 4 simple considerations:

    We find that these are excellent guidelines to adhere to when collecting tokens, on fxhash, and on other platforms - especially if you’re just starting out:

    • Collect the art that you love: before you collect one of the thousands of tokens on fxhash, via the primary or secondary market, ask yourself in what ways the particular piece you’re interested in resonates with you, and in a Mary Kondo-esque way, whether or not holding this digital token in your wallet will bring you joy.

    • Collect projects from artists you want to see succeed: fxhash empowers big and small artists alike. Collecting from the creators that you’d like to see succeed is one of the best ways to support them.

    • Only collect for prices you can afford: Decide how much you can comfortably expend for the purpose of collecting NFTs, without affecting your other financial obligations.

    Following these guidelines should make for an enjoyable collecting experience overall.

    Getting Started: Budgeting and Collecting Affordable Pieces

    To start with the basics — it’s important to set a Budget. Determine how much you're willing and can afford to spend on your purchases, and really stick to that budget. This could mean that you set a monthly spending limit for yourself, or put a maximum limit on how much you want to spend on any single purchase. Setting a clear predetermined budget for yourself will help you avoid overspending in the long run.

    Here you might be asking yourself the following questions: how do you actually determine the value of a digital token? What makes one artwork worth more than another one? Why is there a difference in price between two tokens that look quite similar?

    While at first glance it might seem like the price tags placed on the artworks on fxhash are assigned in a somewhat arbitrary manner. It’s a bit like walking into a grocery store in a foreign country - items can have all sorts of different price points.

    It can be difficult to assess the value of a digital token. Make sure to check out The Value of Generative Art to get an idea what factors determine the specific prices of Generative Tokens on fxhash, then go from there and decide what an appropriate budget is for you.

    When you don’t have a feel for the “price” of things yet - start out small. Start your collection with more affordable pieces. Many artists offer a range of sizes and editions, some cheaper than others—sometimes even as free mints. This makes it possible to start a collection without a significant financial commitment. Here’s some tips towards in that regard:

    • Explore the projects of Emerging Artists. Instead of directly trying to compete in the big leagues, exploring the art of emerging generative artists can be a worthwhile endeavour, they frequently offer their work at more affordable price points compared to established names. Additionally, early works from rising artists can become more valuable over time - and your support plays a crucial role in this setting.

    • Minting during Community Events: frequently the community will come together for special occasions, such as the fxhash anniversary just as an example, where artists will mint pieces revolving around central theme or shared topic; usually the projects minted during these events tend to be on the more affordable side of things. This is often one of the best times to kickstart your collection for cheap.

    • Consider Open/Larger Editions: Some projects on fxhash are available in open editions for a very affordable price (sometimes even free), meaning that there is no limit to the number of copies that can be minted (these projects are generally time limited however). Although it makes the project less exclusive, it will allow you to quickly grow your collection.

    Other times, you can find many pieces being sold on the secondary market for a lesser price than the original minting price. This is frequently due to these pieces having been acquired as speculative purchases in the first place - that’s where you swoop in and grab yourself a beautiful piece of generative art. Even if they might not be highly desirable, they might still be beautiful pieces to have in your collection.

    Check out the discovery tools page where we list some of the tools that facilitate the discovery of specific projects on fxhash.

    One other thing that’s important to mention here: Get a feel for how things work. Before you click buttons at random on fxhash, or on any other platform, make sure to take your time and properly understand how the different interfaces work, and what they’re used for.

    Growing your Collection

    Once you’ve dipped your toes into collecting your very first few pieces, you’ll likely want to start thinking about how to go about growing your collection further and adding more pieces over time. Some considerations that can help do so in a guided manner are:

    • Setting Collection Goals: this could include acquiring specific pieces with a specific aesthetic, creating a themed collection, or focusing on a particular style. Such goals give direction to collecting as a hobby and make it more rewarding. Over time you can then diversify and explore different aspects of your interests to prevent becoming burnt out.

    • Being patient and collecting strategically: Building a collection doesn't have to happen all at once. Take your time to research different artists and projects, and wait for opportunities to acquire pieces that align with your taste and budget - as mentioned early, frequently there will be community events where you’re presented with a large influx of many pieces all at once.

    • Staying up-to-date: Staying informed about the generative art market, pricing trends, and upcoming releases can go a long way when you’re a collector that’s on the hunt for adding affordable pieces to your collection. Becoming acquainted with the different artists, following up with their works in progress, and staying up to date with ongoing events helps in identifying pieces worth collecting early on. Having a complete picture of the different happenings in the space, and an understanding of the current overall state of the market will help you make informed decisions in that regard.

    Networking and Engaging with the Community

    To follow up on the last point of the previous section, staying up-to-date with what’s going on is best done by getting in touch with your favorite artists as well as your fellow collectors. You’d be surprised to learn how happy many of the artists on fxhash are to talk about their practice and give you details about their process. Likewise, connecting with other collectors will allow you to engage in a discourse about the artworks you love, help you gain insights from individuals that may have more experience collecting art, and may have been in the game longer than you.

    One way to do this is by joining online communities and chat groups. Discord has established itself as the most popular communication channel in the Web3 setting. In the fxhash discord you’ll find artists and collectors alike, chatting and discussing all sorts of different topics. The fxhash team will also frequently broadcast updates via the announcement channel.

    If you haven’t joined yet,

    Attending IRL events and galleries can be another great way to connect with others. fxhash hosts and participates in several events in different locations around the world over the course of the year, these are also usually announced on the fxhash social outlets as well as the discord.

    That might be more or less difficult depending on your country of residence - but maybe you can factor in one of these events during your next vacation and make a pit-stop. There’s nothing that beats getting to know others during an IRL event, it can give you an idea of the people behind the online personas that you interact with on a daily basis and lets you connect with other passionate generative art enthusiasts.

    Towards Curation

    Once you’ve accrued a significant number of pieces, you can also start thinking about creating your own curations. This can be a creative and expressive endeavor, allowing you to tell a visual story through your acquisitions, it can also be valuable to document your collection and write about the pieces that resonate with you the most. If this is something that sounds exciting to you—check out the Strategies for Curating Your Collection page of the docs.

    GitHub - fxhash/fxhash-boilerplate: A boiletplate with webpack to develop generative Tokens on fxhashGitHub
    GitHub - fxhash/onchfs: ONCHFSGitHub

    fxparams module

    An introduction to the fx(params) module.

    ⚠️ fx(params) is not currently supported on mainnet ETH or Base ETH based projects. It is however planned at some point in the future.

    Traditionally, projects on fx(hash) generate random outputs for their collectors. This means that collectors have no prior knowledge as to what the iteration they will receive look like beforehand. This is because the hash that is used to seed the PRNG of the generative artwork, can not be known in advance. With fx(params) this paradigm changes.

    Multi-Chain Integration

    This section explores the various blockchains supported by fxhash and delves into the rationale behind their adoption, highlighting the unique advantages each blockchain offers for the platform and it

    Fxhash has always been a platform that embraces openness. Since day one, we've fostered a thriving artistic community where creators of all levels can share their generative art. We understand that the world of blockchain technology is constantly evolving, and that it currently plays a crucial role in distributing generative art.

    That's why we're consistently working towards supporting a wider range of popular blockchains. For these reasons it only makes sense to embrace a multi-chain approach. This allows us to tap into the strengths of each platform, and provide a varied, vibrant eco-system, whatever your preferred chain for creating or collecting might be.

    Fxhash currently supports the following blockchains:

    • Tezos (XTZ): Following a surge in adoption by many artists in 2021, and as a user-friendly, low cost alternative to other smart contract chains, Tezos is an attractive platform for the creation and trading of generative NFTs.

    Minting Interface Walkthrough

    An overview of the fxhash minting interface and a walkthrough of the minting process.

    The minting interface is the portal that takes you through the necessary steps to upload your project to fxhash. The interface will guide you through some final checks to make sure that things are working properly, help you set up the appearance of the final project page on fxhash and allow you to set distribution options such as the edition size, pricing, royalties, reserves and allow lists.

    The minting interface can be accessed from the drop down menu that expands from your profile button in the top right corner by clicking on the ‘mint generative token’ option.

    Once you’ve made sure that your token works properly and created a zip file that contains all of your project files (either through the fxhash CLI or manually), then you’re ready to get started.

    Adding Funds to Your Wallet

    An overview of the different methods for funding your crypto wallets (by converting fiat currency to different cryptocurrencies) as well as a run-down of some of the platforms and tools that allow the

    fxhash currently supports three different blockchains for artists to publish their generative projects on: Tezos (XTZ), Mainnet Ethereum (ETH), and Base (an Ethereum L2). To collect editions from a particular project, your wallet must be compatible with the blockchain the project is minted on. For example, if you want to collect a project that is minted on Tezos, this would require you to have a Tezos compatible wallet (ex. the Temple wallet).

    If you’ve already installed a wallet for the chain of your choice, and have connected it to fxhash -then you're all set!

    Furthermore, collecting a piece of fxhash also require your wallet to contain sufficient funds to cover the purchase cost, and also cover the gas fees associated with effectuating the necessary transactions to acquire the token. Obtaining these initial starting funds can be a little challenging if it’s the first time that you attempt to do so - in what follows we outline some of the different methods for obtaining different cryptocurrencies and funding your wallets with them. We also cover some tools that let you manage your funds later on.

    Market Analysis & Dynamics

    An introduction to market dynamics, the influence thereof on the price of tokens on the secondary market, and an overview of relevant factors that play a role during the valuation of digital art token

    While we’ve previously tackled some of the factors that influence the valuation of individual generative artworks, it is also beneficial to discuss and understand the broader dynamics that arise when collectors compete for the acquiry and sale of tokens on the secondary market. These emergent dynamics are the driving forces play a significant role in determining the worth of digital assets on the blockchain:

    Market Dynamics: The forces that shape the behavior and performance of a market. In the context of NFTs, it's the interplay of factors that determine the price, demand, and supply of these digital assets on the secondary market.

    To a large extent the Web3 NFT markets mirror the dynamics of traditional markets, where supply, demand, and competition play a central role in how prices regulate themselves.

    Deterministic Randomness

    Notes on using the fxhash PRNG and how to create deterministic generative tokens.

    Besides being displayed correctly, the absolutely most important aspect of a GENTK is that it is entirely deterministic, and that it always produces the same output for the same input hash, no matter the circumstances under which it is run.

    In this section we will have a look at an example of a generative artwork, explain how it needs to be modified to become an fxhash compatible piece, and conclude by discussing some of the common causes that might break the determinism of a piece.

    A Preliminary Example

    Let's have a look at an example, a simple circle packing sketch:

    This is a simple generative artwork that produces a different circle packing layout each time that it is rerun. Here’s the code that powers this piece:

    Reserves & Allow Lists

    This section provides an overview of the 8th step in the minting interface, where artists can set up reserves and allow lists for their projects.

    This section provides an overview of how to configure reserves and allow lists for your fxhash projects, if you want an over view of what they are, we recommend checking out the overview in the Allow Lists in the Collector docs.

    Reserves can be configured in the 8th step of the minting interface (distribution):

    Currently there are two types of reserves that can be toggled on a project:

    if ($fx.context === "fast-capture") {
        // generate your fast-capture placeholder image here
        // then trigger the capture with $fx.preview()
        $fx.preview()
    } else if ($fx.context === "capture") {
        // generate the preview image that you want to display on fxhash
        // then trigger the capture with $fx.preview()
        $fx.preview()
    } else {
        // here goes what you intend to display when your  
        // code is run and viewed directly in the browser
    }
    body {
      /* override the default margin of the html body */
      margin: 0;
    }
    
    #canvasContainer {
      height: 100vh;
      width: 100vw;
    
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    #myCanvas {
      max-width: 100%;
      max-height: 100vh;
    }
    <link rel="icon" type="image/x-icon" href="/favicon.ico">
    <canvas width="400" height="400"></canvas>
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>Canvas Example</title>
    	</head>
    	<body>
    		<canvas id="myCanvas" width="400" height="300"></canvas>
    	</body>
    </html>
    style="background-color: darkgray;"
    // We conveniently gave the canvas element an id to fetch it from the DOM.
    const canvas = document.getElementById('myCanvas');
    // The rendering context can be accessed via the getContext() function.
    const ctx = canvas.getContext('2d');
    // This draws a blue rectangle to the canvas
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 200, 100);
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>Canvas Example</title>
    	</head>
    	<body>
    		<canvas id="myCanvas" width="400" height="400" style="background-color: darkgray;"></canvas>
    		<script>
    				// We conveniently gave the canvas element an id to fetch it from the DOM.
    				const canvas = document.getElementById('myCanvas');
    
    				// The rendering context can be accessed via the getContext() function.
    				const ctx = canvas.getContext('2d');
    
    				// This draws a blue rectangle to the canvas
    				ctx.fillStyle = 'blue';
    				ctx.fillRect(50, 50, 200, 100);
    		</script>
    	</body>
    </html>
    // Fetching the Canvas and Context
    const canvas = document.getElementById('myCanvas');			
    const ctx = canvas.getContext('2d');
    
    let counter = 0
    
    // A function which will power the animation
    function draw(){
    
    	// Filling the entire canvas with colored rectangle
    	ctx.fillStyle = "white";
    	ctx.fillRect(0, 0, canvas.width, canvas.height);
    	
    	// Setting the color for the rectangles
    	ctx.fillStyle = "black";
    
    	// A little trigonometry to make the rectangles rotate in a circle
    	
    	for(let a = counter; a < Math.PI*2+counter; a+=Math.PI*2/20){
    		let x = 200 + 100 * Math.cos(a)
    		let y = 200 + 100 * Math.sin(a)
    		
    		ctx.fillRect(x, y, 10, 10)
    	}
    	
    	counter+=.01
    	requestAnimationFrame(draw)
    }
    
    draw()
    <body>
      <div id="canvasContainer">
        <canvas id="myCanvas" width="900" height="1200"></canvas>
      </div>
    </body>
    body {
      /* override the default margin of the html body */
      margin: 0;
    }
    
    #canvasContainer {
      height: 100vh;
      width: 100vw;
    
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    #myCanvas {
      max-width: 100%;
      max-height: 100vh;
    }
    padding: 10px;
    box-sizing: border-box;
    const canvasWidth = 400; // same as original canvas width
    const canvasHeight = 400; // same as original canvas height
    
    const resizeCanvas = function(event) {
        var containerWidth = window.innerWidth;
        var containerHeight = window.innerHeight;
    
        var ratio = containerWidth / canvasWidth;
        if(canvasHeight * ratio > containerHeight) {
            ratio = containerHeight / canvasHeight;
        }
    
        canvas.style.width = canvasWidth * ratio+"px";
        canvas.style.height = canvasHeight * ratio+"px";
    }
    
    resizeCanvas()
    window.addEventListener('resize', resizeCanvas, true);
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    function windowResized() {
      resizeCanvas(windowWidth, windowHeight);
    }
  • Personal Enjoyment and a Desire for Ownership: Art can evoke emotions, inspire thought, and spark creativity. Owning art allows for a deeper engagement with these experiences, enriching one's life on multiple levels.

  • Financial Incentives: Beyond the aforementioned reasons, collecting art can also have financial incentives. Especially in the NFT setting in which it’s quite easy to acquire and re-sell tokens relatively rapidly and in larger volumes as compared to a traditional setting where this would be much more time-intensive and require scheduled events at auction houses.

  • Assume that you will never re-sell your collected pieces and may never make a profit from them: if you’re just starting out, never speculate that you’ll make a profit from any tokens that you collect. Although there is a possibility for the value of collected tokens to increase at some point in the future, there is never a guarantee on that happening. Furthermore, the value of a token can also not be accurately predicted in any manner - it is purely speculative.

  • Free Editions: sometimes artists choose to release their projects free of charge, this is when you should strike and cop an edition for yourself.

  • **Searching for Gralis
    here’s an invite link to the fxhash discord.
    Link to Tweet
    https://www.youtube.com/watch?v=bBC-nXj3Nwww.youtube.com
    What is fx(params)?

    fx(params) is an alternative method to building and collecting generative art on fx(hash).

    Instead of entirely leaving all aspects of the minted iteration up to randomness, the artist can now choose certain parameters that they would like to expose and give the collector control over at mint time.

    fx(params) is the name of the module in the fx(hash) API that gives artists the tools to expose a set of parameters and custom minting interfaces for the collectors to modulate and play with before minting/collecting their own individually customised iterations.

    From the collectors point of view, this changes a couple of things. Instead of directly collecting an iteration from a project, when a project that makes use of fx(params) is collected they obtain a mint ticket instead. This mint ticket is essentially a voucher that they can exchange for an iteration of the project.

    This system is in place to give collectors the time to customise their iteration without having to worry about running out of time and the project completely minting out. Once a mint ticket is secured, the collector can then take their time crafting their own unique individual iteration. You can read more about this in the collector guides.

    From the artist's point of view, to create an fx(params) piece, they will need to make use of the fx(params) module of the API. In this section we will give an overview of the module and explain how to use it. A detailed explanation of the different functions that this module provides can be found in the fx(params) API Reference.

    Using the fx(params) Module of the API

    Creating an fx(hash) project that makes use of fx(params) boils down to using the respective functions in the API such that certain variables in the code are exposed as collector tweakable parameters. The most important function in the API to this end is:

    Invoking the $fx.params() function in your code informs fx(hash) that the project is intended to be an fx(params) piece. Equally important is that this function requires an input in form of an array that defines the desired parameters such that they can be created in the interface by fx(hash). During local development of your project these parameters will also appear in fx(lens).

    For the purpose of an fx(params) piece, the definitions array needs to follow a specific structure:

    In essence this array is a list of objects, each of which represents an individual parameter. We'll talk more about the content of these objects in a second. Another effect of the $fx.params() function is that it feeds the parameter values back into our generative artwork’s code, such that these values can be used for the purpose of shaping the rendered graphics.

    Hence, if we were to copy the above snippet of code into the index.js of a blank fx(hash) project and then boot up fx(lens) (via the CLI with fxhash dev), we would see the following controllers show up in the interface:

    To recap, the effect of $fx.params() is twofold:

    • It informs fx(hash) of the parameters that should be exposed in the minting interface. (during local development these parameters should appear in the fx(lens) interface)

    • It exposes the value of these parameters in our code, such that the generative artwork’s characteristics can be based off of them.

    Parameter Definitions

    The objects contained in the definitions array that we pass as an input to the $fx.params() function needs to follow a strict shape. In essence they are objects containing a number of key/value pairs that describe the controllers in the interface, such as the label next to the controller, the type of controller it is, the value it modulates, and the possible values that it can assume.

    That is why we call these objects Parameter definitions, they essentially define (describe) the parameter controllers in the interface:

    What is a Parameter Definition?

    In the context of fx(hash), a Parameter definition is a small Javascript object that contains a number of properties (key/value pairs) that define specific parameters. These parameter definitions describe the appearance of the parameter controller in the interface, and how they should be referenced within the artists’ code.

    Parameter definitions always require an id and a type, where the id is needed to later retrieve this parameter in the artist's code, and the type, as the name suggests, is required to specify what kind of parameter it is.

    Parameter definitions also have optional properties, such as a name, that the artist can assign and will be displayed as a label in the controller interface. Another options property can be appended depending on the type of the parameter.

    Here's an example of such a parameter definition object:

    Some of the key/value pairs are optional, others are mandatory. The structure of these key/value pairs need to follow a strict set of specifications, you can find a detailed overview of these specifications in the Parameter Definition Specifications page.

    How does fx(hash) inject Parameters?

    Just like the iteration hash, parameters are passed into a generative token as a URL parameter, not individually, but under the form of a single serialised string that concatenates all of the parameters. The API then de-serializes this string splitting it into individual values and mapping them to their respective variables, such that they can be accessed throughout the code:

    It would not be convenient at all to input this string manually, as such we recommend using fx(lens) to work on your fx(hash) projects. fx(lens) comes with built-in tools and hot-reloading to facilitate iterating on your project and manipulating the various parameters as you define those in your code.

    Retrieving Parameter Values within the Artist’s Code

    The snippet API exposes a set of utility functions which lets artists retrieve the active value of the parameters - these functions need to be called after the parameters have been defined with $fx.params():

    • $fx.getParam('parameter_id'): gets the value of a single parameter by its id

    • $fx.getParams(): gets all the parameter values as an object

    • $fx.getRawParam('parameter_id'): gets the raw value of a single parameter as a hexadecimal string

    The $fx.getParam() function for example lets us fetch the active value of a parameter by its id (as a string value) - ‘active value’ here means the value that the parameter is set to by its respective controller in the interface (fx(lens) or minting interface):

    Update Modes

    So far, we’ve seen fx(params) as collector tweak-able variables that control certain aspects of the generated artwork. What’s more, is that fx(hash) also gives the artists control over how these parameters are updated - they don’t have to necessarily be updated from the control panel, but can also be modulated via the code itself.

    The parameter definitions have a special property called ‘update’ which allows the artist to control how this parameter is updated.

    The default update mode is page-reload and describes the known behaviour of updating the parameter by performing a full page-reload of the project. Meaning that the entire code of the generative artwork needs to be re-run to apply this parameter change. The are other options for update property, that behave differently and don’t require a full refresh of the project page.

    For instance, when setting the update mode of a parameter to sync, the change of this parameter via its respective controller would not trigger a full page reload and update the parameter value in real-time:

    Updates on parameters with update: "sync" are received in the background in real-time. Naturally this also requires the artist to structure their code differently for this parameter change to be applied. When using the sync update mode, the artwork code needs to be actively redrawn inside of a loop that can respond when such a synced parameter is changed, (e.g. via requestAnimationFrame), in that manner the code can receive those changes during the runtime of this loop.

    For even more advanced use cases, e.g. if you want to only re-render your artwork when the values of your parameters are changing, you can use the new event listeners described in the section on $fx.on, which is detailed in the fx(params) API reference.

    Code-driven parameters

    What are Code Driven Parameters?

    Code driven parameters are special interactive parameters that are controlled via the artists’ code rather than controllers in the interface. Similarly to the sync update mode, the parameters are also updated in real time without reloading the artwork, with the difference that they’re updated from within the code rather than the controller interface.

    This allows for much more intricate ways of collector collaboration, where in some instances they can directly interact with the artwork, can get hands on for customisation purposes, and artists can even set up custom minting interfaces.

    Besides the sync update mode, another mode is code-driven, which is by far the most interesting and versatile one. page-reload and sync both rely on a signal and change in the external UI to update the parameter value. The code-driven update mode breaks this principle, and gives artists the ability to change the value of a parameter from the code, enabling completely customised minting experiences.

    code-driven parameters can’t be updated from the UI and have to be controlled via the $fx.on() and $fx.emit() functions. Additionally we also need to make use of the $fx.context property to detect if the code is executed during mint time, in which we would execute additional code that accounts for the update of the code-driven parameter, or in the other contexts where this behaviour is not needed.

    The following code snippt exemplifies a code-driven approach:

    This is an example of an implementation. You are free to follow the patterns of your choice.

    Ethereum (ETH): Designed to address limitations inherent in Bitcoin, Ethereum established itself in 2015 as the first blockchain to incorporate smart contracts. This technological innovation served as a fundamental cornerstone for the overall popularisation of NFTs, and later equally for the distribution of generative art.

  • Base (ETH L2): developed by Coinbase, Base is an Ethereum Layer 2 scaling solution, with the objective of enhancing accessibility to the Ethereum blockchain while preserving the core benefits of the original Ethereum chain.

  • *(A timeline graphic here could be cool, November 2021 Launch -> Then proper launch in 2022 -> Announcement of Ethereum Integration in 2022 + seedraise -> Ethereum integration in December 2023 -> Base Integration in 2024)*

    fxhash 1.0: Foundations built on Tezos

    fxhash was initially developed on the Tezos blockchain; due to its accessibility and minimal gas fees, it posited itself as an ideal environment for experimenting with smart contract technology. The emergence of the hicetnunc NFT platform in March of 2021 played a significant role in attracting a large influx of artists to mint their work as NFTs - ever since, Tezos has been recognized and celebrated as the "Art Chain".

    Shortly after the platform's inception, pioneering efforts were made to embed Javascript code within SVG files, enabling interactive code-driven artworks to now live on the blockchain. This paved the way for HEN to directly support mints in the form of HTML files. The fact that Web-native NFTs were now a possibility proved to be a major draw for the creative coders and generative artists that previously relied on sharing their work as captures in non-native image and video formats. This innovation also allowed collectors to directly acquire code-based artistic creations, fostering a novel space for "code as art" exploration.

    At that point in time the idea for a blockchain based distribution model for generative art had already been pioneered by Art Blocks on the Ethereum blockchain. Art Blocks' curatorial model however only allowed a select few artists to publish their generative systems on the blockchain, in addition to the high transaction fees of Ethereum that were virtually unaffordable and required a significant investment from the artists to simply get started without any promise of a return on investment. In other words, there was a significant number of hurdles to overcome with Ethereum, with Tezos these barriers to entry were lifted.

    The foundations for fxhash were laid in November 2021 as an experiment by Baptiste Crespy, aka Ciphrd. The platform immediately attracted the interest of many of the generative artists that had already been dabbling in the NFT eco-system but were looking for a better and more accessible way to share their generative art.

    fxhash 2.0: Ethereum Integration

    Ethereum transitioned away from an energy-intensive Proof-of-Work (PoW) consensus mechanism to Proof-of-Stake (PoS) on the 15th of September 2022. This marked a significant shift in how the network validates transactions and secures the blockchain, but also made a massive impact on the overall energy consumption of the chain - turning it into a much more environmentally friendly and greener platform. Previously the large Carbon footprint associated with Ethereum was a big reason for hesitance from many artists to mint their works the chain.

    Throughout 2023 fxhash's efforts were primarily dedicated towards integrating the Ethereum chain into the platform, with a successful release in December of the same year. With a significantly larger market capitalization when compared to Tezos, a wider adoption rate, and considering that it has a couple of years of a head-start, the chain has a more established ecosystem with an average of 12M active wallets per month (at the time of writing), and therefore is a particularly attractive blockchain for collectors and artists alike.

    Market Capitalization (Cap)

    Within the blockchain industry, the term market capitalization (or market cap) refers to a metric that measures the relative size of a cryptocurrency.

    Besides that, Ethereum was also the first chain to pioneer smart contract technology, and currently enables a massive number of decentralized applications (dApps). For all of these reasons it only makes sense for fxhash to expand beyond Tezos and also support ethereum for a more varied eco-system.

    Ethereum’s transition to Proof-of-Stake also enabled a new kind of scalability solution known as rollups. Rollups are essentially secondary chains that are built on top of a network’s mainnet, and process transactions off the primary chain in a more affordable manner before ‘rolling them up’ - batching them - and then writing them to the main chain. This solution greatly improves transaction speed and the associated gas fees. We often refer to these rollup solutions as L2s, or Layer 2 solutions, and generally the gas fees on them are a fraction of those on mainnet. fxhash now also supports Base, one of the current popular L2 chains that’s being developed by Coinbase.

    Tezos vs. Ethereum

    While explaining all of the minute facets of either one of the chains is beyond the scope of this resource, we want to at least highlight some of the major similarities as well as differences between Ethereum and Tezos that are talking about, wether or not these factors might influence your decision on creating and/or collecting art on that chain.

    Consensus Mechanism

    In decentralized ledgers consensus on the validity of transactions is crucial - currently there are two popular models for achieving this: PoS, short for Proof-of-Stake, and PoW, short for Proof of Work. Tezos and the new version of Ethereum are similar in that both rely on a Proof-of-Stake consensus mechanism:

    Proof of Stake

    Proof of stake (PoS) is a democratic approach to ensuring transaction validity. Users holding cryptocurrency can stake their coins, essentially putting up a deposit, to become validators. The more crypto staked, the higher the chance of being chosen to validate transactions and add new blocks to the blockchain. Dishonesty is heavily disincentivized as validators risk losing their staked crypto.

    Governance

    Although both chains rely on Proof-of-Stake for security, they differ in how governance is handled. Unlike traditional systems with a central authority calling the shots, blockchains by nature are spread out, meaning there's no single entity making unilateral decisions. This distributed nature presents a unique challenge: how do various stakeholders (users, developers, etc.) come together to ensure the smooth running, adaptation, and advancement of the blockchain network? This is where governance comes in:

    Governance

    In blockchain technology, governance refers to the system in place for making choices regarding the operation and evolution of a decentralized network.

    While both chains have decentralized governance models, they are implemented differently:

    • Tezos has On-chain Governance: “The methodology for deciding and implementing upgrades to the Tezos blockchain is on-chain, and is directly incorporated in the code of the underlying protocol itself; the blockchain software automatically goes through every proposed upgrade and voting steps without a centralized director” - from Tezos (XTZ): Superior Governance and Use Cases by Kathleen Breitman

    • Ethereum has Off-chain Governance: “The governance model of Ethereum is largely informal and community-driven. This model relies heavily on the broader community, including developers, miners (now validators post-Ethereum 2.0), and users, to propose and debate changes” - from Cardano and Ethereum: Governance models

    Scalability

    These governance models have a direct impact on the scalability of the two chains. Today, scalability is one of the biggest issues with blockchain technology, as it predicates the speed of transactions and their effective cost as the number of users grows and the traffic on the blockchain increases:

    Scalability

    Scalability refers to a blockchain network's ability to handle and adapt to an increasing number of users and transactions, without sacrificing other important aspects like security and decentralization.

    Tezos unique on-chain governance model allows the seamless incorporation for network wide improvements and upgrades, whereas other blockchains, such as Ethereum, require forks whenever significant changes need to be made:

    Blockchain Fork

    A fork essentially refers to a blockchain splitting up into two diverging paths, often as the consequence of a change in the chain's protocol. There are two types of forks, soft-forks where the new chain is still backward-compatible with the previous iteration, whereas this is not the case for hard-forks.

    The new Proof-of-Stake version of Ethereum strives to minimise hard-forks however.

    Overview and Comparison

    Here’s a quick overview of everything we’ve covered so far:

    Feature
    Tezos
    Ethereum
    Base (Optimism)

    Consensus Mechanism

    Proof-of-Stake (PoS)

    Originally Proof-of-Work (PoW), but migrated to Proof-of-Stake (PoS) in 2022

    Inherits security from Ethereum (PoS)

    Transaction Speed

    Faster transaction speeds than Ethereum

    Slower transaction speeds, but improving with upgrades

    Faster transaction speeds than mainnet Ethereum

    Transaction Fees

    Negligible transaction fees

    Frequently very high transaction fees due to network congestion

    A Multi-Chain Present

    Regardless of the blockchain, fxhash pledges its support to the artists and collectors and aims to provide a varied eco-system for all participants. The current multi-chain approach of fxhash provides the following benefits:

    • By supporting the Tezos chain, the original art community that came together in the haydays of fxhash can continue creating and collecting on the popular low cost art chain.

    • Support for Ethereum plugs fxhash into a much more established eco-system, and exposes artists to a much wider collector pool.

    • On-boarding collectors from one chain to the other expands the overall audience of fxhash.

    • Ethereum opens the doors for h L2 chains, that further expand the eco-system and make things more affordable.

    • Both artists and collectors ultimately have more options to choose from.

    Seamless Integrations

    fxhash takes care of everything, we ensure a smooth experience for artists and collectors alike. Creating and collecting on any of the supported chains happens seamlessly from the user's perspective, with a couple minute differences.

    1. Blockchain Selection

    The first step in the minting process is selecting which blockchain you want to mint your project on, you can choose between Ethereum, Base (Ethereum L2), and Tezos:

    2. Author Selection

    Next you’ll be asked whether your project is an individual original work, or if it is a collaboration with one or more other artists:

    For the purpose of this walkthrough we’ll assume that you are the sole author. The subsequent steps don’t actually vary much when a project is a collaborative one, you simply need to create a collaboration contract beforehand and then indicate the contract during this step. You can learn more about collaborations and collab contracts here:

    Collaborations

    3. Storage Selection

    Next you’ll be asked how you’d like your project to be stored - either on IPFS or Onchain:

    You can read more about the differences between IPFS and On-chain storage here.

    4. Project Upload

    Next, you’ll upload your project's .zip file that contains all of your project files. This zip file can be created manually or with the fxhash CLI via the fxhash build command:

    If there is a problem with the fxhash.js script, it will show you an error in red here - for instance, this happens when the fxhash script is outdated. When publishing your project onchain, green checkmarks next to files indicate that these files already exist on the blockchain and are indexed with fxhash’s file system, hence don’t need to be re-uploaded:

    Here it will also show you an estimate of the storage costs to deploy your project onchain, this varies between the different blockchains available. Make sure to also include any additional license files in this project directory: Licensing your Project

    What’s the size limit on projects?

    Currently the cut-off point is 500MBs - if you require more you can get in touch with us on discord.

    5. Determinism Check

    In the next view you’ll go through a final check to ensure that your piece is deterministic by rerunning the code for the same and different hashes. In this step you also decide on the preview image that will front your project page, this is done by fixing a specific preview hash:

    Here you can also set the iteration number and/or minter address if those influence some aspects of your artwork. In case your token implements parameters and/or features, they will show up here as well. After you’ve checked that everything is working properly you can go ahead and mark the two boxes to proceed to the next step - this will also lock in the hash that determines the preview image of your project.

    6. Preview Capture Settings

    In this step you’ll configure how fxhash generates the previews of the collected iterations via the capture module:

    There’s two different methods for triggering the capture module:

    • Programmatically with $fx.preview(): The capture module will wait until your code calls the fxpreview() function. As soon as it is invoked, the capture will be triggered. The placement of this function in your code is up to you, but usually it should be placed towards the end of your code, when all of the graphics have been rendered. If the piece is animated you might want to trigger it after the initial frame has been drawn.

      The capture module will automatically take a capture after 300 seconds have passed after your project was loaded in the browser. Hence it is important that the rendering of your graphics completes within this timeframe, otherwise it might lead to undesirable preview images.

    • Automatically after a Fixed delay: a fixed time delay indicates that the capture module should trigger automatically after a certain amount of time after the project is loaded. Selecting this option will make a slider appear where you can set how many seconds the capture should wait before triggering, up to 300 seconds.

    In the case of our example token we’re using the programmatic trigger since it is a static artwork where we want to trigger the capture after all shapes have been rendered to the canvas. After setting the capture trigger we also need to indicate the target of this capture; this can be a canvas element, or the entire viewport of the window:

    In our case we only want to capture the canvas, and not the entire viewport. Selecting From <canvas> will reveal a third input field where you need to specific the CSS selector that defines this canvas - make sure to select the correct one if you are using multiple canvases in your project.

    Furthermore, you’ll see a toggle to enable a GPU rendering instance for generating the token previews. By default a CPU instance will be used and is suitable for the majority of projects. A GPU instance should only be used if your project necessitates it - if you’re uncertain about this, reach out on discord. The caveat with GPU instances is that they’re way slower to bootstrap which increases the time it takes to generate the captures.

    In a nutshell, if your project requires a GPU to render, you should **use a GPU-enabled instance**. Since these types of projects are not very common, **we currently only have 4 GPU instances available, as a result the metadata assignment will be slower for projects using these GPU-enabled instances**. We can however scale to a very high number of CPU instances without bloating the rendering queue.

    If you don't use WebGL and only the regular canvas API, it's also possible that your project doesn't render properly on the CPU instance because the canvas API uses GPU acceleration. If you observe differences between the capture and your live version, then try using GPU-enabled rendering.

    If your project is loading asynchronous requests from the project's folder, always consider that one of those resources may be slow to load. In that regard, if you load resources please always use fxpreview() to trigger the capture.

    7. Preview Check

    To verify that the capture actually works properly, the captured preview image should be identical to the generative artwork running in your browser:

    Although the artwork is identical you can see a slight difference between the preview and the generative artwork - the CSS border that we applied to the canvas is actually not a part of the canvas graphics itself.

    8. Distribution Settings

    Next you need to set up how your project will be distributed, pricing your project and deciding on supply is a tricky topic:

    Here you essentially need to specify the following:

    1. The Edition Size: there’s two options for this, either a fixed edition size or an open edition. And open edition means that an indefinite number of tokens can be minted from your project within a given time-frame, whereas a fixe edition size makes only a specific amount available.

    2. The Pricing Mechanism: fxhash currently supports two pricing mechanisms:

      1. Fixed Price: as the name indicates, each iteration is sold at a fixed price.

      2. Dutch Auction: the price of iterations is reduced over the course of a number of time steps, until it settles at a fixed minimum price. Additionally a Rebate toggle is available that will refund collectors in the difference of price when the project mints out.

    3. Opening Date: regardless of which pricing method you select, a release date for your project is required. This field defaults to an hour from the current time.

    4. Primary Splits: primary proceeds refer to the revenue generated from collectors minting available iterations. If you would like to send a portion of these proceeds to another wallet, like a charitable organisation you can specify an additional wallet address here.

    5. Royalties & Royalty Splits: royalties refer to a percentage of the revenue generated from secondary proceeds, when collectors buy and sell your artwork for instance. You can specify this royalty percentage here. Furthermore, you can indicate other wallet addresses if you want a portion of royalties to go towards other wallets.

    6. Reserves: reserves are essentially allow lists that let you reserve iterations for specifiy wallet addresses.

    7. Enabled Toggle: this toggle controls whether or not your project is available for minting directly at the release date. If it is unchecked your project will be published on fxhash, but it will not be possible to mint iterations from your project. To change any of the other settings later on (post-publishing) you will also need to first disable your project via this toggle.

    If you aren’t certain about how to choose these settings, we provide more detailed explanations on all of these settings here: Pricing and Supply

    9. Variation Settings

    In this step you will configure the interface options for previewieng variations generated by you project:

    As the artist, we want you to have control over the freedom viewers will have when exploring variations of your project on the token page. Under the display frame, a variations button can be used to explore different variations, if enabled when you minted the Generative Token:

    https://www.fxhash.xyz/images/articles/guide-mint/variations-button.png

    For projects using fx(params), the explore params button allows users to navigate the parameter space of your Generative Token.

    https://www.fxhash.xyz/images/articles/guide-mint/explore-params-button.png

    You can configure the following settings, for both during the mint period and after fully minted:

    • enabled: Determines if the variations and explore params buttons are active. If disabled, these buttons will be unclickable and visibly deactivated. Note that pre-mint exploration cannot be disabled for fx(params) projects.

    • number of variations:

      • infinite: viewers can explore any amount of variations and so randomly

      • limited set of hashes: define a list of hashes the viewers will cycle through when clicking on the button

    These settings should give enough control to define a strategy during the lifetime of your token. You can for instance disabled infinite exploration after token is minted, so that the front end only display a finite number of states through the minted collection of the token.

    Please note that the variation settings have no effect on the iterations which will be generated from your project.

    10. Project Details

    In the penultimate step you’ll add a quirky title, a description for the project, optionally a different description for the collected iterations, a list of tags that are geared towards discoverability of the project on the fxhash website and other 3rd party exploration tools, as well as some labels that can indicate a special behaviour of your project:

    One step that many artists struggle with, is writing a description for the generative artwork. This description will live on the GENTKs project page and is frequently the first point of contact that collectors have with the artwork. In a way, it's your sales pitch in which you tell your potential collectors a little about the artwork and try to capture them.

    This can be a romantic backstory, the discovery of a bug that led to an interesting visual composition, or even the recount of a quick coding session that led to a new algorithmic method. However, artists make art simply for the love of making art, it is often the case that there isn't a romantic backstory, especially in generative art that often ends up being a very exploratory endeavour. In this case it is also perfectly okay to reflect on the provide retrospective insights into the art-making process.

    It is also a nice gesture to give a little shoutout to the libraries that you might have used and their creators, as well as the people that contributed and helped you in the ideation and development process of the code. And it is also a good idea to provide an overview of the different ways that users can interact with the GENTK, for instance the keys that map to certain user interactions.

    To summarise, a good description provides:

    • A short backstory on the inspirations that led to the project

    • Highlights the primary/prominent techniques and methods used in the piece

    • Mentions the libraries and individuals that contributed to the process

    • Gives an overview of the interaction options

    11. Final Preview

    This is the final preview of your project, and essentially indicates what your project will look like once published:

    Additionally if you selected that your project should be stored on-chain it will indicate how much this storage transaction will cost, and you’ll have to perform this operation to unlock the publish project button. If you chose IPFS you can directly go ahead and publish the project.

    If it happens that you need to break off this minting process, fxhash will save your progress and you can always return later and resume from where you left off, simply hit the ‘continue’ button when it asks you to:

    After you complete all of these steps you’ll have to do another confirmation in your wallet, cover the transaction costs. After a few seconds the project should then show up of your profile page and in the fxhash feed.

    Managing funds via a Centralized Crypto Exchange (CEX)

    Centralized Exchanges (CEXs) are the most common method for funding your crypto wallets, as they facilitate the purchase of cryptocurrencies via various payment methods:

    Centralized Crypto Exchange (CEX)

    A centralized crypto exchange (CEX) is an online platform managed by a central company that facilitates the buying, selling, and trading of cryptocurrencies. They act very similarly to traditional stock exchanges, essentially as intermediaries that hold your crypto funds on their platform and provide you with useful functionalities to manage these funds.

    In that sense, CEXs are online platforms, that provide modern and convenient interfaces for the trade and exchange of different crypto currency pairs, as well as the conversion to and from fiat currency. These platforms generally require you to register by creating an account and verify your identity to check your eligibility for using their services.

    Before you make an account on a given CEX however, it's important to spend some time and research which one of them is the most convenient one for you:

    1. Cross-chain Support: Not all centralised exchanges support all cryptocurrencies, nor do they support trades between arbitrary currency pairs - depending on which chains you intend to be active on this might play a factor.

    2. User Verification (KYC): As mentioned, centralized exchanges are subject to regulations require customer verification (KYC - Know Your Customer), meaning that you'll need to provide identification before using their services. Depending on your country of residence these regulations might be varyingly strict, and some exchanges might not even be available in your geographical location.

    3. Security: It’s important to keep in mind that centralized exchanges are under the control of a central authority, if the platform ever gets hacked or for some reason shuts down, your funds stored on this exchange may be in danger. It is recommended to use a reputable and well-established exchange with robust security measures in place.

    Another thing to consider is that different exchanges might have different fee structures - depending on which kinds of transactions you’re planning on doing most this might also play a factor. The following fees are commonly imposed:

    • Trading Fees: Charged whenever a trade is executed. This fee is either a percentage of the trade amount or a fixed fee per trade.

    • Withdrawal Fees (Cashing Out): Some exchanges charge fees for withdrawing funds from the platform. These fees are either a percentage of the withdrawn amount or a fixed amount.

    Once you've settled on an exchange and purchased the currency that you intend to collect with, you can then transfer these funds to your own browser wallet(s) - essentially the wallet(s) that you intend to use with fxhash. It is generally not possible to purchase NFTs with the wallet addresses on a CEX since they're primarily deposit addresses.

    Withdrawing Funds as an Artist

    If you're an artist, it is a good idea to set up an account on a CEX, to be able to withdraw the earnings you make from selling your generative art on fxhash directly to your bank account.

    Naturally, different exchanges have different interfaces and vary in their functionality - it would be beyond the scope of this documentation to provide explanations for this purpose. It can sometimes even be beneficial to have an account on several exchanges at the same time, depending on the convenience of the different features they provide.

    Purchasing Funds via Credit Card through your Wallet

    Most wallets provide an option for directly purchasing cryptocurrency via a credit card. Both Temple and Metamask currently support this feature:

    This generally provides a streamlined method for funding wallets without the need to register on a separate cryptocurrency exchange. Note that these purchases require identity verification (KYC) for compliance purposes:

    It is also possible to purchase Layer 2 Ethereum in this manner.

    Receiving Funds from Others

    If both of the above methods are not viable for you, it is always also an option to receive funds from someone else - if you're an artist, it might be possible to receive some starting funds from one of your artist friends as a way to cover the initial transaction costs for minting your first project on the blockchain.

    This is especially useful if you intend to mint your project on Tezos or Base, both chains have minimal transaction fees, hence you would only require little starting funds. You can then always repay the favor later, either by returning the funds, or by supporting your artist friends

    Purchasing L2 ETH

    Base is an Ethereum L2, a secondary layer built on top of Ethereum’s mainnet that makes transactions speedier and more affordable.

    Although it also uses ETH as a fungible currency, it operates on a separate network, meaning that it is essentially a different currency even though it has the same identifier. ETH needs to be sent over to that network first before it can be used for transactions on the L2:

    Switching Networks

    When effectuating a transaction on a different network, your wallet will usually ask you to confirm switching to the network first before executing the transaction.

    Coinbase is currently developing the Base L2 chain. Their crypto exchange and software wallet currently streamline most operations on the network - although other platforms/wallets that support Ethereum are quickly catching up.

    Currently there’s three methods for obtaining Base ETH:

    1. Directly purchasing Base ETH on a CEX: Some exchanges allow you to directly purchase Base Ethereum which can then be sent to your browser wallet. Coinbase is one of them. Some other CEXs also support this functionality, but not all platforms support all L2s it is important to verify beforehand, L2s are still relatively new and not supported by all exchanges and/or might only be supported to a limited extent.

    When sending ETH funds from and to your wallets, make sure that your are doing so on the correct networks - sending funds from an address on a different network can cause these funds to be lost.

    1. Purchasing Base ETH via credit card directly in wallet: while previously it wasn’t possible to purchase L2 currencies via wallet credit card transactions - Metamask does support this feature now via a number of different providers.

    2. Transferring mainnet ETH to the Base Network via a bridge: Network bridges are methods for sending assets from one network onto the other - for instance from ETH mainnet to one of its L2s. Bridges are smart contract based dApps that operate in a decentralized manner - there’s a couple of different ones right now, that function in a relatively similar manner where you select the two networks that you want to send funds between as well as the currency that you’d like to transfer:

      Metamask now also provides a bridge functionality:

    Bridge Transaction Times

    While depositing ETH and other assets from mainnet onto the Base network via a Bridge takes a few minutes, withdrawing funds in the opposite direction can take up to 7 days.

    This is due to how L2s are built on top of Ethereums mainnet. Transactions on the L2 network need to be bundled up before they can be sent back and written to a chain’s mainnet. There might be alternatives than can process withdrawals faster, but please make sure to verify their legitimacy.

    Decentralized Exchanges DEXs

    DEXs don't hold your funds like centralized exchanges, but instead make use of smart contracts to facilitate peer-to-peer trading directly between users. The decentralised nature of DEXs generally makes them operate with less regulation, allowing for more anonymity and users to retain control over their funds throughout the process just like with other dApps:

    Decentralized Crypto Exchange (DEX)

    Decentralized crypto exchanges (DEXs) are essentially trading stations for crypto assets that cut out the middleman. Unlike regular exchanges where trades are effectuated with the exchange itself, DEXs connect you directly with other traders. Transactions happen directly between user wallets, with smart contracts handling the exchange securely.

    DEXs are generally intended for the purpose of exchanging different crypto assets on the same chain or network - for example, this is useful when you want to convert and store your funds in form of a stable coin that is resistant to the value fluctuations that can often occur in crypto markets.

    For Tezos a popular DEX is Quipuswap, whereas for Ethereum and its L2s a common DEX is Uniswap. DEXs can sometimes be slightly slower when compared to CEXs due to the reliance on blockchain confirmations - gas fees can also vary depending on the specific DEX and the complexity of the trade, but there’s generally no other platform fees associated as compared to CEXs.

    Other Methods for converting ETH into TEZ

    There are also a couple of ways to convert/bridge ETH into XTZ that provide an alternative fund conversion method to be aware of:

    1. Via the Temple Wallet: the Temple wallet offers an option for purchasing Tezos with Ethereum instead of a Credit Card, via an ETH wallet of yours - when buying XTZ through the wallet simply select the “crypto” option instead of credit card.

    2. Plenty Bridge: A decentralized bridge that lets you bridge ETH and Polygon funds over to Tezos.

    Both of the above methods are explained in more detail in this article:

    Safety Notes when Operating CEXs/DEXs

    To conclude, here is a number of things to always keep in mind when managing crypto funds and assets:

    1. Put security first. Audit platforms before connecting to them: Always be careful about the platforms that you choose to manage your assets with. Never blindly connect you wallet to a random dApp, make sure that it is a trustworthy platform beforehand.

    2. Verify transactions before confirming them: Never blindly trust when a platform or dapp asks you to confirm a wallet transaction - double check the subject is that you’re confirming

    3. Address Verification: Always double check and make sure that you are sending assets to the correct address on the correct network. Lost assets/funds can generally not be recovered, or only be retrieved with great difficulty.

    4. Beware of Phishing and Scams: Double-check URLs, never click suspicious links, and be wary of unsolicited emails or messages requesting sensitive info. The crypto space is filled with rug pulls and fraudulent schemes - learn to identify red flags of potential scams.

    5. Seed Phrase is Sacred: It goes without saying, but your seed phrase is the master key to your non-custodial wallet. NEVER share it, store it offline in multiple secure locations. Never reveal it to anyone. The same is true for other sensitive information.

    Make sure to also read our resource on Staying Safe in the Web3 setting.

    A Note on Gas Fees

    Gas fees are comparable to a network's "fuel" that allows it to process transactions. Gas fees are usually highest when the network is busy, like rush hour traffic. Expect them to be lower at night or on weekdays when fewer people are using the network. You can check online trackers to see current state of gas prices and estimates on transaction costs. It’s important to take these fees into consideration when performing transactions on fxhash.

    Tezos only requires minimal gas per transaction since it is designed for efficiency. Overall it also has a much smaller user base compared to Ethereum, meaning that there's less competition for space on the network, in turn keeping gas fees much lower overall. Tezos fees aren't however zero and can still change based on network activity.Ethereum on the other hand is frequently very congested and gas prices are extremely high, hence the importance of waiting for times when gas fees become relatively afforadable.

    Ethereum Layer 2 (L2) networks like Base achieve significantly lower gas fees compared to the main Ethereum network (L1). This is due to a key difference in how they process transactions. These networks bundle multiple transactions off-chain (outside the main Ethereum blockchain) before periodically submitting them as a single transaction to L1. This "batching" process allows L2s to handle a much higher volume of transactions, reducing congestion and significantly lowering gas fees for individual users.

    It’s important to keep this in mind when collecting on fxhash, and pick strategic moments when gas fees are low.

    On the demand side, factors such as hype, trends, perceived value, and speculation all play a role. NFTs associated with popular artists, projects, or communities often see higher demand and, consequently, higher prices.

  • On the supply side, the edition size of a project, the rate at which creators release new projects, and the success of previous projects can equally impact the price of a token.

  • The interplay of these factors leads to a dynamic setting in which it becomes quite difficult to make predictions for the price of different tokens ahead of time. When it comes to generative art, as well as other art tokens on the blockchain, things get even more complicated as there’s other factors that also need to be considered - with blockchain based generative art being situated somewhere at the intersection of a financial and an art market, it borrows aspects from the two.

    What further amplifies the difficulty of this is that the generative art market has become much more competitive in recent years; with several different platforms entering the playing field, pioneering with innovative sales mechanics, bringing in more and more artists to publish and distribute their creations in a blockchain native format. All of these developments have ultimately rendered the playing field much more involved.

    In this kind of setting, pricing becomes a fairly challenging topic not only for artists but also for collectors. While artists need to specify an initial price point for their projects, collectors are in charge of determining and setting prices through their activities on the secondary market. We generally refer to this process as Price Discovery:

    Price Discovery: Price discovery is the process by which the market determines the fair value of an asset. Unlike traditional markets where prices are established through historical data and comparable assets, the NFT market is relatively new and lacks such benchmarks. Its ever-evolving nature also plays into it, and makes price discovery a dynamic and often unpredictable process.

    Although Web3 environments are commonly known to be volatile, the market does manage to reach a consensus on the pricing of tokens eventually. When purchasing NFTs, whether they are generative artworks originating from fxhash, or tokens minted on other marketplaces, it is important to have a good grasp on the different factors that can potentially influence the price points of these assets.

    In what follows we'll examine some of these factors, and discuss why they might or might not influence the price fluctuations of tokens on the secondary market. By the end, you'll have a clearer picture of how the NFT market functions at large and be better equipped to make informed decisions on your future purchases and sales.

    Not financial advice. This resource’s sole aim is to educate

    Valuation of NFTs

    While the initial minting price set by artists on the primary market can serve as a baseline, the real effective price of an token/asset is determined post-release on the secondary market. As a collector, it’s often beneficial to be able to make an educated guess and estimate on what this secondary price will be ahead of time - be it for speculative purposes, or in the quest for collecting grails. In a traditional setting we refer to this as asset valuation:

    Asset Valuation: In the context of NFTs, Valuation refers to the process of estimating and/or determining the fair market value of a specific non-fungible token (NFT). It's the estimated monetary worth assigned to a unique digital asset based on various factors that influence its desirability and potential for appreciation.

    This means that valuation provides a reference point for buyers and sellers, whereas price discovery confirms or challenges those valuations in the real world later on. Over time, as more transactions occur and data accumulates, valuations then become more accurate for different tokens.

    Valuation estimates are generally not pitched haphazardly - there are a number of metrics that can be examined and leveraged for making an estimate of the market value of digital assets. This way collectors can gain a competitive edge.

    The Intrinsic Value of Tokens

    The intrinsic characteristics and attributes of a specific token play an important role in its valuation - these are aspects of the digital token itself that make it more or less unique and desirable:

    1. Rarity and Traits: Some tokens are intrinsically more valuable due to their rarity and unique traits. On fxhash token features (traits that are manually specified by the artist), are a direct indication on how rare or common a specific output is across the entirety of a minted collection. This is often a direct indicator that determines the rarity of an fxhash token.

      Mints sorted by rarity on a token’s project page.

      Sometimes traits can however also be emergent properties that accidentally manifest themselves as special aesthetic quirks in a generative artwork, which make these outputs stand out from the rest and often renders them more desirable.

      Mints sorted by rarity on a token’s project page.
    2. Historical Significance: NFTs associated with historical moments, events, or cultural phenomena can hold significant value due to their unique place in time. For instance, the projects that were minted during the early days of fxhash are highly sought after.

      The phrase “Being Early” has a little bit of cult-status in the crypto world, while it is often used contemporarily to indicate that the NFT market is still very young, it is generally the case that NFTs minted early on a successful platform tend to become highly sought after - in part also due to the ensuing scarcity.

    3. Provenance as Value: An NFT's history of ownership (provenance) can enhance its value, especially if it has been owned by prominent figures in the NFT community.

    What is Provenance?

    Provenance refers to the history of ownership and authenticity of a digital asset that is recorded on the blockchain. It's like a verifiable trail that documents the origin, ownership transfers, and any other significant interactions an asset has had throughout its existence.

    1. Utility and Functionality: Some NFTs offer utility beyond mere aesthetics, such as access to exclusive events, memberships, or in-game assets, which in turn drive up demand and value. When it comes to art tokens (like GENTKs) ownership can often mean obtaining an allow list slot on an upcoming release from the same artist.

    What is Utility?

    In Web3, utility refers to the practical value or use cases that a digital asset or project offers beyond its speculative value. It's the answer to the question, "What can I actually do with this token/NFT/platform?"

    1. The “Grail” Factor: Ultra-rare or one-of-a-kind NFTs can also sometimes become highly sought-after "grails" for collectors. NFTs can become grails when multiple of the aforementioned factors come together - but also due to other unpredictable reasons.

    While these are some of the indicators for the eventual secondary price of projects, it always makes sense to examine NFTs on a per-project basis.

    Influence of External and Social Factors

    Besides the intrinsic factors, the valuation of an NFT can also depend on external and social factors:

    Creator Reputation

    NFTs from established artists or creators with a strong track record tend to hold more value than those from emerging and lesser-established artists. While the term “reputation” may be a bit abstract in this setting, it can be quantified in some manners. For instance, a creator’s previous involvement in a particular scene/niche can often be a strong indicator for the future success of their projects.

    For instance, when some of the generative art OGs (original greats), that have been formative and leading voices in the scene for many years and decades, minted their projects on fxhash they saw instant success. These projects also tend to maintain a high floor price over time.

    Another example here is puneyvr’s project g l y p h - an open edition that ultimately ended up being the largest generative art collection, in terms of editions collected, in genart history. puneyvr being the very first artist to release a project on fxhash (after fxhash’s genesis mints) likely played a role in the success of the project:

    Another tangible factor that plays into a “creator’s reputation”, can be the size of their following across different social media platforms.

    Community Engagement, Hype, and Trends

    Active and engaged communities around a project and/or a specific platform can increase the visibility and demand of a token, in turn driving up prices. In the same manner NFTs can become immensely popular due to sudden trends, celebrity endorsements, or viral social media campaigns, here we also often use the term FOMO.

    FOMO (Fear Of Missing Out) is the anxiety or apprehension that one might miss out on a potentially lucrative or exciting opportunity within the rapidly evolving world of cryptocurrencies, NFTs, blockchain projects, or other decentralized technologies.

    For example, if a project is being discussed at length prior to it’s release in certain chat groups and/or discord servers, it’s usually a good indicator that it will be a sought after collectible. Naturally, the tone of the conversation also matters here.

    Marketplace & Platform

    The platform on which NFTs are originally minted and later traded on can influence their value. More reputable and popular platforms generally lead higher liquidity and trust.

    Scarcity & Liquidity

    Limited edition and rarer NFTs are often highly sought after, which leads to driving up their perceived value. Similarly, NFTs traded on popular marketplaces with high trading volumes tend to have more stable and predictable pricing.

    Liquidity in context of NFTs refers to the ease of buying or selling of specific NFTs at a fair market price without significant price impact.

    On Price Discovery and Floor Prices

    After the release of a project collectors become more concerned with the floor prices of collection rather than the original minting price. Floor prices act like anchors, and provide a benchmark for the value for a given collection:

    Floor Price: The floor price of an NFT collection is the lowest price at which an NFT within that collection is currently listed for sale. It represents the minimum amount you would need to pay to acquire an NFT from that specific collection.

    The floor price of a collection is generally considered a quick indicator of value and used as a way to gauge the collection’s overall worth and popularity, the floor price is generally important for both buyers and sellers:

    • Buyers can use floor prices as a starting point for evaluating the potential value of an edition and compare its price to others in the collection.

    • Sellers might use the floor price as a reference for setting their own asking price, especially if their token additionally has unique traits or attributes.

    If you’re an up and coming artist and are considering releasing your second or third NFT collection, you might just use the floor price of your first project as a baseline. From collectors’ point of view, the floor price will frequently be used in comparison to the initial minting price as an indicator for the popularity of acollection:

    • Floor Price > Mint Price - Positive Market Sentiment / Successful Release: In this scenario the project had a successful launch and generated significant interest among collectors, suggesting a strong demand and positive sentiment towards the project, so much so that collectors are willing to pay a premium above the initial price.

    • Floor Price = Mint Price - Stable Demand: There's enough interest to maintain the initial price but not enough to drive it significantly higher.

    • Floor Price < Mint Price - Low Interest / Oversupply: When the price of tokens on the secondary is lower than the original minting price, it means that collectors overestimated the interest that the collection would generate upon release and are trying to recuperate a portion of their investment on primary.

    Overall this means that a higher floor price generally suggests greater demand and perceived value, whereas a lower floor prices indicates the opposite. Most, if not all, NFT marketplaces display the floor price of a collection on individual collection pages. While floor prices provide a useful snapshot, they don't always reflect the true value of all NFTs within a collection. Rare or unique NFTs often sell for much higher prices than the floor price.

    Influence of Market Sentiments: Bear vs. Bull

    Beyond some of the more tangible factors that we’ve enumerated above, there’s other factors that also affect the valuation of tokens, that might be a bit more elusive. The currently prevailing market sentiment is one such factor. The term market sentiment refers to the overall attitude of collectors and traders towards a particular asset, market, or the broader economy — in essence it's a collective feeling of optimism or pessimism that can significantly impact market behavior:

    Market Sentiment: in the NFT space reflects the collective psychological attitude and overall mood of investors and collectors towards the market. It is the prevailing emotional tone that influences buying and selling decisions, and can significantly impact the valuation of NFTs.

    In context of cryptocurrencies you’ll frequently hear people say “I’m feeling bullish” or “The market feels bearish” to describe the current market sentiment:

    • Being Bullish indicates an optimistic outlook on the market, where the involved actors (artists, collectors, crypto traders, etc..) expecting the overall market activity to pick up and charts to swing upwards.

    • A Bearish sentiment indicates the opposite of a “bullish” outlook, where the general sentiment is pessimistic and things are expected to slow down in the foreseeable future. This can lead to increased selling activity, putting downward pressure on prices.

    The etymology of the two terms is also interesting to point out here, as there’s several theories about their origin - one of them:

    Origin of the terms Bull vs. Bear

    There’s a couple of explanations for the origin of the two terms Bull and Bear market. Long ago, goods and services were exchanged for other goods and services. Investors who sold bear skins they did not yet own were called bears because they expected a price decline. Bull traders were considered the opposite of bears. They bought assets with the expectation that prices would rise.

    Positive market sentiment can create a self-reinforcing cycle, with rising prices attracting more investors, further fueling demand and pushing prices even higher. Conversely, negative sentiment can lead to a downward spiral, with falling prices triggering panic selling, further depressing values. As for the factors that can influence the market sentiment, there’s a few to consider and often is a mixture of them that leads to a shift in the overall outlook:

    • News and Media: Positive news coverage, successful NFT sales, or endorsements from celebrities can boost sentiment. Conversely, negative news like scams, hacks, or regulatory concerns can dampen it.

    • Social Media: Trends, discussions, and the general buzz on platforms like Twitter and Discord can sway collector and investor emotions and, consequently, market sentiment.

    • Macroeconomic Trends: The overall economic climate and developments in the cryptocurrency market can significantly impact sentiment in the NFT space.

    • Major Events: Large-scale NFT auctions, conferences, or the launch of new platforms can generate excitement and positively influence sentiment.

    Overall, NFT valuation is a complex and dynamic process, with a multitude of factors at play. While the eco-system is generally very volatile, understanding these different factors can help you make informed decisions as a collector and keep track of the happenings on the secondary market.

    Let's boot this generative artwork up with fx(lens) to turn it into a deterministic fxhash project. Fx(lens) will allows us manual control over the input hash and lets us test that if our piece is in fact deterministic or not. Go ahead and create a new project, copy over the previous code into the corresponding project files, and boot up fx(lens) - you should see the following in your browser:

    Naturally you will obtain a visually different circle packing configuration because the sketch isn’t deterministic yet, nor will you have the same hash. Let's talk for a second about circle packing procedures and how they use randomness, this will help us understand what modifications we need to make.

    In essence a circle packing algorithm is a very simple algorithm that tries to randomly distribute circles on a surface (the canvas) in such a manner that they don't overlap. This is generally done by storing the positional information of these circles in an array that we can reference when placing new circles. If a new circle (that we're trying to place) overlaps with any of the circles in that array (if it is stored in the array it means that it already exists on the canvas), we simply discard this new circle and try to place a different circle at a different location on the canvas.

    In this procedure, RNG comes into play during the selection of the circle coordinates and their radii. These are chosen at random from specific ranges:

    Here we created a little helper function that allows us to generate a random number within a given range. This function makes use of the Math library that comes with Javascript by default and provides an RNG out of the box. This RNG is not seeded and will produce different random numbers each time that we run our code.

    We want it to however produce the same sequence of random numbers, given the input hash that the fxhash script injects into our code. To this end we need to replace this default random function with the $fx.rand() function that is based off of the seeded fxhash PRNG:

    Now let's run our code again in fx(lens) by hitting the refresh button, while keeping the same hash. It should produce the exact same circle packing configuration each time we refresh:

    If the placement of the circles stays consistent then it means that the placement procedure is now deterministic and depends on the input hash, refreshing with the hash fixed should always produce the same circle placement - changing the hash should produce a new composition:

    Why do the colors of the circles change when we refresh? Because we aren't using the $fx.rand() function for that aspect of the procedure - if we select the colors using $fx.rand() then the sketch should now be entirely deterministic:

    This is to show that all random number generation, or random selection processes in our code need to be done with the $fx.rand() function. Otherwise some aspects of the generated output will not be deterministic.

    Common Pitfalls

    It is important to understand how seeded PRNGs function and how they create deterministic sequences of numbers. Let's assume that we have some generative token that invokes the $fx.rand() function exactly three times:

    These three random calls will produce three random values. Given the same hash, these three random calls will always produce the same three random values.

    Assume that for some arbitrary reason another part of the code invokes the $fx.rand() function in between the first and the second invocation, this would shift the entire sequence of random numbers:

    This would shift and alter the entire subsequent random number sequence leading to a different output. The most common reason for this is basing the number of random calls on external factors, for instance when we have an $fx.rand() call within a loop that isn’t guaranteed to run an exact number of times. In our circle packing procedure we hard coded the number of iterations to a value of 5000 attempts. Another common pitfall, is basing the number of random calls off of the browser window’s dimensions that might vary on different devices, or leaving random calls within the code that are not based off of fxhash’s PRNG. Sometimes floating number imprecision can also lead to this issue.

    The important notion here is that the number of random calls in the GENTKs code needs to be consistent. Hence, no part of the code should make an unpredictable number of random calls, it would break the determinism of the piece.

    In most cases, non-deterministic outputs are the result or external factors influencing the code. If this is the case, you should scan your code for such external factors, it might not always be immediately obvious what the problem is.

    Using other PRNGs

    Some libraries provide their own random number generators that can be seeded, for instance, the PRNG used in P5 can be set via the randomSeed() function. This function however requires as input a number and not an alphanumeric hash. An easy workaround for this is by using the fxhash PRNG to generate an intial deterministic number and then feeding it into P5s randomSeed() function:

    We also briefly mentioned earlier that it is possible to create your own PRNG. You would just need to make sure that you seed this PRNG correctly.

    Access/Allow Lists: A list of wallet addresses that have exclusive access to a number of reserved editions/iterations of the generative project.
  • Mints Passes (Token Gates): Holders/Owners of a specific token obtain exclusive access to a number of reserved editions/iterations of the generative project.

  • We will tackle these two methods in what follows.

    Adding Access Lists

    When selecting an access list as a reserve we see the following in the UI:

    Before we have a look at the slider, we’ll have to create a list of addresses that will comprise the access list. We can either enter these addresses manually by copy pasting them in and hitting the ‘add’ button, or we can import an entire list at once. And there’s three options for this:

    Import from Event

    Essentially imports all wallet addresses that participated in a live mint at a specific IRL event:

    Importing from a CSV file

    many other NFT/crypto platforms, as well as 3rd party tools allow you to export a list of wallet addresses, this could be a list of all holders of a specific token on another platform for example. It might be that you want to reward these collectors by reserving some editions of your project on fxhash for them. Here you can simply import this csv list and fxhash will parse it for you filling in the list:

    Make sure to format this list properly though, where each address is followed by a semicolon, a space, and non-negative non-zero integer.

    Import addresses of current holders of previous projects

    It might also be the case that you want to reward edition holders of your previous fxhash projects, the third option lets you do this, there’s some nuance to this import option however. In this pop-up box you can select the projects for which you’d like to import the addresses of the current holders. You can select one, or several:

    After that you need to select an import strategy, this determines how many reserve slots each holder will obtain:

    • One Per User: each imported address obtains 1 access list slot regardless of how many iterations they own in total from the same project or across the multiple projects that you’ve selected to import from.

    • One per User per Project: imported addresses will have as many slots as projects for which they hold at least one iteration. This limits the number of slots to 1 even if a user holds 10 iterations of the same project. If you only import the holders of one project each address on the access list will have 1 slot.

    • Full Import: imported addresses will have as many slots as the total number of iterations they own across all of the projects that you import. If you import two projects for example, and one address holds 5 editions of the first project, and 3 editions of the second project, then they would get 8 reserve slots in total.

    Once you import the addresses you also need to adjust the slider that indicates how many editions the reserve will cover - for this you need to have set the total amount of editions earlier:

    Naturally, you can still manually edit the amount of slots each imported address will obtain on the reserve.

    💡 **Open editions and Reserves:** When creating an open edition, it is not possible to create a reserve, since there is an unlimited supply for the project.

    Adding a Mint Pass

    We’ve already established that smart contracts are self-executing pieces of code on the blockchain, that users can interact with to do all sorts of things - for example it’s the tech that enables artists to create NFTs, and in turn also enables collectors to purchase NFTs. And all of that in a decentralized manner without the need of an intermediary. These interactions are usually facilitated by the interfaces of the different platforms.

    Because smart contracts are stored on the blockchain, they require a unique identifiable address - we generally refer to this address as a contract address:

    💡 **Contract Address**

    A unique identifier on a blockchain network that acts as the location of a smart contract. It's a string of alphanumeric characters that allows users and other smart contracts to interact with it. Think of it like the digital mailbox address of a self-executing contract.

    NFT Platforms leverage this unique smart contract identifier to make Mint Passes possible. Although we generally describe a Mint Pass as a sort of voucher token that grants access to a certain gated Web3 service - such as minting rights for another NFT, or viewing rights for a piece of content - the token gate check is effectuated via the contract address that this Mint Pass Token is created under.

    💡 **Mint Pass / Token Gate**

    A specific type of NFT (or sometimes a social token) that grants holders exclusive access to mint (create) other NFTs during a designated minting event or within a specific collection. Mint passes are a form of token gating.

    We do this instead of checking the individual NFT addresses, for a few main reasons:

    • One Verification: Rather than verifying a whole list of individual (yet-to-be-minted) NFT addresses, using the main contract address allows the minting system to efficiently confirm if someone holds a legitimate mint pass with a single check.

    • Collection-Wide Rights: several tokens can be minted under the same contract address, meaning that holders of any of the tokens under that contract become eligible for the token gated services. Naturally the contract creators can limit this to a single token.

    • Pre-Minting Mechanics: Mint passes are frequently used to grant early access or whitelist spots for minting (creating) NFTs that haven't been generated on the blockchain yet.

    All of this said, adding a mint pass to one of your projects on fxhash is different from configuring an access list, as discussed, the contract address of a token needs to be specified when creating the reserve:

    And to recap, if you want to reserve a number of editions for holders of a specific token, you need to insert the contract address under which this token has been minted - in this manner, any NFT can essentially be a mint pass, as long as it is minted under its own unique contract!

    Many NFT platforms out there provide a functionality that lets you create your own contract, under which you can then mint NFTs. On Tezos for instance, collections on Objkt.com each have their own unique contract, similarly a platform like Manifold.xyz is entirely geared towards this purpose, acting as a sort of contract factory for different types of Ethereum contracts.

    Where do you find the contract address of a token?

    • On Tezos: When inspecting an NFT on Objkt.com you can find the contract address under the properties tab. This opens the contract address on tzkt.io from where you can copy it.

    • On Eth: The best place for Ethereum is Opensea, that also covers the other Ethereum L2 Networks - here you’ll find the contract address under the details tab. This will then navigate you to Ethscan/Basescan.

    And that’s all there is to it, simple paste the contract address into the input field of the reserve, and adjust the slider to specify the size of the reserve - this grants one reserve slot for each mint pass holder.

    Use cases

    Here are some of the scenarios in which it makes sense to set reserves on your projects:

    • Reserving Editions for yourself / Artist Proofs: Create a separate reserve of type Access List, give it the number of slots you'd like to reserve for yourself, and add your own wallet address in the access list with the same number of slots. You will be guaranteed to be able to mint the same number of editions whenever you'd like.

      💡 Previously projects needed to be launched in a disabled state for the artist to mint from them prior to a public release. This is no longer the case, and artists can set reserves for themselves.

    • Rewarding your collector base: It is nice to show appreciation towards your past collectors and provide them with reserve slots. As discussed earlier, the fxhash UI facilitates this in that wallet addresses of previous project holders can be easily imported. Other tools exist however to import the addresses of holders of tokens on other platforms as well.

      💡 Please keep in mind that reserves are not dynamic. Future collectors won't be included in a previously created reserve.

    • Locking N editions for later: By setting a reserve as an access list to a burn address (or to yourself if you're not planning on consuming it), you can lock a certain number of editions which can then be safely unlocked. This can be useful if you want to do raffles and/or giveaways in the future.

    We would recommend to also keep new collectors in mind however, while it's great to reward your previous collectors, we wouldn't want the platform to become locked to new-comers because of this feature.

    💡 **Access Lists are currently limited to 1000 addresses per list**.

    Updating Reserves

    Reserves are static. When a user mints from a reserve, it updates the smart contract storage, which then has to be indexed to be displayed on the UI with the update. It means that what you see on the UI may not be completely up-to-date with on-chain storage.

    Consider the following case:

    From the contract's perspective, the following happens:

    • Reserve: 10 (User A: 10)

    • User A mints from reserve

    • Reserve: 9 (User A: 9)

    • User A: get NFT

    • Author updates reserve

    • Reserve: 10 (User A: 10, User B: 1)

    This is known as a race condition, and measures must be taken to prevent those cases from happening. That's why the Smart Contract will reject update_reserve calls if token are not disabled. When updating a reserve, we suggest following these steps:

    • disable the token

    • wait until the UI displays your token as disabled (refresh page)

    • update the reserve

    • enable the token

    These steps will ensure that no race condition can happen between the UI state and the contract storage.

    CLI Reference

    In this section we have a brief look at how to use the CLI, and will have a more detailed look at the individual CLI commands.

    CLI Commands Overview

    Command

    Options

    Description

    Default

    fxhash create Creates a blank fx(hash) project. Allows you to choose between several starting templates.

    —

    fx(hash) create

    Creates a new project directory that contains the fxhash template.

    Once you've installed the CLI, you can conveniently create a new and blank fxhash project with the fxhash create command. Running the command will spawn a new folder in the current terminal directory. This folder will essentially contain the boilerplate files.

    The command will ask you to provide a name for your project and additionally ask you to choose a template—currently there are two of them:

    • Simple Template: If you are new to the platform and/or don't need any special customization, we recommend starting with the simple template.

    • The Ejected Template: Needs an explanation of the ejected template

    The fxhash create command has no options.

    fxhash dev

    Runs your project inside fxlens, the fxhash development environment.

    The fxhash dev command can be used when you navigate into the directory that is created with the fxhash create command. This will launch your project inside the fxhash's fxlens development environment and automatically opens up a new tab in your default browser.

    If you haven’t already written some code for your artwork in the index.js, it will show the following default screen:

    The panel on the left-hand side is fxlens, fx(hash)’s interactive project viewer that comes out of the box with the CLI. , it provides a number of functionalities for testing the determinism of your generative artwork and is an important tool for building fx(params) pieces.

    The fxhash dev command runs two local servers, one for the project itself, and another for the development environment that displays the project in a nested manner. The options let you set the ports on which these local servers run:

    • --portStudio:

    • --portProject:

    • --srcPath:

    fxhash dev automatically checks and updates itself when it is run.

    fxhash build

    When your artwork is ready for being minted it should be uploaded to fx(hash) in the form of a .zip file. The CLI provides the fxhash build command that bundles all of your project files as such a .zip. This will create an upload.zip file in your project directory, that can later be drag-n-dropped into the fx(hash) minting interface.

    Before you upload a project to fx(hash) however make sure to read the rest of the artist guides to ensure that your project works correctly and is properly configured to be compatible with the platform. fx(hash) can not check this for you.

    fxhash capture

    The CLI also lets you test the appearance of your project once it’s iterations have been collected on fx(hash). For this you’ll first have to bundle your project with the fxhash build command, to then subsequently run the fxhash capture command which will then generate a jpg of the artwork, here’s what this would look like:

    The capture command provides a number of options to specify some of the information that needs to be fed into the token to generate specific captures, and to control how the capture should be taken. They are detailed in the overview table above.

    fxhash update

    fxhash update command updates the CLI and all of it’s features to the latest version, in case that there is a newer version.

    Configuring Default Options with .env

    When you run the CLI commands, it checks for a .env file inside the current difrectory. The .env file allows you to overwrite the default options of the various commands—for example if you want to run fxlens and your project on different ports:

    This way you can customize how the CLI behaves for different projects.

    Options passed in manually to commands still always override what's set in the `.env` file.

    Node.js — Introduction to Node.jsnodejs.org

    Pricing and Supply

    Over view of step 8 of the mint flow, including supply and pricing methods, primary and secondary splits, and allow lists. Additionally considerations on how to chose appropriate settings.

    Here’s a quick overview of the distribution settings section of the minting interface:

    These settings need to be chosen carefully as they have a direct impact on the success of your project!

    1. Supply Methods (Editions)

    fxhash currently supports two supply models: Fixed Limited Edition and Open Editions.

    In a fixed limited edition a set number of editions is specified allowing for that many unique iterations to be minted. These editions can be minted for an indefinite amount of time either until all available editions are acquired by collectors, in this scenario we refer to collection as being

    Open-form ↔ Art Coin: Mechanics & Economics

    Art coins are project native currencies linked at the contract level. They enable new mechanics, unlock alternative value around your work, and incentivize interaction at scale.

    Open-form generative art introduces a new model for how collectors interact with generative projects on fxhash. Each open-form project is linked to its own art coin—a dedicated ERC20 token deployed on the Base L2 chain. This art coin powers all collector interactions with the project, including minting, burning, re-rolling, locking, and evolving NFTs.

    Art coins establish onchain economic systems that reflect collector interest, scarcity, and market demand. This page provides an overview of how open-form mechanics work, the role of art coins, how fees and royalties are structured, and how artists and collectors both benefit from this flexible framework.

    Open-form mechanics overview

    Open-form project editions can be minted

    System Overview

    ONCHFS is a permissionless unix-like content-addressable file system fully stored on-chain designed to be delivered through the http protocol, with cross-blockchain compatibility in mind.

    System components

    FILE-OBJECTSCONTENT-STOREHTTP-PROXY-RESOLVERUSERAPP-CONTRACTCREATORSwrite/read content-addressed chunksresolvesrequest to view content through httpreferencesinsert files & directoriesuse file objectsdiscover content

    $fx.params(definitions) // API function that creates the parameters in the interface
    definitions = [
    {
    	id: "number_id",
    	name: "A number",
    	type: "number",
    },
    {
    	id: "boolean_id",
    	name: "A boolean",
    	type: "boolean",
    },
    {
    	id: "color_id",
    	name: "A color",
    	type: "color",
    },
    ]
    **{
    	id: "number_id",   // required
    	name: "A number",  // optional
    	type: "number",    // required
    	options: {         // optional
    		min: -10,
    		max: 10,
    		step: 0.1,
    	},
    }**
    const paramValue = $fx.getParam('number_id')
    {
      id: "number_id",
      name: "A number/float64",
      type: "number",
      update: "sync", // <-- new update property
    },
    
    // defining parameters two code-driven parameters
    // that are uneditable from ui, and will be controlled by the code!!
    $fx.params([
      {
        id: "size",
        name: "Size",
        type: "number",
        update: "code-driven",
      },
      {
        id: "x_pos",
        name: "X position",
        type: "number",
        update: "code-driven",
      },
    ])
    
    // this is the draw loop in which we render the graphics
    // and listen for changes of the code-driven parameters
    function draw() {
      // resetting the fx.rand function is important to ensure every time it's
      // called, the same values will be generated
      $fx.rand.reset()
    
      // GRAHPICS ARE DRAWN HERE
    }
    
    // this renders an interactive UI in the minting context
    function drawUI() {
      // draw UI here
    }
    
    // depending on the execution context, 2 different codes are executed
    
    // when the code is executed in a "minting" context
    // we run the first clause of the condition
    if ($fx.context === "minting") {
      // we draw the piece, and the UI on top
      draw()
      drawUI()
    
      // updating the parameter from the code - this would be called when some input
      // is registered, such as clicking the mouse for example
      window.addEventListener("click", () => {
        $fx.emit("params:update", {
          size: Math.random(), // anything here, it will update the parameter value
        })
      })
    
      // when the params are updated we re-draw the graphics and the UI
      $fx.on(
        "params:update",
        // we do nothing when the event is received
        () => {},
        // once the params are updated and available, we trigger a re-draw
        () => {
          draw()
          drawUI()
        }
      )
    }
    // the piece is ran by itself, for the final output or for the capture
    else {
      // we just draw
      draw()
    }
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>simple</title>
    		<meta charset="utf-8" />
    		<script src="./fxhash.js"></script>
    		<link rel="stylesheet" href="./styles.css" />
    	</head>
    		<body>
    		<div id="canvasContainer">
    			<canvas id="myCanvas" width="900" height="1200"></canvas>
    		</div>
    		<script src="./index.js"></script>
    	</body>
    </html>
    body {
    	/* override the default margin of the html body */
    	margin: 0;
    }
    
    #canvasContainer {
    	height: 100vh;
    	width: 100vw;
    
    	display: flex;
    	align-items: center;
    	justify-content: center;
    }
    
    #myCanvas {
    	max-width: 100%;
    	max-height: 100%;
    	border: 2px solid black;
    }
    const canvasWidth = 900; // same as original canvas width
    const canvasHeight = 1200; // same as original canvas height
    const PAD = 75
    
    const palette = ["#0a0a0a", "#f7f3f2", "#0077e1", "#f5d216", "#fc3503"]
    
    // JavaScript code to draw a blue rectangle on the canvas
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    function getRandomNum(min, max) {
      return Math.random() * (max - min) + min;
    }
    
    let circs = []
    
    for(let n = 0; n < 5000; n++){
      let randX = getRandomNum(PAD, canvasWidth-PAD)
      let randY = getRandomNum(PAD, canvasHeight-PAD)
      let randRadius = getRandomNum(10, 100)
    
      let placeable = true
    
      for(let i = 0; i < circs.length; i++){
        let xDistance = randX - circs[i].x
        let yDistance = randY - circs[i].y
    
        let cDistance = Math.sqrt(xDistance*xDistance + yDistance*yDistance)
    
        if(cDistance < randRadius+circs[i].radius+5){
          placeable = false
        }
      }
    
      if(placeable){
        circs.push({x: randX, y: randY, radius: randRadius})
      }
    }
    
    for(let i = 0; i < circs.length; i++){
      let c = circs[i]
    
      ctx.lineWidth = 3
    
      ctx.moveTo(c.x+c.radius, c.y)
      ctx.beginPath()
      ctx.fillStyle = palette[Math.floor(Math.random() * palette.length)];
      ctx.ellipse(c.x, c.y, c.radius, c.radius, 0, 0, Math.PI*2)
      ctx.fill()
      ctx.stroke()
    }
    
    //canvas.style.width ='100%';
    const resizeCanvas = function(event) {
      var containerWidth = window.innerWidth;
      var containerHeight = window.innerHeight;
    
      var ratio = containerWidth / canvasWidth;
      if(canvasHeight * ratio > containerHeight) {
        ratio = containerHeight / canvasHeight;
      }
    
      canvas.style.width = canvasWidth * ratio-20+"px";
      canvas.style.height = canvasHeight * ratio-20+"px";
    }
    
    window.addEventListener('resize', resizeCanvas, true);
    resizeCanvas()
    function getRandomNum(min, max) {
      return Math.random() * (max - min) + min;
    }
    
    // PAD is a parameter chosen by us - margin to the canvas boundaries
    let randX = getRandomNum(PAD, canvasWidth-PAD)
    let randY = getRandomNum(PAD, canvasHeight-PAD)
    let randRadius = getRandomNum(10, 100)
    function getRandomNum(min, max) {
      return $fx.rand() * (max - min) + min;
    }
    $fx.rand() // 0.25
    
    // other code happens
    
    $fx.rand() // 0.88
    
    // other code happens
    
    $fx.rand() // 0.124
    $fx.rand() // 0.25
    
    /*
    	some other part of the code invokes $fx.rand() - 0.88
    */
    
    $fx.rand() // 0.124
    
    // other code happens
    
    $fx.rand() // 0.87
    let p5Seed = $fx.rand() * 999999
    randomSeed(p5Seed)
    
    random() // p5's random number generator is now deterministic
    
    address;amount
    tz1dtzgLYUHMhP6sWeFtFsHkHqyPezBBPLsZ;2
    tz1PoDdN2oyRyF6DA73zTWAWYhNL4UGr3Egj;4
    tz1MGzgRu6qJ3RaBUErnpFDLarFVPgaApKrA;1
    
    Core properties

    Permissionless

    Anyone can write data, create files & directories, & reference files stored on the file system.

    On-chain

    Every byte necessary to fully reconstruct the file system is stored on-chain. Standards provide a way to write & read the file system.

    Immutability

    Content created on the file system can never be altered.

    Interoperability

    The raw bytes of data are stored as chunks in a dumb Content Store contract, only supporting low level operations such as write & read. Because the chunks of data are Content-Addressed, many applications can use the Content Store for various purposes without impacting each other. This protocol provides extra abstraction layers to improve upon just having a Content Store.

    Content-Addressed

    Chunks of data, files & directories are hashed and identified by their in the Content Store hash.

    Unix-like

    An abstraction layer inspired by inodes on Unix-like file systems provides a generic way to organise the Content Store into files & directories.

    An inode can be a file or a directory:

    • file: an ordered list of pointers to chunks of bytes in the stored in the Content Store, and some extra data describing the file

    • directory: a list of inodes with their assigned names

    inodes are also Content-Addressed, the hash of their content is used to identify the inodes on the file system. Such hashes are used as entry points to the file system, and are referred to as Content Identifiers (CID).

    Designed for the http protocol

    As browsers are the main (if not the unique sensible) gateway to web3 assets, the protocol is designed to easily serve its content through the http protocol, in such a way that assets can easily reference and load other assets stored in the file system, using the native behaviour of modern browsers through the http protocol.

    While the http protocol isn’t directly built into the Smart Contracts (yet), the protocol specifies particular guidelines so that consumers of the system provide particular metadata for delivering resources through the http protocol, in an optimised fashion.

    However the protocol specifies how proxy servers should be implemented to navigate the file system using the URIs native to the file system.

    Extensible

    As the protocol provides very low level primitives, it’s easy to extend it by providing other abstraction layers for navigating the file system.

    For instance, we could imagine an “http-like” contract which would take “http-like” requests to return content stored in the file system with http-compliant response messages.

    Logo

    —

    —

    fxhash dev [options] Runs your project inside fxlens, the fxhash development environment.

    --portStudio

    The port fxlens is served on.

    3300

    --portProject

    The port the project is served on.

    3301

    --srcPath

    The path to the source of the project. This is just relevant for ejected projects that actually have a nested structure.

    /src

    fxhash build [options] Creates a bundled version of the project directory. The output file will be called upload.zip and can be uploaded as it is on fxhash.xyz.

    --minify

    Enable minification when creating the bundle.

    false

    --noZip

    Disable the zip file creation.

    false

    --srcPath

    The path to the source of the project. This is just relevant for ejected projects that actually have a nested structure.

    /src

    fxhash update [options] Will update the whole fxhash environment. It will download the latest version of fxlens and the fxhash-snippet. Optionally you can inject the latest snippet into your html file.

    --srcPath

    The path to the source of the project. This is just relevant for ejected projects that actually have a nested structure.

    /src

    fxhash eject Will eject your project into a nested structure. It will copy all your code into a srcPath (Default: /src) and create a package.jsonfile in the root of your project. This will allow you to configure any custom tooling you like while still being able to use the @fxhash/cli in your ejected project.

    --srcPath

    The path to eject the code into. If you set a custom path here you also must specify this path to the other commands.

    fxhash add <package@version> Installs existing libraries. Beside being a convenience feature. This ensure that you are reusing existing libraries from the ONCHFS, which reduces the costs of storing your project on-chain 😎.

    --list

    Lists all existing libraries that can be imported

    —

    --inject

    Will also inject a <script /> tag into your projects html entry point pointing to the downloaded library

    fxhash capture [options] With the capture command you can test your bundled project agains the fx(hash) capture module. For params token you currently must provide the inputBytes yourself. You can copy the inputBytes from the url when you are running the fxhash dev command.

    --zip

    The path (absolute or relative) to the project's zip file you want to create the capture of.

    upload.zip

    --hash

    The hash that is injected when the capture is taken.

    random hash

    --minter

    The minter address that is injected when the capture is taken.

    random address

    --iteration

    The iteration number that is injeted when the capture is taken.

    1

    --inputBytes

    The inputBytes that are injected when the capture is taken.

    undefined

    --x

    The width in pixels. Capped at 2560.

    800

    --y

    The height in pixels. Capped at 2550,

    800

    --trigger

    The trigger mode. Either DELAY or FN_TRIGGER.

    delay

    --delay

    The delay in ms for the trigger mode DELAY.

    3000

    --selector

    The id of the canvas element to capture.

    —

    fx(lens) is explained in more detail here
    Running the fxhash create command in the terminal + the files that it spawns
    The default boilerplate will display a bunch of text in the main area of the browser window that represent some default debug information.
    PORT_PROJECT=3301
    PORT_STUDIO=3300
    SRC_PATH=/src
    MINIFY=false
    minted out.
    Alternatively, after a longer period of inactivity if not all available editions are collected, the artist can choose to either disable the project (more on how to enable/disable a project later in this page) or burn the remaining editions.

    In this scenario you must specify a number to indicate how many editions are to be minted - considerations on how to choose this value can be found towards the end of this page. It largely depends on your audience size and the amount of variety your generative project can produce.

    Open Edition: an open edition indicates that a project doesn’t have an upper limit on how many iterations can be minted by collectors - this is useful for special projects and special occasions where there might be a much larger number of collectors.

    When Setting up and Open Edition you can also specify a closing time after which the project can no longer be minted. If not specified then the project can be minted forever. It’s important to note here that this can not be changed anymore after the project is published

    2. Pricing Methods

    When publishing a project on fxhash, artists can choose between two pricing methods: Fixed Price Sales and Dutch Auctions.

    As the name indicates, setting a fixed price for a project is a straightforward and the more common method to distribute individual iterations generative token. Individual iterations are essentially sold at a fixed price.

    The price of a project can be changed manually by the author(s) of the project. This only affects un-minted iterations and not ones that have already been collected.

    Dutch Auction are more involved**.** A dutch auction is a type of auction in which GENTKs can be collected at a gradually decreasing price over a specific period of time before settling at a predetermined minimum. Setting up a Dutch Auction involves specifying the start time, price decrement steps, and time intervals:

    How does this work? The Dutch Auction begins at the opening time, with the first price of the list. After every time step, the next price in the list becomes active. This is repeated until the last price of the list is met, ie the reserve price. For instance, if you set the following settings:

    • opening time: 01/01/2100 at 00:00

    • 50 / 30 / 10 / 5 / 2

    • 10 minutes

    Your project will only become mintable (even by yourself) on the 01/01/2100 at 00:00. The starting price will be 50. After 10 minutes, the price will become 30. So on so forth until the reserve price of 2 is met at 00:40. Then the price will never change.

    **Important Notes:** - Pricing methods and details are flexible and can be updated anytime, except for Dutch Auction settings in projects released before March 20, 2023. - Not all pricing mechanisms are currently available for all supported chains. For instance, our Base integration currently doesn’t support Dutch auctions.

    3. Opening Time

    The opening date refers to the exact time your project becomes available for minting. This is different from the publishing date where the project appears on the fxhash feeds, and obtains its own proper project page.

    One thing of note when setting an opening for your project, is that there needs to be at least an hour between the moment your project is created and it officially becomes available for collectors to mint editions from it. This time buffer is put in place for the moderators and the community to verify that the project is legitimate, not a copy-mint, and also doesn’t have any other issues.

    Generally it is recommended to publish your project a couple of days ahead of an official opening date that you’ll convey to your collectors and fans so that they can be ready for the launch of the project. It is also important to choose an appropriate time for the release of your project, that doesn’t coincide with any other major events that might overshadow your project. We discuss this in the “Before releasing your Project” Section.

    4. Primary Splits

    When publishing a project, you can configure how revenue will be split both from primary & secondary proceeds. Smart contracts offer a lot of flexibility in this regard.

    With primary splits we refer to the collect transaction that collectors perform when they mint an individual GENTK from an fxhash project, essentially creating this GENTK:

    What are Primary Proceeds?

    Primary proceeds refer to the initial sale of a GENTK, when a collector purchases a GENTK directly from the generator. As a creator, you can specify a percentage of these proceeds to be automatically sent to other wallet addresses when creating your project. This is useful in the case of collaborations with other artists, as well as donating to library creators, or charities.

    As the creator of a project you can choose if you’d like some of these primary proceeds to go to another wallet, this can be maybe the wallet address of someone that helped you develop your project, the wallet address of the creators of a library that you’re using in your project, or even a charitable organization. You’d simply have to add in their wallet address and indicate what percentage of the primary proceeds should go towards that address:

    fxhash also provides a list of endorsed addresses that you can donate to if you choose to do so:

    5. Royalties and Royalty Splits

    Secondary proceeds are artist royalties that are received whenever a GENTK from one of the artists’ projects gets resold on the secondary market:

    What are Secondary Proceeds? Secondary proceeds are royalties from resales. A resale in this setting refers to the action of a collector selling a GENTK on the secondary market to another collector. When creating a project, the artist can specify a royalty percentage between 10% and 25% - whenever a secondary sale occurs, this percentage amount of the resale price will automatically be sent to the artist’s wallet.

    This royalty percentage can be set at mint time when creating a project:

    Additionally, the artist can choose to reward initial collectors with a share of this royalty percentage. Meaning that they will receive a share of the secondary proceeds whenever a secondary resale occurs. You can also add other wallet addresses to receive a share of secondary proceeds, however we recommend keeping the number of splits under 10, because otherwise it will make any transaction where the splits have to be distributed slightly more expensive for the initiator of the transaction.

    Note on Updating Royalties: When updating the royalty settings of a project, this will not affect the royalty percentage of already minted GENTKs from that project - they will retain their original royalty percentage. This change will only affect future minted iterations.

    fxhash honors artist royalties: fxhash honors artist royalties, ensuring that the splits set for a GENTK remain unchanged throughout its lifetime.

    6. Reserves & Allows Lists:

    Setting allow lists is an intricate topic in of itself - hence we cover the relevant notions in a page of its own, in the next page of the docs. In brief, allow lists are a feature that enable artists to reserve a number of editions from their project for specific list of wallet addresses. These reserved editions are not publicly available and can only be minted by the wallet addresses included in the allow list.

    Refer to the other resource to learn more about allow lists.

    7. The Enable Toggle:

    The “Enable” checkbox allows you to disable minting of your project. If you want your project to be mintable by collectors, you need to select this toggle. Sometimes it is useful to disable a project, for instance when you need to change some of its settings.

    Pricing Considerations

    Deciding on a price point for your work is a challenging yet necessary step before releasing your project on fxhash. Some general considerations for both emerging and established artists in this regard are:

    • Human Factors:

      • The size of your social media following (potential collector base):

      • Apparent interest in your project from teasers and WIPs: are your WIPs garnering a lot of engagement on social media? Are people talking about your work? Have people asked when you’re going to mint?

      • How long have you been active in the generative art/creative coding space? Are you a veteran generative art wizard or just starting out on your generative art journey?

      • The success of your previous projects (if any): did your previous projects mint out instantly?

    • Project related factors:

      • How varied is the output space of your project? Does your project have the ability to generate a large variety of different styles? Or is it limited in that regard? After how many iterations do generated outputs become repetitive?

      • The edition size of the project: adding on to the previous point, there is a soft correlation between price and edition size, usually a larger edition size warrants a lower price point, but that’s just a rule of thumb.

    • Market Conditions:

      • You also need to consider the state of the market, if it’s currently a bear market or a bull run, and whether collectors are currently in a state of mind for collecting or not.

    These are some of the aspects that you should keep in mind to find a good pricing/edition ratio, ultimately you need to strike a balance that considers all of these aspects. Beyond these general considerations, there’s also some different considerations depending on your state as an artist; if you’re just starting out, or already have quite a few projects under your belt.

    Considerations for New Artists

    If you’re a new artist and are about to publish your first couple of projects your pricing is crucial. Without an active collector base, you’ll find it easier to attract collectors with lower prices, offering a low barrier to entry to new and established collectors. Besides the general considerations above, you can ask yourself some other questions and examine what other artists are doing on fxhash:

    • What prices did other established artists use for their first projects?

    • What are some of commonly used pricing/edition size schemes on fxhash

    • If you’ve sold previous work on fxhash or elsewhere, what was the average selling price?

    • Do you anticipate releasing often or seldomly?

    • From an external perspective, how much would you be willing to spend to collect an interation of your project?

    Once you've answered these questions, you should have an idea of where you’d like to price your upcoming project.

    Considerations for Established Artists

    If you have an active collector base and are ready to release a new project on fxhash — pricing becomes much more complicated and may require extensive consideration. Below is a list of recommendations to employ while determining the price of your work.

    Median floor price What is the median floor price of your work across your collection of projects? For example, if your median floor price is 250 XTZ across two previously minted projects on fxhash — 250 XTZ may be the ideal starting price (fixed or DA) for your next release.

    Hype and botting consideration Established artists are typically targeted by bot networks that have the potential to mint out projects instantly. With this in mind, it’s recommended to price your upcoming project at a price that will deter bots while allowing real collectors a chance to purchase your work. To do so, fxhash enables artists to harness Reserve Lists (Allow Lists) and Dutch Auction.

    Dutch Auctions generally favor a very high starting price, decreasing over time to more attractive prices for collectors of all levels. Although bots may still present a problem at a Dutch Auction's lower levels, more collectors are likely to purchase your work than if you had yet to employ the DA mechanic.

    Example 1: You want to avoid an instant mint of your new 256 edition project that’s receiving a lot of hype on Twitter and Discord. Instead of using a fixed price mechanic of 250 XTZ, you can set the DA to 1,000 - 750 - 500 - 250 - 100 XTZ. In this example, the artist provides a range, and the market participants (collectors) determine the fair and final value. Suppose you want to avoid utilizing the DA mechanic but want to ensure your work gets into the hands of previous collectors. In that case, the Reserve List is an excellent method to generate a list of prior supporters’ wallets. Whether you choose to produce a 100% Reserve List or a 50% AL/50% Public FCFS (or any other ratio) is your decision. Example 2: You want to reward your collector base by ensuring they have unencumbered access to your upcoming 500 edition project. You can generate a list of wallets that hold at least one of your previous works and then use a lottery system to pick 500 winning wallets. Once the mint is live, only these 500 Allow Listed wallets can access the project. After a predetermined time, you can open the project to the general public on a FCFS basis if the project is not minted out. In this example, pricing is flexible due to the absence of bot networks.

    Example 3:

    Similarly to Example 2, you could also over-allocate the allowlist, meaning that more collectors are allowed to mint than the project's edition size. This encourages minting, as supply is less than demand. After a predetermined time, you can open the project to the general public on a FCFS basis if the project is not minted out. In this example, pricing is flexible due to the absence of bot networks.Read more on reserves in the Reserves documentation.

    A Note on Market Dynamics

    Overall, artists should understand the constant shift in market dynamics. In general, instant mints are detrimental to new and established collectors alike. Higher prices are generally known to slow minting speed but also produce a barrier to entry of its own to new collectors. Established artists should understand that fluctuating market dynamics make it incredibly challenging to find the ideal price to satisfy everyone. However, fxhash offers a wide range of useful tools that allow the market to determine a fair value (Dutch Auctions) and the ability to show your appreciation to previous collectors with Reserve Lists.

    Ultimately, it’s your decision to price your work as you see fit, but hopefully, this document helps you find the ideal balance while pricing your work on fxhash. If you’re still experiencing issues regarding pricing, please head over to the # | artist-support channel on **our Discord.**

    Platform Fees and Royalty Fees

    Because Tezos and Ethereum are two different chains with their own characteristics, each one requires its own approach to fees — so you will find two different fee structures on fxhash depending on the chain.

    A pillar of the fxhash vision is ensuring artists take home as much of their earnings as possible, we want you to make a living from your art, no matter who or where you are. We believe our fee structure is a reflection of that vision, and hope you find it fair as well. As far as collectors are concerned that engage with the secondary market, we seek to achieve a balance that enables them to enjoy the proceeds from a sale as well.

    Hence our fee structure aims to minimize platform fees while maximizing the takeaway for everyone using fxhash:

    • Ethereum fees:

      • primary sales: 10%

      • secondary sales: 25% of royalties, no marketplace fee

    • Tezos fees:

      • primary sales: 5%

      • secondary sales: 2.5%

    Please take a moment to understand the ethereum fee structure. There is no traditional fixed marketplace fee — instead, the only amount taken from a secondary sale is 25% of the royalties set by the artist. Let’s have a look at an example and see how this is broken down - in a 1 eth secondary market sale for an artwork set with 10% royalties:

    • The seller receives .9 eth from sale

    • The artist receives .075 eth from royalties

    • fxhash receives .025 eth from royalties

    This dynamic fee structure enables us to forego having a traditional fixed secondary marketplace fee and takes artists, buyers, and sellers into account. All the while fxhash retains the lowest fees of any generative art NFT platform today.

    ,
    burned
    ,
    re-rolled
    ,
    locked
    and
    evolved
    👇

    Mint

    Minting a new edition from an open-form collection incurs two fees for collectors:

    1. Purchase cost/price in art coin: X amount of art coins. This amount of art coins is escrowed (temporarily deposited) in the contract at time of purchase.

    2. Mint fee in Base ETH: a mint fee directly paid out to the artist. This mint fee is initially set to be the same for all projects on fxhash. A minimum value applies to the mint fee.

    Both art coin price and mint fee are set by the artist.

    Editions collected from open-form projects are regular NFTs (ERC721 tokens) that can be traded and sold on secondary just like normal editions from long-form projects.

    Burn

    Collected (and evolved editions) of an open-form project can be burned by their holder (unless they are locked). This destroys the NFT and refunds the collector with the amount of art coins spent to mint or evolve it.

    There is no mint fee attached to burning an open-form edition.

    Traditionally, for ERC721 NFTs, "burning" means sending the NFT to a burn(er)/dead wallet, that isn't owned by anyone, and from which the NFT can't be retrieved anymore. In essence a crypto trash-can.

    Re-roll

    After you mint (or evolve) an edition, you can re-roll it to get a new one. In the background the NFT is burned and a new NFT with a different random hash is minted. This means that:

    1. The collector is first refunded with the amount of art coins they spent to initially mint/evolve the NFT.

    2. Then minting the new edition with a different hash will directly spend that same amount of art coins again (escrowing them in the contract again) and incur a mint fee in Base ETH.

    Effectively, re-rolling only incurs a mint fee in Base ETH.

    Lock

    Locking an open-form mint immutably locks its metadata. Once locked:

    • the NFT can not be unlocked anymore.

    • the NFT can not be burnt (and consequentially not re-rolled) anymore.

    • the NFT can now be evolved.

    Locking does not incur any fee. An open-form edition can be traded on the secondary market just like a regular NFT, whether it is locked or not has no influence on this. Locked mints remain locked even when traded.

    Locking an open-form mint permanently locks the escrowed art coins in the contract.

    Evolve

    Locked open-form mints can be evolved. Evolving a mint creates a new child NFT that is linked to its parent on the contract level. The child NFT receives its own random hash, in addition to inheriting its parent's random hash, it's parent's parent random hash, and so forth. In form of a list/array.

    In essence an evolved NFT has access to all random hashes that lie between itself and the root mint that it is a descendant of. We call this a lineage.

    How this evolution mechanism is defined is entirely up to how the artist has configured their generative script. Learn more about programming an open-form generative artwork here.

    • Evolving does not destroy or consume the parent NFT.

    • An evolved edition can be burned, re-rolled, locked, and evolved, just like a normal open-form mint.

    Similarly to minting a new edition, evolving an edition incurs both a:

    1. Purchase cost/price in art coins: Escrowed in the contract just like before until the token is locked.

    2. Mint fee in Base ETH + evolution fee: Paid out to the artist, fxhash, in addition to holders of the evolved token's lineage parents. Explained in more detail in the Lineage royalties & evolution fee section.

    Summary

    Action
    Action Cost (in Art Coin)
    Circulating Supply
    Action Fee (in Base ETH)

    Mint

    -X

    Escrows X Art Coins

    -fee$

    Burn

    +X

    Releases X Art Coins

    –

    Reroll

    –

    Naturally, there is also a gas fee attached to all transactions above.

    Lineage royalties & evolution fee

    Evolving open-form mints adds an extra "evolution fee" on top of the base mint fee. This evolution fee increases based on how many times the edition has already evolved — in other words, how deep it is in its lineage. Each new evolution adds a flat amount to the mint fee, so the deeper the lineage, the higher the cost to evolve.

    Collectors earn royalties when their editions (or their descendants) are evolved. They receive a share of the base ETH mint fee paid during the evolution.

    Let’s use simple numbers to illustrate how the mint and evolution fees are distributed, assume the following dummy numbers for an open-form project:

    • Base mint fee: $1

    • Evolution fee: +$0.25 per depth

    • Current depth: 3 evolutions (Collector 3 holds the 3rd evolution)

    When a new collector evolves the third token in the lineage to create a new, 4th evolution, the total evolution mint fee to be paid by the collector:

    $1 (base fee) + $0.25 × 3 (depth) = $1.75

    This $1.75 is distributed as follows:

    • The artist receives $1.2375: $0.90 from the base fee (90%) + $0.1125 × 3 = $0.3375 from the evolution fees (90% of 50% of each $0.25)

    • Each prior lineage collector receives 50% of one $0.25 evolution fee:

      • Collector 3 (depth 3): $0.125

      • Collector 2 (depth 2): $0.125

      • Collector 1 (depth 1): $0.125

    • fxhash receives $0.1375: $0.10 from the base fee (10%) + $0.0125 × 3 = $0.0375 from the evolution fees (10% of 50% of each $0.25)

    Evolution fees are paid out to the previous 40 lineage collectors. If an evolved mint has more than 40 ancestral tokens, no royalties are paid out to any earlier collectors. For example, if a depth of 41 is evolved, collector #1 does not receive a royalty.

    This does not cap the actual fee however, which continues to increase with further evolutions even after a depth of 40 is reached—50% of the accumulated evolution is distributed in equal to those 40 collectors.

    For an initial period of time, open-form editions can be evolved by anyone, and not just their owner. Collectors will able to toggle this option on their collected NFTs later on, deciding if they make their collected editions available for others to evolve.

    Art coin price & scarcity dynamics

    Interacting with an open-form project—by minting, burning, locking and evolving editions—has a direct effect on the associated art coin's supply.

    • Minting a new edition, or evolving an already existing edition, temporarily removes that amount of art coins from the overall circulating supply. This amount of art coins is inaccessible as long as the NFT isn't burned.

    • When burning an edition, the collector regains the spent amount of art coins. These coins re-enter the circulating supply and can be sold by the collector for $FXH.

    • Locking an edition permanently locks the art coins in the contract, effectively removing them from the circulating supply.

    As more editions are permanently locked, the overall circulating supply shrinks. This means that a smaller number of coins is left for the market, and needs to be shared among collectors and traders.

    This doesn't immediately increase the art coin's value, but increases the art coin's scarcity—an indicator that there is demand for the project, which can place upward pressure on the value of the remaining coin supply.

    As the art coin's price fluctuates, depending on market activity, the effective price of a project in art coins regulates itself. This also depends on the effective price of the $FXH token.


    Dummy numbers to show how increasing the price per mint in an open-form edition locks a higher percentage of a fixed 1 million art coin supply (as mints are permanently locked).

    # of locked mints
    art coin price per mint
    % of locked supply

    1000

    5 $art

    0.5%

    1000

    25 $art

    2.5%

    1000

    50 $art

    5%

    1000

    100 $art

    How do artists profit from their art coin(s)?

    While open-form projects already provide a direct revenue stream through the mint and evolution fees, a project's associated art coin enables secondary streams of revenue. Artists can earn through:

    • Sale of their art coin holdings: artists are required to reserve a minimum starting supply when creating their open-form project and kicking off the bonding curve launch of their art coin—ranging anywhere between 10 to 30% of the art coin's overall 1M supply. With the success of the linked open-form project(s), the art coin's valuation will prospectively increase in value, allowing artists to capture this gain through the sale of these initial holdings. This can be done through the fxhash interface or a DEX.

    • Capturing liquidity pool transaction volume: when art coins graduate, the invested $FXH and the art coin reserve is migrated to a primary liquidity pool on the open market, through which the art coin can be freely traded. Artists receive 0.75% of the trades that happen on this primary art coin ↔ $FXH liquidity pool (0.75% of the cumulative volume).

      This 0.75% is also captured from the trades happening during the bonding curve launch.

    Revenue earned from an open-form project and its associated art coin depends on a number of factors as well as the selected starting parameters artists choose, we cover this in more detail and share some example scenarios in an upcoming page.

    Multi-project art coins

    One art coin can be linked to multiple projects. Artists can create an art coin:

    • for a single project.

    • for a series of projects.

    • for an entire body of work.

    Why link multiple projects to a single art coin? Similarly to how the supply of an art coin directly reflects interest in a single project, the same concept applies when the art coin is used as a shared currency by multiple projects.

    Artists seldomly release only a single project and call it a day—art coins make it possible to group projects in a continuous, liquid fashion and link them in more than just a semantic manner.

    • First Project: When launching the first project with a new art coin the artist sets how many art coins are required to mint or evolve an edition. This implicitly creates an edition size for the project based on the one million art coin supply.

    • For any future projects linked to the same art coin: the artist chooses the number of editions they want to allocate for the remaining supply of the art coin—the price per edition is then automatically calculated.

    This process can be repeated indefinitely, and the prices for earlier projects remain unchanged. Because the supply of art coins is fractional, the remaining supply of an art coin can always be allocated to new projects — even if most of it is already locked away by collectors minting and evolve.

    An important note here, is that linking a new project to an existing coin is not the same as updating the code of the same current project.

    Much lower transaction fees than on mainnet Ethereum

    Smart Contract Language

    Michelson

    Solidity

    Solidity

    Governance

    On-chain governance

    Off-chain governance

    Inherits governance from Ethereum (Off-chain)

    Scalability

    Designed for scalability with regular upgrades

    Struggling with scalability limitations, undergoing upgrades

    Aims to improve scalability of Ethereum

    Focus

    Scalability and future-proofness

    Decentralization and programmability

    Faster transactions and lower gas fees that mainnet Ethereum

    Link to Tweet

    Primary Market

    This section provides an overview of fxhash’s primary market functionalities, where collectors participate in the initial release of generative tokens, in addition to a run-down of the interfaces

    fxhash's primary market is where new generative artworks are sold for the first time, directly from creators to collectors. On fxhash, collected generative artworks are created at the moment of purchase: when a collector buys an edition from an artist's generator, a contract is initiated, and a new token is issued on the blockchain. In essence, the artists code is run, and new asset is issued on the blockchain. This token represents the artwork, establishes its provenance, and can be sold or traded later on, much like any regular NFT.

    fxhash offers artists various ways to configure the sales mechanics for their generators, including setting token prices and controlling how collectors acquire them. For example, in addition to the standard method where collectors mint random iterations, fxhash also allows for custom minting experiences using fxparams.

    In the following sections, we provide a detailed overview of the interfaces that facilitate primary sales on fxhash and explain the relevant UI elements, ensuring collectors have a clear understanding of their purchases.

    Exploring Projects on fxhash

    While there’s a couple of different ways to scour for upcoming releases, either by following your favorite artists over on social media, or via third party discovery tools. However, fxhash's explore page provides the most direct way to do so, via an interface that provides filterable list of upcoming projects and currently minting ones.

    When you find a project that you’re interested in collecting, clicking on it will take you to its dedicated project page.

    Project Page Overview

    fxhash automatically sets up an individual project page for each generator that is published on the platform (sometimes also referred to as minting page). This page displays all of the relevant information that the artist has configured, such as the project’s title, its price and pricing method, a description, as well as a preview of the artwork itself that’ll let you generate any number of preview variations:

    Collecting on primary is most commonly done from this project page; it is advised to go over the information displayed here prior to collecting. Here you’ll find information about the price of the project and some of the options for collecting it:

    #
    Label
    Description

    Verified Artists

    The profile icon and name of the project’s creator. Here it’s important to look out for the checkmark next to the artist’s name - it indicates that they have been verified by the fxhash team (you still need to do your due diligence in this regard and check that projects are actually original works).

    If the project is a collaboration between multiple artists, the UI will indicate multiple profile icons:

    Mint Status

    An indicator visualizing how many iterations of the project have been sold already, and how close the project it is to ‘minting out’. While open editions are an option (meaning that collectors can mint indefinitely from the generator), artists often choose to limit the number of artworks that a generator can spawn.

    A project is only considered “fully minted” or “minted out” once all its available editions have been collected. In the case of open editions, artists may or may not choose to put a limit after a certain amount of time has elapsed, or make them time-limited right from the get-go. There’s a number of different states that this indicator can come in, here are some examples:

    1. This project is an edition of 100, of which 70 have been collected, and 30 are still available.

    2. This project is fully minted - the checkmark indicates that no more iterations can be collected.

    3. This project is an edition of 512, 256 of which have been collected and the other 256 have been burned (made unavailable by the artist)

    Mint Iteration / Ticket

    This button will trigger the collect transaction in your wallet. If you don’t have a wallet connected yet it will ask for that instead - depending if it is a Tezos or Ethereum project it will trigger or ask you to connect a compatible wallet with the chain. You can learn more about and .

    Before confirming this transaction always make sure that the gas fees are reasonable (mainly when collecting on mainnet ETH where gas fees can be significant sometimes).

    Project Number/Contract

    For Tezos projects this indicates the project number, whereas for Ethereum projects this will indicate the contract address of the project. This is because Tezos projects are all minted on the same fxhash marketplace contract, whereas ETH projects are minted on their own individual contracts.

    Labels

    Labels are special indicators that artists need to toggle at the time of publishing their projects. They are there to indicate certain aspects of the project, such as Epileptic Triggers if the project has flashing images, or a Sexual content label if the project involves this kind of imagery.

    • Onchain/IPFS: whether a project is stored with ONCHFS or with IPFS.

    • Epileptic Trigger

    • Sexual Content

    • Sensitive Content (blood, gore, …)

    Sale Details

    Scrolling a little further down, after the project’s description, additional information about how the primary and secondary proceeds of a project is distributed can be seen:

    Pricing Methods

    1. Fixed Price: When artists set a fixed price, iterations can be collected for the exact price that is indicated on the project page. Artists do have the ability to change this price after the project has been published, but this only affects un-minted iterations that are still available and doesn’t have any retroactive impact.

    2. Dutch Auction: Artists can also sell their Generative Tokens via dutch auctions. In a dutch auction the price of the project decreases over a given period of time, in set time intervals, until settling at a minimum asking price. Here’s an example:

      This gives incentive to collectors to purchase at a higher price if they want to claim an iteration from the piece early on, to prevent missing out when iterations might mint out more quickly as the price decreases.

    One other thing of note, is that the indicated prices on fxhash do not include gas (networks) fees, which may vary at different times throughout the day and week. Your wallet will indicate the final price before asking you to confirm the transaction.

    Payment Methods

    To acquire editions, fxhash currently provides two payment methods for collecting on fxhash.

    1. Wallet Mint: The main way to collect editions from fxhash projects is by doing so directly via a connected software wallet - clicking on the ‘mint iteration’ button will generally trigger a compatible wallet (ETH or Tez) that you’ve set up your fxhash account with, and then ask you to confirm the transaction. The collected NFT should then show up in your collection after completion of the transaction.

    2. Credit Card Mint: Because it is sometimes difficult to fund your wallets with crypto currency, fxhash also makes it possible to easily collect projects via Credit Card. Clicking on the ‘Credit Card’ button will trigger our current credit card payment provider Wert to effectuate the purchase - naturally you still need a wallet to receive the collected GETNK, hence if your wallet is not connected it will prompt you to do so now.

      After that you need input some information for KYC/compliance purposes, in addition to your card details. Before confirming the purchase, Wert will also indicate the gas (network) fee, and a processing fee (5% of the total):

    A Note on the current Credit Card Payment Provider: previously fxhash has relied on Winter as a credit card payment provider. Winter has recently been acquired by crossmint and will be integrated as one of their products. Winter will no longer be used as a CC payment option after end of March 2024 - Until crossmint fully integrates. In the interim fxhash will rely on Wert for this purpose.

    Learn more about funding your wallets in the .

    Custom Mint Experiences

    fx(params) allows artists to set up an interactive minting experience, where collectors can customise the generative artwork, either via the standard fx(params) interface or a custom one before the final NFT is immutably written to the blockchain.

    Depending on what kind of project it is, collecting a project will either yield a new, never seen before edition/iteration of the project directly in your wallet, or alternatively a mint ticket via which the final iteration can configured with the fx(params) feature. We cover how fx(params) works from the collectors POV in .

    Motivations

    Existing solutions and their drawbacks

    In order to properly understand why onchfs improves upon existing solutions, it's worth looking at the state of the space.

    Art Blocks

    The current solution used by Art Blocks revolves arround storing a raw javascript code on-chain, as well as the script dependency (p5js, etc...). Only the javascript part of the project is stored, so either they have to

    Let's look at a practical example, with a the wonderful project . If we query the Smart Contract view projectScriptByIndex(457, 0), a string is returned (note that the string has been truncated for practical purposes):

    Under the hood, Art Blocks is storing the string as bytes using contract code storage, see contract for reference:

    This flow roughly works as follows:

    • artists only upload the raw JS portion of their project

    • they specify a dependency, among those made available by Art Blocks

    • the string is stored as-is, without compression (using UTF-8 encoding)

    • the JS part of the project can be retrieved from the contract

    It should be known that some Javascript code, especially the one directly returned by Art Blocks contracts, cannot be executed by itself. A web browser needs to see a valid HTML document it can interpret, which references javascript a way or the other. Moreover, there needs to be a mechanic where iteration inputs are injected so that they are accessible via Javascript. There needs to be a process where an HTML string is built from the various inputs: libraries, inputs, and code. We believe Art Blocks is using an off-chain process to compose such a string (which by the way is perfectly fine, as proper specifications will allow such reconstructions to easily happen in the future). The full HTML string for Torrent looks like this:

    In essence, something like the following pattern is used to compose the actual HTML output:

    It's interesting to note a few things with this approach:

    • the HTML string is built off-chain (it could be built on-chain, as a matter of fact we'll look at such an implementation afterwards)

    • the template defines strict rules which can interfer with some artistic practices

    • libraries are handled by an authority, there is no way to ensure a library is actually properly served by the authority

      • in such a case we trust

    As denoted along many of the points, while the Art Blocks approach works for Art Blocks, it unfortunately doesn't translate well at all in open ecosystems.

    Scripty & EthFS

    While ArtBlocks has pionereed Generative Art code stored on-chain, others have improved upon their solution to address some of what they considered to be issues (or sub-optimal solutions) in the Art Blocks approach. One of these projects is , a set of contracts/tools to handle on-chain code storage and delivery.

    While scripty improves upon a few points, it's worth noting it follows similar principles as Art Blocks conceptually. The main differences are:

    • HTML reconstruction on-chain: no need for an external process; the full HTML script can be exported from the contract directly

    • data compression (mostly gzip)

    • better handling of libraries: shared between "scripty apps" (leveraging EthFS under the hood), still provided manually by artists

    This is a fair improvement, however it still fails to address what we consider to be important issues, mainly revolving around artistic interference & lack of safety & decentralization in handling libraries (due to the inherant nature of ethfs not being fully content-addressed).

    Code of Conduct

    fxhash’s code of conduct

    At fxhash, we are committed to fostering a positive and inclusive environment where all individuals are treated with respect and dignity. We aim to create a fair and safe environment for both artists and collectors. By being a part of our community, you agree to adhere to the following code of conduct:

    1. Respect and Inclusivity: Treat all members with respect, kindness, and consideration, regardless of their background, identity, or beliefs. Embrace and celebrate diversity, recognizing that our differences make us stronger. Racism, sexism, transphobia, homophobia, ageism, or any other form of discrimination will NOT be tolerated.

    2. Harassment-Free Zone: fxhash has a zero-tolerance policy for harassment, bullying, or discrimination of any kind. Harassment includes, but is not limited to, offensive comments, unwelcome advances, and any form of intimidation.

    3. Inclusive Language: Choose inclusive and considerate language. Avoid offensive jokes, slurs, and derogatory remarks that may make others feel unwelcome.

    4. Open Communication: Foster an environment of open and constructive communication. Listen actively, be receptive to others' opinions, and engage in discussions with empathy. Disagreements are natural, but they should be approached respectfully.

    5. Reporting Violations: If you witness or experience a violation of this code of conduct, promptly report it to the fxhash team. All reports will be taken seriously and handled confidentially.

    6. Consequences: Violations of this code of conduct may result in appropriate actions, including warnings, temporary suspension, or permanent moderation, as deemed necessary.

    Remember that fxhash is a shared space where everyone deserves to feel safe and valued. By abiding by this code of conduct, you contribute to creating a welcoming and supportive community for all. Beyond this there are a specific guidelines when it comes to creating and collecting projects on fxhash.

    p5.js Web Editoreditor.p5js.org
    p5.js Web Editoreditor.p5js.org
    Why Love Generative Art? — ArtnomeArtnome
    Timeline - Le RandomTimeline - Le Random
    The Rise of Long-Form Generative Art | Tyler HobbsTyler Hobbs
    fxhash-boilerplate/fxhash.min.js at master · fxhash/fxhash-boilerplateGitHub
    You can find the latest and up to date snippet here.
    Canvas API - Web APIs | MDNMDN Web Docs

    fxparams API Reference

    Detailed explanations of the individual API functions related to fxparams

    Function
    Function Signature
    Purpose Effect

    Genart on the Blockchain

    An introduction to Generative Tokens and GENTKs.

    In contrast to traditional NFT marketplaces, where the purchase of a digital asset simply involves a transfer of ownership between seller and collector, fxhash introduces a new paradigm for the distribution of code generated artworks. Instead of having generative artists mint individual outputs from their generative systems as NFTs, they can now mint the code itself such that it acts as a generator for digital collectibles. On fxhash we refer to these artist created generative systems as Generative Tokens.

    Collectors can then acquire ownership over individual outputs produced by these Generative Tokens. We refer to the collected outputs as GENTKs.

    By providing the technological infrastructure and a web based interface, fxhash facilitates this tokenization process and streamlines the distribution of generative art in form of digital tokens on the blockchain. In this section we'll have a closer look at the intricacies of how fxhash handles the distribution of code generated artworks.

    What is ONCHFS?

    ONCHFS is a file storage system that improves security, interoperability, and flexibility for on-chain generative art.

    The idea for ONCHFS came together when fxhash geared up for it’s 2.0 launch in December of 2023. Alongside integrating fxhash into the Ethereum eco-system, we also wanted to provide artists with the possibility to store their projects fully onchain, as an alternative to the default IPFS based storage method. This led us to investigate the current state of onchain storage for genart projects, and how other platforms were doing it.

    One common approach can be describe as html reconstruction, which generally involves 2 things:

    • JavaScript code proper to the project in question, uploaded as a string, and usually encoded, minified, and compressed in various ways.

    • A list of dependencies pointing to scripts previously uploaded by a central entity. In most cases without the option for users to upload additional libraries for others to use in a convenient way.

    The actual content is stored in a Content-Addressable Store, and some logic is responsible for reconstructing the chunks of content into digestable files. Two notable projects towards that end are:

    • ethfs: general-purpose Content-Addressable Store + shared name-based file system

    • scripty: HTML reconstruction built on top of ETHFs

    While this approach provides on-demand HTML reconstruction as long as a node is available, it presents strong disadvantages for what we would consider to be a long-lasting backbone for an open Generative Art ecosystem:

    • interferences on artistic practices: artists have not only to think about implementing each platform API for their project to be compliant, but also they must obey to some predefined code structure as eventually their whole code is going to be one string

    • inter-operability between assets: while file data is content-addressed, files are addressed by their name on the system; this introduces major inter-operability issues as user can never fully trust some name faily describe the data it contains

    • security, vector for Supply Chain Attacks: users have to rely on central entities to provide a list of verified files, which in essence can be composed of any arbitrary data which can only be verified by querying and inspecting such file. This introduces a vector for injecting malicious code in what would seem to be a legit and trusted file (imagine embedding a wallet drainer which would trigger past a given date on a file named processing-1.3.1.min.js, yet exposing all the features of its valid counterpart). While this approach may work for centralized & semi-centralized platforms, if we want to build an open ecosystem where anyone can provide libraries for public access, such system cannot fully be trusted.

    • too specialised: outside of HTML reconstruction, it becomes hard to extend current approaches for any kind of file-based application

    ONCHFS aims at solving what we consider to be core issues, at a cost we consider to be negligable. To give a quick overview, our approach solves all the points above but requires a file resolver (which can be an http-proxy or a service worker).

    Artists' Code of Conduct

    Collectors' Code of Conduct

    Logo
    Logo
    Logo
    How innovative your project is: does your project stand out aesthetically and/or technically from the project that currently exist on fxhash?
  • The amount of work/time that went into your project: how long did it take to complete the project? What would you consider a fair price for the amount of effort that went into your project?

  • —

    -fee$

    Lock

    –

    Locks X Art Coins

    –

    Evolve

    -X

    Escrows X Art Coins

    -fee$

    10%

    Terms and Conditions

    ßGENERAL CONDITIONS OF SALE AND USE FX HASH EFFECTIVE AS OF 31/05/2023 TERMS OF SALES The FXHASH FOUNDATION platform (the “Marketplace”) allows professional and non-professional collectors who have reached legal majority in their country of residence (the “Collector” or the “Collectors”) and creators, professional or not, who have reached legal majority in their country of residence (the “Artist” or the “Artists”) to:

    • convert their original creations into Non-Fungible Tokens (“NFT”) and store the NFT metadata on an Interplanetary File System (IPFS) infrastructure; or store the creations on-chain

    • offer their NFTs to Collectors and conclude with them contracts for the sale of these NFTs against digital assets (“Primary Market”) The Marketplace also allows Collectors to resell among themselves the NFTs acquired from Artists (“Secondary Market”). The Marketplace is not the provider of the NFTs offered through the website https://www.fxhash.xyz (the “ Website”). It is recalled that NFTs are FA2 standard tokens on the TEZOS blockchain and which represent a digital object with unique characteristics. NFTs are not intended to represent rights of claim or to serve as a means of payment. The NFTs traded through the Marketplace are represented by a JSON file and are unique randomly generated iterations from a Generative Token, according to the terms indicated to Artists in the guide available at this url: https://www.fxhash.xyz/doc/artist/guide-publish-generative-token. NFTs are, therefore the subject of a property right but are not their representation and in this sense are excluded from the definition of digital assets given in articles L.552-2 and L.54-10-1 2° of the Monetary and Financial Code. NFTs are original variations of a creation that is itself original, and are therefore creations protected by copyright, within the meaning of article L.111-1 of the Intellectual Property Code. The present General Terms and Conditions of Sale (the "T&Cs") describe the methods of distance selling ("Transaction") of NFT through the Marketplace and define the obligations and rights of the Parties in this respect. In addition, the present T&Cs set out the terms and conditions of the contractual relationship between Artists and Collectors for the sale and shipment of tangible goods (the "Products") that may be ordered by Collectors when purchasing NFT. 1 ARTICLE 1- SCOPE The present General Conditions of Sale apply, without restriction or reservation, to all transactions concluded between the Artist and the Collector, and the Collectors between them, through the Marketplace, from its website: https://www.fxhash.xyz. The present T&Cs only concern relations between Artists and Collectors, and Collectors among themselves, who acknowledge being of legal age in their country of residence and have the capacity required to contract and acquire the NFTs offered on the Website. They therefore do not govern the relationship between Artists and the Marketplace, which are defined in the Artists’ General Terms and Conditions of Use (Artists' Terms of Use), nor the relationship between Collectors and the Marketplace, which are defined in the General Terms and Conditions of Use. Collectors (GTU Collectors), and which the present T&Cs supplement. Only the Artist, whose name is indicated on the descriptive sheet of each NFT, is the Collector's co-contractor for the Primary Market. Within the framework of the Secondary Market, the Collectors can resell the NFTs and have the quality of co-contractors. The NFTs cannot therefore be taken back or exchanged for another NFT by the Marketplace. They are accessible at any time on the Marketplace Website and will prevail, where applicable, over any other version or any other contradictory document. The present T&Cs may be subject to subsequent modifications, the applicable version is that in force on the Website on the date of the Transaction. ARTICLE 2- CHARACTERISTICS OF NFTs AND PRODUCTS 2.1- Characteristics of NFTs The NFTs offered for sale on the Marketplace Website are the subject of a description allowing the Collector to know their main characteristics, and in particular:

    • the name of the Artist as well as his descriptive sheet, including his profile photograph, his social network accounts, the url of his website, the creations and collections published on the Marketplace, his activity on the Marketplace, as well as its public receiving address on the TEZOS blockchain;

    • the name of the work, its description, its keywords (“Hashtags”) the project number as well as the token whose code represents the primary creation of the Artist (“Generative Token”) and which will generate randomly unique iterations of this primary creation, of which the NFTs offered for sale will be variations;

    • Statistics on NFT prices on the Primary Market and the Secondary Market, with indication of the highest, lowest, and median price for the sales concluded on the Marketplace, this being exchanged for TEZ tokens (XTZ) circulating on the Shared Electronic Record Device (the “Blockchain”) TEZOS. 2 The metadata of each NFT created through the Marketplace can be consulted by accessing the URL indicated by hypertext link (“view on IPFS”) on the description sheet. The Collector is required to read it before any acquisition of an NFT, the choice and acquisition of it being his sole responsibility. The photographs and graphics presented on the Website are non-contractual and cannot engage the responsibility of the Marketplace. The Collector is required to refer to the description of each NFT to know:

    • description, quantity, and quality,

    • the quality and performance characteristics, if these are different from those reasonably expected for a non-fungible token. The descriptive information is presented in English, but the Collector can obtain their translation via his browser. The NFTs available on the Marketplace site are offered for sale worldwide. Local duties or taxes may be payable, and will be the sole responsibility of the Collector purchaser. 2.2- Characteristics of the Products

    • Products offered for sale The main characteristics of the Products for sale on the Website, including all the substantial information required by the applicable regulations and in particular the specifications, illustrations and indications of dimensions or capacity of the Products, are presented on the Website in the product sheets. The Collector is obliged to read them before placing an order. The choice and purchase of a Product are the sole responsibility of the Collector. The photographs and graphics presented on the Website are not contractual and do not engage the responsibility of the Marketplace. The Collector must refer to the description of each Product in order to know its properties, essential characteristics and delivery times, as well as, in the case of continuous or periodic supply of a good, the minimum duration of the proposed contract. The contractual information is presented in French or English and is confirmed at the time of validation of the order by the Collector. The Collector acknowledges that he/she has the capacity required to contract and acquire the Products offered on the Website.

    • Placing the order 3 It is up to the Collector to select the Products he/she wishes to order on the Website. The Collector has the possibility to check the details of his/her order, its total price and to correct any errors before confirming his/her acceptance. It is the Collector's responsibility to check the accuracy of the order and to report or rectify any error immediately. The registration of an order on the Website is carried out when the Collector accepts the present T&Cs by confirming the transaction provided for this purpose and validates his order. This validation implies acceptance of the entirety of the present T&Cs. The sale is final only after the Artist has sent the Collector confirmation of acceptance of the order by e-mail, which must be sent without delay, and after the Artist has collected the full price due. Any order placed, validated by the Collector and confirmed by the Artist, under the conditions and in accordance with the procedures described above, on the Website constitutes the formation of a contract concluded at distance between the Collector and the Artist. The Collector may follow the progress of his/her order on the Website. Once confirmed and accepted by the Artist, under the conditions described above, the order cannot be modified. Once confirmed and accepted by the Artist, under the conditions described above, the order cannot be canceled. ARTICLE 3- WARNINGS ON RISKS By accepting the present T&Cs, you acknowledge having been informed of the risks associated with the acquisition of non-fungible tokens created and exchanged through the Blockchain. You should be aware of the specific risks associated with non-fungible tokens and associated products and services, in order to carefully assess whether the risks are acceptable given your preferences and personal financial situation. In particular, you risk:

    • losing your invested digital assets;

    • to see prices fall and rise rapidly over short periods of time, the price of NFTs not being regulated and freely set by the law of supply and demand;

    • to be the victim of scams, fraud, operational errors or cyberattacks, however, the Platform has taken reasonable steps to limit such scenarios;

    • not to be able to claim any protection or compensation in the event of a problem. Consequently, Collectors acknowledge being informed that Artists (in the context of the Primary Market) or Collectors (in the context of the Secondary Market) cannot guarantee the interoperability of the NFTs offered for sale, i.e. the ability for legally acquired non-fungible tokens to remain available without restriction of access or implementation, regardless of the software or hardware environment in which they are provided. 4 You also acknowledge being informed that neither the NFTs nor the Blockchain are affected by the obligation provided for in article L.111-6 of the Consumer Code, which only concerns internal software applications and therefore developed by the supplier, which excludes decentralized applications and technologies. The Marketplace exercises no control over the quality or conformity, either of the creation represented by the NFT, or of the information given by the Artist (on the Primary Market) or the Collector (on the Secondary Market). The Marketplace is not responsible for any loss of NFTs, or price fluctuations that are related to supply and demand. The Collector expressly acknowledges that pursuant to Article L.224-25-14 III of the Consumer Code, he may not invoke any lack of conformity related to the specificities of the non-fungible token. ARTICLE 4- DURATION OF VALIDITY OF OFFER NFT's offers are within the limits of available stocks, as specified on the descriptive sheet supplemented by the information obtained from the Artist and/or Collector seller. ARTICLE 5- TERMS OF TRANSACTION The purchase of NFTs offered on the Marketplace is done exclusively in TEZ (XTZ) which is the protocol token of the Blockchain TEZOS. The TEZOS blockchain is used for the deployment of smart contracts (“Smart contract(s)”) allowing you to create (“Mint”) as well as circulate (“Transfer”) NFTs. To use our services, you must therefore have a wallet (“Wallet”) composed of a private key and a public key on the TEZOS Blockchain. To use our services, this Wallet must be connected to the Marketplace by clicking on the "SYNC" button at the top right of the site and following the steps indicated. The process of creating and integrating the TEZOS Wallet is explained in detail in our documentation: https:// www.fxhash.xyz/doc/collect/guide As part of the Primary Market, the Collector has the option of going to the page of the selected Generative Token and “minting” an NFT which represents a unique iteration of the Generative Token, and validating the Transaction by clicking on the “mint iteration” button " with the indication of the counterpart in TEZ (represented by the symbol ÿ). This validation entails the acceptance of all of the present General Conditions which are encoded in the metadata of the NFT on IPFS, which can be consulted on the Website. A confirmation of the Transaction is sent to the Collector's Wallet, which must validate it. The Transaction is sent on the TEZOS Blockchain and materializes by the Transfer of the NFT in the Wallet of the acquiring Collector and the payment of the sale price to the public address communicated by the 5 Artist (Primary Market) or the Collector seller (Secondary Market ) minus the costs specified in Article 7 hereof. The Transaction materializes both the sale and the Transfer of the NFT. During the time required to generate the metadata of the NFT, it will appear in white with the mention "waiting to be signed". Once the Transaction has been validated by the Collector-purchaser on his Wallet, it becomes final and the NFT purchase process is irrevocable. It cannot be cancelled or modified. The Collector must therefore check his purchase before validation. ARTICLE 6- EXCLUSION OF THE RIGHT OF WITHDRAWAL Articles L. 221-28 2° and 13° of the French Consumer Code specify that "the right of withdrawal cannot be exercised for contracts:

    • the supply of goods or services whose price depends on fluctuations in the financial market beyond the control of the trader and which may occur during the withdrawal period; and

    • the supply of digital content not provided on a tangible medium, the performance of which has begun after the consumer has given his express prior consent and expressly waived his right of withdrawal". Pursuant to these texts, the User expressly acknowledges and accepts that the right of withdrawal cannot be exercised for transactions involving crypto-assets/NFTs. The user wishes that transactions involving NFTs be carried out immediately. Therefore, the user expressly agrees in advance and expressly waives his right of withdrawal. ARTICLE 7- PRICES CONDITIONS The prices are indicated excluding taxes in TEZ () and are payable in cash. 7.1- Fixing the price of the NFT 7.1.1- Primary market The NFTs are sold at the price freely set by the Artist, appearing on the NFT's description sheet, in compliance with the laws and regulations in force. This price must be mentioned on the description, all taxes and costs included, but excluding transaction costs linked to the use of the Blockchain network. It is reminded in this respect that the Marketplace is not subject to the "VAT Package" since Blockchain technology does not allow the public address for receiving the NFT after Transfer to be located in a given territory. 7-1-2 Secondary Market fxhash does not intervene, arrange or more generally participate in the conclusion of the sale between Buyers and Sellers on the Marketplace in any way, nor does it intervene in any way in the 6 choice and/or price of the Collectibles subject to the Offers on the Marketplace. fxhash is not a party nor an agent to the sale or purchase of a Collectible on the Marketplace, and fxhash does not act as an execution intermediary for the bilateral or multilateral matching of the interests of Buyers and Sellers. This means that fxhash will not arrange and/or match potential buying interests of the potential Buyers to Collectibles posted for sale by the Buyers, or otherwise direct Offers to potential Buyers. You are solely responsible for your offers to sell or buy Collectibles; we make no claims regarding any Offer, Seller, price, Buyer, and/or Collectible value. Taxes. As a matter of principle, the Seller is responsible for all taxes, duties, and levies due in respect of the transaction it enters into with a Buyer. It is reminded in this respect that the Marketplace is not subject to the "VAT Package" since Blockchain technology does not allow the public address for receiving the NFT after Transfer to be located in a given territory. 7.2- Fixing of the fee due to the Artist In order to allow the Artist to benefit from the valuation of his works offered through the Marketplace, each NFT is accompanied by a fee separate from the acquisition price and the amount of which is freely set by the Artist. Its amount is indicated on the NFT description sheet. 7.3- Amount actually paid by the acquiring Collector The price actually paid by the Collector (“Total of the Transaction”) includes the price of the NFT the royalty due to the Artist, the mining costs associated with the recording of the Transaction on the Blockchain, and the Marketplace commission. The Marketplace commission is set at:

    • 5% of the amount excluding tax of the sale expressed in TEZ for the Primary Market;

    • 2.5% of the amount excluding tax of the sale expressed in TEZ for the Secondary Market. The Total Transaction does not include telecommunication costs which are the sole responsibility of each party. ARTICLE 8- TRANSFER OF OWNERSHIP AND TRANSFER OF RISK 7 The transfer of ownership of the NFT from the Artist to the Collector (Primary Market) or from the Collector-seller to the Collector-buyer (Secondary Market) will be carried out as soon as the Transaction is completed, materializing the agreement of the parties on the thing and on the price. ARTICLE 9- DELIVERY OF ORDERED PRODUCTS AND RESPONSIBILITY OF THE ARTIST/SELLER/PLATFORM Delivery of the Products means the transfer to the Collector of physical possession or control of the Products ordered. The Products ordered by the Collector will be delivered within the timing indicated on the Product sheet, plus the processing and delivery time, to the address indicated by the Collector when ordering on the Website. The Artist/Seller/Platform (depending on the selling entity) undertakes to do his or her best to deliver the products ordered by the Client within the time limits specified above. However, these deadlines are given as an indication. Deliveries are made by an independent carrier, to the address mentioned by the Collector at the time of the order and to which the carrier will have easy access. The Collector therefore acknowledges that it is the carrier's responsibility to make the delivery and has no recourse in warranty against the Artist or the Marketplace in the event of failure to deliver the goods transported. The Collector is required to check the condition of the products delivered. He/she has a period of seven (7) days from delivery to formulate by e-mail any reservations or claims for non-conformity, defect or apparent vice of the delivered Products (e.g. damaged package already opened, etc.). After this period and if these formalities are not respected, the Products shall be deemed to be in conformity and free of any apparent defect. WITH REGARD TO THE SALE AND DELIVERY OF THE PRODUCTS, THE RESPONSIBILITY FOR THEIR QUALITY, THEIR CONFORMITY AND THEIR DELIVERY LIES SOLELY WITH THE ARTIST AND POSSIBLY THE CARRIER, BUT IN NO CASE WITH THE PLATFORM/MARKETPLACE. ARTICLE 10- SELLER’S LIABILITY AND WARRANTY The NFTs sold through the Marketplace comply with the regulations in force in France and have performances compatible with the expected uses of non-fungible tokens. The Collector acknowledges and accepts that the guarantee provided for in articles L. 224-25-16 and following of the Consumer Code is not applicable, neither the Artist nor the Marketplace can be considered as the "Producer" within the meaning of the definition given by Article 1 of Ordinance No. 2021-1247 relating to the legal guarantee of conformity for goods, digital content and digital services ("the manufacturer of a good, the importer of property in the European Union or any other person who presents himself as a producer by affixing his name, trademark or other distinctive sign to the property ") 8 of "digital content" (" data produced and supplied in digital form ") since the digital content and associated services offered on the Website are carried out by an automated computer program (“Smart Contract”) deployed on the Blockchain in a totally decentralized manner and without the intervention of a centralizing third party. The Collector acknowledges taking the NFT as is and the warranty for hidden defects is excluded. In any case, the responsibility of the Artist (Primary Market) or the Collector (Secondary Market) cannot be engaged for the following cases:

    • Non-compliance related to blockchain technology;

    • Non-compliance related to NFT price volatility;

    • Non-compliance related to the incompatibility between the NFT and the computer hardware of the Collector;

    • Non-compliance related to the non-compliance by the Collector with the legislation of his country;

    • Non-compliance related to the Collector's negligence or misuse of the NFT, in particular in the event of use not conforming to the expected use. ARTICLE 11- PROTECTION OF PERSONAL DATA Pursuant to Law 78-17 of January 6, 1978, amended by Law No. 2018-493 of June 20, 2018, it is recalled that the personal data requested by the Marketplace are for identification purposes for the protection of the parties and limiting fraud. This data may under no circumstances be used for other purposes. Each selling Artist or Collector only has access to the public address of the acquiring Collector's Wallet during the Transaction. The Collector has the option of publishing a profile with a nickname that is authenticated on the Blockchain, but this data is not collected by the Marketplace. The processing of data collected by the Marketplace meets the legal requirements for the protection of personal data, the information system used to ensure optimal protection of this data. The holder of personal data that has been processed by the Marketplace has, in accordance with the national and European regulations in force, a right of permanent access, modification, rectification, opposition of portability and limitation processing with regard to information concerning him. These rights can be exercised by writing to the address indicated in article 13-2 hereof. ARTICLE 12- APPLICABLE LAW - LANGUAGE The present T&Cs and the resulting operations are governed by and subject to French law. They are written in French. In the event that they are translated into one or more foreign languages, only the French text shall prevail in the event of a dispute. 9 ARTICLE 13- PARTIAL NULLITY If one or more stipulations hereof are held to be invalid or declared as such pursuant to a law, regulation or final decision of a competent jurisdiction, the other stipulations will retain their full force and scope. ARTICLE 14- PRE- CONTRACTUAL INFORMATION 14.1- Acceptance The fact that a natural or legal person acquires an NFT on the Marketplace website implies full and complete acceptance of the present General Conditions, which are encoded in the metadata of the NFT that can be consulted on IPFS. 14.2- Contact Our contact information is as follows: SASU FXHASH FOUNDATION Address : 13 Place du Couvant 43150 LE MONASTIER-SUR-GAZEILLE RCS number (Le Puy) : 908 947 617 Intra-community VAT number: FR09908947617 Mail : [email protected] Phone number : (+33)642253709 ARTICLE 15- DISPUTES Any dispute relating to the interpretation and/or execution of the present T&Cs is subject to French jurisdiction. All disputes are settled directly between the Collector and the Artist, or between the Collectors. The Artist can be contacted:

    • through its social network account(s) accessible via the link(s) hypertext(s) present on his profile page.

    • Through the social network Discord, where the Collector has the possibility of contact by tagging his nickname. The Collector-seller can be contacted through the social network Discord, where the Collector-purchaser has the possibility of contacting him by tagging the nickname of his profile authenticated on the Blockchain. The Collector and the Artist, or the Collectors between them, will make their best efforts to reach an amicable resolution of the dispute. Depending on the case, the declared dispute may give rise to reimbursement of the NFT, under the conditions specified herein. 10 The Collector-purchaser is informed that he can in any case resort to conventional mediation, in particular with the Consumer Mediation Commission (C. consom. art. L 612-1) or with the FEVAD Mediator (https://www.mediateurfevad.fr/) or any alternative dispute resolution method (conciliation, for example) in the event of a dispute. ARTICLE 16- THIRD PARTY SITES AND APPLICATION The present T&Cs or the Marketplace site may include hyperlinks to other websites or resources (“Third-Party Sites and Applications”). The Marketplace has no control over the content or security of such Third-Party Sites and applications and may not be liable for any transactions carried out outside of our Marketplace. By clicking on a hypertext link, you acknowledge and agree to leave the scope of the Marketplace. The Marketplace cannot be held responsible for the unavailability of third-party Sites and applications or their content, or for any damage that may be incurred while browsing them. 11 GENERAL CONDITIONS OF USE - ARTISTS ARTICLE 1- OBJECT The FXHASH FOUNDATION platform (the "Marketplace") aims to connect professional or non-professional collectors who have reached legal majority in their country of residence (the "Collectors”) and artists, professional or not, who have reached legal majority, legal in their country of residence (the “Artists”), in order to allow Collectors to purchase from Artists, or other Collectors, through the Marketplace, non-fungible tokens (the “NFTs”). The present General Terms and Conditions of Use (the "T&Cs") define the conditions under which the Marketplace provides Artists with the technological tools allowing them to edit NFTs from their Generative Token and sell them to Collectors, such as presented on the website "https:// www.fxhash.xyz" (hereinafter "the Website") through the Marketplace. They supplement the General Conditions of Sale which govern sales made between Collectors and Artists, or Collectors among themselves, through the Marketplace. The present T&Cs are accessible at any time on the Website. The present T&Cs may be subject to subsequent modifications, the applicable version is that in force on the Website on the date of Transfer of the NFT. The fact for an Artist to use the services offered by the Marketplace entails full and complete acceptance and acceptance of the present T&Cs, which is expressly recognized by the Artist, who waives, in particular, to avail himself of any contradictory document, which would be unenforceable against the Marketplace. ARTICLE 2- SCOPE The present T&Cs apply, without restriction or reservation, to the use of the services and technological tools made available to Artists by the Marketplace. The Marketplace allows Artists to verify the execution and visualization of their Generative Token(s) in a secure environment via the "SANDBOX" tool, then to generate NFTs representing iterations of their Generative Token, to be linked with Collectors, to reference and describe the NFTs they offer for sale on the website, to collect the price, to transfer the NFTs. Sales made via the Marketplace within the framework of the Primary Market are concluded directly between the Collector and the Artist. ARTICLE 3- SERVICES OFFERED BY THE MARKETPLACE No registration is required to use the services, which are however prohibited to minor users in their country of residence. To protect Collectors, the Marketplace offers an identity verification device. Verified Artists have advantages over unverified Artists: 12

    • A certification badge next to their nickname

    • Exemption from locking their token for a period of 3 hours from their creation (“Mint”). Any information collected relating to the identity (and not the simple pseudonym) of the Artists can only be communicated to the judicial authorities, upon requisition. The verification process is explained in detail in our documentation: https://www.fxhash.xyz/doc/fxhash/verification In the event of non-compliance with the present T&Cs by the Artist, the Marketplace reserves the right to temporarily or permanently interrupt its access, by suspending or terminating the present Terms without notice or compensation. The Artist acknowledges and accepts that the guarantee provided for in articles L. 224-25-16 and following of the Consumer Code is not applicable, the Marketplace cannot be considered as the "Producer" within the meaning of the definition given by Article 1 of Ordinance No. 2021-1247 relating to the legal guarantee of conformity for goods, digital content and digital services ("the manufacturer of goods, the importer of goods into the European Union European Union or any other person who presents himself as a producer by affixing his name, trademark or other distinctive sign to the good ”) of “digital services” (“ allowing the consumer to create, process or store data in digital form or to access it, or a service allowing the sharing or any other interaction with data in digital form that is uploaded or created by the consumer or other users of this service ") since the digital content and associated services offered on the Websites are made by a Smart Contract deployed on the Blockchain in a totally decentralized way and without the intervention of a centralizing third party. Only the services offered within the framework of article 8 fall within the scope of this guarantee but are excluded from it since they are offered without financial or other compensation. ARTICLE 4- OBLIGATIONS OF ARTISTS The contracts for the sale of NFTs offered by the Artist on the Website within the framework of the Primary Market are concluded between the Artist and the Collector. The Artist expressly acknowledges having been informed that the service is exclusively reserved for adults and declares to be of legal age according to the laws of his country of residence. The Artist undertakes to make all declarations to the administrative and tax authorities related to his activity on the Marketplace, in his country of tax residence, in particular any declaration of VAT and/or exchange of goods and guarantees the Marketplace to this effect. The Artist is invited to consult the legal professional of his choice in order to determine whether the transactions concluded on the Marketplace are subject to VAT but cannot in any case engage the responsibility of the Marketplace in this regard. Indeed, it is specified that the Marketplace is not exposed to the "VAT Package" which entered into force on July 1, 2021, Blockchain technology not making it possible to locate the public transaction addresses which materialize the dispatch and delivery of NFT. 13 As soon as the turnover achieved by the Artist on the Marketplace reaches the threshold of €5,000 excluding taxes, he must justify the discharge of his social and tax obligations by producing a vigilance certificate, if based in France. (to know more: https://www.urssaf.fr/portail/home/employeur/declarer-et-payer/obtenir-une- attestation/attestation-de-vigilance.html). The Artists undertake to implement, in good faith, all necessary means to fulfill their obligations by delivering NFTs that comply with the description communicated for publication on the Marketplace. Professional Artists, who are required to identify themselves as such to Collectors on the Website and undertake to comply with the applicable legislation in the exercise of a commercial activity (in particular registration, accounting, social and fiscal obligations) as well as the laws and regulations applicable to NFTs sold through the Website. The Artists declare that they own the NFTs offered for sale on the Website or that they are duly authorized to sell them. In particular, Artists are prohibited from offering for sale infringing NFTs within the meaning of the Intellectual Property Code or whose marketing is regulated under legislative, regulatory or contractual provisions prohibiting or restricting the sale of NFTs through the Marketplace. The Artists are solely responsible for the sale of the NFTs that they offer on the Website as well as the description that they communicate to the Marketplace. Thus, they undertake to establish, in good faith, precise, exact descriptions that do not risk misleading Collectors on the NFTs offered for sale through the Marketplace, both in terms of their characteristics, price and value added tax. The visuals, in particular, must comply with the Generative Token and respect the rights of third parties, the Artists guaranteeing to the Marketplace that they have all the rights necessary to use these descriptive elements. The Artists are prohibited, in particular, from using visuals or other descriptive elements or making comments or other messages that would be offensive, contrary to public order or morality, which would infringe the rights of persons or the rights third-party intellectual property rights, laws and regulations, which could then temporarily or permanently interrupt access to its services, by suspending or terminating them under the conditions provided in clause 7. ARTICLE 5- REMUNERATION FOR MARKETPLACE SERVICES The Marketplace will receive, from the Artist, for each purchase of NFT made by a Collector on the Website, a commission equal to 2.5% of the amount of the NFT expressed in TEZ for secondary, with 5% for primary. ARTICLE 6- DISPUTES AND PROCESSING OF COMPLAINTS Collectors may, at any time, contact the Artists and send them any complaints concerning the NFTs ordered using the social network accounts whose URL is published on the Artist's description sheet, or via the Discord social network, by tagging the Artist's nickname. 14 As sales are concluded directly between the Collector and the Artist, the latter is personally responsible for complaints. Artists must favor the amicable resolution of disputes. ARTICLE 7- SUSPENSION OF ACCESS TO MARKETPLACE SERVICES Artists may stop accessing the services of the Marketplace, without having to justify a particular reason, subject to requesting the withdrawal of the Generative Tokens published and honoring the sales in progress. In the event of a breach of any of its obligations by the Artist under the present T&Cs, the Marketplace may, after notification sent to the social network account(s) communicated by the Artist , or on the Discord social network by a notification tagged with the Artist's username, permanently cut off access to its services immediately, in particular by blocking access to the member profile(s), without that the Artist can claim any compensation. ARTICLE 8- SPECIFIC PROVISIONS FOR THE USE OF THE SANDBOX AND THE FORM OF CREATION OF THE GENERATIVE TOKEN The Generative Token creation form is a feature that allows Artists to publish and store their Generative Tokens via the IPFS protocol in order to allow the generation of unique iterations that will be represented by the NFTs offered for sale. Artists can only publish new Generative Tokens during the times indicated on the site at the url: https:// www.fxhash.xyz/community/opening-schedule Thanks to the "SANDBOX" tool, Artists can check the execution and visualization of their Generative Token(s) in a controlled environment. The use of these services is free. The works uploaded to the Marketplace and encoded in the metadata of the Generative Token as well as randomly generated NFTs are the exclusive property of the Artists and are protected by French and international laws relating to intellectual property. On the other hand, the source code and the object code created specifically by the Marketplace, within the framework of the aforementioned services, are the exclusive property of the Marketplace and are protected by French and international laws relating to intellectual property. ARTICLE 9- PERSONAL DATA Pursuant to Law 78-17 of January 6, 1978 amended by Law No. 2018-493 of June 20, 2018, it is recalled that the personal data that may be requested from the Artist by the Marketplace are necessary, both for him guarantee access to Marketplace services only for the processing of NFT purchases. The Marketplace undertakes to ensure the security of the personal data it retains for the purposes of carrying out and tracking transactions. 15 The processing of information communicated via the Website meets the legal requirements for the protection of personal data, the information system used to ensure optimal protection of this data. The Artist has, in accordance with the national and European regulations in force, a right of permanent access, modification, rectification, opposition to portability and limitation of processing with regard to information concerning him. This right can be exercised by writing to the address indicated in article 14-2 hereof. ARTICLE 10- INTELLECTUAL PROPERTY The content of the Website that does not come directly from Artists or Collectors is the property of the Marketplace and its partners and is protected by French and international laws relating to intellectual property. Any total or partial reproduction of this content is strictly prohibited and is likely to constitute an offense of counterfeiting. ARTICLE 11- RESPONSIBILITIES It is recalled that the Marketplace is not the Seller of the NFTs. It can therefore in no way be held responsible for sales made between Collectors and Artists, to which it remains unrelated. NFTs cannot be taken back or exchanged by the Marketplace and any dispute relating to a sale transaction carried out via the Marketplace must be settled directly between the Collector and the Artist. The responsibility of the Marketplace with regard to the Artist can only be engaged for facts which would be directly attributable to it and which would cause the Artist direct damage, to the exclusion of any indirect damage. The liability of the Marketplace is excluded in the event of improper use of the services of the Marketplace by the Artist or fault on his part. Nor can it be held liable for facts attributable to a third party or to a foreign cause. The Artist guarantees and indemnifies the Marketplace at first request for any prejudice and against any action for liability that may be brought against the Marketplace as a result of the violation by the Artist of any right of a third party, including a Collector, whether this prejudice results from the sale of NFT, from the use made by the Artist of the services of the Marketplace or from any other fact attributable to him. ARTICLE 12- PARTIAL NULLITY If one or more stipulations hereof are held to be invalid or declared as such pursuant to a law, regulation or final decision of a competent jurisdiction, the other stipulations will retain their full force and scope. ARTICLE 13- APPLICABLE LAW 16 The present T&Cs and the resulting operations are governed by French law. They are written in French. In the event that they are translated into one or more languages, only the French text shall prevail in the event of a dispute. ARTICLE 14- PRE-CONTRACTUAL INFORMATION 14.1 Acceptance By accepting the present General Terms and Conditions, the Artist acknowledges having been informed of all the essential characteristics of the service offered by the Marketplace, taking into account the communication medium used and the service concerned, pursuant to Article L.111 -1 1° of the Consumer Code. The Artist is also informed that the Marketplace provides an informative insert, accessible on the Site, concerning the classification, referencing, and de-referencing of the NFTs offered by the Artists. 14.2- Contact Our contact information is as follows: SASU FXHASH FOUNDATION Address : 13 Place du Couvant 43150 LE MONASTIER-SUR-GAZEILLE RCS number (Le Puy) : 908 947 617 Intra-community VAT number : FR09908947617 Mail : [email protected] Phone number : (+33)642253709 ARTICLE 15- DISPUTES Any dispute relating to the interpretation and/or execution of the present T&Cs is subject to French jurisdiction. Complaints must be sent to the address indicated in article 14-2 hereof. It is recalled that any dispute or claim concerning the execution of the sale of the NFTs and/or the Products must be settled directly between the Collector and the Artist. 17 GENERAL CONDITIONS OF USE - COLLECTORS ARTICLE 1- OBJECT The FXHASH FOUNDATION platform (the "Marketplace") aims to connect professional and non-professional collectors who have reached legal majority in their country of residence (the "Collectors") and artists, professional or otherwise, who have reached legal majority. legal in their country of residence (the "Artists"), in order to allow Collectors to purchase from Artists, through the Marketplace, NFTs offered for sale on the website "https:// www.fxhash.xyz” (the “Website”). The Marketplace also allows Collectors to get in touch with each other with a view to reselling NFTs. The present General Terms and Conditions of Use (the "T&Cs") define the conditions under which the Marketplace makes available to Collectors the technological tools enabling them to acquire and resell, on the Marketplace, which is not the seller of the NFTs, the latter on the Website. They supplement the General Conditions of Sale which govern sales made between Collectors and Artists, or Collectors between them, through the Marketplace and are accepted by the Collector by means of validation in the computer program to be executed automated allowing the transfer of the NFT and tracing the transaction (“Smart Contract”) on the occasion of each purchase made through the Marketplace. ARTICLE 2- SCOPE The present T&Cs apply, without restriction or reservation, to the use of the services and technological tools made available to Collectors by the Marketplace. These tools allow Collectors to be put in contact with Artists, to order NFTs, to pay the price, to confirm receipt and to communicate with Artists if necessary. They also allow Collectors to resell the NFTs acquired on the Marketplace as part of the Primary Market, at a price freely set by them. Sales made through the Marketplace are concluded directly between the Collector and the Artist, or the Collectors between them. The present T&Cs are accessible at any time on the Website and will prevail, where applicable, over any other version or any other contradictory document. The present T&Cs may be subject to subsequent modifications, the version applicable to the Collector's purchase is that in force on the website on the date of purchase of an NFT. The fact for a Collector to use the services offered by the Marketplace entails full and complete acceptance of the present T&Cs, which is expressly recognized by the Collector who waives, in particular, to avail himself of any contradictory document, which would be unenforceable against the Marketplace. 18 ARTICLE 3- SERVICES OFFERED BY THE MARKETPLACE Access to the Marketplace is strictly reserved for professional or non-professional Collectors of legal age in their country of residence, which the Collector declares and acknowledges when he uses the services of the Marketplace, further agreeing to carry out good faith, all purchase and/or sale transactions concluded through the Marketplace. The use of the Marketplace is free for Collectors (excluding any connection costs billed by the operator) and with no obligation to purchase. Only the purchase or sale of NFT is chargeable, according to the conditions provided for in the Marketplace T&Cs, which the Collector also accepts when he buys or sells an NFT through the Marketplace. In compensation for its connection services and the provision of the technological tools necessary for this purpose, the Marketplace will receive, for each sale of NFT made between Collectors on the website, a commission equal to 2.5% of the amount of the NFT expressed in TEZ. In the event of non-compliance with the present T&Cs by the Collector, the Marketplace reserves the right to temporarily or permanently interrupt its access, by suspending or terminating the present T&Cs with 7 days’ notice, without compensation for the Collector. Collectors may stop accessing the services of the Marketplace, without having to justify a particular reason, subject to honoring the sales in progress on the Secondary Market. The Collector acknowledges and accepts that the guarantee provided for in articles L. 224-25-16 and following of the Consumer Code is not applicable, the Marketplace cannot be considered as the "Producer" within the meaning of the definition given by the Article 1 of Ordinance No. 2021-1247 relating to the legal guarantee of conformity for goods, digital content and digital services ("the manufacturer of goods, the importer of goods into the European Union or any other person who presents himself as a producer by affixing his name, trademark or other distinctive sign to the goods”) of “digital services” (“allowing the consumer to create, process or store data in digital form or to access it, or a service allowing sharing or any other interaction with data in digital form that is uploaded or created by the consumer or other users of this service") since the digital content and associated services offered s on the Website are carried out by a Smart Contract deployed on the Blockchain in a totally decentralized way and without the intervention of a centralizing third party. ARTICLE 4- PROTECTION OF PERSONAL DATA Pursuant to Law 78-17 of January 6, 1978, amended by Law No. 2018-493 of June 20, 2018, it is recalled that any personal data requested from the Collector by the Marketplace are necessary, both to guarantee him access to Marketplace services and for the purchase of NFTs. This data is not communicated to Artists or other Collectors. 19 The collector can create and authenticate a profile including his nickname and linked to his TEZOS public address, but this functionality is carried out on Blockchain and does not give rise to any data collection from the Marketplace. The Marketplace undertakes to ensure the security of the personal data stored. The processing of information communicated through the Marketplace meets the legal requirements for the protection of personal data, the information system used to ensure optimal protection of this data. The Collector has, in accordance with the national and European regulations in force, a right of permanent access, modification, rectification, opposition to portability and limitation of processing with regard to information concerning him. This right can be exercised by writing to the address indicated in article 9-2 hereof. ARTICLE 5- INTELLECTUAL PROPERTY The content of the Website that does not come directly from Artists or Collectors is the property of the Marketplace, and/or its partners, and is protected by French and international laws relating to intellectual property. Any total or partial reproduction of this content is strictly prohibited and is likely to constitute an offense of counterfeiting. ARTICLE 6- LIABILITY 6.1- Limits of liability IIt is recalled that the Marketplace is not the seller of the NFTs. It can therefore in no way be held responsible for sales made between Collectors and Artists, or between Collectors among themselves, to which it remains unrelated. NFTs cannot be taken back or exchanged by the Marketplace and any dispute relating to a sale transaction carried out via the Marketplace must be settled directly between the Collector and the Artist. The Collector undertakes to make all declarations to the administrative and tax authorities related to his activity on the Marketplace, in his country of tax residence, and guarantees the Marketplace for this purpose. It is in particular the Collector's responsibility to find out from a legal professional of his choice about tax obligations and if he considers that the transactions concluded through the Marketplace may be subject to VAT, notify the Artist. by any means. The responsibility of the Marketplace with regard to the Collector can only be engaged for facts which would be directly attributable to it and which would cause the Collector direct damage, to the exclusion of any indirect damage. The liability of the Marketplace is excluded in the event of misuse of the services of the Marketplace by the Collector or of fault on his part. Nor can it be held liable for facts 20 attributable to a third party or to a foreign cause. In accordance with the regulations in force, the Marketplace cannot be held liable for the content made available on the Website, in particular with regard to the description of the NFTs, unless it did not make them promptly inaccessible after having been informed of their unlawfulness under the conditions laid down. 6.2- Obligations of the Collector The Collector is solely responsible for the use of the services of the Marketplace, in particular for the assessments he makes of its content, and undertakes to guarantee on first request, to indemnify and compensate the Marketplace for any damage, loss, failure to win, which it could incur if it were held liable by a third party, as a result of an action related to this use by the Collector. In application of 1° of article 242 bis of the CGI, platform operators are required to communicate during each transaction, to the buyer, to the service provider or to the parties to the exchange or the sharing of a good or a service, when they have received receipts or income in France through the platform, fair, clear and transparent information on the tax and social obligations incumbent on persons who carry out transactions through them. Pursuant to this article, the Marketplace therefore informs the Collector that receipts and income from sales made through the Marketplace may be subject to the tax regimes and social regulations applicable in France. In the event of a breach of his obligations, the Collector may therefore be liable to penalties from the tax authorities and organizations for the collection of social security contributions. Regarding tax obligations in France, the necessary information is available by consulting the following link: https://www.impots.gouv.fr/portail/node/10841 Regarding social obligations in France, the necessary information is available by consulting the following link: https://www.urssaf.fr/portail/home/espaces-dedies/activites relevant-de-leconomie.html. The Collector undertakes to make all declarations to the administrative and tax authorities related to his activity on the Marketplace, in his country of tax residence, in particular any declaration of VAT and/or exchange of goods, and guarantees the Marketplace in this regard effect. He is invited to consult the legal professional of his choice in order to determine whether the transactions concluded on the Marketplace are subject to VAT but cannot in any case engage the responsibility of the Marketplace in this regard. Indeed, it is specified that the Marketplace is not exposed to the "VAT Package" which entered into force on July 1, 2021, as Blockchain technology does not make it possible to locate the public transaction addresses which materialize the dispatch and delivery of NFTs. 21 As soon as the turnover achieved by the Collector on the Marketplace reaches the threshold of €5,000 excluding tax, the Collector-seller must prove that he has fulfilled his social and tax obligations by producing a certificate of vigilance (for find out more: https://www.urssaf.fr/portail/home/employer/ declarer-et-payer/obtention-une-attestation/attestation-de-vigilance.html). The Collectors undertake to implement, in good faith, all necessary means to fulfill their obligations by delivering NFTs that comply with the description communicated for publication on the Marketplace. Professional Collectors, who are required to identify themselves as such to Collectors on the Website and undertake to comply with the applicable legislation in the exercise of a commercial activity (in particular registration, accounting, social and fiscal obligations) as well as the laws and regulations applicable to NFTs sold through the Website. The Collectors declare that they own the NFTs offered on the Secondary Market on the Website or that they are duly authorized to sell them. ARTICLE 7- PARTIAL NULLITY If one or more stipulations hereof are held to be invalid or declared as such pursuant to a law, regulation or final decision of a competent jurisdiction, the other stipulations will retain their full force and scope. ARTICLE 8- APPLICABLE LAW The present General Conditions of Use and the resulting operations are governed by French law. They are written in French. In the event that they are translated into one or more languages, only the French text shall prevail in the event of a dispute. ARTICLE 9- PRE-CONTRACTUAL INFORMATION 9.1- Acceptance By accepting the present General Terms and Conditions, the Collector acknowledges having been informed of all the essential characteristics of the service offered by the Marketplace, taking into account the communication medium used and the service concerned, pursuant to Article L.111- 1 1° of the Consumer Code. The Collector is also informed that the Marketplace provides an informative insert, accessible on the Site, concerning the classification, referencing, and dereferencing of NFTs offered on the Marketplace. 9.2-Contact Our contact information is as follows: SASU FXHASH FOUNDATION 22 Address ; 13 Place du Couvant 43150 LE MONASTIER-SUR-GAZEILLE RCS number (Le Puy) : 908 947 617 Numéro de TVA intracommunautaire : FR09908947617 Mail : [email protected] Phone number: (+33)642253709 ARTICLE 10- DISPUTES Any dispute relating to the interpretation and/or execution of the present T&Cs is subject to French jurisdiction. Complaints must be addressed directly to the Artist or Collector seller according to the methods indicated in the General Terms and Conditions of Sale of NFTs (article 9). It is recalled that any dispute or claim concerning the performance of the NFT sales contract must be settled directly between the Collector and the Artist, or between the Collectors among themselves. The Collector-purchaser is informed that he can in any case resort to conventional mediation, in particular with the Consumer Mediation Commission (C. consom. art. L 612-1) or with the FEVAD Mediator (https://www.mediateurfevad.fr/) or any alternative dispute resolution method (conciliation, for example) in the event of a dispute. 23

    Logo
    Art Blocks for delivering p5js properly, however it seems they are using cloudfare cdn for serving it
  • this opens up a vector for supply chain attacks - what if cloudfare somehow decided to inject a wallet when deliverying p5.min.js ? (this can be mitigated using checksum verification, which in their case was not implemented at the time this document was written)

  • in any case, there are very few ways for artists to be sure their dependencies are properly delivered (depending on the implementation, there might not be any way), as they need to rely on an authority to do so. Again, mostly fine with Art Blocks as they have a strong incentive to properly maintain that

  • artists only have access to a subset of libraries; those maintained by the platform. For instance, p5js is now at version 1.7.0, while only version 1.0.0 seems to be available (released 3 years ago)

  • the JS code a stored as a raw string, without any compression

  • only the JS code has to be pushed by artists; they don't have to upload the HTML template which saves a few bytes—at the cost of lossing access to html and js directives.

  • discrepancies between the dev environment of artists & prod; artists have to use some kind of carefully crafted dev environment that mimics prod behavior

  • Torrent, by Jeres released on Art Blocks
    GenArt721CoreV3
    BytecodeStorageV1
    scripty

    $fx.getRawParam()

    (string) => string

    Provides the raw parameter data (as a bytes string) as it was passed to the iteration.

    von()

    (string, function, function) => function

    Registers an event listener and returns a function to deregister it.

    $fx.emit()

    (string, any) => void

    Sends an event to the parent context, useful for dynamic parameter updates from within the code.

    $fx.params(definition)

    The $fx.params(definition) function is necessary to create an fx(params) piece, it takes as input a list of parameters definitions that collectors can modulate and tweak to create their own custom iterations. Parameter definitions are object that contain a number of key/value pairs that describe the parameters.

    You can learn more about the speficications for the these parameter definitions here:

    Parameter Definition Specifications

    Here is an example of this definition array:

    Invoking the $fx.params() function has a number of important effects:

    • It informs fxhash that the project is an fx(params) project and creates the respective controllers in the UI (if the params are not code-driven)

    • It reads the fxparams URL parameter, processes the bytes and converts it into values based on the provided definitions and maps them to their respective variables to generate the corresponding artwork.

    • The values of the parameters are stored and made accessible throughout the artist’s code via utility functions.

    $fx.params() must be called before trying to access any parameter value with the parameter fetching functions that follow.

    $fx.getParam(id)

    Returns the value of a parameter based on the params definition provided to $fx.params(definition) and the input bytes passed to the code via URL parameters (&fxparams={byte_sequence_here}), the bytes sequence will be processed by $fx.params() when it is called.

    The $fx.getParam(id) will fetch and return the value of parameter through its id as defined in your params definition:

    Depending on the type of the parameter, the fxhash snippet may apply extra processing to facilitate their usage in your code. For instance, in the case of color parameter, it will be returned in different forms. See the parameter definition specifications section for more details on each parameter type.

    $fx.getParams()

    Returns an object containing all parameters, where the keys in this object are the individual parameter ids:

    $fx.getRawParam(id)

    Given a parameter id, $fx.getRawParam(id) returns the hexadecimal string byte sequence corresponding to that parameter, before processing and converting it into a value:

    $fx.emit(eventId, data)

    This function is mainly used for the purpose of updating parameters that have their update mode set to code-driven. As its name suggests, $fx.emit(eventId, data) allows you to emit events (think of it like a signal), to an fxhash specific pipeline of events, which can then be listened to by the $fx.on() function. Currently there is only one type of event that is supported, namely the param:update signal.

    Additionally, this event can also carry a payload which can be specified with the second input parameter of the $fx.emit function, the data variable. The data variable should be an object where the key/value pairs are the parameter ids and the updated associated values respectively. This is still subject to the constraints of the parameter (as set by its parameter definition), so for instance if a number between 0 and 10 is expected and you pass a value of 12, it will clamp to 10. You are not required to pass all the parameters in the data, only those which need to be updated.

    Here’s an example, let’s first set up a couple of parameters:

    And then send out an event whenever we move the mouse:

    Here we used a native Javascript eventlistener to detect whenever the mouse is moved, making it in turn trigger the $fx.emit() function to update the mouse_x parameter.

    Following is the typescript definition of the $fx.emit function:

    $fx.on(eventId, handler, onDone)

    The $fx.on() function listens to events in the fxhash pipeline that are emitted by $fx.emit(). Currently there is only one type of event that is supported, namely the param:update event. $fx.on() can then trigger functions when this event is registered and certain conditions are met. Note that the eventId must match an existing eventId that you can subscribe to.

    The handler is the function that is called when the event is triggered. Additionally you can opt-out of the default behaviour of an event handler by returning false from the handler. The onDone function is called as the last thing of any event, e.g. after the default behaviour of the event was applied.

    Following is the typescript definition of the $fx.on function:

    The function returned by the $fx.on function can be called to remove the registered event listener.

    Note: there are 2 ways to apply changes to the UI when you emit a parameter from the code:

    $fx.params()

    (array) => void

    Define collector-modifiable parameters for your piece by calling this with an array.

    $fx.getParam()

    (string) => any

    Returns the value of a param via its ID.

    $fx.getParams()

    () => object

    Returns a dictionary of all parameter key-value pairs, as currently set.

    const min=Math.min,max=Math.max,abs=Math.abs,round=Math.round,int=parseInt,map=(e,t,n,o,i)=>o<i?o+(e-t)/(n-t)*(i-o):o-(e-t)/(n-t)*(o-i);let __randomSeed=int(tokenData.hash.slice(50,58),16),rCount=0;function rnd(e,t){rCount++,__randomSeed^=__randomSeed<<13,__randomSeed^=__randomSeed>>17;const n=((__randomSeed^=__randomSeed<<5)<0?1+~__randomSeed:__randomSeed)%1e3/1e3;return null!=t?e+n*(t-e):null!=e?n*e:n}const iden=e=>e,rndint=(e,t)=>int(rnd(e,t)),prb=e=>rnd()<e,posOrNeg=()=>prb(.5)?1:-1,sample=e=>e[Math.floor(rnd(e.length))],noop=()=>{};function chance(...e){const t=e.reduce((e,t)=>e+t[0],0),n=rnd();let o=0;for(let i=0;i<e.length;i++){if(n<=(o+=(!0===e[i][0]?1:!1===e[i][0]?0:e[i][0])/t)&&e[i][0])return e[i][1]}}function times(e,t){const n=[];for(let o=0;o<e;o++)n.push(t(o));return n}const allRunningIntervals=[];function setRunInterval(e,t,n=0){const o=()=>{e(n),n++};o();let i=!1,r=setInterval(o,t);
    //...
    <html><head><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/><meta charset="utf-8"/><script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script><script>let tokenData = {"tokenId":"466000139","hash":"0x898ae0c16d5dce2f9a69db2bc57835c63655b90b828fd399f0cc86c461f5486a"}</script><script>const e=[];for(let t=0;t<32;t++)e.push(tokenData.hash.slice(2+2*t,4+2*t));e.map((e=>parseInt(e,16)));const t=parseInt(tokenData.hash.slice(0,16),16);console.log(`${tokenData.hash}`);let i=new class{constructor(){this.useA=!1;let e=function(e){let t=parseInt(e.substr(0,8),16),i=parseInt(e.substr(8,8),16),r=parseInt(e.substr(16,8),16),o=parseInt(e.substr(24,8),16);return function(){t|=0,i|=0,r|=0,o|=0;let e=(t+i|0)+o|0;return o=o+1|0,t=i^i>>>9,i=r+(r<<3)|0,r=r<<21|r>>>11,r=r+e|0,(e>>>0)/4294967296}};this.prngA=new e(tokenData.hash.substr(2,32)),this.prngB=new e(tokenData.hash.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}random_num(e,t){return e+(t-e)*this.random_dec()}random_int(e,t){return Math.floor(this.random_num(e,t+1))}random_bool(e){return this.random_dec()<e}random_choice(e){return e[this.random_int(0,e.length-1)]}};const r=()=>i.random_dec(),o=e=>i.random_bool(e),n=(e,t)=>i.random_int(e,t),a=e=>i.random_choice(e);let s=!1,h=new URLSearchParams(window.location.search),d="true"==h.get("print"),u=1*(h.get("width")??1),c=1*(h.get("speed")??0),f=1*(h.get("frame")??0),l=(h.get("scene"),"true"==h.get("animated"));const v="true"==h.get("fullscreen")?window.innerHeight/window.innerWidth:4/3,m=o(.04),p=o(.095),_=!m&&!p&&o(.1),g=p||_?0:Math.max(m?5:1,a([1,2,2,3,3,3,3,3,3,4,4,4,4,5,5,5,6])),w=_?10:p?0:a([1,1,2,2,2,3,3,3,3,4,4,5]),x=m?7:_?0:n(p?4:2,7)+(0==g?2:0),y=n(0,5),A=n(1,3),b=p||o(.9),k=(o(.5),o(.6)),D=!m&&o(1/3),E=!m&&o(.05),C=!_&&!p&&!m&&g>0&&o(.4),F=!_&&!p&&!m&&g>0&&o(.2),B=n(1,12),M=Y(.15+r()/(_?3:1.75)),U=20;var W,T,I,R,S,$,G=0,z=void 0,L=c>0?c:10,P=!1,H=[],O="#F4EEDC",V="#45413C";const N=e=>e.match(/.{6}/g).map((e=>"#"+e)),j=[V,O],J=N("a83830c858484a746a46C6962169BAc93b36c854704c9784948f9f8cd1e0d5773d048962d9103233a89d96c2ffFF8F0100AAFF3E92CC2A628F3E92CC2A628F18435AAAABBCf8c492f7bdd9ee79ba7aa7faF792567DCFB600B2CA1D4E89FF8303FEDEBEfb7c86fca1a0d06549e19b7170d1c955a5a339797e1e4d583763b34876c5a6a2df66DDAAFD5602FE6E00f870302650a1ff4266F3D537EE6ABB92B3D5C1162E0828B68FD8A095A0D55DA7B81B4C49E82A47ABE373"),Q=N("ff6c88ff8199e69ddcc370cf965db3a48ec2a27aa6a06689ba87a7ff5777FD5DA8ff4266732c8a");function Y(e){return Math.floor(1e3*e)/1e3}function q(e){e.strokeWeight(0);var t=e.color("#fff");t.setAlpha(0),e.stroke(t)}const K=e=>e.min(e.width,e.height),X=e=>{var t,r=(t=H,i.random_choice(t)),o=e.color(r);return o.setAlpha(n(D?64:202,242)),o},Z=(e,t,i)=>{e.push();var o=t+e.floor(r()*i);e.stroke(X(e)),e.strokeWeight(e.width/o/2);for(var n=Math.floor((r()-.5)*(o/2)),a=n;a<o+n;a++)(F||m)&&e.stroke(X(e)),e.line(e.width/o*a,0,e.width/o*(a+o/5+3*e.random()),e.height);e.pop()},ee=(e,t,i,n)=>{e.strokeWeight(i);for(var a=0;a<t*(.5+.25*A);a++){var s=X(e),h=o(.2),d=o(.1),u=e.color(h?V:d?O:s);u.setAlpha(n),e.stroke(u),e.line((r()-.25)*e.width*2,(r()-.5)*e.height*2,(r()-.25)*e.width*2,(r()-.5)*e.height*2)}},te=e=>{e.push();var t=r()*e.width/w;e.strokeCap(e.SQUARE);for(var i=0;i<w;i++){e.strokeWeight(K(e)/8*(3*e.random()+1)*(_?.8:1)),e.stroke(X(e));var o=e.width/w*i+t+e.width/2*(r()-.5),n=e.height*(r()-.2)*M;e.line(o,n,o+(r()-.5)*e.width/6,n+e.height*(r()/2.5+.15)*M)}e.pop(),e.push();var a=(e.random()-.4)*e.width,s=e.random()*e.height,h=(e.random()+.5)*K(e)/4,d=m?0:12,u=20/d;e.strokeCap(e.ROUND),e.angleMode(e.DEGREES),e.noFill(),e.stroke(b?V:O),e.strokeWeight(K(e)/600);var c=e.random()*h/4,f=e.random()*h/4;for(i=0;i<d;i++){o=h*Math.cos(i*u)+a+c,n=h*Math.sin(i*u)+s+f;var l=h/(e.random()+.5)/.1;e.line(o,n,o+(e.random()-.015)*l,n+(e.random()-.015)*l),c+=(e.random()-.4)*h/20,f+=(e.random()-.4)*h/20}e.pop()},ie={},re=(e=0,t=!1)=>{var i=ie[e]??((e=0)=>{var t={},i=0==e?k:o(.5);0==e||o(.5),t.u_horiz=i,t.u_x_inv=i;for(var n=1;n<=3;n++){var a=Y(r()/1.5+1/3);t[`u_r${n}`]=a}return t})(e);t||Object.keys(i).forEach((function(e){S.setUniform(e,i[e])})),ie[e]=i,z=e},oe=e=>{if(se(e),q(e),e.background(O),!m&&o(.8)){var t=e.color(X(e));t.setAlpha(60),e.background(t)}var i=C?20:200,n=C?3:1;p||_||(g>0&&Z(e,21/n,i),g>1&&Z(e,21/n,i),e.fill(X(e)),e.rect(0,.25*e.height,e.width,.1*e.height),e.fill(X(e)),e.rect(0,.5*e.height*r(),e.width,e.height/3),g>2&&Z(e,30/n,i),te(e),e.fill(X(e)),e.rect(e.width*r()*.8+.1*e.width,e.height/2,e.width*r(),e.height),g>3&&Z(e,30/n,i)),p||te(e),_||(e=>{var t=4*x;e.fill(X(e));for(var i=0;i<t;i++){if(o(y/10)&&e.fill(X(e)),m&&p){var n=e.color(o(.8)?V:O);n.setAlpha(222),e.fill(n)}o(.1)?q(e):(e.stroke(e.color(b?V:O)),e.strokeWeight(K(e)/600)),e.circle(e.width*r()*.8+.1*e.width,e.height*r()*.8+.1*e.height,.2*K(e)*(.2+r()))}})(e),p||_||(g>4&&Z(e,30/n,i),g>5&&Z(e,8,12)),((e,t=1)=>{var i=m?15:1.5;e.push(),e.noFill(),q(e),e.strokeCap(e.PROJECT),e.blendMode(e.BURN),ee(e,B*t/i,K(e)/1200,220),e.blendMode(e.SOFT_LIGHT),ee(e,500*t/i,K(e)/3e3,140),e.blendMode(e.OVERLAY),ee(e,188*t/i,e.width/10,22),e.pop()})(e,5),e.stroke(e.color(b?V:O)),e.strokeWeight(K(e)/500),e.line(0,0,e.width,0),e.line(0,e.height*M,e.width,e.height*M)},ne=e=>{$=!0,e.loop()},ae=e=>{$=!1,e.noLoop()},se=e=>{ne(e),e.randomSeed(t),e.noiseSeed(t),e.noFill(),e.angleMode(e.DEGREES),W=f},he=(e,t,i)=>{e.save(`Torrent_${tokenData.hash}_f${t}_s${i}.png`)};var de=`canvas { max-width: ${Math.min(window.innerWidth,window.innerHeight*(1/v))}; max-height: ${Math.min(window.innerWidth*v,window.innerHeight)}; }`,ue=document.createElement("style");ue.innerText=de,document.head.appendChild(ue);new p5((function(e){e.preload=function(){},e.setup=function(){e.frameRate(d?100:40),m?j.forEach((e=>H.push(e))):(J.forEach((e=>H.push(e))),E?Q.forEach((e=>H.push(e))):H.push(O));var t=Math.min(window.innerWidth,window.innerHeight*(1/v));u>t*e.pixelDensity()&&(e.pixelDensity(1),t=u);var i=e.pixelDensity(),r=t*v;d?(T=e.createGraphics(t,r),I=e.createCanvas(t,U,e.WEBGL),T.canvas.style.display="block",I.canvas.style.display="none"):I=e.createCanvas(t,r,e.WEBGL);(R=e.createGraphics(1*(k?r:t),1*(k?t:r))).pixelDensity(i),S=e.createShader("precision highp int;precision highp float;attribute vec3 aPosition;attribute vec2 aTexCoord;varying vec2 vTexCoord; void main() { vTexCoord = aTexCoord; vec4 positionVec4 = vec4(aPosition, 1.0); positionVec4.xy = positionVec4.xy * 2.0 - 1.0; gl_Position = positionVec4;}","precision highp int;precision highp float;varying vec2 vTexCoord;uniform sampler2D u_imageInput;uniform float u_time, u_r1, u_r2, u_r3, u_mod, u_speed, u_noise, u_tileoffset, u_tiledivisor;uniform bool u_horiz, u_x_inv;uniform vec2 u_resolution;vec3 fade(vec3 v, float y, bool fade) { return v - (fade ? y/u_mod/9. : 0.); }float tt(float x) { return mod(u_time, 500.) / x / u_speed; }float c(float x) { return float(int(x * 100.)) / 100.; }float r(in vec2 st, in float r1, in float r2, in float r3) { return fract(c(sin(dot(st.xy, vec2(12.989 + r1 + tt(75.), 78.23 + r2 + tt(62.))))) * 43758. + r3 + tt(50.)); }float n(in vec2 st) { vec2 i = floor(st), f = fract(st);float a = r(i, u_r1, u_r2, u_r3), b = r(i + vec2(1., 0.0), u_r1, u_r2, u_r3), c = r(i + vec2(0.0, 1.), u_r1, u_r2, u_r3), d = r(i + vec2(1., 1.), u_r1, u_r2, u_r3);vec2 u = f * f * (3.0 - (2.0) * f);return mix(a, b, u.x) + (c - a) * u.y * clamp(1.0 - u.x, 0., 1.) + (d - b) * u.x * u.y;}float f(in vec2 st) {float v = 0.0, a = 0.9;for(int i = 0; i < 7; i++) {v += a * n(st);st *= 2.2 + u_r3 / 4.;a *= .4;}return v;}void main() {vec2 uv = vTexCoord;float y = 1.0 - uv.y;y = u_tileoffset + y / u_tiledivisor;if (u_horiz) {uv.y = uv.x;uv.x = y;} else {uv.y = y;}if (u_x_inv && u_horiz) { uv.y = 1. - uv.y; }if (u_x_inv && !u_horiz) { uv.x = 1. - uv.x; }uv.y = mod(f(uv) + mod(u_time, 1000.) / u_speed, u_mod);vec3 oC = fade(texture2D(u_imageInput, uv).rgb, uv.y, true);gl_FragColor = vec4(clamp(oC + (fract(sin(dot(uv, vec2(12.9898,78.233)*2.0)) * 43758.5453)) / u_noise, 0., 1.), 1.0);}")},e.draw=function(){if(!s){se(e),s=!0,oe(R),e.shader(S),S.setUniform("u_imageInput",R),S.setUniform("u_resolution",[e.width,e.height]),S.setUniform("u_noise",7.5+(e.width*e.pixelDensity()<2e3?2e3-e.width*e.pixelDensity():0)/250),S.setUniform("u_mod",M),l||d||ae(e);var t=Math.max(0,~~(f/200));if(f>0)for(var i=0;i<t;i++)console.log(`pre config: ${i}`),re(i,!0);W%200==0&&z!=t&&d&&re(t)}e.shader(S);var r=Math.max(0,~~(W/200));r==z||d||re(r),d?(S.setUniform("u_tileoffset",U/T.height*G),S.setUniform("u_tiledivisor",T.height/U)):(S.setUniform("u_tileoffset",0),S.setUniform("u_tiledivisor",1)),S.setUniform("u_speed",120*L),S.setUniform("u_time",W%1e5),e.fill("#fff"),e.rect(0,0,e.width,e.height),d?(T.image(e,0,U*G,T.width,U),++G*U>=T.height&&(setTimeout(he,0,T,W,L),ae(e))):W++,P&&(P=!1,ae(e))},e.windowResized=function(){},e.keyPressed=function(){var t=e.keyCode;d?83==t&&he(T,W,L):(65!=t&&90!=t||(ae(e),W+=90==t?-2:0,P=!0,ne(e)),83==t&&he(e,W-1,L),80==t&&($?ae(e):ne(e)),70==t&&(ne(e),L=Math.max(1,L-1)),68==t&&(ne(e),L+=1))},e.mouseClicked=function(){d||($?ae(e):ne(e))}}),window.document.body);</script><style type="text/css">html {
      height: 100%;
    }
    body {
      min-height: 100%;
      margin: 0;
      padding: 0;
    }
    canvas {
      padding: 0;
      margin: auto;
      display: block;
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
    }</style></head></html>
    <html>
      <head>
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1, maximum-scale=1"
        />
        <meta charset="utf-8" />
        {% if library
        <script src="%%library%%"></script>
        %}
        <script>
          let tokenData = { tokenId: "%%token_id%%", hash: "%%iteration_seed%%" }
        </script>
        <script>
          %%project_code%%
        </script>
        <style type="text/css">
          /* Some generic-purpose css */
        </style>
      </head>
    </html>
    // this is how params are defined
    $fx.params([
    	{
    		id: "number_id",
    		name: "A number",
    		type: "number",
    		options: {
    			min: -10,
    			max: 10,
    			step: 0.1,
    		},
    	},
    	{
    		id: "boolean_id",
    		name: "A boolean",
    		type: "boolean",
    		//default: true,
    	},
    	{
    		id: "color_id",
    		name: "A color",
    		type: "color",
    	},
    ])
    // define the params
    $fx.params([
    	{
    		id: "a_param_id", // this property will be used for $fx.getParam(id)
    		name: "A random name",
    		type: "boolean",
    	},
    	{
    		id: "another_param",
    		name: "Super param!",
    		type: "color",
    	},
    ])
    
    // depending on the sequence of bytes injected into the code when it's executed,
    // the values will be different
    
    // get the value of parameter "A random name"
    // output example:
    // true
    console.log($fx.getParam("a_param_id"))
    
    // get the value of parameter "Super param!"
    // output example:
    // {
    //   arr: {
    //     rgb: [25, 6, 158],
    //     rgba: [25, 6, 158, 104],
    //   },
    //   hex: {
    //     rgb: "#19069e",
    //     rgba: "#19069e68",
    //   },
    //   obj: {
    //     rgb: { r: 25, g: 6, b: 158 },
    //     rgba: { r: 25, g: 6, b: 158, a: 104 },
    //   }
    // }
    console.log($fx.getParam("another_param"))
    // define the params
    $fx.params([
    	{
    		id: "a_param_id", // this property will be used for $fx.getParam(id)
    		name: "A random name",
    		type: "boolean",
    	},
    	{
    		id: "another_param",
    		name: "Super param!",
    		type: "color",
    	},
    ])
    
    console.log($fx.getParams())
    
    // output example:
    // {
    //   a_param_id: false,
    //   another_param: {
    //     arr: {
    //       rgb: [25, 6, 158],
    //       rgba: [25, 6, 158, 104],
    //     },
    //     hex: {
    //       rgb: "#19069e",
    //       rgba: "#19069e68",
    //     },
    //     obj: {
    //       rgb: { r: 25, g: 6, b: 158 },
    //       rgba: { r: 25, g: 6, b: 158, a: 104 },
    //     }
    //   }
    // }
    
    // the byte sequence injected determines the value of the parameters
    
    // define the params
    $fx.params([
    	{
    		id: "a_param_id", // this property will be used for $fx.getParam(id)
    		name: "A random name",
    		type: "boolean",
    	},
    	{
    		id: "another_param",
    		name: "Super param!",
    		type: "color",
    	},
    ])
    
    // depending on the sequence of bytes injected into the code when it's executed,
    // the values will be different
    
    // get the value of parameter "A random name"
    // output example:
    // "01"
    console.log($fx.getRawParam("a_param_id"))
    
    // get the value of parameter "Super param!"
    // output example:
    // "19069e68"
    console.log($fx.getParam("another_param"))
    // define your parameters
    $fx.params([
    	{
    		id: "mouse_x",
    		type: "number",
    		// a code-driven parameter
    		update: "code-driven",
    	},
    	{
    		id: "number_2",
    		type: "number",
    		// a code-driven parameter
    		update: "code-driven",
    	},
    	{
    		id: "number_3",
    		type: "number",
    		// a normal parameter, cannot update with params:update
    		update: "page-reload",
    	},
    ])
    // example: when the mouse moves, we update the first parameter
    window.addEventListener("mousemove", evt => {
    	const X = evt.clientX / window.innerWidth // normalized X position of mouse
    	// we request the update of a parameter
    	$fx.emit("params:update", {
    		mouse_x: X,
    	})
    })
    type FxEmitFunction = (
    	eventId: string
    	data: any
    ) => void
    // define your parameters
    $fx.params([
    	{
    		id: "number_id",
    		type: "number",
    		update: "sync",
    	},
    ])
    
    function main() {
    	// render artwork
    }
    
    $fx.on(
    	"params:update", // subscribe to the params update event
    	newValues => {
    		// opt-out param update when number_id is 5
    		if (newValues.number_id === 5) return false
    		// opt-in any other param value update
    		return true
    	},
    	() => main() // render artwork when event was handled
    )
    type FxOnFunction = (
    	eventId: string
    	handler: (...args) => boolean | Promise<boolean>
    	onDone: (optInDefault: boolean, ...args) => void
    ) => () => void
    const removeListener = $fx.on("params:update", newValues => {
    	// do something
    })
    
    removeListener() // <-- Will remove the event listener
    // FIRST WAY
    // Emit the update, and update the view only when receiving the params:update
    // back. This ensures a proper flow of data, and a proper sync of the minting
    // UI and your project
    window.addEventListener("mousemove", evt => {
    	const X = evt.clientX / window.innerWidth
    	$fx.emit("params:update", {
    		mouse_x: X,
    	})
    })
    
    $fx.on("params:update",
    
    () => {}, // do nothing to check the params received
    
    () => { // once the update is fully registered, update the view
    		draw()
    		// in this case draw() can rely on $fx.getParam("mouse_x") to be synced with
    		// the up-to-date value
    	}
    )
    // SECOND WAY
    // Custom draw logic where the params effects are applied right after emitting
    // the update
    window.addEventListener("mousemove", evt => {
    	const X = evt.clientX / window.innerWidth
    	$fx.emit("params:update", {
    		mouse_x: X,
    	})
    
    	// here trigger a draw, but you need to handle the change in value manually,
    	// as $fx.getParam("mouse_x) will point to the old value
    	draw(X)
    })

    5

    Quantity Selector

    Lets you collect multiple iterations at once when you subsequently hit the ‘Mint Iteration’ or ‘Credit Card’ buttons.

    6

    Credit Card

    fxhash also allows the purchase of GENTKs via credit card - more about this in the .

    7

    Open Marketplace

    Navigates to a project's associated marketplace page that shows statistics about the primary and secondary sales, besides listed editions. Merged with the project page in V2.0.

    8

    Mint Iteration

    Triggers the collect transaction in your wallet.

    9

    Project Number / Contract

    For Tezos-based projects this indicates the project number, whereas for Ethereum projects it indicates the contract address of the project. All Tezos projects are minted on the same fxhash marketplace contract, whereas ETH projects are minted on their own individual contracts.

    10

    Publishing Date

    the original date the project was minted on the blockchain and published on fxhash.

    11

    Labels

    Special indicators that artists need to toggle at the time of publishing their projects.

    This project has an edition size of 120, half of which have been burned, 39 collected and 21 still available:

  • This project is an open edition, indicated by the infinity symbol - 8508 iterations have been collected.

  • This project has two reserved editions, meaning that the artist(s) reserved these for specific collectors via an allows list or mint pass. You can learn more about allow lists here.

  • Image Composition
  • Animated

  • Interactive

  • Profile Picture Project (PFP)

  • Audio

  • Includes pre-rendered components

  • Custom Minting Interface

  • Artists can set up a reserve/allow list for their projects. A reserve indicates a list of wallet addresses that are elligible for minting iterations that are not available to everyone - .

    Dutch Auction with Rebate: Artists can also set Rebates on their Dutch Auctions. This means that early collectors who paid a higher price will get refunded for the difference with the final price at which the mint concludes. For instance, if a collector mints from the project for a price of 512 tez, then the project mints out at 256 tez, they get refunded for the difference, that is 256 tez.

    1

    Artist

    The profile icon and name of the project’s creator. Lets you navigate to the artist(s)' profile.

    2

    Project Title

    Title of the project. Specified by the artist(s).

    3

    Current Price

    The current price for collecting an iteration or mint ticket from the project. Learn more in the Pricing Methods segment below.

    4

    Mint Status

    An indicator visualizing how many iterations of the project have been sold already, and how close the project it is to ‘minting out’.

    Price

    The price and currency for which an edition can be collected.

    Minting Opens

    Essentially the first date at which the project became available for minting.

    Primary Split

    This percentage determines how the initial proceeds of the sale are divided. It clarifies how much the artist receives from the first purchase of an iteration from their generative project. In this case it’s an Ethereum based project where 10% go towards fxhash. For Tezos projects this is 2.5%.

    Royalties

    Royalties dictate a percentage of resale generated revenue that goes back to the original artist - essentially the portion of the secondary proceeds that is sent back to the artist’s wallet. This provides ongoing compensation for the artist whenever an edition is sold on the secondary market - artists can set this value between 0% and 25%.

    Royalties Split

    This specifies how the royalty percentage is further divided, typically between the artist and the platform facilitating the sale. For Ethereum based projects the platform fee is set at 25% whereas there is no fee for Tezos based projects.

    Tags

    Artists can tag their projects with specific tags, which help with discoverability later on.

    Metadata

    The metadata that describes the project on the blockchain.

    setting up your wallet here
    connecting it to fxhash here
    Acquiring, Exchanging, and Managing Cryptocurrencis Section
    the page fx(params) and Mint Tickets here

    Reserves

    What are Generative Tokens?

    Taking a step back, we defined generative artworks as code based systems that have the ability to generate different kinds of media artifacts. Depending on what the code artist aims to express, these systems can come in many shapes and forms. Most popularly they are designed to generate static, sometimes animated, computer graphics drawn to a digital canvas. The key-concept here is that these code based generative systems have the ability to generate a variety of outputs by leveraging random processes:

    A generative artwork is a label for a piece of code that can generate a variety of different outputs.

    A generative artwork is a label for a piece of code that can generate a variety of different outputs.

    On fxhash generative artworks become Generative Tokens. To fully understand how Generative Tokens function and how collectors can actually acquire ownership over individual outputs of a Generative Token, we need to talk a little about randomness, how it is achieved in programming, and how fxhash leverages it for this purpose.

    In many applications and computer programs it often is the case that the programmer wants to make a random decision, like simulating the roll of a dice for instance. This can be achieved with random number generators, frequently abbreviated as RNGs. If you're a fan of video-games you might already be familiar with the term:

    What is an RNG?

    RNGs, or Random Number Generators, are algorithms designed to produce sequences of numbers that lack any discernible pattern. These numbers appear to be random and are commonly used in various applications, such as computer simulations, cryptography, and gaming.

    RNGs are also incredibly useful in generative art where they're leveraged to introduce randomness into the algorithmic procedures that create the ultimate graphics. Using RNGs has the consequence that generative artworks produce a different output every time their code is executed. That's why we call it generative art after all.

    Generative Tokens need to behave a little differently however. We don't only need them to be able to generate a variety of outputs via random processes, but also need them to be able to re-generate specific outputs, which is very important when it comes to assigning ownership over individual outputs - we want to be able to query and retrieve specific outputs from the Generative Token again in the future. How can this be achieved? By leveraging a special type of RNG, called Pseudorandom Number Generators:

    What is a PRNG?

    Just like an RNG, a Pseudorandom number generator is also an algorithm that has the ability to generate sequences of random numbers that appear to be random. The difference is that these generated sequences are actually generated in a deterministic manner. Meaning that they are in reality predictable and reproducible - which is an important property in the context of Generative Tokens.

    The exact sequence of "random" numbers generated by a PRNG is usually determined by an initial seed value:

    What is a Seed?

    An initial input value passed into a pseudorandom number generator. This input seed is used by the PRNG to generate a specific sequence of random numbers. The PRNG will always generate the same sequence of numbers given the same input value.

    The same seed should always generate the same output.

    This is in essence how Generative Tokens work. They are code based systems that leverage PRNGs to deterministically generate specific outputs. Generative Tokens are in this manner deterministic systems:

    What is a Deterministic System?

    "Deterministic" is an adjective used to describe systems, processes, or events that are predictable and governed by fixed rules or deterministic algorithms. In a deterministic system, given the same initial conditions and inputs, the outcome or behavior is certain and follows a specific, predefined path.

    Now we still need about how to generate these input seeds and how to attribute them to individual owners. And this is where blockchain technology comes into play: when a collector collects an output from a Generative Token, a blockchain transaction gets registered which comes with an associated transaction hash. This hash simply being an alphanumeric string is perfectly suitable for seeding a PRNG.

    What is a transaction hash?

    A blockchain operation hash, often simply referred to as a "transaction hash" or "tx hash". It is a unique identifier for a specific transaction on a blockchain. It is a long string of alphanumeric characters that is generated through cryptographic algorithms, and serves as a digital fingerprint for that transaction.

    In the context of Generative Tokens on fx(hash), it's the initial input value that determines the specific iteration a GENTK will produce.

    There are various websites that allow the inspection of transactions on different blockchains. Here’s an early fxhash transaction on the Tezos blockchain as seen on

    Now it should also makes sense why the platform is called fx(hash)! Since the transaction hash originates from the blockchain, it is immutable and can be used a reliable source for seeding Generative Tokens. This is essentially how the fx(hash) paradigm comes to life - immutable blockchain transactions make it possible to distribute unique outputs of deterministic generative artworks to collectors.

    It's important to point out here that artists hold the responsibility for creating and correctly implementing the code behind these deterministic generators—if not done with care and according to platform specifications, it can lead to a plethora of issues. Although fx(hash) provides the tools to create and publish generative tokens, it can not be guaranteed that these generative tokens always work correctly, hence collector discretion is advised.

    fxhash provides a number of different tools and features aimed at assisting artists in the development of their Generative Tokens - detailed explanations about these tools as well as instructions for properly configuring Generative Tokens in an fxhash compatible manner can be found in the fxhash Artist Guides.

    How are Generative Tokens stored?

    When an artist creates a new Generative Token on fxhash two things happen:

    1. A metadata file is written to the blockchain holding descriptive information about the project. This is essentially a Non-Fungible Token that represents the Generative Token on the blockchain and attributes authorship to its creator, and in this sense, a Generative Token is itself an NFT.

    2. The project/code files are stored either off-chain on IPFS or on-chain with ONCHFS. The artist can choose their preferred storage solution at mint/upload time. The metadata file on the blockchain holds a pointer to these project files, which are retrieved and used for the purpose of generating new and old outputs whenever someone interacts with the Generative Token via the fxhash web interface.

    What is Metadata?

    Metadata is essentially data that describes other data. For instance Generative Tokens on fxhash have an associated metadata file that holds information such as an ID, the publishing date, the number of iterations that can be collected, the location of the project files on IPFS or ONCHFS, etc. This information is required for smart-contracts to interact with Generative Tokens and GENTKs.

    What raw metadata looks like

    Traditionally, due to the high cost of storing files directly on the blockchain, decentralised storage solutions like IPFS are more commonly preferred to store files in Web3. This was the default storage method for the first two years of fxhash's lifecycle. With the introduction of ONCHFS however, it is now also possible to store projects in their entirety on the blockchain. You can learn more about the specifics of both IPFS and ONCHFS over in the Decentralised Storage Solutions page of the docs.

    The project files that are stored essentially represent the code written by the artist. Moreover, because fxhash is a web-based platform that serves content over the internet, one requirement is that Generative Tokens need to be packaged in the form of small, self-contained web projects such that they can be served properly on the interface. In other words, this means that the stored project files for a Generative Token are little bundles of code that represent a tiny websites which display generative graphics.

    GENTKs vs Generative Tokens?

    GENTKs are the collectible digital tokens that are spawned by Generative Tokens. You can think of Generative Tokens as little factories that produce artwork tokens. Sometimes the two terms ‘Generative Token’ and ‘GENTK’ are used interchangeably for both the generative system and the output, but it should usually be clear which one is meant from context.

    There’s a couple of other terms with which we refer to GENTKs - sometimes we refer to them as an iteration from a specific project or as an edition:

    Iteration(s) and Edition(s)

    Alternative terms to refer to GENTKs. With the term iteration we're indirectly alluding to the notion of repetition in programming - we often use the term iteration or iterating in the context of instructions that are repeated a certain number of times. This is because Generative Tokens have the ability to generate many GENTKs.

    Likewise the term edition is used, which stems from the world of publishing, where it is used to refer to a specific instance of a published work.

    Under the collection tab on your fxhash profile you can see all collected GENTKs.

    What are GENTKs and how are they stored?

    GENTKs are themselves NFTs. When a collector collects an edition of a Generative Token, they obtain ownership of a metadata file that is written to the blockchain that represents this GENTK.

    This metadata file immutably links back to the parent Generative Token and also holds the necessary information that needs to be input into the Generative Token code to produce the collected output, such as the seed for instance. Additionally it also holds a pointer to an image preview of the output that is stored on IPFS, such that we don’t necessarily have to run the code to view the output and can simply fetch it from IPFS.

    Here’s a brief breakdown of what happens behind the scenes when a collector clicks the collect button on a Generative Token's project page. Essentially two procedures take place - firstly, a transaction is registered on the blockchain and the input seed is generated:

    1. The fxhash platform fires a smart-contract call and a new transaction is registered on the blockchain which subsequently creates a transaction hash.

    2. The fxhash Ramdomizer module gets triggered, supplementing this transaction hash and preparing it to be passed into the Generative Token. Why not simply use the transaction hash as is? Although that is possible, there are certain security considerations that make this undesirable, which is why fxhash devised randomizer module for this purpose. You can learn more about the Randomizer module here.

    After this initial transaction, the output is technically already accessible since the input seed exists, but the GENTK still needs to be created and written to the blockchain as a self-contained token - essentially, the GENTK NFT still needs to be created. The fxhash signing module takes care of this with a follow-up procedure:

    1. The fxhash signing module gets triggered when it notices that a new transaction has been effectuated on the fxhash contract.

    2. The respective project files are retrieved, then the previously generated input seed is used to create a preview image (by feeding it into the generator) as well as the metadata for the GENTK.

    3. This metadata is written to the blockchain to represent the GENTK. Colloquially we say that the GENTK is “signed”. The preview image is stored on IPFS so that the collected GENTKs can be displayed on the fxhash interface without having to run the project code every single time.

    After this second procedure is completed, the GENTK is successfully created and becomes it’s own standalone NFT.

    The signer module in action as seen on

    Summary

    With this we’ve already covered a lot of ground, and hopefully you have a much better idea of how fx(hash) works at this point. It’s important to understand how these different technologies tie into each to bring to life this new paradigm in digital art.

    Let's recap the important notions that we've covered in this section:

    1. Generative Tokens are packaged under the form of web based projects that display generative graphics in the browser.

    2. Generative Tokens are NFTs. Their code/project files are stored on either IPFS or ONCHFS.

    3. Generative Tokens are factories for unique collectible digital tokens called GENTKs. This is made possible by leveraging blockchain technology and Pseudorandom Number Generators.

    4. GENTKs are collectible NFTs, each one is unique.

    This is essentially how Generative Tokens work in their most basic form. It’s important to note here that new features like fx(params), where the collector assumes the role of a co-creator, has opened many opportunities for artistic expression and introduces some nuances to this process. There are also differences between Generative Tokens on the Tezos and Ethereum blockchains. Exploring the other pages of the documentation will elucidate some of these nuances.

    Logo
    Logo

    Parameter Definition Specs

    An overview of the parameter definition specifications and the different types of parameters that are currently available.

    When calling $fx.params(definition), a definition array of parameter definitions must be passed to the function. This array must be constant, which means that the same value must be passed every time the code is executed. There cannot be any source of randomness in the definition.

    A parameter definition is an object following strict guidelines. Example:

    The TypeScript type for a parameter definition is:

    Definition Specifications

    Each property's role is outlined as follows:

    id required

    A string identifier, which will be used to get the parameter value later in the code. This is also used to populate an object of the different parameter [id; value] when the bytes are deserialized into values when $fx.params() is called.

    Each id must be unique! Two parameters cannot have the same id.


    name optional

    A string which will be used as a display name on the minting interface. If not set, the parameter name will be its id. We recommend setting a name for every parameter so that collectors can see a nice text displayed next to the controller. We also recommend sticking with short names to keep the minting UI clean.


    type required

    The type of the parameter, must be one of the available types (number, string, boolean, color, select, bigint). See below for each type specification.


    default optional

    A default value for the parameter. If defined, when the minting interface with the controllers is loaded, the corresponding value of the controller will be set to this one. If not set, the controller value will be set to a random one within the constraints defined in the parameter options.


    update optional

    Specifies the update mode of the parameter. There are 3 update modes available:

    • page-reload: (default) the parameter can only be updated from the fxhash UI, the whole project will be refreshed when any page-reload parameter is updated

    • sync: the parameter can only be updated from the fxhash UI, will be sent to the project when the parameter is update. The page is not refreshed, so you need to handle the update of the view yourself

    • code-driven: the parameter can only be updated from your code, by.

    General overview of params update in the .


    options optional

    An object with type-specific options. Each type has specific options, described in the section below. Default values are used for each option if not defined. The default values are also described in the section below.


    Parameter Types

    Each type comes with specifications:

    • a list of available options

    • a format in which the bytes are deserialized and made available to your code

    • a kind of controller which will be displayed to modulate the parameter (this will happen outside the context of the piece itself, most often in a parent context)

    number

    Numbers are deserialised into (default javascript number type).

    Option Table

    Example:

    Corresponding controller: a slider and a text input


    string

    Strings are deserialised into a series of UTF-8 characters.

    Option Table

    Example:

    Corresponding controller: a text input


    boolean

    Booleans are deserialised into native javascript booleans.

    There are no available options for the boolean type.

    Example:

    Corresponding controller: a checkbox


    color

    Colours are serialised with 4 bytes, each byte representing the value between 0 and 255 of one channel (red, green, blue, alpha). When a colour is deserialised, it is processed into an utility-object to facilitate their usage.

    The object is constructed as follows:

    There are no available options for the color type.

    Example:

    Corresponding controller: a color picker and a text input


    bytes

    Arbitrary data which can only be manipulated with code, not from the UI; the update mode must be code-driven. Allows to store bytes in an optimised way, the bytes are serialised to hexadecimal and deserialised to .

    Example:


    select

    A select is defined by a list of strings, where each string defines an option which can be selected. A select can take up to 256 entries. A select is stored as a single byte on-chain, which is the hexadecimal representation of a number between 0 and 255, corresponding to the index of the selected option in the array of options. When deserialised, the string of the option is extracted.

    The options property of a select is required and must be an array of strings, corresponding to the available options.

    Option Table:

    Example:

    Corresponding controller: a select with various options


    bigint

    A bigint is deserialized into an int64, which is the . Bigint can represent very big integer values which cannot be represented usually with javascript float numbers (between -9223372036854775808 and 9223372036854775807). If you need an integer value between -9007199254740991 and 9007199254740991, use the number type instead as integer values can be represented with 100% precision with float64.

    Option Table:

    Example:

    Corresponding controller: a slider and a text input

    Privacy Policy

    fxhash's privacy policy

    INTRODUCTION FXHASH FOUNDATION and its affiliates (hereinafter referred to as "fxhash", the "Company", "we", "us" or "our") are committed to protecting and respecting your privacy (hereinafter referred to as "Users", "you" or "your"). This privacy policy (hereinafter referred to as "Privacy Policy"), together with our legal notice, disclaimers, documentation, and general terms and conditions, explain how fxhash operates and how it may - from time to time only - use your personal information (hereinafter referred to as "Personal Information" or "Personal Data") when Users access the website: https://www.fxhash.xyz/ (hereinafter referred to as the "Site"). For more information about the Company, the User is invited to consult the legal notice. fxhash has developed a platform (hereafter referred to as the “Application” or the "Marketplace") that brings together professional and non-professional collectors who have reached the legal age of majority in their country of residence (the "Collector") and creators, professional or not, who have reached the legal age of legal age in their country of residence (the "Artist") in order to allow the latter to:

    • convert their original creations into Non-Fungible Tokens ("NFT") and store the NFT metadata on an Interplanetary File System (IPFS),

    $fx.params([
        {
            id: "number_id",
            name: "A number",
            type: "number",
            options: {
                min: -10,
                max: 10,
                step: 0.1,
            },
        },
        {
            id: "boolean_id",
            name: "A boolean",
            type: "boolean",
        },
        {
            id: "color_id",
            name: "A color",
            type: "color",
        },
    ])
    // a parameter definition
    type ParameterDefinitionType = {
        id: string // required
        name?: string // optional, if not defined name == id
        type: "number" | "string" | "boolean" | "color" | "select" | "bigint" // required
        default?: string | number | bigint | boolean // optional
        update?: "page-reload" | "sync" | "code-driven" // optional
        options?: TYPE_SPECIFIC_OPTIONS // (optional) different options per type (see below)
    }
    offer their NFTs to Collectors and enter into contracts with them to sell these NFTs for digital assets ("Primary Marketplace"). The Marketplace also allows Collectors to resell NFTs acquired from Artists to each other from Artists ("Secondary Market"). In addition, the Marketplace allows Artists to sell and ship to Collectors tangible goods (the "Products") that may be ordered by Collectors when redeeming the NFT on the Marketplace. In this context, this Privacy Policy describes why and how we may collect and use Personal Information and provides information about individuals’ rights in relation to Personal Information.
    1. PURPOSE OF PRIVACY POLICY 1 The purpose of this Privacy Policy is to set out in an accountable and transparent way the collection and use of information by fxhash. In order to comply with General Data Protection Regulation (GDPR) and applicable regulations, fxhash may gather personal information from Collectors and Artists to facilitate the delivery of the Products from Artists to Collectors (if applicable) when purchasing an NFT on the Platform. fxhash may also gather personal information from Collectors and Artists for the purpose of verifying that they have reached the legal age of majority in their country of residence.

    2. ELIGIBILITY fxhash does not allow persons under the age of 18 to use the fxhash Services and does not knowingly collect personal data from children under the age of 18.

    3. PERSONAL INFORMATION COLLECTION - PURPOSE - LEGAL BASIS Personal information is information which identifies you personally or by which your identity can reasonably be ascertained. The Personal Information which may be processed is listed below. What personal data does fxhash collect and process? Why does fxhash process my personal data? Legal basis for our use of personal data

    • First and last name,

    • email address,

    • telephone number,

    • nationality,

    • personal address,

    • content, within any messages you send to us via our contact address: [email protected] (such as feedback, questions, job applications, etc.). Transaction Services. We use your personal information to process your orders and to communicate with you about orders and services, in connection with the above-mentioned Products. Communicating with you. We use your personal information to communicate with you regarding fxhash Services. Fulfilment of a contract when we provide products or services to you, or communicate with you about them. This includes where we use your personal data to take and process orders, and to process payments. Legal obligation to comply with our legal obligations under applicable laws and regulations. Your consent where we ask for your consent to process your Personal Data for a specific purpose that we communicate to you. Where you consent to fxhash processing your Personal Data for a specific purpose, you may withdraw your consent at any time, and we will stop processing your Personal Data for that purpose. Withdrawal of consent does not affect the lawfulness of the processing based on the consent prior to its withdrawal.

    • the Internet Protocol (IP) address used to connect your computer to the Internet, To provide, troubleshoot and improve the fxhash Services. We use your personal data to Legitimate interest and the interests of our Users when, for example, we detect and prevent 2

    • audience and technical measurements of the fxhash Services (e.g., occurrences of technical errors, your interactions with the features and content of the Services, and your preferences for settings),

    • version and time zone settings. provide functionality, analyze performance, correct errors, and improve the usability and efficiency of the fxhash Services. fraud and abuse to protect the safety of our Users, ourselves or others. Fulfilment of a contract when we provide products or services to you, or communicate with you about them. This includes where we use your personal data to take and process orders, and to process payments. Important notice: Blockchains provide transparency into transactions, and fxhash is not responsible for preventing or managing information broadcasted on a blockchain.

    1. PROTECTION AND USE OF PERSONAL INFORMATION fxhash is committed to protecting your privacy. Internally, only a specified number of employees within our business have access to your Personal Information. fxhash’s systems and data are constantly under review to ensure that you are getting the best access and that market borrowing and lending security features are in place. fxhash reserves the right to retain and share certain Personal Information in order to meet our regulatory and statutory requirements. In addition, fxhash reserves the right to retain and share certain Personal Information with our corporate partners, and third parties acting on behalf of fxhash. Personal Information and other related data may be exported outside of the jurisdiction in which you reside. Your Personal Information may be processed and stored in a foreign country or countries. Under those circumstances, the governments, courts, law enforcement or regulatory agencies of that country or those countries may be able to obtain access to your Personal Information through foreign laws. You need to be aware that the privacy standards of those countries may be lower than those of the jurisdiction in which you reside.

    2. ACCESS AND CHANGING OF PERSONAL INFORMATION You have the right to access the Personal Information we hold about you, and to require the correction, updating and blocking of inaccurate and/or incorrect data by sending an email to us. We will aim respond to your request within 14 days. You may also request the deletion or destruction of your Personal Information, your account details, etc. fxhash will act on your request only when it is not inconsistent with its legal and regulatory obligations and compliance procedures. Upon your written request, we will inform you of the use and general disclosure of your Personal Information. Important notice: The exercise of these rights is nevertheless limited, with regard to Personal Information that may be necessary for the operation of a blockchain. Indeed, this Data required for the operation of blockchains cannot be modified or erased during the lifetime of the blockchain in question. In addition, the retention / storage of said Data in said blockchains is not the responsibility of fxhash, which does not manage nor control said blockchains and therefore has no power to determine or control the processing of Personal Information which may be implemented in connection with said blockchains, nor to pass on the exercise by Users of their rights to said blockchains. 3

    3. RIGHTS You benefit, under the terms and conditions and within the limits defined by the legal and regulatory provisions on the protection of Personal Information, the following rights with regard to your Data: ● Right of access: you can obtain confirmation whether or not Personal Information concerning you is processed by the Company and, when they are, access to said Personal Information, as well as certain information relating to the processing of your Personal Information and the characteristics of such processing; ● Right of rectification: you can request the correction of your Personal Information that you consider incomplete or inaccurate; ● Right to erasure: you can, in certain cases, request the erasure of your Personal Information (except for example if they are necessary for the execution of your contractual relations with the Company where applicable, or if they are necessary for the Company to comply with its legal or regulatory obligations or to ascertain or exercise its rights); ● Right to limitation of processing: you can request limitation of processing of your Personal Information, allowing you to request in certain cases the marking of your Personal Information in order to limit future processing; ● Right to the portability of your Personal Information: you have the right in certain cases and under certain conditions to request to receive the Personal Information concerning you that you have provided to us or, when technically possible, to they are transferred to a third party, in a machine-readable form (it being specified that this right to data portability only applies to processing based on the consent of the Persons concerned or on the execution of contractual relations, and this provided that the Data processing is carried out using automated processes); ● Right to withdraw your consent: you can withdraw your consent if the processing is carried out on the basis of your consent, without the withdrawal of such consent prejudicing the lawfulness of the processing based on the consent made before the withdrawal of it; ● Right to define guidelines for the retention, erasure or communication of your Personal Information after your death: in this regard, in the event of death which would be brought to our attention, please be aware that your Personal Information will in principle be deleted (unless it is necessary to keep it for a specified period for reasons relating to our legal and regulatory obligations), after having been communicated to a third party possibly designated by you. Regarding the processing of your Personal Information implemented by the Company, these rights are exercised: (i) by email to the following email address: [[email protected]] or, (ii) by post to the address next: 13 Place du couvant, 43150 Le Monastier-sur-Gazeille, In any event, in the event of reasonable doubt as to the identity of the person submitting such a request to exercise their rights, the Company may always request that it be provided with additional information necessary to confirm the identity of the Person concerned and request for this purpose, when the situation so requires, a photocopy of an identity document bearing the signature of the holder.

    4. COOKIES (i) THE COMPANY’S COOKIES POLICY? With regard to cookies, the Company does not wish to implement any kind of cookies. 4 Cookies and other tracers or similar technologies will not be installed and / or read in your browser or terminal during your visit to the site. (ii) WHAT IS A COOKIE? A cookie is a small file for storing and retrieving information, generally made up of alphanumeric characters (cf. letters and numbers), deposited by a web server on the computer or electronic terminal of the User of the site to send state information to said browser and likewise obtain such information back from the browser. The status information can be, for example, a session identifier, a language, an expiration date, a response domain, etc. Cookies usually make it possible to obtain certain information on the browsing habits of the User, his computer or his terminal, in particular in order to improve the content and the service offered by the site in question, to know the traffic of said site and to provide Internet Users with personalised services. The notion of cookies covers all types of tracers or other similar technologies, for example: ● HTTP Cookies; ● but also the use of other techniques: o “local shared objects” sometimes called “Flash Cookies”; o “local storage” implemented within HTML 5; o identifications by calculating the fingerprint of the terminal (“device fingerprinting”); o identifiers generated by operating systems (whether advertising or not: IDFA, IDFV, Android ID, etc.); o hardware identifiers (MAC address, serial number or any other identifier of a device); o etc. In any case, cookies can be: ● session cookies, which disappear as soon as the User leaves the browser or the Site; ● where permanent cookies that remain until the expiration of their lifespan or validity, or until the User deletes them by means of the functionalities of his browser for example or through the cookie management module set available on our Site. (iii) WHAT ARE THE MAIN “FAMILIES” OF COOKIES? "Functional" cookies not subject to User consent Functional Cookies, ie those whose sole purpose is to allow or facilitate electronic communication on, from or to a site or which are strictly necessary for the provision of a communication online at the express request of the User of a site, are exempt from the need for the publisher of a site to request the User's consent for their installation. The Company may thus use such functioning cookies, in particular technical cookies essential for navigation on the Site and cookies strictly necessary for the provision of certain services explicitly requested by the User, without requesting prior consent from you. If the User deactivates these “operating” cookies for example by means of the functionalities offered by his browser, he may not be able to access the Site, and / or not correctly receive the content and information available on the Site and / or not being able to benefit from all the features of the Site. Other cookies, subject in principle to the consent of the User The use of other cookies as referred to below is subject in principle to the prior consent of the User, the latter being free to either accept them by expressly consenting to their installation and reading in his 5 browser (it being specified that the latter will then have the possibility to withdraw his consent at any time), or to refuse them.

    5. SECURITY We take reasonable steps to protect your Personal Information from misuse, loss, unauthorised access, modification or disclosure, including implementing appropriate security measures. The security measures in place will, from time to time, be reviewed in line with legal and technical developments. However, we give no guarantee that such misuse, loss, unauthorised access, modification or disclosure will not occur. There are protective measures that you should take, which as well include but are not limited to changing passwords regularly and not sharing your Personal Information with others unless you clearly understand the purpose of their request and you know with whom you are dealing.

    6. RETENTION OF PERSONAL INFORMATION We will hold your Personal Information only for as long as we must do so, having regard to the purposes described in this Privacy Policy and our own legal and regulatory requirements. In general, Personal Information relating to you shall be deleted after a period of five (5) years after your account is closed. Similarly, we usually retain information about transactions on your account for a period of five (5) years from the date of the transaction.

    7. LINKS There may be links from our Site to other sites and resources provided by third parties. This Privacy Policy applies only to our Site. Accessing those third-party sites or sources requires you to leave our Site. We do not control those third party sites or any of the content contained therein and you agree that we are in no circumstances responsible or liable for any of those third party sites, including, without limitation, their content, policies, failures, promotions, products, services or actions and/or any damages, losses, failures or problems caused by, related to or arising from those sites. We encourage you to review all policies, rules, terms and regulations, including the privacy policies, of each site that you visit.

    8. CHANGES Our policies, content, information, promotions, disclosures, disclaimers and features may be revised, modified, updated, and/or supplemented at any time and without prior notice at the sole and absolute discretion of the Company. If we change this Privacy Policy, we will take steps to notify all Users by a notice on our Site and will post the amended Privacy Policy on the Site.

    9. COMPLAINTS TO THE SUPERVISORY AUTHORITY If you consider that we have not responded adequately to your request or your questions, you are entitled to lodge a complaint with the competent authority in matters of Personal Information protection, the National Commission for Informatics and Liberties (CNIL), at the following Internet address:

    • https://www.cnil.fr/fr/plaintes ;

    • or to the following postal address: CNIL - 3 PLACE DE FONTENOY - TSA 80715 - 75334 PARIS CEDEX 07.

    1. CONSULTATION OF APPLICABLE TEXTS 6 The text of the General Data Protection Regulation (GDPR) is freely accessible at the following Internet address: https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:32016R0679; or on the CNIL website at the following internet address: https://www.cnil.fr/fr/reglement-europeen-protection-donnees as well as all applicable texts on the protection of Personal Information and protection of rights and freedoms on the Internet (https://www.cnil.fr ). To understand your rights, you can also refer to the explanations provided by the Cnil here: https://www.cnil.fr/fr/les-droits-pour-maitriser-vos-donnees-personnelles. We point out that in application of articles L.223-1 et seq. Of the Consumer Code, you can, if you are a consumer, object at any time to being canvassed by telephone by registering for free on the site www.bloctel.gouv.fr.

    2. CONTACT US If you have any questions, comments, or concerns regarding our Privacy Policy, please contact us at [email protected] FXHASH FOUNDATION is a French société par actions simplifiée having its registered office at 13 Place du couvant, 43150 Le Monastier-sur-Gazeille, registered with the Lepuy-en-velay Trade and Companies Register under number 908 947 617, and represented by Mr. Baptiste Crespy, acting as Chief Executive Officer (Président), fxhash contact email address: [email protected]

    Logo
    Logo
    Payment Methods section
    reserves and allow lists are covered in more detail here
    tzkt.io
    tzkt.io

    Property

    Type

    Default

    Description

    min

    number

    Number.MIN_VALUE

    The minimum value the number can take. Controllers will be bound to [min; max]

    max

    number

    Number.MAX_VALUE

    The maximum value the number can take. Controllers will be bound to [min; max]

    step

    number

    undefined

    If defined, specifies the granularity that the value must adhere to. Only values which are equal to the basis for stepping (default if specified, min otherwise, eventually the random value generated if none are specified) are valid. If undefined, any number is accepted.

    Property

    Type

    Default

    Description

    minLength

    number

    0

    The minimum number of characters which has to be inputted

    maxLength

    number

    64

    The maximum number of character which can be inputted. We recommend keeping this value as low as possible, because this will always be the number of bytes sent onchain, even if a smaller string is inputted.

    Property

    Type

    Default

    Description

    length

    number

    0

    (Required) The maximum number of bytes which can be stored by this bytes parameter buffer.

    Property

    Required

    Type

    Default

    Description

    options

    Required

    string[]

    /

    A list of strings, corresponding to available options in the select.

    Property

    Type

    Default

    Description

    min

    number

    -9223372036854775808

    The minimum value the number can take. Controllers will be bound to [min; max]

    max

    number

    9223372036854775807

    The maximum value the number can take. Controllers will be bound to [min; max]

    a params:update event
    emitting a params.update event
    fx(params) section
    javascript float64 numbers
    Uint8Array
    BigInt javascript type
    $fx.params([
    {
    id: "a_number",
    name: "A number",
    type: "number",
    default: 5,
    options: {
    min: -10,
    max: 10,
    step: 1,
    },
    },
    ])
    $fx.params([
    {
    id: "a_string",
    name: "A string",
    type: "string",
    default: "Default value",
    options: {
    minLength: 5,
    maxLength: 32,
    },
    },
    ])
    $fx.params([
    {
    id: "a_boolean",
    name: "A boolean",
    type: "boolean",
    default: false,
    },
    ])
    {
    arr: {
    rgb: [25, 6, 158],
    rgba: [25, 6, 158, 104],
    },
    hex: {
    rgb: "#19069e",
    rgba: "#19069e68",
    },
    obj: {
    rgb: { r: 25, g: 6, b: 158 },
    rgba: { r: 25, g: 6, b: 158, a: 104 },
    }
    }
    $fx.params([
    {
    id: "a_color",
    name: "A color",
    type: "color",
    default: "abababff",
    },
    ])
    $fx.params([
    {
    id: "some_bytes",
    name: "Some bytes",
    type: "bytes",
    update: "code-driven", // required!!
    options: {
    length: 4,
    },
    // the default value must be an Uint8Array
    default: new Uint8Array([0, 255, 48, 57]),
    },
    ])
    $fx.params([
    {
    id: "a_select",
    name: "A select",
    type: "select",
    default: "one",
    options: {
    options: ["one", "two", "three", "four"],
    },
    },
    ])
    // output example:
    // "one"
    console.log($fx.getParam("a_select"))
    $fx.params([
    {
    id: "a_bigint",
    name: "A BigInt",
    type: "bigint",
    default: 1458965n,
    options: {
    min: -1000000000000000n,
    max: 1000000000000000n,
    },
    },
    ])

    Programming Open-form Genart

    Practicable notes on seeding open-form generative artworks and crafting interesting projects

    Building the deterministic randomness of an open-form generative artwork is different from the traditional manner of building a long-form generative artwork. Before tackling this technical resource, learn more open-form genart here.


    Similarly to long-form projects, open-form generative artworks still need to be deterministically random: the art generating script should always produce the same output for the same input seed/hash that it derives its randomness off of.

    The difference with open-form generative art, is that the art generating script now receives an array of hash strings as input, rather than a single input hash.

    This array is an ordered list of all the elapsed hash strings associated with the individual tokens that form an evolution lineage.

    • New editions collected at the root of a project behave like editions minted from a regular long-form project, they have a simple input hash.

    • Editions that are evolved from other editions, receive their own proper new input hash, as well as the hash of their parent, as well as the parent's parent, and so on. In form of an array.

    • The last entry in this array is the current edition's assigned hash string.

    As an artist this means that you are now designing a new kind of generative algorithm that leverages multiple randomness generators—each seeded by one of the hash strings in the input array.

    Conceptually, open-form projects are systems of systems: each minted edition can be thought of as a generator in its own right that serves as a template to spawn new child editions.

    Before diving into the technical details, check out the open-form simulator below to get a feel for how this works—and try it out for yourself :

    API Reference

    Developing an open-form genart project introduces a number of new fields in the API:

    Function
    Function Signature
    Purpose/Effect

    $fx.lineage

    Open-form genart introduces a new URL schema where an evolved edition receives all of its parent hashes {url}?fxhash={hash}#lineage={parent-hash-0},{parent-hash-1},{parent-hash-2}, in addition to its own hash. In the API you can access the individual parent hashes through the $fx.lineage array:

    Note that in this array, the last hash in the array is the current edition's hash.

    $fx.depth

    The depth of the current iteration. It encodes the number of parents an iteration has. It is always equal to $fx.lineage.length - 1

    $fx.randAt()

    In regular long-form projects $fx.rand() provides a deterministc PRNG that's seeded an individual input hash. Through $fx.randAt() you now have access to multiple PRNGs—one for each of the hashes in a token's lineage, accessible by passing the hash's index into the function.

    $fx.randAt will throw an error ("Invalid depth") if you try to access a PRNG that doesn't exist.

    $fx.randAt($fx.depth) and $fx.rand() point to the same PRNG, meaning that $fx.rand() is simply the PRNG seeded by the last hash in the lineage, which is basically the latest and current hash. Additionally for $fx.depth == 0 we have $fx.rand(), $fx.randAt(0), and $fx.randAt($fx.depth) all pointing to the same PRNG.

    The individual randomness generators provided through $fx.randAt() are independent of each other. Their invocation of one does not advance the random state of another. For example, the two following examples are identical—the ordering of $fx.randAt() only matters for each individual depth index:

    is identical to:

    Each PRNG can also be reset in the following manner:

    Seeding your own PRNGs with $fx.createFxRandom

    Besides the new open-form specific API fields there is now also a new $fx.createFxRandom function that lets you instantiate your own PRNGs, based on an input hash. This is useful when you want to create an isolated randomness generator, for a specific function or class in your code. Make sure that you check the determinism of your code when doing so, and that the input hash that you are basing this custom PRNG off of is generated in a deterministic manner in your code. This custom PRNG returned behaves just like the regular PRNG fxhash provides.

    Caution with $fx.randminter & params in open-form projects

    While the entirety of the fxhash API is exposed within all projects, the $fx.randminter and params fields are not compatible with open-form projects. Hence these parts of the API should not be used, only the fields outlined in this resource. Otherwise the project will behave in a non deterministic manner.

    Developing open-form projects locally with fxlens

    If you've previously developed a long-form project for fxhash and are familiar with the CLI and fx(lens), getting started on developing an open-form project is as simple as running npx fxhash create from your terminal. A new open-form template option will be available.

    Then navigate into the new directory cd <your_project_folder> and run npx fxhash dev, which will boot up fx(lens) in your browser.

    If it's your first time developing a project for fxhash, .

    The structure of an open-form artwork has not changed, it is an index HTML file, an optional CSS style sheet, and a script file that now needs to be configured using the new open-form API. Your project can still not make networked requests or load in packages from URLs.

    In case you plan to develop and release a regular long-form project in the coming days prior to open-form genart going live on fxhash, you need to prevent the SDK from being updated when running the fxhash dev command that launches fxlens from the terminal.

    npx fxhash dev --noUpdate : adding the --noUpdate frag prevents updates from being installed when starting the dev server through the terminal.

    The local dev environment fx(lens) got a new tab that lets you change between the existing “long form” and the new “open form” modes. The UI will help you to explore the lineages of your generative art project. You will see a list of all the hashes. A visual representation of each edition in the lineage. Aswell as a graph visualization of the current tree of generations.

    The individual artworks displayed in the open-form UI are captures and not live running artworks. This is done to avoid potential performance problems in case of the generative artwork requiring heavier computations. When evolving lineages in quick succession through the UI captures are queued are queued in the background, meaning that there's always only one live instance of your artwork running at a given time. is used for creating the capture—triggered just as normally when you call $fx.preview() in your code.

    In case you experience problems with captures—please reach out on discord. We are still improving the local capture pipeline.

    By selecting one edition from the tree or graph you will enter the already known live mode of the edition. The graph will highlight the lineage of the node. You can now experiment with different hashes of the edition. In case the edition already has children, these updates will then be propagated accordingly.

    Programming open-form genart

    In what follows we provide a couple of examples on how to configure randomness in your open-form project, showcasing how $fx.randAt in combination with $fx.depth can be used for practical purposes. There are a couple of major ways to design open-form mechanics:

    1. Depth-based Traits: aspects of the artwork that are directly tied to an minted/evolved edition's depth.

    2. Root Traits: a common characteristic based off of the hash string of an edition minted at the root of an open-form project (first in a lineage).

    3. Inherited Traits (Re-generating Parent Randomness): evolved editions inherit traits by recreating/reproducing the random steps parent editions have previously computed.

    4. Random Mutations

    Depth-based Traits

    The simplest new mechanic in open-form genart to create an interesting, evolving artwork is by tying visual, or other parameters, of the artwork to the corresponding depth that it's minted at.

    For example, in the open-form simulator, the resolution of the pixel grid (its width and height) can increase as the depth of the longer a token's lineage is.

    And in your code you'd simply use the $fx.depth parameter that's exposed by the API to make this happen.

    One idea here could be tying an obvious visual characteristic of the artwork to the depth, so that it's immediately evident what depth the artwork belongs to.

    Root Randomness

    Editions minted at the root of a project (that aren't evolved from another edition and don't have a parent) behave like editions collected from a regular long-form generative artwork. In root mints $fx.rand(), $fx.randAt(0), and $fx.randAt($fx.depth) will all point to the same PRNG. From an open-form design point-of-view, this root randomness can be used to set lineage defining characteristics.

    For example, let's use this root randomness to select a color palette to be used in whatever graphics we draw next:

    Keep in mind that the hash string at index 0 of the hash list will be the same for all evolutions/child tokens derived from this root edition. This means that using $fx.randAt(0) in this manner will use same randomness to make a palette selection, whether it's the root edition, or the tenth edition down the lineage—the same palette will be picked.

    In other terms, the root randomness (randomness derived from the index 0 hash) can be used to select lineage defining characteristics. As a simple visual example, this could be the color palette, giving each lineage of the open-form project a unique characteristic:

    This same concept applies to using $fx.randAt() at any depth, in case you want a certain behavior to emerge at a specific depth.

    Re-generating Randomness: Trait Inheritance

    There is no direct way to pass values from parent editions to child evolutions. However, this is likely a common type of behavior that most projects will aim to implement; where editions pass on traits, characteristics, and variables to their evolutions.

    To achieve this kind of inheritance the open-form script should be designed in such a manner that the evolved editions reproduce the randomness (random selections and randomly generated numbers) that parent tokens have previously computed.

    In practice, this simply boils down to looping over the lineage PRNGs, recomputing the previously made random decisions, and then adding to it with the current edition's randomness. More concretely, we would simply call $fx.randAt in a loop, from 0 up until the current $fx.depth.

    In the following example we are simply constructing a sentence, such that we add a new randomly selected word with each evolution.

    Assuming that our artwork revolves around this constructed sentence in some manner, evolutions will inherit the first part of the sentence that was chained together throughout the preceding lineage, and add their own individual word:

    L-system Example

    A more complicated setting to exemplify this would be an L-system, in which the string is mutated over the course of the collected and evolved editions. Let's assume a simple alphabet and grammar like the following:

    In this grammar each letter has a couple of replacement options—for an evolved child token we want to choose a replacement option at random and construct a new string that will be the base for the collected edition. The evolution logic would be as follows:

    This behavior would look as follows:

    Pitfalls to avoid

    While the API might seem minimal, open-form genart comes with its own complexities; your code always needs to account for the existence—or non-existence—of hashes depending on its mint depth.

    Besides the regular determinism pitfalls that you should avoid — — there likely are many scenarios that could cause the deterministic evolutionary sequence of your open-form projects to break. Make sure to carefully design your open-form randomness and test your project plenty ahead of release.

    As an example, one scenario that comes to mind are conditional blocks that assume the existence of a specific depth. What's the problem with the following block of code?

    Inside of the for loop we're assuming a certain depth/length of the hash list that might not exist yet when the code runs. For the first three minted/evolved editions the loop will simply not do anything, and the phrase string will be remain empty—whereas on the fourth evolution it will do a sudden jump and catch up with the suddenly filled hash list, likely resulting in a random artwork that does not follow the intended open-form progression.

    Random Mutations

    In addition to having root traits for individual lineages, as well as traits that are passed on between evolutions, you'll likely also want to spawn new random traits sometimes.

    This involves adding a small algorithmic chance to make a modification appear at random, at a certain depth. In the open-form simulator there's a small chance for new colors to appear after depth 4 has been reached.

    Let's revisit our color palette example from earlier—assuming that we're selecting a base palette with the root randomness, we could randomly append a new color to the selected palette:

    This random chance could also be made relative to the depth, such that as the depth increases, the more likely it becomes for these random traits to appear—as an additional incentive for collectors to explore the open-form tree in a depth-first manner.

    Random Traits

    In case you would like to have completely random deterministic aspects for your artwork, you can simply use the last hash in the lineage array—essentially the native hash of the current edition.

    Conclusion

    Keep in mind, you'll want to design your randomness in such a way that collectors are incentivized to collect your open-form project horizontally and vertically—exploring its parametric space in full, and participating in shaping and curating an interesting collection.

    Make sure to also read through the other sections provided in the open-form docs.

    Base | Ecosystembase
    How To Swap ETH for XTZ Without a Centralized Exchange.Medium
    Logo

    You can also revert to the previous version of the CLI/SDK with the update command and specifying the correct version:

    npx fxhash update --sdkVersion=0.0.13 : installs the last version of the sdk that has no open-form features.

    : random traits that appear in evolved editions after a certain depth is reached.
  • Completely Random Traits: using the seed of the current edition (final seed in the seed list).

  • $fx.lineage

    string[]

    An array of hash strings. One for each of the parents in an evolved edition's lineage of parent tokens.

    $fx.depth

    number

    Simply a number that represents the number of parents a minted edition has.

    $fx.randAt: (depth: number)

    number

    A random number that's generated by a PRNG seeded by the individual lineage hashes at a given depth.

    here
    learn all about setting up an fxhash project and the fx(lens) local dev environment here
    html2canvas - Screenshots with JavaScript
    some of which we have outlined here
    $fx.lineage = [{parent-hash-0}, {parent-hash-1}, {parent-hash-2}, {hash}]
    $fx.depth: number
    $fx.randAt(0) // prints 0.11
    $fx.randAt(1) // prints 0.83
    $fx.randAt(0) // prints 0.52
    $fx.randAt(0) // prints 0.11
    $fx.randAt(0) // prints 0.52
    $fx.randAt(1) // prints 0.83
    $fx.rand() // 0.4928672278765589
    $fx.randAt($fx.depth) // 0.40502416901290417
    $fx.randAt.reset($fx.depth)
    $fx.rand() // 0.4928672278765589
    $fx.randAt($fx.depth) // 0.40502416901290417
    let customHash = "0x31613e9006c9de9a9ccfcfa263b6b42e1404f3abefcf73e8df2f320c7497852c"
    let customRNG = $fx.createFxRandom(customHash)
    
    customRNG() // 0.4928672278765589
    // grid dimensions increase by 2 squares every evolution
    const gridWidth = 6 + $fx.depth*2
    const gridHeight = 6 + $fx.depth*2
    
    // draw your artwork here
    // three distinct color palettes
    const palettes = [
        ["#0a0a0a", "#f7f3f2", "#0077e1"],
        ["#f7f3f2", "#0077e1", "#f5d216"],
        ["#0077e1", "#f5d216", "#fc3503"]
    ]
    
    // use root randomness to pick a palette
    const palette = palettes[Math.floor($fx.randAt(0) * palettes.length)]
    
    // draw some art here using the palette
    const words = ['this', 'is', 'a', 'random', 'string']
    let phrase = ''
    
    // loop over the hash list
    for(let n = 0; n < $fx.depth; n++){
        // add a word to the phrase at random
        phrase += ' ' + words[Math.floor($fx.randAt(n) * words.length)]
    }
    gen. 0     gen. 1       gen. 2                 gen. 3
    
    is------>  is this   -> is this random    ->   is this random string
     |
     └------>  is random -> is random string  ->   is random string this
                    |
                    └-----> is random this    ->   is random this string
    let alphabet = ['A', 'B', 'C'];
    
    const rules = {
        'A': ['AB', 'AC'],
        'B': ['BC', 'BA'],
        'C': ['CA', 'CB'],
    };
    /*
        create an initial base string with n distinct letters
        using the root randomness
    */
    const baseStringLength = Math.floor($fx.randAt(0) * 4) + 1;
    let currentString = '';
    for(let i = 0; i < baseStringLength; i++){
        currentString += alphabet[i];
    }
    
    // compute the replacement string depending on the depth
    for(let i = 0; i < $fx.depth; i++){
    
        let replacementString = '';
        for(let n = 0; n < currentString.length; n++){
            let replacement = rules[currentString[n]][Math.floor($fx.randAt(n) * 2)]
            replacementString += replacement;
        }
        
        currentString = replacementString;
    }
    
    // use the computed string for art purposes in what follows
    Iteration 0:            A               B            C
                        ┌───┴───┐       ┌───┴───┐     ┌──┴──┐
    Iteration 1:        A       B       B       A     C     B
                      ┌─┴─┐   ┌─┴─┐   ┌─┴─┐   ┌─┴─┐ ┌─┴─┐ ┌─┴─┐
    Iteration 2:      A   B   B   A   B   C   A   C  ...
    
    const words = ['this', 'is', 'a', 'random', 'string']
    let phrase = ''
    
    for(let n = 0; n < $fx.depth; n++){
        if($fx.depth > 4){
            phrase += ' ' + words[Math.floor($fx.randAt(n) * words.length)]
        }
    }
    // three distinct color palettes
    const palettes = [
        ["#0a0a0a", "#f7f3f2", "#0077e1"],
        ["#f7f3f2", "#0077e1", "#f5d216"],
        ["#0077e1", "#f5d216", "#fc3503"]
    ]
    
    // some other colors to inject randomly
    const otherColors = ["#584594", "#e488b7", "#d74c41", "#f0d235", "#36ad63", "#69bcea"]
    
    // use root randomness to pick a palette
    const palette = palettes[Mat.floor($fx.randAt(0) * palettes.length)]
    
    // draw some art here using the palette
    // after the fourth generation select
    if($fx.depth > 3){
        for(let n = 0; n < $fx.depth; n++){
           // small chance to add a random color to the palette
           if( $fx.randAt(n) > 0.99 ){
              palette.push(
                 otherColors[ Math.floor( $fx.randAt(n) * otherColors.length ) ]
              )
           }
        }
    }
    
    // create the artwork here
    // make sure the altered palette doesn't break the sequencing/pattern though
    $fx.randAt($fx.depth)

    API Reference

    Overview and detailed explanations of the individual API functions

    A reference for fx(params) related API functions can be found in the API Reference fx(params)

    API Overview

    Explanation of the open-form part of the API:

    $fx.hash

    The string hash injected into the iteration. Will be unique for every iteration of a project. Directly grabbed from the fxhash URL parameter when the iteration is loaded.

    $fx.rand()

    The $fx.rand() function is a Pseudorandom Number Generator which outputs a number between 0 and 1 ([0; 1[). It uses the unique hash injected into the code as a seed, and will always output the same sequence of numbers.

    The fx(hash) API provides an implementation of SFC32 () as the PRNG. The $fx.rand() function also points to the equivalent fxrand() function, although they can be used interchangeably, we recommend using the syntax that prepends the $fx object for consistency across your code.

    It is not mandatory to use the $fx.rand() function as your source of randomness, you can implement the PRNG of your choice instead, as long as it uses the hash as the seed.

    $fx.rand.reset()

    You can reset $fx.rand() PRNG to its initial state by calling $fx.rand.reset():

    $fx.minter

    The string wallet address of the minter injected into the iteration. Directly grabbed from the fxminter URL parameter when the iteration is loaded.

    $fx.randminter()

    Similarly to the $fx.rand() function, the $fx.randminter() function is another Pseudorandom Number Generator that derives its randomness from the minter address injected into the code as a seed, and will always output the same sequence of numbers. It outputs a number between 0 and 1 ([0; 1[).

    The fxhash snippet provides an implementation of SFC32 () as the PRNG. The $fx.randminter() function also points to the fxrandminter() function. You can use the two of them interchangeably, but we recommend using the $fx syntax for consistency accross your code.

    It is not mandatory to use the $fx.randminter() function as your source of randomness, you can implement the PRNG of your choice instead, as long as it uses the minter address as the seed.

    $fx.randminter.reset()

    Similarly to $fx.rand.reset() you can also reset the $fx.randminter() PRNG to its initial state by calling $fx.randminter.reset().

    $fx.context

    The $fx.context property is a flag that indicates the context in which the code is executed. There are 3 possible values for this flag:

    • standalone: (default) when the final output should be displayed, on the main project page for instance

    • capture: when the code is executed in the capture environment, to get an image preview of an iteration

    • minting: when the code is executed during the minting flow of the collector

    This flag is passed in by fx(hash) via the fxcontext URL parameter.

    $fx.iteration

    The $fx.iteration property indicates the iteration number of the collected GENTK, it can be used for experimental purposes to base certain aspects of the artwork off of it:

    The iteration number is passed in by fx(hash) via the fxiteration URL parameter.

    $fx.preview()

    The $fx.preview() function triggers the capture module when the code is run in the capture context, which creates the image previews that will be displayed by fxhash and other websites to show the collected iterations.

    For projects where an animation is rendered, this function can be particularly useful to trigger a capture for a particular frame:

    Also make sure to properly configure the capture settings when minting your project on fxhash, you can read more about this in

    $fx.isPreview

    The $fx.isPreview is a boolean which will be set to true if your code is being run in the capture context. It can be useful when you want to run a certain snippet of code only during when the artwork is being captured.

    When a capture of an iteration is taken by fxhash capture module, an url parameter preview=1 is added. The fxhash snippet detects if this parameter is set to 1 and sets $fx.isPreview to true or false based on that.

    $fx.features(features)

    Artists have the option to expose certain characteristics in an explicit manner via fx(hash) ‘features’. Features are essentially attributes that describe certain aspects of the artwork once it is collected. For instance, the artist can choose to explicitely indicate the rarity of a certain output with a feature, or can also describe the randomly chosen color palette that is used for the coloration of the artwork by exposing the name of this color palette with another feature.

    In other words, features are tags that describe the randomly chosen qualities of the collected artwork. They are entirely optional.

    If you would like to set them in your project, you can do so via the $fx.features() function. This function expects as input an object with key:value pairs, where these values can have the following types string, number or boolean. Here’s an example:

    What’s important is that features should not be hardcoded, but rather be randomly generated with the PRNG, and they should always match the visual characteristics of the Token (ie reflect the settings behind the generative process of the token).

    $fx.features() should only be called once, as multiple calls of $fx.features() will erase features set by a previous function call. For the fx(hash) module to pick up the artist set features, the $fx.features() function must be called once the page is loaded. For instance, the following code might result in features not getting picked up by our module:

    Fxhash automatically computes the rarity of a particular feature by counting the number of occurences among all the tokens of the collection. Two feature values are considered the same if a between those returns true. If you want the rarity of a feature to be meaningful, you must define its values in a way that ensures multiple occurrences to appear.

    For instance, this will not work well with the rarity module:

    If defined in such a way, each token will have a different Intensity feature value and thus they will all have the same rarity in regard to that feature. What you can do instead, is to assign a string to a range of values:

    With this implementation, the value of the feature will only be low, medium or high. This ensures that the rarity module will correctly assign the Intensity feature rarity when a Token is minted. Of course, this is a very naïve implementation, you may want to adapt it to fit your needs in a better way.

    $fx.getFeature(name)

    This function outputs the value of a feature, given its name. Must be called after $fx.features(). The name parameter should match a key defined of the object passed to $fx.features():

    Since this function requires the name of the feature to be passed to it, it can become quite verbose and redundant to call it every time you need to access the value of a feature, especially if you need this value a lot. In such a case, we recommend storing the feature value in a variable instead:

    $fx.getFeatures()

    Returns the whole object passed to the $fx.features(object) function. Must be called after $fx.features().

    Logo

    Function

    Function Signature

    Purpose / Effect

    $fx.hash

    string

    The hash string provided (or injected into) for each iteration.

    $fx.rand()

    () => number

    Generates a pseudo-random number using the hash as the seed, ranging from 0 (inclusive) to just under 1 (exclusive).

    $fx.rand.reset()

    () => void

    Reinitialises the $fx.rand() generator to its original state.

    $fx.minter

    string

    The wallet address of the minter, provided (or injected into) for each iteration.

    $fx.randminter()

    () => number

    Similar to rand(), but uses the minter's address as the seed, with the same output range.

    $fx.randminter.reset()

    () => void

    Reinitialises the $fx.randminter() generator just like rand.reset().

    $fx.context

    string

    Indicates where the code is running: standalone, during capture, or while minting.

    $fx.iteration

    number

    The iteration number of the collected GENTK.

    $fx.preview()

    () => void

    Triggers the image capture module at mint time to create the image preview for the collected iteration.

    $fx.isPreview

    boolean

    Set to true when the code runs in the fxhash capture module. Useful for defining capture-specific properties.

    $fx.features()

    (object) => void

    Function that specifies the features of the collected iteration.

    $fx.getFeature()

    (string) => any

    Retrieves the value of a named feature as set by the features() function.

    $fx.getFeatures()

    () => object

    Returns the entire features object as defined by features().

    $fx.params()

    (array) => void

    Define collector-modifiable parameters for your piece by calling this with an array.

    $fx.getParam()

    (string) => any

    Returns the value of a param via its ID.

    $fx.getParams()

    () => object

    Returns a dictionary of all parameter key-value pairs, as currently set.

    $fx.getRawParam()

    (string) => string

    Provides the raw parameter data (as a bytes string) as it was passed to the iteration.

    $fx.on()

    (string, function, function) => function

    Registers an event listener and returns a function to deregister it.

    $fx.emit()

    (string, any) => void

    Sends an event to the parent context, useful for dynamic parameter updates from within the code.

    Open-form API

    —

    —

    $fx.lineage

    string[]

    An array of hash strings. One for each of the parents in an evolved edition's lineage of parent tokens.

    $fx.depth

    number

    Simply a number that represents the number of parents a minted edition has.

    $fx.randAt: (depth: number)

    number

    A random number that's generated by a PRNG seeded by the individual lineage hashes at a given depth.

    Programming Open-form Genart
    Standard Fast Counter 32
    Standard Fast Counter 32
    Minting Interface Walkthrough
    strict equality
    console.log($fx.hash) // output example: ooj2HmX8dgniNPuPRcapyXBn9vYpsNwgD1uwx98SLceF6iCZJZK
    const randomNumber = $fx.rand() // number [0; 1[
    const otherRandomNumber = fxrand() // same effect as above
    $fx.rand() // 0.25
    $fx.rand() // 0.88
    $fx.rand() // 0.124
    
    // reset fxrand
    $fx.rand.reset()
    
    // calling fxrand again will yield the same outputs as the first calls
    $fx.rand() // 0.25
    $fx.rand() // 0.88
    $fx.rand() // 0.124
    console.log($fx.minter) // output example: tz18jgjtEDRtkvNoV9LToradSmVNYFS9aXEe
    const rand01 = $fx.randminter() // number [0; 1[
    const r2 = fxrandminter() // same effect as above
    $fx.randminter() // 0.25
    $fx.randminter() // 0.88
    $fx.randminter() // 0.124
    
    // reset fxrandminter
    $fx.randminter.reset()
    
    // calling fxrandminter again will yield the same outputs as the first calls
    $fx.randminter() // 0.25
    $fx.randminter() // 0.88
    $fx.randminter() // 0.124
    if ($fx.context === "minting") {
    // run code for the minting UI
    } else {
    // otherwise display the final output
    }
    console.log($fx.iteration) // output example: 42
    function draw() {
    	
    	// ...
    	// code that generates the graphics
    	// ...
    	
    	// trigger the capture module when all graphics have been generated
    	$fx.preview()
    
    }
    let counter = 0
    function draw() {
    	
    
    	// ...
    	// code that generates the graphics
    	// ...
    	
    	// increment frame counter
    	counter++
    	
    	// when reaching frame 6000, trigger the capture
    	if (counter === 6000) {
    		$fx.preview()
    	}
    
    	requestAnimationFrame(draw)
    }
    
    requestAnimationFrame(draw)
    if ($fx.isPreview) {
    	// will be executed only when preview is taken by fxhash
    } else {
    	// usual execution
    }
    // call this function before performing computations
    $fx.features({
    	'A feature of type string': $fx.rand() > 0.5 ? 'Super cool' : 'Not cool !',
    	'Feature number': Math.floor($fx.rand() * 100),
    	'A boolean feature': $fx.rand() > 0.8 > true : false,
    	'A constant feature': 'constant value',
    })
    // WILL NOT WORK CONSISTENTLY
    setTimeout(() => {
    $fx.features({
    	// here define the token features
    })
    }, 1000)
    $fx.features({
    // each token will have a different "Intensity" feature value between 0 and 1
    Intensity: fxrand(),
    })
    function getFeatureString(value) {
    	if (value < 0.5) return "low"
    	if (value < 0.9) return "medium"
    	else return "high"
    }
    
    $fx.features({
    	// feature can only be "low", "medium" or "high"
    	Intensity: getFeatureString(fxrand()),
    })
    // defining the features
    $fx.features({
    	"First feature": 0.5,
    	"Another feature": true,
    })
    
    // outputs "0.5"
    console.log($fx.getFeature("First feature"))
    
    // outputs "true"
    console.log($fx.getFeature("Another feature"))
    const feat1 = "feature value here"
    $fx.features({
    	"A very long feature name, not practical": feat1,
    })
    
    // same outputs
    console.log($fx.getFeature("A very long feature name, not practical"))
    console.log(feat1)
    // first define the features
    $fx.features({
    	"feat 1": 0.8,
    	"feat 2": true,
    })
    
    // outputs:
    // {
    //   "feat 1": 0.8,
    //   "feat 2": true
    // }
    console.log($fx.getFeatures())
    Logo

    Collaborative Projects

    An overview of how Collaborations function on fxhash

    fxhash comes with built-in tools so that the work that is the fruit of a collaboration between many artists can be released in the best possible conditions and such that profits generated from the sale of the project can be distributed fairly and automatically. We provide a collaboration factory contract which can be used to originate collaboration contracts between any number of entities.

    What is a collaboration contract ?

    A collaboration contract allows entities to create, approve and send operations to the blockchain as a group.

    Creating a collaboration contract doesn't bind the different parties together, but sending operations through the collaboration contract is binding. An operation can be sent through a collaboration contract if and only if all the parties have approved the transaction. Only then the transaction can be executed by any member of the collaboration. Not all the transactions are made available through the collaboration contract but only a list of operations provided by fxhash. This ensures that the transactions that are sent through the collaboration contract are safe to be sent.

    How to create a collaboration ?

    Anyone can create a collaboration by going to the . You need to add all the collaboration members to the form.

    The shares will be used in case some funds are sent to the contract (if other marketplaces were to pay royalties directly to the collaboration contract for instance). We recommend leaving the default shares, so that the funds are equally split between all the members of the collaboration.

    Please note that the shares of collaboration contract itself don't guarantee that the proceeds made by publishing the token through the collaboration will be split between all the parties. You still need to define how the proceeds will be split on the primary and secondary market at the creation of the generative token. By default if you author the piece as a collaboration, the UI will pre-fill the splits on primary and secondary so that each collaborator gets the same amount.

    You can setup different splits if you author different pieces with the same collaboration contract for instance.

    Integration on the Platform

    When fxhash detects that a work was published with a collaboration contract, it assigns all the members of the collaboration as authors. We tried to provide a seamless integration of the collaboration contracts as we feel that they play a major role in the development of our artist community.

    If a work is published as a collaboration, it will also appear on all the profiles of the collaborators.

    How to send operations as a collaboration group?

    We tried to make the usage of the collaboration as transparent as possible for you. For instance, you can edit the settings of a token as you would do if you were its only author, but instead of sending the update operation directly it creates a proposal in the collaboration contract itself.

    The collaboration manager

    When you go to your , you will see all your collaborations. Clicking on each will take you to a page where you can manage the collaboration. There are 3 tabs on this page:

    • operations awaiting: operations not sent to the blockchain yet

    • operations executed: operations previously approved and executed

    • informations: extra informations about the collaboration, such as the shares, the contract balance and a button to withdraw the funds

    Inspecting an operation

    Operations can be inspected before approval. By clicking on the operation type, you can toggle a preview which will show what the operation will do in an elegant manner:

    You can also check the exact call parameters if you want to be sure of what you are approving.

    You must be very careful when approving an operation on a collaboration contract, and make sure that you agree with its application. Our UI makes it easy to inspect those operations, and you should review those thoroughly.

    By approving an operation, you give your formal agreement for its execution. It's as if you sent the operation yourself.

    Approving and executing

    By default, the initiator of the operation will be marked as approving it. All other members must approve before it can be executed. You can approve or reject an operation with the corresponding buttons. These actions are not final, and you can change your vote as long as the operation hasn't been executed. Once all members have approved, the execute operation button is enabled, and any member can execute the operation.

    By clicking this button, the operation is executed, and voilà!

    Projects authored as a collaboration

    When a project is created through a collaboration contract, the address of the contract is stored as the author onchain. And since the members of a collaboration own the collaboration contract, they are indirectly co-authors by definition.

    On the fxhash website, when you edit a project co-authored, it will automatically create proposals in the collaboration contract (displayed in the operations awaiting section of the manager). Because we don't yet have a notification system, you will need to inform your collaborators that they need to approve the operation.

    Extra costs

    There are some extra costs that come with using a collaboration contract. First, the contract needs to be originated. Then, each operation needs to be stored twice, for the creation of the proposal (where the parameters are stored onchain) and for its execution (same cost as if you were to send the same operation by yourself).

    We recommend splitting those costs by having different members creating and executing an operation. Moreover, collaboration contracts can be reused.

    collaborations page
    collaborations page