5/5
## Defining the ZK Panagram Architecture in README.md The first step in building our "ZK Panagram" project involves establishing a clear architectural blueprint. This is crucial for guiding development and ensuring all components work cohesively. We'll document this architecture within the project's `README.md` file, replacing any default Foundry content. The core elements of the ZK Panagram architecture are as follows: * **Project Title**: ```markdown # ZK Panagram ``` * **Core Game Concept**: The game revolves around "answers" (e.g., specific words), where each correct answer defines a "round." * Essentially, each "answer" corresponds to a unique "round." * Rounds are designed to be continuous. The contract owner has the exclusive ability to initiate the subsequent round. * **Owner's Role and Responsibilities**: * A designated smart contract owner will exist. * Crucially, only this owner is authorized to start a new round of the game. * **Round Mechanics and Rules**: * **Minimum Duration**: Each round must last for a predefined minimum duration. * **Starting New Rounds**: A new round can only be initiated if the preceding round has concluded with a declared winner. * **Determining the Winner**: The winner of a round is the first user to submit the correct guess for that round's answer. * **Runners-Up**: Other users who submit correct guesses after the official winner has been determined are acknowledged as "runners-up." * **NFT Contract (ERC-1155 Standard)**: * The main `Panagram` smart contract will adhere to the ERC-1155 token standard. This standard is chosen for its ability to manage multiple distinct token types (semi-fungible tokens) within a single contract. * **Token ID 0**: This token ID will be minted and awarded to the winners of each round. * **Token ID 1**: This token ID will be minted and awarded to the runners-up in each round. * **Token Minting Logic**: * Token ID 0 (Winner's Token) is exclusively minted to the user who is the *first* to submit a correct guess in a given round. * Token ID 1 (Runner-Up Token) is minted to users who submit a correct guess but are *not the first* to do so in that round. * **Verifier Smart Contract Integration**: * To ascertain the correctness of a user's submitted guess, the `Panagram` contract will delegate this task by calling a separate, specialized "Verifier smart contract." * The blockchain address of this Verifier contract will be a required parameter, passed into the `Panagram` contract's constructor during deployment. ## Initializing the Panagram Smart Contract (`Panagram.sol`) With the architecture defined, we begin the implementation of the primary smart contract, `Panagram.sol`. The initial setup includes the standard SPDX license identifier and the Solidity pragma version: ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; ``` ## Setting Up Dependencies and Project Configuration Our `Panagram` contract will be an ERC-1155 token, so we'll leverage OpenZeppelin's battle-tested implementation. * **Installing OpenZeppelin Contracts**: Use the Foundry `forge install` command to add OpenZeppelin contracts to your project. Note that the `--no-commit` flag is no longer necessary with recent versions of Foundry. ```bash forge install openzeppelin/openzeppelin-contracts ``` This command will install the library, and for this project, version `v5.3.0` of OpenZeppelin contracts is used. * **Foundry Remappings (`foundry.toml`)**: To enable the Solidity compiler and your development environment to locate the installed OpenZeppelin library files, you need to configure path remappings. Add the following to your `foundry.toml` file: ```toml [profile.default] src = "src" out = "out" libs = ["lib"] remappings = [ '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/', 'forge-std/=lib/forge-std/src/' ] # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options ``` These remappings tell Foundry to look for imports starting with `@openzeppelin/contracts/` in the `lib/openzeppelin-contracts/contracts/` directory. * **VS Code Remappings (`remappings.txt`)**: For an improved developer experience, especially for Solidity language support in VS Code (e.g., the Solidity extension by Nomic Foundation), create a `remappings.txt` file in the root of your project. This file helps the extension resolve import paths correctly. Its content should mirror the remappings in `foundry.toml`: ``` @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ forge-std/=lib/forge-std/src/ ``` ## Importing Essential Contracts for Panagram Now, we import the necessary contracts into `Panagram.sol`. * **ERC1155 Standard**: We import the base `ERC1155` contract from OpenZeppelin, which our `Panagram` contract will inherit from. ```solidity import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; ``` * **IVerifier Interface**: The `Panagram` contract needs to interact with the external `Verifier.sol` contract to check guesses. To facilitate this, we import an interface, `IVerifier`. This interface (which would be defined in `Verifier.sol` or a dedicated interface file) declares the function signatures of the Verifier contract, such as a `verify()` function, that `Panagram` will call. ```solidity import {IVerifier} from "./Verifier.sol"; // Assuming Verifier.sol is in the src/ directory alongside Panagram.sol ``` ## Building the Panagram Contract: Definition and Constructor We can now define the `Panagram` contract structure, declare necessary state variables, and implement its constructor. * **Contract Shell**: The contract is named `Panagram` and inherits from `ERC1155`. A NatSpec comment `@title` is included for documentation. ```solidity // @title Panagram contract Panagram is ERC1155 { // Contract implementation will go here } ``` * **State Variable for Verifier Address**: We declare an `immutable public` state variable named `verifier` of type `IVerifier`. This variable will store the address of the Verifier contract. * `public`: Automatically creates a getter function for this variable. * `immutable`: The value of `verifier` is set once in the constructor during deployment and cannot be changed thereafter. This enhances security and can lead to gas savings. ```solidity IVerifier public immutable verifier; ``` * **Constructor Implementation**: The constructor is responsible for initializing the `Panagram` contract. 1. It accepts the address of the Verifier contract (`_verifier`) as an argument. 2. It initializes the `verifier` state variable with the provided `_verifier` address. 3. It calls the constructor of the parent `ERC1155` contract. The `ERC1155` constructor requires a URI string that points to the metadata for the tokens. An example IPFS URI is used: `"ipfs://bafybeicqfc4ipkle34tgqv3gh7gccwhmr22qdg7p6k6oxon255mnwb6csi/{id}.json"` The `{id}` placeholder in this URI is a standard ERC-1155 convention. It allows client applications to dynamically construct the full metadata URL for each specific token ID by replacing `{id}` with the actual token ID (e.g., 0 or 1). The complete `Panagram.sol` contract with the initial setup, imports, state variable, and constructor is as follows: ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; import {IVerifier} from "./Verifier.sol"; // Assuming Verifier.sol is in the same directory // @title Panagram contract Panagram is ERC1155 { IVerifier public immutable verifier; constructor(IVerifier _verifier) ERC1155("ipfs://bafybeicqfc4ipkle34tgqv3gh7gccwhmr22qdg7p6k6oxon255mnwb6csi/{id}.json") { verifier = _verifier; } } ``` ## Key Web3 Concepts in ZK Panagram This initial setup touches upon several fundamental Web3 and smart contract development concepts: * **ERC-1155 Token Standard**: A versatile multi-token standard. It's ideal for `Panagram` as it allows the contract to manage multiple copies of different token types (Winner tokens - ID 0, Runner-up tokens - ID 1) efficiently within a single contract. * **Game Rounds**: The game's progression is structured into "rounds," each associated with a unique "answer." This modularizes the game flow. * **Owner-Controlled Actions**: Certain critical functions, such as initiating new rounds, are restricted to the contract owner. This is a common pattern for administrative control in smart contracts. * **Verifier Contract (Separation of Concerns)**: Offloading the guess verification logic to a separate `Verifier` contract promotes modularity and maintainability. The `Panagram` contract focuses on game flow and token management, while the `Verifier` handles the specifics of guess validation (which could potentially involve ZK proofs, hence "ZK Panagram"). * **Foundry Remappings**: A configuration feature in the Foundry development framework. Remappings allow developers to define aliases for import paths (e.g., `@openzeppelin/` pointing to a local `lib` directory). This simplifies dependency management and improves code readability. `foundry.toml` handles this for compilation, while `remappings.txt` aids IDEs like VS Code. * **Immutability**: Declaring state variables like `verifier` as `immutable` means their value is set at deployment (in the constructor) and cannot be altered later. This provides security guarantees (the verifier address cannot be maliciously changed) and gas optimization, as the value is directly embedded into the contract's bytecode. * **Metadata URI (ERC-1155)**: Both ERC-721 and ERC-1155 token standards use Uniform Resource Identifiers (URIs) to link to JSON files containing token metadata (name, description, image, attributes, etc.). The `{id}` placeholder in the base URI is a common pattern for ERC-1155, enabling a single base URI to serve metadata for all token IDs managed by the contract. ## Important Development Notes and Tips * **Foundry `forge install` Update**: Be aware that the `forge install` command in Foundry has evolved; the `--no-commit` flag, previously common, is generally no longer required. * **VS Code Integration with `remappings.txt`**: Creating a `remappings.txt` file in your project root significantly enhances the developer experience when using VS Code with Solidity. It helps the Solidity extension correctly resolve import paths defined in `foundry.toml`, leading to better autocompletion and error highlighting. * **OpenZeppelin Contracts Version**: The version of OpenZeppelin Contracts utilized as the base for this project is `v5.3.0`. Always refer to the specific version used if you encounter compatibility issues or are looking for particular features. This foundational setup prepares the ZK Panagram project for the implementation of its core game logic and token mechanics.
A foundational blueprint for Defining the ZK Panagram Architecture in README.md - Establish the ZK Panagram's architectural design in its README, detailing game mechanics, ERC-1155 token rewards, and the Verifier contract's role. This lesson then guides the initial setup of `Panagram.sol`, including OpenZeppelin integration and Verifier contract linkage.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Course Overview
About the course
Noir syntax
Create a witness, a proof, and Solidity verifier contracts
Use the Poseidon commitment scheme
Create ZK circuits and build a full ZK protocol
ZK Merkle trees and hashing in Noir
Verify signatures without revealing the signer
Build the backend for a full-stack ZK application with noir.js and bb.js
How to create proofs and verify them in a front-end
Last updated on June 12, 2025
Duration: 6min
Duration: 1h 11min
Duration: 2h 12min
Duration: 3h 19min
Course Overview
About the course
Noir syntax
Create a witness, a proof, and Solidity verifier contracts
Use the Poseidon commitment scheme
Create ZK circuits and build a full ZK protocol
ZK Merkle trees and hashing in Noir
Verify signatures without revealing the signer
Build the backend for a full-stack ZK application with noir.js and bb.js
How to create proofs and verify them in a front-end
Last updated on June 12, 2025