Last Thursday, eniwhere_ challenged me on twitter with a "wen mint" after I posted a midjourney generated image in response to a public call-out by Only Dust. Using Starksheet, I have been able to no-code deploy the collection now called the Dusty Pilots with current floor price at 0.035 ETH and volume 0.2579 ETH in less that half-a-day, spending most of my time in the image generation and curation process.
This blog post aims at breaking down the step-by-step guide to deploy your own NFT collection with Starksheet!
The Starksheet app is a spreadsheet-like application deployed in Starknet. Unlike a regular spreadsheet, Starksheet aims at offering a mid-level entrypoint to everything on-chain: reading values, making single or mutlicall transactions, storing data.
More precisely, each sheet is made of 225 cells and is, from a Blockchain standard point of view, a classic NFT collection of up to 225 NFTs: minting a cell is really minting an NFT as in any other deployed collections.
Of course, a cell can do more but for this simple need, it is just enough to understand a cell as an NFT and forget about the rest. Much like in a spreadsheet where one can do massive mingled computation or just type some constant values in neighbors cells that look like a table.
If one just want to create a NFT drop and let the users mint as fast as possible:
go to app.starksheet.xyz
click "+" to add a sheet (cost 0.01 ETH/sheet)
click "Save" and wait for the tx to be "Accepted on L2"
retrieve the address in the transaction page, under "Deployed Contracts" (see this example tx)
your sheet is available at app.starksheet.xyz/{address}, (app.starksheet.xyz/0x00d1540fbe29acb2522694e9e3d1d776f1ab70773d33149997a65d06cc8a816f in the tx above)
Et voilà! You can now share this unique address with whoever you want to be able to mint your NFT: tell them to type any random value in the cells and click "Save" to mint.
Deploying a Sheet with the Starksheet interface puts some default values to parameters that you can change later on using, for example, starkscan.co.
Some are basic parameters while some others may require a more advanced skill set. For blockchain beginner, you need to be aware of the fact that a block explorer splits the possible calls into two categories:
READ: these calls are not making any transaction, these are just view functions to read some on-chain data provided by the contract. For example, your Sheet has a owner
view function, that returns the sheet's owner address, ie the address you used to deploy the collection
WRITE: these calls are making a transaction and costs gas because they modify the state of the blockchain. So be sure to double-check whatever you put in because you may lose money or break the Sheet. Fortunately, not all the calls are difficult to make!
Let's dig into some of the parameters a Sheet offers:
READ:
owner: the address of the collection owner (this address will be able to update anything on the collection, especially on Mint Square)
contractURI: returns metadata about the collection, see also Mint Square doc
tokenURI: this is the function called by any marketplace or wallet to get the information related to a given token. Notice that it takes a tokenId
as parameters
totalSupply: the total number of minted NFTs.
WRITE:
closeMint: by default, a Sheet is mintable when it is created. You may want to close it and open it later on with the openMint function.
setName: use this to update the name of the collection (default is "Sheet0"). Note that the name needs to be the hex string representation of the name. If you are not sure, you can use an online converter and paste the result (something like 0x1234)
setSymbol: use this to update the symbol of the collection (default is "SHT0"); see above for standard string to hex string.
setContractUri: use this add a url to fetch the contract data uri from. This is more advanced and requires you to:
get a permalink to a json file containing your contract uri (use for example IPFS)
split the url in chunks of no more than 31 characters long strings. For example, the url "ipfs://QmZQKPF3PHsKo8bUz8sEiVoqFh7qfGkFb6vY7N1VEVSdQj" is 53 character longs, so you would need to split it. This is an example url, not the one you have to put! For the sake of completeness, this url could be split in 4 like 'ipfs://QmZQKPF3P', 'HsKo8bUz8sEiVoqF', 'h7qfGkFb6vY7N1VE', 'VSdQj'. Then convert each of these chunk with the above mentioned tool, which should give '0x697066733a2f2f516d5a514b50463350', '0x48734b6f3862557a38734569566f7146', '0x68377166476b4662367659374e315645', '0x565364516a'
setCellRenderer: update the contract called to produce your token image. By default, a cell image is its value in a blue rectangle. You probably want to update this to you own NFT! For this, you need to deploy a contract and then call this function with its address. The following section gives all the details regarding this operation.
The minimal changes that you need to do for you collection to look like the Dusty Pilots is:
setContractUri
to give more data for Mint Square to add a banner and profile picture
setCellRenderer
to use a custom cell renderer, ie to change the cell image from the basic default blue rectangle to your own NFT
Usually, a NFT collection is made up of several images, each with their own characteristics, known as metadata. This data is retrieved by the marketplace calling the tokenURI
function of your contract.
In the Starksheet protocol, this call is indeed delegated to the CellRenderer
contract.
While you can develop your own CellRenderer
, you can also use the UriRenderer
the Starksheet team has made available for free. This renderer needs to be deployed with a base_uri
string and will produce for each token a tokenURI
like: base_uri/{token_id}.json
.
For example, the token uris of the Dusty Pilots are built with the following base_uri
https://raw.githubusercontent.com/the-candy-shop/starksheet-monorepo/main/packages/starksheet-cairo/dust_pilots/token_uris
And token 2
for example is retrieved at (see the added /
):
https://raw.githubusercontent.com/the-candy-shop/starksheet-monorepo/main/packages/starksheet-cairo/dust_pilots/token_uris/2.json
This contract needs to be set up with 2 parameters:
owner: the address owning the contract, and thus able to update it later on if required
base_uri: the uri to be concatenated with the token number as explained above.
To use your own renderer contract, you need to go to The Universal Deployer contract page and fill it as follows:
classHash: 0x1675f7720f525b280d71bbf04f646a16d3804d1de2f8e571636cacaa42b2fc3
salt: 0x1
unique: 0x1
calldata_len: 2 + number of chunks of the base uri
calldata: owner address, number of chunks of the base uri, chunks of the base uri
If you do it right, you have calldata_len
values separated by a ,
in calldata
.
Click "Write" and sign the transaction. Open the tx page and look for the "Deployed contracts" again. Opening the contract page, you can check that everything is set up properly by querying the getBaseUri
method.
If you want to first do the mint, and then later on unveil the tokens, you can call setUseTokenId
(Write tab) with 0
and it will only return the baseUri
Y ou can also update the base_uri
to something else, again splitting in chunks and converting to hex strings.
Finally, copy the address of the deployed contract and go back to your sheet page. Use this address as input for the setCellRenderer
, "Write", sign, and boom! you have customized your NFTs! As an owner of the collection, you can call "Refresh all" on the Mint Square page to propagate the changes.
Now that the tech part is fully covered, well, you need to generate your NFT data!
Each NFT uri (like base_uri/token_id.json
) should return a json file with at least the following data:
{
"description": "Description of the item",
"image": "Image url",
"name": "Name of the item",
"attributes": [
// a optional list of attributes displayed by marketplaces
{
"trait_type": "a first category",
"value": "value for this trait"
},
{
"trait_type": "a second category",
"value": "value for this trait"
}
]
}
For the Dusty Pilots collection I have simply used Github as a main repository. Depending on your skill set, you may opt in for different options; chat GPT may help as well. Just be careful: the final url for reach file needs to be {base_url}/{token_id}.json
.
In this article, I wanted to share how to use Starksheet as a backend to easily deploy a NFT collection on Starknet. Using Starksheet lets focus on the creative work and the narrative of a collection, the tech part of it being mostly automated!
This is only one example of what you can do with a sheet! Go crazy and share your work on twitter!