The Stanford CS251 Course NFT

Dan Boneh
7 min readMar 30, 2022

--

By Dan Boneh, Daniel Marín, and Kydo

In the Fall of 2021 we experimented with issuing an NFT to all the students who finished our introductory blockchain course, CS251. The NFT was designed to be a fun hands-on experience for the students in the class. This blog post describes our experience in making this happen and some challenges we had to overcome. The post is meant to help others who wish to issue an NFT to participating students.

First, some background. CS251 is our undergraduate course on blockchain technologies at Stanford. We have been teaching the class for several years. The class attracts somewhere between a hundred and two hundred students, depending on the state of the blockchain market. It is designed for Computer Science undergraduates and has a large programming component.

The CS251 NFT is intended to celebrate the completion of the class. Our goals for the NFT were threefold:

  • The NFT should be non transferable. Students should keep the NFT and not transfer or sell it to others. A better name for this would be a Non-Transferable Token, or NTT, but the NFT has to properly interact with the existing NFT infrastructure: it should be viewable on OpenSea and other marketplaces. As such, we had to follow the ERC721 standard. See also Vitalik’s post about non transferable tokens.
  • The NFT is not personalized. We would have liked to include the student name in the NFT, but could not due to privacy requirements. Instead, our NFT is specific to the course, but does not contain any student details. We will discuss personalized NFTs that respect student privacy at the end of the post.
  • Not an airdrop. We wanted the students to mint the NFT for themselves by interacting with our on-chain contract. Once minted, the students could view their NFT on any NFT marketplace that supports Polygon. This gave the students a sense of ownership over the NFT they had just minted. If instead we had done an airdrop, the student experience would have been quite passive: an NFT would simply appear in their wallet without any action on the part of the student.

From the professor’s point of view the system works as follows. First, we designed the NFT art with the help of Laya Mathikshara, an amazing 3D artist. Next, we deployed an ERC721 contract, but where we disabled the `transfer()` function. This ensured that once the contract mints an NFT, the NFT cannot be transferred. In addition, our contract included the professor’s public signing key. Finally, we sent an email to every student in the class with a unique credential signed by the professor. We will discuss these steps and their implementation in more detail in the next section.

From the student’s point of view, each student received a credential from the professor by email. The student also received a small number of tokens from us to pay for the gas needed to mint the NFT. The student then used his or her signed credential to request our contract to mint an NFT for the student. This can be quite easily done using Metamask. Once minted, the NFT showed up in the student’s wallet.

The results. Over half the students in the class minted their NFT. Oddly, some students tried to sell their NFT even though any sale attempt would necessarily fail.

This experience made us realize that we could be at the beginning of a grassroots effort to transform how transcripts are recorded. If students were to request an NFT from every professor with which they take a class, then a future college transcript could simply be a bag of NFTs recorded on-chain, one NFT for each class that the student took. We will come back to this vision at the end of the post.

Why not use POAP? In principle, the proof of attendance protocol (POAP) could be used to issue course NFTs. However, the POAP workflow is quite different from what we wanted. In particular, POAP badges do not satisfy our first and third requirements. Moreover, we plan to eventually issue course NFTs that contain the student’s name and grade, with proper privacy controls. We will discuss this further in the last section.

The art

For the NFT art, we wanted something that students would want to showcase in their social media profiles. Our final design is a 3D card object constructed with Cinema4D. We inscribed the class name and the instructors’ names on the front, and a picture reminiscing Stanford on the back. The overall art design is simple, but reflects the relation with blockchain technology. More details are provided in the footnote*.

The NFT art
The Stanford CS251 Fall 2021 NFT

We decided to launch the NFT contract on the Polygon chain with the NFT metadata hosted on IPFS using Pinata. We chose Polygon due to its low transaction fees, which made a big difference given the large number of students in the class. IPFS is the standard decentralized storage solution for NFTs.

We sent an email to the students with instructions on how to create a wallet on Polygon and asked them to send us their wallet addresses. We then sent a small amount of Polygon’s native token $MATIC to their wallets. This step was aimed to ease the onramp process for the students. On the day of the launch, we sent out a (nonce, key) pair to students’ emails with instructions on how to mint their NFTs on etherscan.io.

Technical Details

