Ok ETHDenver, you win

Leo Jacoby
4 min readFeb 21, 2022

Monday 2/21/22

Ok ETHDenver, you win. I’m Solidity-pilled. A man can only hear how in-demand Solidity devs are and the power that smart contracts will wield in the next iteration of the internet so many times before he breaks down and starts the CryptoZombies.io tutorial. And that’s exactly what I did. After a few weeks of getting my hand held I finished the tutorial and was ready to leave the nest. I knew just enough to punch in the right questions into Google.

Knowing myself, starting a project was the only way I was going to progress towards my learning goals. But no single idea stuck out to me as a project I truly believed had high-growth potential. I settled on building NBA top-shot-esque platform for amateur athletes, teams, and athletic departments. I call it Contender. The vision is for athletes to design a collection — eventually being able to create sweet jpegs and gifs using templates from designers — and allow fans to mint them. Compensating amateur athletes is legally tricky, so I’m incorporating charity as a central component to the projects.

A sweet jpeg from https://dot.la/ballertv-nft-2653283659/particle-2

Github: Frontend, Contracts

The hurdles

  • How do I make a basic NFT smart contract? Answer: OpenZeppelin. I copy and pasted their meat and potatoes ERC-721 contract as a starting point.
  • How do I test? Answer: Rinkeby. I started with Ganache but because of MetaMask’s lack of NFT-support for their Chrome extension and my inability to connect to a local network from my phone, I settled on Rinkeby as my testnet.
  • How do I deploy a smart contract? Answer: Truffle. I’ve used Truffle to handle compiling and deploying my contracts.
  • How do I interface with my contracts from a frontend? Answer: web3.js. Their package has everything I need to connect to a contract, call methods, and listen for events.
  • How do I store metadata? Answer: After receiving a token name, description, and image on the frontend, I pin the content to IPFS using Pinata. They have a clean API that lets me host the data and just store a simple hash of the image and metadata JSON on chain. Here was a big milestone I reached after I implemented Pinata with my minting interface…minting a Blue Chip “Cousin Greg” NFT to my Rainbow wallet on the Rinkeby network
  • How do I authenticate users? Answer: My Web2 instincts drove me to add Firebase Auth to my app, but I quickly realized that Ethereum sign accomplishes everything I need, given that Google’s user information is of little use to me. I store the user’s address using MobX so I can access it app-wide. I still need to do a better job of making that data persistent.
  • How do I store data? Answer: Hybrid on/off chain. I have two schemas: Athlete and NFT Collection. The only reason I need to store Athlete information is so I can make it easy for them to create additional collections and make their collections linked within the interface. These seemed like UI issues and not functional concerns, so I decided to use Firestore to keep track of athletes. On the other hand, I care deeply about allowing anyone to interface with the smart contracts without using my app. To accomplish this, I needed to keep Collection data on chain. To minimize storage costs, I use events to track each time an athlete creates a collection, which I can then query from a frontend. Additionally, I use a mapping from collection ID to a counter to keep track of the current number of mints for each collection. I’m still struggling to fuse these two sources of information on the frontend when it’s time to display the data.

Where I’m at:

Users can log in, create an athlete, log out, log back in, and reassume their identity as that athlete. They can then create a collection that appears on their athlete page for all of their fans to see. Fans can mint NFTs from specific collections, but I’m still working out the kinks of that flow when fans pay for NFTs. Mo is my little brother btw :)

What I’m struggling with:

  • Adding current collection index (number of mints) to the collection data that comes from the event stream. This should be done on the frontend.
  • Allowing fans to send ETH to the contract and receive an NFT in return. It works without the payment part, so I’m not sure where it’s breaking.
  • Solidity doesn’t like decimals and javascript doesn’t like big numbers. The athlete inputs price in ETH, I convert it to WEI, and when I send it to the contract, it turns into an entirely different number. I’m using the “toWei” function from web3.js.
  • As you may have noticed, I’ve spent zero effort into design. Will definitely make that a priority before I show this to anyone important.

I’m going to try to keep updating this post as I make progress, but I have a bad habit of not making writing a priority. Also, I decided to write more generally, so look out for some more pieces about tech stuff and beyond.

Update: I’m making additional posts so check my profile for those.

--

--