ECDSA_728x364

Try Minting!

Mint your Kanji NFTs here! (Rinkeby)
The solidity source code can be found here.

It is common for NFT projects to rely on a “Whitelist” to control who can mint their NFTs. There are different ways to implement a whitelist. In this post I will go over the ECDSA signature method and how to use it without associating a list of wallet addresses.

Whitelisting

Whitelisting introduces several major advantages for an NFT project:

  • avoiding gas wars amongst users
  • more fair launches (spots on the whitelist can be given in the most appropriate and fair way possible before the mint event)

A common implementation approach is to store the merkle root of all the whitelisted addresses on the contract, so that any address can be verified against the merkle tree by submitting a merkle proof that their address is on the whitelist. However this gets tedious when addresses are frequently added or removed from the whitelist (which happens a lot IRL). As a new merkle tree is needed when even just 1 address (merkle leaf) changes.

Another approach is to use ECDSA signatures.

ECDSA Signatures

ECDSA signatures are a type of asymmetric encryption algorithm.

General Idea

Signing:
Hash(Data) + Signer’s Private Key Signature

Public Key Recovery:
Hash(Data) + Signature Signer’s Public Key

Data can be anything. However, anything we put in here will need to be reproduced exactly during the Public Key Recovery, otherwise the public key recovered will not match the Signer’s public key. It is this particular property that allows us to verify the authenticity of the Data.

Our Approach:

This project implements the ECDSA signatures approach with random alphanumeric strings (Secrets) that are given to users who are allowed to mint. Unlike the common approach of using wallet addresses, using secrets allows users to use any wallets they wish. Users can also decide on the wallet at the time of minting.

Signing

Hash(Prefix + User Address + NFT Amount + Contract Address + ChainId + Secret) + Private Key Signature

  1. Prefix - State the purpose of this message (referencing Ethereum’s "\x19Ethereum Signed Message:\n")
  2. User Address - User wallet that is invoking the transaction
  3. NFT Amount - Number of NFT to mint (usually 1 for NFT, more useful for ERC20)
  4. Contract Address - Address of the deployed NFT contract to prevent reply attacks between different deployments
  5. ChinaId - Chain to execute a transaction on to prevent replay attack between different networks (e.g. testnet and mainnet)
  6. Secret - A secret that is used for minting to prevent the same secret from being used again (usually called a nonce)
  7. Private Key - Signer’s private key

Public Key Recovery

Hash(Prefix + Sender Address + NFT Amount + Contract Address + ChainId + Secret) + Signature Public Key

It is important that the server does its own hashing of the data:

  • allows the server to independently get the values of Sender Address, Contract Address and ChainId
  • prevent the case where data is not actually hashed and the signature is crafted such that an arbitrary address can be recovered

Architecture

There are 3 components to this project:

  1. React for frontend
  2. Cloudflare for server
  3. Solidity for smart contract

The flow of the minting process is illustrated in the diagram below.

kanji-nft-flow-diagram.drawio

Minting AI Generated Kanjis

kanji-87-small

The NFTs that you’ll be minting are AI generated Kanjis that were produced with sketch-rnn. You can see the collection that has been minted so far in this OpenSea Collection.

Secrets

The secrets are 80 of the most common pinyins for Kanji. Here’s a hint

Resources