Anon Exchange

Introduction

Anon Exchange uses Semaphore protocol to create an NFT exchange that can protect the anonymity of NFT sellers and buyers.

Semaphore is a zero-knowledge protocol that allows you to cast a signal (for example, a vote or endorsement) as a provable group member without revealing your identity. Additionally, it provides a simple mechanism to prevent double-signaling. Use cases include private voting, whistleblowing, anonymous DAOs and mixers.

This project utilizes the privacy setup of Semaphore protocol to form groups of buyers and sellers. So when transactions happen, public cannot tell the actual identities involved in the trade, while double spending can also be prevented.

For the simplicity of the initial system, we make the all NFTs traded at 0.01 ETH. It is possible to extend to other price levels in the future to support different sizes of transactions. More in the last section for future ideas.

System Components

User: NFT Seller

NFT Seller can perform the following 2 operations

  • List NFT on the smart contract and get Semaphore id

  • Claim ETH using the Semaphore id after the NFT is sold. A new address could be specified to receive the ETH. From public people can not tell among all the sellers whose NFT got sold withdrew the fund.

User: NFT Buyer

NFT Buyer can perform the following 2 operations

  • Deposit ETH to the smart contract and get Semaphore id. With the id buyer can prove that it is eligible to buy the listed NFTs

  • Buy NFT with the proof generated by Semaphore id. A new address could be specified to receive the NFT. From public people can not tell among all the depositors who made the purchase.

System: Semaphore Groups

There are 2 Semaphore groups for anonymity of seller and buyer.

  1. NFT_SOLD_SELLER_GROUP_ID: consist of sellers whose NFT got sold

  2. ETH_DEPOSITED_BUYER_GROUP_ID: consist of buyers who have deposited 0.01 ETH

The Semaphore id can only be signaled once, so it can prevent the issue of double spending.

How it works

Sellers Lists NFT

When a seller lists the NFT on the exchange, a Semaphore identity is generated. Seller needs to note down the private Semaphore id (trapdoor and nullifier). The smart contract will record the NFT with the corresponding public Semaphore id.

Buyers Deposits ETH

A buyer needs to deposit ETH before it can buy NFT. When buyer deposits, a Semaphore id is generated. Buyer needs to note down the private id (trapdoor and nullifier). The smart contract will add the public id into ETH_DEPOSITED_BUYER_GROUP_ID

Buyer Purchases NFT

Buyer submits the Semaphore proof that anonymously prove its membership of ETH_DEPOSITED_BUYER_GROUP_ID. Smart contract will verify the proof and signal the operation to prevent double spending. Buyer will provide a fresh address to receive the NFT. Additionally, the Semaphore id of seller associated with the sold NFT is added to NFT_SOLD_SELLER_GROUP_ID.

Seller Claims ETH for NFT Sold

Seller who wants to claim the ETH will submit the proof generated by its private Semaphore id, anonymously proving that it's a member of NFT_SOLD_SELLER_GROUP_IDand eligible to claim ETH. Smart contract will verify the proof, and signal the operation so it cannot be double claimed. Seller will also provide a fresh address to receive the ETH.

Anonymity

Note that transaction for buying NFT and claiming ETH can be sent from any address as long as the proof is valid. To remain anonymous the approach of this project is to maintain a relayer. The relayer will just submit the transaction for the user. From public people can only know Buyer or Seller is one in the group but wouldn't be able connect the NFT purchase to the original payer.

The Demo App

A demo app is developed to implement the operation flows above: anon-exchange.vercel.app. It’s deployed on Sepolia testnet.

The experience should be self explanatory. Some special notes

  • At the listing NFT page, it allows user to mint test NFT to experience the project

  • At the pages “Buy NFT” and “Claim ETH”, users do not need to connect wallet to perform the operation. The transaction is handled by relayer wallet so the privacy is preserved

  • The project uses randomly generated UUID as private secret to construct the Semaphore ID. There are other approaches to do it as well. A common practice could be asking the user to sign a message using wallet. The demo app avoid it deliberately to emphasize that user can operate completely without the wallet. For more information, please refer to the document here: https://semaphore.pse.dev/docs/guides/identities#create-deterministic-identities.

Future ideas

  • More trading sizes

    Merkle forest is something to be explored to support different prices so users can trade different prices of NFTs. Or even allow users to create new groups freely. However the privacy would be reduced when the users are split to many groups and less members in the group.

  • ERC20 payment

    Building on the previous point. It’s also possible to create group of buyers that pay in ERC20 with a set amount.

  • Support listing more asset types

    Besides selling NFTs, it is possible to list ERC20 or other asset types, or even a bundle of assets. More generally, it can be any defined operations that can be triggered when buyers pay. For example, it can be a transfer of smart contract wallet ownership.

  • Sustainable relayer

    To take from fee from the trades to make the relayer operation sustainable, or employ incentives for anyone to run a relayer.

Subscribe to 0xa388…415a
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.