A Framework for Trustless, Verifiable, and Private Card Games on the Blockchain

The problem Tazza solves

Numerous games have been released in the Web3 ecosystem, but most simply tokenize game assets as NFTs on the blockchain, while gameplay takes place on centralized servers. One exception is Dark Forest, an experimental ZK-based, fully on-chain game on Gnosis chain that operates without a server, relying solely on contracts. Despite its potential, there has been a lack of fully on-chain games since Dark Forest's release. This is due to two main obstacles:

  1. High barrier to entry for Zero-Knowledge (ZK): The complex nature of ZK tools discourages developers and users from adopting privacy and security measures.
  2. Complexity of implementing game logic in ZK: The complex nature of traditional game logic makes it difficult to translate into a ZK-compatible format.

To address these issues, we decided to provide an abstract SDK focused specifically on card games, which typically involve a limited number of private actions. Enter Tazza, an architecture designed for ZK-based, fully on-chain card games. We used circom to create circuits for card actions such as shuffling decks, drawing cards, and opening cards, and used snarkjs to generate Tazza contracts and Tazza JS SDK. These tools make it easy for game developers to create contracts and clients for card games. The key advantage of Tazza is its universal applicability to different card games.

Tazza leverages the features of Gnosis chain to revolutionize the gaming industry. It benefits from low-cost on-chain verification with the option to integrate Gnosis chain's on-chain randomness to empower various card games for mass adoption. Tazza on Gnosis chain enables fast and cost-effective, yet fair and decentralized game play.

Challenges we ran into

The biggest hurdle we faced was providing an SDK that could be easily used by developers without any knowledge of zero-knowledge proofs. We solved this by:

  1. Providing an encapsulated contract that stores and manages the state of cards and decks.
  2. Providing a high-level interface with functions such as creating decks, shuffling, and drawing cards.

While building the deck shuffling circuit using circom and snarkjs, we noticed that the library size and computational complexity increased linearly when the number of cards increased. Although we couldn't solve this problem during the hackathon, two possible solutions were suggested:

  1. Use a shuffle-specific zero-knowledge proof method optimized for shuffling, without relying on circom and snarkjs.
  2. Repeat the shuffling of the two cards in parallel to optimize it up to O(log^2 n) rounds.