We developed the NFT contract using a Hardhat and Typescript setup. We leveraged the ERC-721 OpenZeppelin implementation, hosted the NFT metadata on IPFS using Pinata, and tested it all on the Mumbai testnet before launching on Polygon. Let us describe the process in more detail.

NFTs are usually compliant with the ERC-721 standard so they can interoperate with NFT marketplaces like OpenSea, Foundation or Rarible, as well as many crypto wallets. In fact, many of these marketplaces allow users to build an NFT collection without ever having to write a single line of code. However, as previously mentioned, we wanted our course NFTs to have two non-standard properties: non-transferability and the ability to be minted by anyone with a valid signed credential (sent to them by the professor).

To do so we coded our own ERC-721 contract to satisfy these requirements (see our GitHub repo for the details). Our contract uses the OpenZeppelin ERC-721 implementation with the following modifications:

  1. Save the professor’s public key in the contract (using OpenZeppelin’s Ownable library).
  2. Block all token transfers except for minting, using the `beforeTokenTransfer()` hook of the OpenZeppelin implementation.
  3. Allow a user to mint an NFT only if the user provides a (tokenId, signature) pair where `signature` is the EIP-191 signature of `tokenId` under the professor’s secret key and the NFT hasn’t already been minted.

To verify requirement (3) on-chain, we used the `ecrecover` Solidity function to verify the validity of the signature (see here, here, here and our implementation here for more information). Once a student minted their NFT by calling the `mint(tokenId, signature)` function on the contract through the contract’s etherscan.io interface, any NFT marketplaces could automatically display the NFT in the student’s Polygon account.

Cost. Executing `mint()` had an average gas cost of 0.005 MATIC, equivalent to 0.01 USD as of March 2020. Therefore, we sent each student about 0.05 MATIC (0.1 USD), giving them more than enough to claim their NFT. Likewise, deploying the contract had a cost of 0.1 MATIC (0.2 USD), so we spent in total about (100 students) * (0.05 MATIC) + 0.1 MATIC = 5.1 MATIC, which is roughly equivalent to 10 USD.

To send 0.05 MATIC to all students, we requested their Ethereum/Polygon address and completed all transfers with a single on-chain transaction using a small MultiSender contract we wrote. Future developers interested in sending MATIC in bulk to a group of students on the Polygon network may simply use our deployed contract to get the job done. While there are online tools that already provide bulk crypto asset transferring services (like multisender.app), they were all too expensive.

Finally, we opted for the Pinata IPFS free-tier service to host the NFT metadata, both the 3D image and the manifest. The same metadata is shared by all NFTs (i.e. all individual NFTs display the same image and link to the same metadata), which we made sure to conform to OpenSea’s metadata standards.

Discussion, Implications, and the Future

A Course NFT (CNFT) is an example of an NFT that records an accomplishment. Anyone who runs an educational activity could issue a CNFT to students who successfully complete the activity. As more students request CNFTs, we could see a grassroots effort to transform how educational records are stored. Universities and online education companies could continue to issue traditional transcripts, while professors and teachers would issue CNFTs to students who request them. Over time, this grassroots effort would mean that a transcript is simply a bag of CNFTs recorded on-chain.

For this to take off, CNFTs will need to become more personalized. They will need to include metadata such as the student’s name and the student’s performance in the course. However, one cannot write this private data on-chain in the clear because it must not be universally viewable. Instead, the on-chain CNFT metadata could contain a cryptographic commitment to the student’s name and another cryptographic commitment to the student’s grade. The student could then choose to open the commitment to anyone who needs to view the metadata. A potential employer could verify the authenticity of the data provided by the student by verifying the commitment on-chain. Access control is in the hands of the student. We are working on developing the tools to support this.

Footnotes

  • The name of the NFT collection should be chosen with care. In our tests, we found that OpenSea auto appends “V#” to a collection’s name if there already existed another collection with the same name.
  • One unforeseeable consequence of having a 3D model is the sheer size of it. Currently, the 3D file is more than 100MB and therefore would take more than ten seconds for OpenSea to load. This could introduce friction in displaying the object. Even after compression to 11MB, the loading time is still much slower compared to other NFTs. Also, OpenSea currently does not support a good viewing experience for a 3D NFT: only zoom and rotation are supported.

--

--