NFTs, Blockchains, and Standards Explained without BS
Tags: blockchain, solidity, cryptocurrency, learning
Published: 2023-07-28 11:43:11

This was originally written for my colleagues who were working on a same project. I am definitely not a cryptochad or a crypto promoter, but I find this technology quite interesting. If you want a no BS explanation without the hype or something being sold to you – then read on. This is the explanation I wish I had when I’ve started researching this technology. Please comment on any misconceptions / mistakes.

## What is a Token / NFT

First we need to clarify some terminology. NFT stands for Non-Fungible Token, however people just use it as a catch-all term for everything crypto. What is the difference between fungible and non-fungible tokens?

Think about a fungible token as just a simple 50 cent coin in your wallet. It is no different from any other 50 cent coin, and you probably don’t care whether you have that particular coin, or any other 50 cent coin. They are the same, they are interchangeable – they are fungible.

Non-Fungible, however, means unique. Think of it as a commemorative coin with a stamped serial number. You might own the coin with the serial number 001, and your friend might own a coin with a serial number 050. They might look similar, but are unique because of their serial number. You wouldn’t exchange a 001 coin for a 050 coin, unless 050 had more sentimental value to you than 001.

## Technical Workings of Smart Contracts

Another very important thing to understand is how smart contracts work and what they are. Smart contracts are just code that runs on Blockchain, that’s it. There’s no magic involved. It’s not much different from a Java class. Smart contracts are written in Solidity language, which is a [Turing Complete](https://en.wikipedia.org/wiki/Turing_completeness) language, which means that pretty much any programming goal can be achieved with the language.

However, there is a caveat – each operation on blockchain takes a very long time and can even cost money, so huge and complex functionality may not be feasible. Great care must be taken when developing smart contracts to reduce the complexity, operations, and thus the cost of execution. A cost of execution is referred to as **Gas Fees**.

Smart Contracts can also store data (for example token ownership information) on the blockchain. This costs even more Gas.

### Views vs Transactions

An important distinction should be made between views and transactions. Retrieving data from blockchain (such as user’s crypto balance) does not warrant any gas fees from the user. As far as the end user is concerned, retrieving and showing data from blockchain is free. As long as no data is altered, the operations are free. To call a view function, user does not need to sign anything, the data will just be returned.

Storing, manipulating, changing the data on Blockchain, however, is not free. Data manipulation on blockchain is called a **transaction**. If any data is being changed (such as changing the owner of a crypto token), then all operations done within the same transaction will incur Gas Fees. Different operations have different gas cost – adding two numbers together is cheaper than making a call to an external smart contract. User will also need to sign the transaction, which basically means that before the transaction is executed, user will see a prompt from MetaMask and will have to confirm the transaction.

All transactions are public. Everyone can see who made the transaction and what data has been changed and when it happened. Gas fees and any crypto transfers are also visible to the public.

Transactions also come in two flavors – **payable** and **non-payable**. A payable transaction means that some amount of chain’s native currency (Ether on Ethereum, and Matic on Polygon) is attached together with the transaction. How the currency is distributed is in the sole discretion of the smart contract. A good analogy would be: you take an envelope and put in a note with the instructions and you also add a couple of dollars in that same envelope. The receiver of the envelope reads the instructions, and then gives a couple of dollars to their boss, takes a dollar to themselves, and then sends a dollar back to you. The postal fees you have paid to send that envelope are completely separate (analogy for gas fees). Money added to a transaction is referred to as **transaction value**. Transaction value and gas fees are absolutely separate and unrelated. A non-payable transaction will incur gas fees anyway: again you’re paying for the postal office to send your letter, you’re just not adding any bills in the envelope.

### Smart contracts in terms of crypto tokens

A crypto token, be it some coin or an NFT – is a smart contract. Tokens have different standards, with different functionality and different goals, and those will be explained further down the line. Token contracts store their ownership information inside themselves, which means that from a technical perspective, saying that a token has been added to a wallet is incorrect. Technically nothing ever gets “added” to the wallet. The contract stores a wallet token balance inside itself, so the more accurate description would be: “Wallet gets assigned a balance in the contract”.

This is extremely important to understand, because this part is where most miscommunication happens, with regards to crypto tokens.

### A word on immutability

Immutable means unchanging over time or unable to be changed. Smart contracts are immutable. This means that once the contract is deployed on blockchain, no one can change the functionality of it. Data stored by the contract can still be manipulated, granted that the functions to manipulate that data were developed, but you cannot add or remove those functions.

This brings us to the biggest pitfall of smart contracts – they need to be developed correctly from the start. If a security vulnerability is later found in the contract, there’s nothing you can do about it. This is one of the reasons a lot of famous hacks have happened.

So how can one upgrade the contract functionality? The answer is – deploy a completely new and separate smart contract with new functionality. This means that this new contract has new data completely unrelated with the previous contract. And that’s where we enter migration territory.

### Contract migrations

The moving of data from one smart contract to another is called a **migration**. There’s no standard way to migrate the data, if it is possible at all. When smart contracts are developed, any future migrations should be had in mind upfront. If no functions were developed to read the data in the smart contract, the migration might not be possible at all.

Technically a migration might happen as a communication between old contract and new contract:

> *New Contract:* Hey, old contract, how much of token 1 does wallet 0x123 have?
> *Old Contract:* 42
> *New Contract:* Ok, then I’ll note in my storage that wallet 0x123 has 42 counts of token 1. Hey, old contract, how much of token 2 does wallet 0x123 have?
> And so on…

This can get expensive pretty fast. Remember, each storage procedure costs gas. The more distributed your token gets, the more expensive it will be to migrate.

A way to save gas fees in case of migration, would be to offload the costs to your users. This is more of a communication exercise, rather than a technical challenge. A functionality to copy the balance of the old token to the new token contract could be developed and your users could be told to call that functionality themselves, and pay the gas fees. This could however frustrate your users.

Another thing to note is that after the migration, your old token contract, together with its ownership data will still be on the blockchain. This means that users that have migrated the tokens will still have their tokens in the old contract, as well as their tokens in the new contract, thus duplicating the information. Unless, of course, you develop a functionality that burns the tokens in the original contract.

### Differences between blockchains

Nowadays there are a lot of different blockchains. Ethereum is the most popular blockchain, but there are others, such as Polygon. However, most of those chains are just a copy of Ethereum, which means that they use the same language and principles for smart contract development, which in turn means that smart contracts developed for Ethereum will work on Polygon or most other chains without any changes.

Even if smart contract code is the same, contracts deployed on different blockchains will have nothing in common between them. If you launch your token on Ethereum and Polygon, they will not share ownership data, limits, metadata, or anything else. It’s like having two different Volkswagens – one on Earth and another in Mars. The blueprint is the same, but they don’t interact with each other.

It is also important to mention that Bitcoin is a whole different beast on its own. It’s not based on Ethereum and cannot run the same smart contracts. Forget Bitcoin, it does not exists as far as we’re concerned.

## Token Standards

So what are the options for token standards? A couple of standards are defined in the ERC (Ethereum Request for Comment). I encourage you to read the mentioned ERCs, so you can have the information from the horse’s mouth, but I’ll try to quickly run through the standards in my own words.

### ERC-20

[Read EIP](https://eips.ethereum.org/EIPS/eip-20)

Your most common fungible token – a shitcoin, pardon the expression. All those Pepe Coins, Shib Coins, etc are ERC-20 tokens. It’s supposed to be like a currency, like your dollars and euros. You could also look at it as stocks – pieces of a company (you can cap the supply of the coin for artificial scarcity). No matter how you look at it, a piece of ERC-20 is the same as any other piece of that same ERC-20 token.

The ownership data is stored as a map of `Wallet Address → number of coins owned`:

- Wallet 0x123 owns 3 tokens,
- Wallet 0xABC owns 7 tokens,
- etc

### ERC-721

[Read EIP](https://eips.ethereum.org/EIPS/eip-721)

The most common non-fungible token, the original NFT. This is also sometimes referred to as collection. A collection has a name, such as “Bored Ape Yacht Club”, and it also has a ticker symbol, such as “BAYC”. BAYC, by the way, is a real token collection, where you can collect apes. Each ape is different from another (non-fungible).

Each NFT in the contract is identified by a unique ID. This number does not change for the life of the contract. The ownership information is essentially stored as a map of `Token ID → Wallet Address`: “Token ID 42 is owned by wallet 0x123”. No quantities are at play here. If a single wallet owns different tokens in the same contract, each record is stored separately:

- Token ID 42 is owned by wallet 0x123
- Token ID 69 is owned by wallet 0x123
- etc

### ERC-777

[Read EIP](https://eips.ethereum.org/EIPS/eip-777)

This standard defines a new way to interact with a token contract while remaining backward compatible with ERC-20.

It defines advanced features to interact with tokens. Namely, *operators* to send tokens on behalf of another address — contract or regular account — and send/receive *hooks* to offer token holders more control over their tokens.

So it’s basically a shitcoin on steroids. I have to admit, I don’t have much experience with this standard, but it does look interesting. Again, I encourage you to read the original EIP, it is quite well written and an interesting read.

### ERC-1155

[Read EIP](https://eips.ethereum.org/EIPS/eip-1155)

Now this standard is the most advanced and it builds on the experience of the previous standards. While ERC-20 and ERC-721 requires deployment of separate contracts per token type, ERC-1155 is a Multi Token standard, that allows mixing fungible and non-fungible tokens in the same contract, with their own supplies, limits, and metadata.

Tokens still have their own unique IDs as with ERC-721, however now the ownership information also includes the number of particular token owned. The ownership information is stored as a multi dimensional map of `Token ID → Wallet Address → Number owned`. So ownership data is stored in such a manner:

- Token ID 42 is owned by:
    - Wallet 0x123 owns 2 tokens
    - Wallet 0xABC owns 5 tokens
- Token ID 69 is owned by:
    - Wallet 0x123 owns 1 token
    - Walled 0x999 owns 42 tokens

As you can see, this is a merge between ERC-20 and ERC-721 concepts as it includes non-fungibility (through unique token IDs) as well as fungibility through ownership quantities.

## Operator Approvals

An owner of a token may allow other addresses (wallets or contracts) to operate their tokens in that particular smart contract. In that case, the 3rd party is called an operator, and the act of allowing an operator is called an approval. This might be a bit different between the standards, but I want you to get the general gist of it.

The operator has full reign over the tokens. This means that if you have approved an operator for your tokens, they are free to transfer all of your tokens from that smart contract to anyone. Usually when placing a token for sale on a marketplace, it asks you to grant approval to that market contract.

This is basically the same as giving your house keys to your local Tesco manager, and trusting that they will only take one Gorilla figurine from your shelf. They might be trustworthy, but don’t be surprised if one day all your actions figures are gone. It might not even be the manager themselves, they might get robbed and your key gets stolen from them.

Some more advanced contracts may implement their own more sophisticated approval systems, but those are out of scope of this article.

## OpenZeppelin

A funny thing is that you don’t even need to develop any of this yourself. There’s a company that has developed the implementation of the standards described above. Want your own shitcoin? It’s as easy as opening their [Contract Wizard](https://www.openzeppelin.com/contracts) and selecting the features that you want.

A lot of the meme coins don’t even have their own code in them. This is a valid coin contract:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MemeCoin is ERC20 {
    constructor() ERC20("MemeCoin", "SHT") {
        _mint(msg.sender, 42000 * 10 ** decimals());
    }
}
```

All it does is assigns a limited number of coins to the contract deployer address. Deployer can then build the hype around that coin and sell on a marketplace.

## Blockchain Scanners

For the sake of completeness I also need to mention blockchain scanners. As you already know, all transactions on blockchain are public and transparent. For that reason, most of the blockchains have public scanners, which are just websites that show transactions in a convenient way. Ethereum has [Etherscan](https://etherscan.io/), and Polygon has [Polygonscan](https://polygonscan.com/). Any transfers, purchases, method calls, and contract deployments you make will appear in those scanners for everyone to see and inspect. Whether this is good or bad, I’ll leave it to your own consideration.

## Outro

Thank you for taking the time to read through this article.

There are a lot of misconceptions about the blockchain, NFTs, and coins, and there’s no shortage of people willing to take advantage of the uninformed. I hope this article has given you at least some technical understanding on what the hype is all about.

If you know someone who might benefit from this knowledge, please share this article with them, so that the working principle is demystified.

If you’ve enjoyed the article, please like it, so that I know it was interesting / useful. Discuss any issues in the comments. And maybe consider following me here on DEV. I won’t be focusing on crypto topics, but I might put out an article about it once in a while.

And with all that said – have a great rest of your day.