Generative art collections on Highlight are sets of NFTs that are rendered by an artist's code at the time they're minted. This repository hosts CLIs that help creators and collectors manage and augment collections.
CLIs
Supported networks
All 15 networks that are supported on Highlight are supported here. They are:
Chain | Supported networks (chainId) | CLI name (used in CLI args) |
---|---|---|
Ethereum | Mainnet (1), Goerli (5) | ethereum, goerli |
Polygon | Mainnet (137), Mumbai (80001) | polygon, mumbai |
Arbitrum | Mainnet (42161), Goerli (421613) | arbitrum, arbitrum-goerli |
Optimism | Mainnet (10), Goerli (420) | optimism, optimism-goerli |
Base | Mainnet (8453), Goerli (84531) | base, base-goerli |
Zora | Mainnet (7777777), Goerli (999) | zora, zora-goerli |
Forma | Mainnet (984122) | forma |
Mantle | Mainnet (5000) | mantle |
Scroll | Mainnet (534352) | scroll |
- File deployment context
- File management context
- Setup
- Check how much it costs to deploy a file
- Deploy a file
- Add a file to a file system
- Remove a file from a file system
The Highlight File System client is a CLI tool to upload generative art projects onchain, and manage your onchain file systems. Each Generative Series contract hosts its own FileSystem to enable flexibility.
Writing a new file onchain consists of two major steps: deploying the file, and adding it to a contract's file system. Since this process is modular, creators can easily add files that are already deployed to a given chain to their contract's file system, without having to deploy a new copy themselves. For example, Highlight has already deployed the minified version of p5.js 1.6.0 to Base's Mainnet and its Goerli testnet. The tools in this repository make both steps extremely easy, and are easy to customize.
When you deploy a Generative Series collection on Highlight, your project is uploaded to Arweave by default. However, your contract has a file system built in that will let you, as the contract creator and owner, put your project onchain. The most gas-efficient way of storing files onchain (on the storage trie) is to deploy file contents as the raw bytecode of new smart contracts. Highlight has deployed a light-weight factory called the "FileDeployer", which uses parts of SSTORE2 by Solmate to deploy text as contract bytecode.
As per EIP-170, smart contracts on Ethereum have a 24kb size limit. Therefore, files over 24kb need to be partitioned into chunks of 24kb and uploaded. Additionally, deploying a 24kb smart contract costs about 5M compute units. While different chains place different limits on the total amount of compute units a single block can consume, Ethereum's (and most L2's) limit is 30M.
The deploy tool in this repository currently chunks files into 20kb blocks, and deploys a maximum of 4 contracts per transaction. Deploying files that are larger than 80kb will submit multiple transactions. Although on most chains this config can be bumped up, this allows users of chains with a 20M block compute limit to deploy files through the deploy tool. Users deploying files that are greater than 20kb but less than 24kb may want to update file-system/src/constants.js
to bump the config. A maximum configuration would likely consist of 24kb chunks with 5 contracts being deployed per transaction.
Once deployed as bytecode, an uploaded chunk can be read by converting the bytes back to human-readable text. Files split up into chunks can be read by appending the text of each deployed contract together. The file system on each Generative Series contract handles the conversion and concatenation of bytecode into a file's full contents.
Once a file is "uploaded" to the chain, with its content stored in bytes format, the owner of a Highlight Generative Series contract can add a file to the
The file system has 5 functions:
Function | Type | Parameters | Description |
---|---|---|---|
addFile |
write | fileName, fileStorageAddresses | Add a file to the file system |
removeFile |
write | fileName | Remove a file from the file system |
fileStorage |
read | fileName | Return addresses that make up file |
fileContents |
read | fileName | Return human-readable contents |
files |
read | Return all file names in system |
fileStorageAddresses are the addresses that hold the bytecode making up the contents of a file. Concatenating the human-readable version of the bytecode at these addresses returns the full file contents, which is what fileContents
does.
This repository has tools to add and remove files from a file system. To read a contract's file system, it is recommended to access the contract's interface on a block explorer, like Etherscan.
There are 4 commands supported by the CLI:
- Deploying a file
- Checking the cost to deploy a file
- Adding a file to a file system
- Removing a file from a file system.
file-system
has 3 folders / files a regular user will want to interact with.
file-system/files
are where you'll add files you want to deployfile-system/deployments
are where files you've deployed will have their addresses automatically recorded (per-chain). You shouldn't need to ever edit these files, unless you want to add a file to a file system that has already been deployed elsewhere or beforefile-system/config.json
are where you can edit the rpc urls of each chain, and manage your Ethereum accounts
The config is made up of:
addresses
, which holds the deployed address of theFileDeployer
singleton on each chain (not recommended to edit)rpc
, which holds the rpc urls for each chain (recommended to edit with private rpc urls)accounts
which uses a name-based accounts system to submit transactions with different Ethereum accounts
accounts
is a key-value store where the key is an account name, and the value is your account's private key. Each command that submits a transaction takes in an optional --acount
argument, which lets you specify what account you want to use to submit transactions. It defaults to the default
account, which this repository seeds accounts
with. You will need to add a private key here.
After cloning the repository, make sure you have yarn installed. Installing yarn. Then, follow these steps:
- Run
yarn install
- Run
yarn env:refresh
(oryarn env:refresh:legacy
if your npm version < 5.2.0) - Add a private key as the value of the
HL_FS_PK_DEFAULT
key in.env
The file system will take any --account
arguments and capitalize them, then prepend HL_FS_PK_
when looking for any accounts in your environment.
Common arguments in the following commands:
Argument | Description | Example |
---|---|---|
--name |
Name of file in file-system/files/ |
p5.min.js |
--network |
Network name, choices in file-system/config.json |
arbitrum-goerli |
--account |
Account name, from your environment | default |
--contract |
Your generative series contract address | 0x... |
--account
is always optional as it defaults to default
.
The following commands are all meant to be run in the root of this repository.
Before deploying a file, you can check how much it will cost to deploy a file. The cost is calculated using the network's current gas fee. Add a file to file-system/files/
to proceed.
Format: yarn cost --name <file name> --network <network name> --legacy <optional, defaults to false>
Example: yarn cost --name p5.min.js --network ethereum
If legacy is set to false, the cost estimator will use the maxFeePerGas
value to estimate the cost, instead of gasPrice
. It's recommended to keep legacy as false.
To deploy a file, add a file to file-system/files/
to proceed. The tool uses the name of the file to name the chunks that are deployed on-chain (these names are emitted in events, and are of the format sample-1
, sample-2
, etc.) and to name the deployment file that will be generated in file-system/deployments/
. For example, deploying sample.js
will create or update file-system/deployments/sample.js.json
. Every file in file-system/deployments
stores file storage addresses by chain, so that you can deploy the same file to multiple chains without overwriting anything. However, deploying a file by the same name to the same chain as another entry will overwrite that entry.
You will be able to use the generated deployment file immediately after deployment to add a given file to your contract's file system.
Files that are larger than 20kb will be automatically split up into chunks of 20kb. These chunks will be stored in a "split" folder, named in the format {fileName}-split
in the file-system/files
folder (the same folder). If you run the deploy command with a file that already has a split folder, the tool will re-use the existing chunks in the split folder.
Therefore, if you modify any files larger than 20kb and wish to re-deploy them, (meaning they have an existing split folder that was previously deployed), make sure to delete the split folder corresponding to the file.
Format: yarn deploy --name <file name> --network <network name> --account <optional>
Example: yarn deploy --name p5.min.js --network ethereum
Files that have an entry in a deployment file (in file-system/deployments
) are eligible to be added to a file system via the CLI. You can seamlessly move on from deploying a file to this step, or manually paste in the storage addresses for a file that you know is already deployed to a chain.
You must be the owner of the contract hosting the file system you're adding a file to. The file name must not already exist on the file system - otherwise, remove the file if you wish to overwrite it.
Format: yarn add-file --name <file name> --network <network name> --contract <contract address of file system> --account <optional>
Example: yarn add-file --name p5.min.js --network ethereum --contract 0xc279f14a9fC0Ea2c715B025040E121BECF943323
You must be the owner of the contract hosting the file system you're removing a file from. The file name must already exist on the file system.
Format: yarn remove-file --name <file name> --network <network name> --contract <contract address of file system> --account <optional>
Example: yarn remove-file --name p5.min.js --network ethereum --contract 0xc279f14a9fC0Ea2c715B025040E121BECF943323
Highlight has deployed some commonly used libraries accross our multi-chain system so that creators can easily add existing libaries to their file system without having to deploy them.
Additionally, the HL FileSystem is compatible with historically relevant file systems on Ethereum, such as Mathcastles and ETHFS. Some libaries deployed via these file systems on Ethereum mainnet (chainId: 1) are also present in the list below.
Chain | File | Deployments File (containing file addresses) | Deployer |
---|---|---|---|
Ethereum | p5.min.js (1.4.2) | p5-v1.4.2.js.json | Mathcastles |
Ethereum | three.min.js (0.144.0) | three-v0.144.0.js.json | Mathcastles |
Base | p5.min.js (1.6.0) | p5-v1.6.0.js.json | Highlight |
Optimism | p5.min.js (1.6.0) [gzipped] | p5-v1.6.0.js.gz.json | Highlight |
Zora | p5.min.js (1.6.0) [gzipped] | p5-v1.6.0.js.gz.json | Highlight |
The Token Metadata Downloader is a CLI that anyone can use to:
- Download all metadata of all tokens in a collection into a single csv
- Download all images of all tokens (ie. token previews for generative art collections) into a single folder
This command lets you download all metadata of all tokens in a collection into a single csv. This is particularly useful for inspecting / analyzing distribution of traits.
Arguments:
address
Collection contract addressnetwork
Network name, as available in chains.jsondest
Path of csv file to put token metadata inrecursion
(optional) recursion depth: Toggle to try longer/shorter to get all token metadata in the case of failures
Format: yarn download:collection:metadatas --address <collection contract address> --network <network name> --dest <file path for csv> --recursion <*(advanced)* recursion depth, inspect code to see ability>
Example: yarn download:collection:metadatas --address 0xc111b1033DC8f32d85c152D7ac89C4311344D77D --network base --dest ./features.csv
This command lets you download all images of all tokens (ie. token previews for generative art collections) into a single folder. If you've already run "Download token metadatas" for this collection, it is advised to pass the path to the csv file (from the root of this repository) to the metadata
argument (to not re-compute token metadata) to save time. If your collection is really big, you can easily stop and start this process by re-running the command with --skip
, which will let you start where you left off.
Arguments:
address
Collection contract addressnetwork
Network name, as available in chains.jsondest
Path where to put folder of downloaded imagesmetadata
(optional) Path of a csv file to draw token metadata fromskip
(optional) If true, skip uploading token images that already exist at destination folderrecursion
(optional) recursion depth: Toggle to try longer/shorter to get all token metadata in the case of failures
Format: yarn download:collection:previews --address <collection contract address> --network <network name> --dest <folder path for downloaded images> --metadata <path of csv to draw token metadata from> --skip <if true, skip uploading uploaded token previews> --recursion <*(advanced)* recursion depth, inspect code to see ability>
Example: yarn download:collection:previews --address 0xc111b1033DC8f32d85c152D7ac89C4311344D77D --network base --dest ../Collection-Name --metadata ./features.csv --skip
The Highlight File System client and related information is offered on an as-is basis. Sea Ranch Labs, Inc., dba Highlight, gives no warranties regarding its use and disclaims all liability for damages resulting from its use to the fullest extent possible. Usage is fully governed by Highlight’s terms of service and privacy policy, available at the links provided. Please remember that blockchain transactions are immutable, and only proceed if you have requisite technical understanding.