CryptoPunks smart contracts
A look at some of the most historically significant smart contracts in NFTs
TLDR:
CryptoPunks launched in 2017 before NFT standards even existed and set a precedent for much of what’s happened in the space.
The main contract hardcoded well known values, allowed free assignment of Punks, and had native marketplace functionality built in.
Images were stored as a hash on the main contract until the cryptopunks data contract was created and the full Punk images became eternalised on-chain.
Wrapped Punks contract allows Punks to be used with standard marketplaces.
The v1 Punks did not have marketplace functions so they were scrapped.
This week I’ve been finishing off the first draft of my short course on “NFT Tech”. One of the final sections I’ve been writing has been about some famous smart contracts out in the wild and one of the ones that I decided to dive into was the CryptoPunks smart contract!
I found it very interesting going down “memory lane” in NFT history with one of the most important smart contracts for the space. So I thought it would be interesting to share more about the CryptoPunks contract this week.
Note that if you’re unfamiliar with reading smart contracts then check out a couple of my previous posts on navigating smart contracts on Etherscan and a Solidity 101 that’ll teach you how to read a standard NFT minting contract.
CryptoPunks
CryptoPunks are one the most established names in NFTs and what’s most interesting is that they were created before the ERC721 standard for NFTs was established. The fact that they came before the standard isn’t that surprising though since most people value the Punks for their historical significance as they are considered one of the very first NFTs on Ethereum!
If you are reading this and by chance haven’t come across the CryptoPunks then a very brief history is that they were created by a tiny 2-man studio called Larva Labs in 2017. The Punks were meant as an experiment showcasing what smart contracts on Ethereum were capable of but ended up becoming the poster-child of NFTs since they set the precedent for so much that came later in NFT culture.
The Punks IP was eventually bought by Yuga Labs who are the biggest company in the space today, and to buy even one of the cheapest Punks from the 10,000 NFT collection with current ETH prices will cost you just shy of $100k!
When looking at the Punks there’s a few smart contracts worth looking into:
The main contract with the 10,000 punks.
The cryptopunk data contract used to eternalise their images on-chain.
The wrapped contract to wrap them into ERC721s.
The original “v1” contract that had a bug!
Main Contract
https://etherscan.io/address/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb#code
One of the first things you’ll note when you open the contract is that its actually quite short with only 250 lines of code! This is because there were near to no set standards in Ethereum at the time so unlike today’s smart contracts that have several imported files, and often 1000s of lines of generic code, here there are no imports since most of the imported contracts from today didn’t even exist!
Looking at the constructor you can see the historic 10,000 number is hard coded in to the totalSupply, manually enforcing a total of 10,000 punks available. Little did Larva Labs know it would spawn thousands more 10k PFP projects further down the line.
At the time there was no clear concept of “minting” an NFT and Punks were free to get hold of at the start. There was a getPunk() function on line 102 that simply allowed you to assign one of the currently unassigned Punks to yourself until the variable punksRemainingToAssign reached zero! In reality it took a few weeks for them all to be assigned, very different to popular PFP mints nowadays that can sell out in hours.
To transfer a punk you call transferPunk() on line 114. Naturally since there was no NFT standard yet they didn’t make use of today’s commonly used safeTransferFrom() and transferFrom() found in the ERC721.
It’s also very interesting that the contract had marketplace functions directly coded into it with a couple of structs for offers and bids that get directly assigned to Punks so that you know which are up for sale or have a desired buyer.
Today we use marketplaces like Opensea and Blur to do all this but back in 2017 marketplaces didn’t exist so Larva Labs coded marketplace functions for enterBidForPunk() and acceptBidForPunk() directly into the contract! To this day you can still see all this on-chain marketplace activity on their site with the different backgrounds of Punks suggesting whether they have an active offer or bid on them.
From off-chain to on-chain images
https://etherscan.io/address/0x16f5a35647d6f03d5d3da7b35409d65ba03af3b2#code
From the main contract you can see that they don’t store the image data of the Punks within the contract only the following hash:
To get this hash Larva Labs would have taken the sprite-sheet file with all the 10,000 Punks and passed it through the SHA256 hashing function such that only this specific sheet full of Punk pictures gave that output hash!
This is a really interesting and an incredibly smart way to store the images using minimal data within the contract since changing even a single bit of of data will completely change the outputted hash. So hardcoding this hash into the contract was enough to guarantee the exact configuration of the 10,000 Punks without having to upload the full sprite-sheet to the blockchain!
Instead the Punks sprite-sheet was stored off-chain and you could use a lookup table with the Punk’s index to see its image. However, since the Punks grew to be such a success Larva Labs decided to create a new contract to save the Punk images on-chain forever since they have become a part of Ethereum’s history and as they are pixel-art they are not very large to store any way.
This image storing contract simply has functions to store data on-chain and then others to retrieve it. The addAsset(), addComposites(), and addPunks() functions are there for storing and punkImage(), punkImageSvg(), and punkAttributes() are there for retrieving.
Since Larva Labs uploaded the Punks data with the storing functions on this smart contract, now anyone can forever go and find the Punks on-chain and retrieve them for as long as the Ethereum blockchain exists!
Wrapped Punks
https://etherscan.io/address/0xb7f7f6c52f2e2fdb1963eab30438024864c313f6#code
As the Punks came before the ERC721 standard they do not have some of the crucial functions or even the right metadata structure to be supported by marketplaces like Opensea and Blur. Marketplaces work inter-operably with all NFTs exactly because NFTs follow these standards.
With Punks you can only buy and sell them through their native marketplace functions in the main contract described above. To make up for this the Wrapped Punks contract was made by a community member so Punks would be compatible with NFT marketplaces.
There’s two key contract structures to look at in the code: UserProxy on line 1535 and WrappedPunk on line 1575. As a Punk holder you first need to call registerProxy(), which basically creates an internal UserProxy structure on-chain that represents you and allows the contract to transfer the Punk on your behalf.
Next you need to transfer your Punk over to the on-chain UserProxy and once you’ve done this you can call the mint() function to create an equivalent Wrapped Punk NFT for it. You can see the mint() function does a proxy.transfer() call to send the Punk over to the main contract and then mints the Wrapped Punk.
With this newly minted NFT you can now view it in any marketplace just as with any other NFT since it has all the necessary standard functions implemented. If you want to get the original Punk back in your wallet then there’s burn() function that takes the Wrapped Punk NFT, destroys it, and sends the original Punk back to you.
V1 Punks
https://etherscan.io/address/0x6Ba6f2207e343923BA692e5Cae646Fb0F566DB8D#code
Finally, we can take a brief look at the original contract that came before the one we all understand to be the main contract. This contract looks very similar to the main contract however it lacked the marketplace functions that we discussed earlier.
Since there were no marketplace functions in the V1 Punks there was no easy way for them to be traded, so Larva Labs uploaded a new contract with these functions added. Due to this Larva Labs also named the contract differently, with V1 called CryptoPunks while the main contract today that we know and love called CryptoPunksMarket!
Later with the growth of the Punks people dug around and found these V1 Punks and wanted to buy them. So a V1 Wrapped Punks contract was created that works similar to the above one essentially minting and burning new NFTs when the Punk is wrapped up, and explicitly adds the ERC721 standard functions that the marketplaces require for interoperability -https://etherscan.io/address/0x282bdd42f4eb70e7a9d9f40c8fea0825b7f68c5d
And that’s all for today!
I hope its been as interesting to you going down memory lane as it was for me. It’s fascinating to think how simple yet elegant the main CryptoPunk contract is but also incredibly fundamental to the Web3 movement it created. With the 10,000 collection size, the marketplace functions, and on-chain storage of images, Punks were a real precursor to a lot of NFT culture and what continues to happen in the space.