Skip to content
Home » Blockchain » How Metaschool Replaced Certificates with NFTs for Proof of Completion

How Metaschool Replaced Certificates with NFTs for Proof of Completion

Upgrading Learning Achievements with NFT-Based Certificates (1)

Generally, when you complete a course on a mainstream learning platform, you get a standard email along with a digital certificate, which is prone to getting edited, misused, and even copied.

We, at Metaschool engineering, transformed this approach. The outcome? When you complete Metaschool courses, you are rewarded with blockchain-verified NFT certificates, offering a secure and unique token of your success.

Benefits of NFT-Based Certificates

These digital assets not only signify completion just like traditional certificates; they also bring with them sundry Web3 benefits such as:

Immutable Proof: NFT ownership can’t be faked or tampered with, giving lasting validation of your skills.

Share-ability and Display-ability: You can show off your NFT certificates in your crypto wallets and on sites like OpenSea.

True Ownership: Certificates no longer sit unseen in a drawer. You fully own your achievements on the blockchain.

Overcoming Key Challenges

As exciting as an NFT-based certificate program sounds, it wasn’t the one without a unique set of challenges. Nevertheless, my team and I succeeded in resolving these issues via multiple iterations and by following a very specific ideation process. Here are some examples to show how we did it:

Transferability: The issue of NFT transferability was a minor challenge. We customized the contract to mint NFTs directly to the recipient’s wallet, ensuring they remain non-transferable. This effectively preserves their authenticity.

Gas Fees: This can be a big challenge when minting NFTs. Therefore, we chose to deploy our NFT-based certification program on Polygon to remove the cost barrier of gas fees, ensuring developers have equal and free access.

Authorization: Despite decentralization, we still felt a need for centralized control over mints. Thus, our contracts restrict access to only authorized admin keys.

Technical Implementation

The technical implementation of our NFT-based certification program was carried out in a very strategic manner. The team and I used Polygon blockchain to build the solution and meticulously leveraged OpenZeppelin contracts. Here is how the code looked like:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract MyToken is ERC721, ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;
    bool allowsTransfers = false;

    constructor() ERC721("Metaschool", "MTA") {}

    function safeMint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = _tokenIdCounter.current();
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);

    function setAllowsTransfers(bool _allowsTransfers) external onlyOwner {
        allowsTransfers = _allowsTransfers;

    // The following functions are overrides required by Solidity.

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {

    function tokenURI(uint256 tokenId)
        override(ERC721, ERC721URIStorage)
        returns (string memory)
        return super.tokenURI(tokenId);

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
            from == address(0) || to == address(0),
            "Not allowed to transfer"
        return super._beforeTokenTransfer(from, to, tokenId);

The Key Aspects Implemented

While brainstorming the unique NFT-based certificate program, the team outlined a few key aspects that they wanted to implement such as:


They overrode the _beforeTokenTransfer hook to restrict transfers. Ensuring that NFTs remain non-transferable is a major focus here so that the individual who has completed the course is the only one who owns that NFT and not transfer it to a friend. The ERC-721 standard includes an internal _beforeTokenTransfer function that is invoked before any transfer action.

The engineers at Metaschool tweaked it a little and added the following condition:

from == address(0) || to == address(0)

It checks the from and to addresses involved in a transfer. Here, as you can see, I have restricted the action to only allow minting from address(0) and burning to address(0) operations. Any attempt to transfer an NFT from one user to another (where both from and to addresses are non-zero) triggers the function to revert the transaction, effectively making the NFTs non-transferable post-minting.

function _beforeTokenTransfer(
  address from,
  address to,
  uint256 tokenId
) internal virtual override {

    from == address(0) || to == address(0),
    "ERC721: transfer not allowed"


Secure Minting

The lead backend engineer used the Ownable modifier to restrict the minting ability to ensure authenticity. This also meant that the distribution of our NFTs is possible only through the owner of the contract/s, which is none other than Metaschool’s engineering team.

function safeMint(/* */) public onlyOwner {
  // Only contract owner can mint

Metadata Storage

When it comes to metadata storage, IPFS is usually recommended. However, due to time constraints, the team and I chose to go forward with Amazon S3 bucket to store all the NFT metadata. Our NFTs point to URLs like this:{unique-id}.json.

Each NFT’s metadata is detailed and includes the course name, a unique image, and other key details about the recipient’s achievement. Additionally, an NFT might link to metadata that looks something like this:

	"name":"Metaschool NFT",
	"description":"Completed the metaschool course How does Ethereum work? A deepdive",
			{"trait_type":"Course","value":"How does Ethereum work? A deepdive"},
			{"trait_type":"Completion number","value":"964"}

Seamless NFT Distribution

Distribution anywhere is challenging to crack. What I and my engineering team did is that they created an automated backend process to handle certificate minting and delivery:

  1. A cron job runs every after every one hour, identifying you who recently completed a course.
  2. We check if you have connected a crypto wallet.
  3. NFT metadata is prepared with course details.
  4. Our contract mints an NFT and transfers it to your wallet.

This provides a smooth, gasless NFT claiming experience for all certificate earners. This architecture as a whole allows us to securely mint completion NFTs for you, our builders. The end result is a scalable system where you can claim NFT certificates as soon as you complete you course/s.


This is just one example of how engineering @ Metaschool managed to provide our builders a more engaging way to own their achievements on-chain by leveraging design, coding and the key principles of engineering. You can check out our sleek NFTs on Polygon here.

We don’t just stop here. Metaschool has a few more on-chain rewards planned for some of our existing courses.

👉 If what we do sounds interesting to you and can help you improve your skills, join us. Metaschool is hiring for tech roles. You can apply here.

👉 Lastly, if you have got more ideas that you want us to implement, well, feel free to drop us a quick Hello on either Twitter or LinkedIn.