Plotting a Course to the Purple Coast
0x008F
April 27th, 2022

Making the Origin Collection NFT

In January, MAB, my friend and erstwhile web2 colleague, asked if I would collaborate on a NFT project featuring her 35mm photography. She encouraged my explorations into NFTs and I was excited to work with her on this project. From this collaboration we have launched the Purple Coast Origin Collection, an NFT which is now available for minting and on the secondary market. For more on the background of the art and the associated magic spray, check out MAB’s Enter the Purple Mist post.

Through the winter months, we brainstormed, discussed concepts, and arrived at the following goals for the project:

  • Release an NFT featuring MAB’s photography.
  • Make available MAB’s sprays as a physical good that can be claimed once per token.
  • Allow minters to co-create their tokens by choosing a permanent title for the token.
  • Encourage accessibility through a decreasing mint price.
  • Make the smart contract extensible by exposing data for future use.
  • Be “serverless”, keep metadata on-chain, and use IPFS for the photograph assets.
  • Keep things simple, but deliver a unique experience.

Here is one of the minted tokens on Rarible:

As I started working on the contract for the Origin Collection NFT, I drew on well-tested code from the open source community to build from a solid foundation. The contract uses the following open source libraries:

  • The core functionality for NFT tokens is from OpenZeppelin. Instead of using the basic ERC721 class, I used ERC721Enumerable (link), which adds functions for listing the tokens that have been minted. For example, an app could use the tokenOfOwnerByIndex function to show all of the tokens that an account owns.
  • The contract requires access control so that only an authorized account can withdraw the ETH paid to mint tokens and claim tokens for gifting. I used OpenZeppelin’s Ownable (link) class to define the authorized account, allow changing the account if needed, and limit access to certain functions.
  • Additionally I used OpenZeppelin’s ReentrancyGuard (link) and SafeMath (link) classes to improve the safety of the contract code. It is important to take precautions against potential bugs or misuse, since a published contract’s code is immutable and problems cannot be fixed later.
  • Finally, I used Brechtpt’s base64 library (link) to support encoding a string with the Base64 algorithm. This allows for storing the tokens’ metadata on-chain by following the convention to return Base64-encoded JSON from the tokenURI function.
The Solidity code for the Origin Collection's mint function.
The Solidity code for the Origin Collection's mint function.

These libraries are a great foundation for any NFT, but our goals for the Origin Collection call for giving this NFT a unique experience. To accomplish this, I made the following customizations:

  • For many NFTs, the mint function accepts no inputs and simply assigns the next token to the minter. The Origin Collection’s mint function requires two inputs: the token ID and five numbers that correspond to words from a list of “essences”. This allows the minter to choose which one of the eleven photographs will be associated with their token and to choose the permanent title for the token. The function also assigns an “element” attribute, which is a one of four words selected based on the token’s minting sequence.
  • The contract provides a tokenURI function that returns the metadata for a token. According to NFT standards, this function can either return a URL for a JSON file (hosted independently) or Base64-encoded JSON data that can be generated on-the-fly by the contract. By using the latter approach, all token metadata is on-chain and maintained by Ethereum. This metadata includes the token’s title, the five essence words and element as attributes, and the URL to the associated photograph.
  • The contract implements a few other custom functions to allow for the variable pricing model (the first tokens minted cost more than later ones), to allow MAB to claim tokens, and to withdraw the funds paid for minting.

While Ethereum provides resilient storage for the contract and on-chain data, it is important to consider how to store any content not stored on-chain. For the Origin Collection, I did not want to try to store the image files on-chain, since it is costly and discouraged to store data on the blockchain that could just as well be stored elsewhere. Instead I chose to store the image files on IPFS, which offers some key advantages over the web for NFT images. The most important is that when files are added to IPFS, they receive a permanent address irrespective of how or where the files are hosted. With a permanent address for the images, the contract does not need to account for URLs that may change over time and need to be updated.

Viewing token details on the Origin Collection website.
Viewing token details on the Origin Collection website.

The final component is the Origin Collection website that showcases the eleven photographs, supports minting the eleven tokens, and allows token holders to claim their spray. This site is built with Vue.js and hosted on Amazon Web Services using a “serverless” static site architecture. To provide a fast web experience, the data for the token gallery is cached and updated periodically from the blockchain. Users are only required to sign in with their wallet if they want to mint a token or claim benefits as a token owner.

This is a look back on the path to building the Purple Coast Origin Collection NFT smart contract and web experience. If you are an NFT enthusiast, I encourage you to visit the Purple Coast, see the photographs, mint a token, or find one on the secondary market. Also, follow this space for future posts on the Origin Collection contract as an API and lessons learned from the project.

Arweave TX
1GpMip3rAo_4f1occOgSy6CLg7dudBZ2zsFjRVEqJZ0
Ethereum Address
0x008F84F0e0C4Bc04eBDa43Aa927002B1b89dD74B
Content Digest
wdRuMvorsVDjZPq1IJGQFVY6_3x80yHKcOsRafOXFbE