Unique NFT ASA Implementation

That looks interesting.

First two remarks:

  • I don’t think you will be able to check primality on-chain. But I guess this is not a real issue as you can do it offchain.
  • Block proposers can “steal” prime numbers: if they see the creation of an NFT for a prime number, they can just not include the transaction and create it themselves.

Let’s first ignore this second issue.
You can ensure uniqueness of NFT by issuing the NFT from a smart contract account where the prime number p is hardcoded.

Concretely, you first create an application App (stateful TEAL) whose role will be described later.
Let C_p be the smart contract account for the stateless TEAL script that:

  • have p hardcoded as a constant
  • require any transaction from C_p to be in a group of transactions with a call to App

Note that the address C_p can be computed from a smart contract application. See Bond Implementation - #7 by fabrice

Now, to create an NFT for the prime p, Alice would send the following group of transactions:

  • Alice sends 1 Algo to C_p
  • C_p opts-in to App - App will check that C_p was not already opt-in. If not, it will store in the local storage of C_p two variables: p = p and creator=Alice
  • C_p creates the NFT

Then Alice opts in to the NFT.

Finally, Alice send the following group of transactions:

  • C_p calls App. App check that p and creator are set, and erase creator. It also checks the second transaction is an NFT transfer from C_p to creator.
  • C_p sends the NFT to Alice

Now to solve the issue that a block proposer can steal the prime number, what you can do is add a registration phase to the App

To register p, Alice opts in to App providing a hash value h = SHA256(Alice || r || p), where Alice is Alice’s address and r is a 32-byte random number chosen by Alice, and || is the string concatenation.
The App stores in Alice’s local storage the round round of the App call and h.

Then to create an NFT for p as above, Alice needs also to provide r and have in its local storage the above h. Furthermore, the App restricts the creation of an NFT for a registration h to happen after round round + 10,000.

Now, if a block proposer try to steal p, it will first see h. h does not reveal anything about p, so the block proposer cannot do anything meaningful about it.
Then, 10,000 rounds later, Alice will reveal r and p to allow the creation of the NFT for p.
To be able to steal p, the block proposer would then need to re-register p using h' = SHA256(r' || BadBlockProposer || p) and wait 10,000 rounds! This means that the block proposer needs to prevent the transaction from Alice to be committed for 10,000 rounds. This is virtually impossible (except if the bad block proposer has virtually all the Algos in the blockchain).

6 Likes