SECRET OF CSS

How To Burn an NFT. With an ERC721 Solidity contract | by Paolo Servillo | Aug, 2022


With an ERC721 Solidity contract

0*VbfI8XDgWf l4KQv
Photo by Yaoqi on Unsplash

A non-fungible token (NFT) is a uniquely identifiable digital asset stored in a blockchain. Unlike cryptocurrencies, which are fungible, an NFT is unique.

The ownership of an NFT is registered in the blockchain and can be transferred by the owner, enabling the sale and exchange of NFTs.

NFTs typically refer to digital files (images, videos, or others), and the NFT’s market value is tied to the digital file it refers to.

So, if NFTs are valuable digital assets, why should I burn them?

One reason would be the hope to make an NFT of a specific collection more valuable by making it rarer. For example, someone who owns all ten NFTs of a soccer player figurine may decide to destroy all except one to increase the value of the remaining one.

But, more frequently, companies:

  • offer owners the chance to burn their NFTs in exchange for physical products or an “upgraded” version of the NFT
  • urge people to purchase NFTs of a drop rapidly by announcing that they would destroy all unsold NFTs after a specific date
  • eliminate unsold or problematic NFTs

The weird thing is that the EIP-721 states:

“…destruction of NFTs (“burning”) is not included in the specification. Your contract may implement these by other means.”

OK, let’s discuss the burning feature!

We need to start from an ERC-721 implementation. The OpenZeppelin ERC721 is one of the most widely utilized implementations.

This is a snippet of the contract code:

As we can see, this implementation already provides an internal _burn function. The function accepts the token id as the input and does the following:

  • gets the NFT’s owner
  • calls the _beforeTokenTransfer hook function (what a hook is will be clearer later)
  • clears all approvals for the token
  • decreases the owner balance
  • emits the Transfer event
  • calls the _afterTokenTransfer hook function

So, the job is done?

Wait, something is missing!

The function does not check if the sender is authorized to operate on the token. Let’s do it ourselves!

For this purpose, we can use the _beforeTokenTransfer hook function.

As stated in OpenZeppelin documentation:

“Hooks are simply functions that are called before or after some action takes place. They provide a centralized point to hook into and extend the original behavior.”

The _beforeTokenTransfer hook is an internal virtual function intended to be called before any token transfer, including minting and burning, with these conditions:

  • when both “from” and “to” are non-zero, we are in the token transfer case
  • when “from” is the zero address, we are in the minting case
  • when “to” is zero, tokenId is going to be burned
  • “from” and “to” are never both zero

Following the OpenZeppelin Rules of Hooks, follows a BurnableNFT implementation.

In row 33, we check that we are in the burning or transfer scenario (“from” is not the zero address).

Then, the only address allowed to transfer or burn an NFT must be its owner so, at row 34, we get the owner of tokenId and “require” that it must equal to the sender of the transaction (msg.sender).

Then, the only thing to do is to add a public burn function that calls the parent contract _burn function.

All solidity code and tests can be found at: https://github.com/donpabblo/burnable-nft

If you are here, thank you for reading. I sincerely hope that this explanation was useful to you.



News Credit

%d bloggers like this: