Welcome
Experiments V1 is a project where I learn, explore, and experiment with 100% onchain generative art and onchain mechanics. This project is inspired by platforms like ArtBlocks and others. One important difference however is that here, there will never be any offchain code, p5.js, javascript, ipfs, or URLs to servers. Raw SVG code is generated and returned 100% onchain forever. This is a 'platform' for sharing and minting generative onchain art/ideas. It's permissioned, but open to anyone! click here for more information. The goal of this project is to learn a lot, experiment with onchain art and mechanics, demonstrate some possibilities of onchain SVGs, encourage other artists to get involved, develop my personal style, and emerge with a set of tools and techniques to work with SVG in solidity to create onchain art. Then take what I've learned and start thinking about a v2.
These "experiments" (also "editions") are managed by a single ERC721 smart contract on the Base L2 blockchain. Each individual edition is linked to its own immutable Art Generator contract. This contract is in charge of generating the raw SVG code and any attributes that this experiment may or may not have.
Each token has 32 bytes of storage that is stored in the ERC721 smart contract. This can be number, string, bytes, etc. When it comes to generative art, it is usually a "random" number. This number can be derived from block data like timestamp, block hash, minters address, etc. The seed can also be any arbitrary data that can fit into 32 bytes, and can be packed, unpacked and modified by the art generator contract.
This project is my submission to Base's Onchain Summer Buildathon 2024. To get it started, I've created several editions that will be deployed and mintable as soon as this project is ready. I will continue to create and add new editions over time to develop my personal style and to show the possibilities of onchain SVG art and hopefully inspire others to get involved.
One thing worth noting is that, since everything is onchain, you're faced with a couple limitations. For example contract size, gas limit, computing power, lack of standard SVG solidity libraries (for now...), etc. I actually like this "feature". For me, it pushes me to be more creative will less options. It also helps keep me from overthinking.
The token IDs work like this: (editionId x 1,000,000) + editionCounter
For example: tokenId #1000001 is the first token of edition 1, #4000056 is the 56th token of edition 4, etc.
Below are some flowcharts that show the basic moving parts for some of functions in this project.
Constructing the SVG images
when an SVG for a token id is being rendered by the main smart contract, it will first get the seed of the token, call the art generator contract to get the raw svg code, then insert the code into a blank 1000x1000 SVG template. At the top of the blank template, the contract will add a <title> and <desc> element with the name and artist address of the edition. If the artist chooses to add a signature, that will be added to the bottom of the SVG. By default it will be placed in the bottom right corner, the artist can change that by adding a getSignatureTranslate()
function to the art generator contract (more info here). The code that is returned from the art generator contract can be any valid SVG elements that can inside an SVG for example:
- another SVG → <svg>...</svg>
- a group of elements → <g> <rect/> <circle/> ... </g>
- any other elements → <rect/> <circle/> ...
Minting:
Minting is very straight forward. When a user mints, a few basic checks are done to make sure the edition exists and the max supply is not reached. If they all pass, the contract will call the art generator contract to create the seed, store it, then mint the token to the user. Each Art Generator can create the seed in any way they want. it might be a "random" number from block data. It could store specific data, or be blank.
Token URI
When you call tokenURI(id)
, the contract will look up the edition data, get the art generator address and token seed, then call getRawSvgAndAttributes(seed)
with the seed. The Art Generator contract will generator the raw svg code and any attributes that the edition may have. It then returns the svg and attributes to the main contract. the main contract then base64 encodes the svg, creates a json string with the name, description, attributes, etc. Then encodes all of that together and returns it as a base64 data uri.
Modifying:
Modifying allows an owner of a token to modify the seed of the token and store the new value in the contract. Each edition can modify the seed in different ways. If an edition does not allow modifying, it will revert. To modify, a user calls modify(uint tokenId, bytes calldata data).
`data`
is an array of bytes that is abi.encoded
off chain. The data that is encoded depends on which edition is being modified. `tokenId`
is the id of the token being modified, must be owned by the caller.
- A user calls
modify
on the main contract with the token id and the encoded data. - The contract verifies that the token is owned by the caller.
- The token ID is divided by 1,000,000 to get the edition ID, then the contract will look up the edition, get the art generator address, and attempt to call
modify
on the art generator contract passing the same data. - The art generator either revert, or will try to decode the data into the correct types and modify the seed.
- this is where everything happens, the artist/creator can do whatever they want here.
- The contract at this point has 3 things:
- the token id
- the main contract address
(msg.sender)
- the input data from the user
- some examples could be:
- it could ignore all that data and instead use `random` block data to create a new seed.
- pack together all the user input to create a new seed
- call the main contract, get the current seed of the token, increment a counter and revert if reached a certain point, check if the owner also owns other editions/ids, etc.
- the art generator then returns a new bytes32 seed which is stored by the main contract.
As you can see, this project is pretty simple, but very fun! As said above, this is a place for me to experiment and draft ideas, while at the same time creating a finished product that best conveys my vision and that anyone can use and enjoy. This is version 1 of n versions. Brainstorming for V2 can be found here. I encourage all onchain generative art enthusiasts to reach out if you want to contribute or have ideas!