Skip to content

Commit 02b4dbb

Browse files
committed
feat: update README
1 parent a0781bd commit 02b4dbb

1 file changed

Lines changed: 82 additions & 93 deletions

File tree

README.md

Lines changed: 82 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,114 @@
1-
# 🧱 TaskBoard
1+
# TaskBoard (A decentralized platform for CTF-style challenges using Ethereum, IPFS, and zkSNARKs.)
22

3-
Design and build a **decentralized task board and badge collector** for developers and learners. Tasks are challenges with predefined correct solutions, and successful solvers earn **on-chain badges** (NFTs or SBTs) that they can collect as verifiable proof of their skills.
3+
See a small [blog](https://lasmichal.com/projects/taskboard/taskboard.html) about this dApp.
4+
5+
TaskBoard is a dApp for creating and solving CTF-like tasks using smart contracts, IPFS, and zero-knowledge proofs (ZKP).
6+
Users solve challenges by proving knowledge of a hidden secret without revealing it. Successful solvers are rewarded with task-specific tokens.
47

58
To ensure trustless and scalable operation:
69

710
* Solutions are verified automatically (no manual approval).
811
* Tasks and descriptions are stored off-chain via IPFS.
912
* Proof validation is handled using ZK circuits.
1013
* Submissions remain **private** to avoid copying.
14+
* Rewards issued as non-transferable ERC-1155 tokens.
1115

12-
---
13-
14-
## Core Features
16+
## Tech stack
1517

16-
### 1. **Task Creation**
18+
* Frontend – React
19+
* Backend – [Node.js](https://nodejs.org/en) ([Fastify](https://fastify.dev/)) + [Postgres](https://www.postgresql.org/)
20+
* Smart contracts – Solidity (ERC-1155, AccessControl)
21+
* Storage – IPFS (local - [Kubo IPFS](https://docs.ipfs.tech/install/command-line/) / [Pinata](https://pinata.cloud/))
22+
* Proof system – snarkjs + Groth16
1723

18-
* Any user can create a task
19-
* Task includes:
24+
## How it works
2025

21-
* Title, description, difficulty
22-
* Required tags (e.g., Solidity, ZK, Rust)
23-
* Solution validation mechanism (hash or ZK circuit hash)
24-
* Reward badge config (SBT metadata)
25-
* Deadline (optional)
26-
* Metadata is uploaded to IPFS
27-
* The contract stores minimal task data + IPFS CID
26+
1. Task creation – Creator commits a secret (Poseidon hash + salt) stored on IPFS.
27+
2. Solving – Solver submits a ZKP proving they know the secret.
28+
3. Verification – Smart contract checks the proof and mints a reward token.
2829

2930
---
3031

31-
### 2. **Task Solving / Proof Submission**
32-
33-
* Any dev can attempt the task
34-
* They submit a **proof** of solution
35-
* The contract verifies it:
32+
## Set up
3633

37-
* If correct → mints badge (NFT/SBT) to solver
38-
* If wrong → rejected, optional retry delay
39-
* Optional: support encrypted solution uploads for future reference
34+
1. Compile the circuit and generate a trusted setup with `make circuit` (testing only).
35+
2. Export smart contract ABI with `make export-task-manager-abi`.
36+
3. Start the Postgres DB and use `make delete-db` and `make init-db`.
37+
- Postgres has to have user `app` and created database called `task_board_db`.
38+
4. Start Anvil and deploy smart contracts with `make deploy-local` and add creator `add-creator-local`.
39+
- The creator is Anvil's account (1) with address _0x70997970C51812dc3A010C7d01b50e0d17dc79C8_, add it to your wallet (e.g., MetaMask).
40+
5. Start Kubo IPFS `ipfs daemon`.
41+
6. Start the backend from `/backend` directory with `npm run dev`.
42+
7. Start the frontend from `/frontend` directory with `npm run dev`.
4043

41-
---
42-
43-
### 3. **Badge Minting**
44+
## Environment files
4445

45-
* Each task has a custom badge
46-
* Badges are:
46+
### Root `.env` (for smart contracts)
4747

48-
* Non-transferable (SBT)
49-
* Include metadata about task
50-
* Linked to IPFS data
51-
* Optional: user profile page with badge portfolio (off-chain frontend)
52-
53-
---
48+
```bash
49+
### ENV for local Anvil node
50+
PRIVATE_KEY_LOCAL=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
51+
PRIVATE_KEY_CREATOR=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
52+
PRIVATE_KEY_SOLVER=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a
5453

55-
## Example Task Flow
54+
CREATOR_ADDR=0x70997970C51812dc3A010C7d01b50e0d17dc79C8
5655

57-
1. Alice creates a task:
56+
TASK_MANAGER_ADDR=0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9
57+
TASK_ACCESS_ADDR=0x5FbDB2315678afecb367f032d93F642f64180aa3
5858

59-
* **"Write a smart contract that verifies Merkle Proofs"**
60-
* IPFS CID with metadata: `bafy...abc`
61-
* Creator writes a ZK circuit
59+
TASK_ID_TO_DEACTIVATE=1
6260

63-
2. Task posted on-chain with IPFS CID and hash
61+
### ENV for Sepolia deployment
6462

65-
3. Bob solves it:
66-
67-
* Generates a ZK proof using the circuit
68-
* Submits the proof to the smart contract
69-
* If valid → badge minted
70-
71-
---
72-
73-
## Proof Validation Logic Options
74-
75-
Choose from these validation types (extendable):
76-
77-
---
78-
79-
### Zero-Knowledge Proofs (Advanced)**
80-
81-
* Creator writes a ZK circuit using **Circom**
82-
* Contract stores `circuitHash`
83-
* Solver:
84-
85-
* Builds the solution off-chain
86-
* Generates a ZK proof using the circuit
87-
* Submits the proof to the smart contract
88-
* Contract verifies proof → badge minted
89-
90-
**Good for**:
91-
92-
* Math challenges, logic puzzles, data constraints, Merkle inclusion
93-
94-
**Requires**:
63+
PRIVATE_KEY=0xYOUR_PRIVATE_KEY # Wallet private key
64+
ETHERSCAN_API_KEY=YOUR_ETHERSCAN_KEY # Etherscan API key (for verification)
65+
SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY> # RPC provider (Alchemy)
66+
```
9567

96-
* ZK circuit storage (IPFS or registry)
68+
### Backend `.env`
69+
70+
```bash
71+
SERVER_PORT=3000
72+
IPFS_STORAGE_MODE='local' # 'dev', 'local', or 'prod'
73+
IPFS_LOCAL_API_URL='http://127.0.0.1:5001' # if IPFS_STORAGE_MODE='local', then this is the API URL of the local IPFS node
74+
IPFS_LOCAL_GATEWAY_URL='http://127.0.0.1:8080' # if IPFS_STORAGE_MODE='local', then this is the gateway URL of the local IPFS node
75+
PINATA_API_KEY='<Pinata API key>' # if IPFS_STORAGE_MODE='prod', then this is the Pinata API key
76+
PINATA_JWT_TOKEN='<Pinata JWT token>' # if IPFS_STORAGE_MODE='prod', then this is the Pinata JWT token
77+
PINATA_GATEWAY_URL='blush-peculiar-quail-924.mypinata.cloud' # if IPFS_STORAGE_MODE='prod', then this is the Pinata gateway URL
78+
PINATA_TASKS_GROUP_ID='<Pinata tasks group ID>' # if IPFS_STORAGE_MODE='prod', then this is the Pinata tasks group ID
79+
PINATA_IMAGES_GROUP_ID='<Pinata images group ID>' # if IPFS_STORAGE_MODE='prod', then this is the Pinata images group ID
80+
81+
LISTENER_MODE= 'local' # 'local' or 'prod'
82+
INFURA_API_KEY='<Infura API Key>' # if LISTENER_MODE='prod', then this is the Infura API Key
83+
CONTRACT_ADDRESS=0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 # TaskManager contract deployed address
84+
START_BLOCK=0 # Needed for fetching history of events. This has to be number of block inside which the TaskManager contract was deployed
85+
FINALITY_BLOCKS=5 # Number of blocks until events will be recorded into the database
86+
87+
DATABASE_USER='app'
88+
DATABASE_PWD='app'
89+
DATABASE_HOST='localhost'
90+
DATABASE_NAME='task_board_db'
91+
DATABASE_PORT=5432
92+
```
9793

9894
---
9995

100-
## Task Metadata (IPFS)
101-
102-
Example task metadata JSON:
96+
## Token metadata and Task Data
10397

10498
```json
10599
{
106-
"title": "Merkle Tree Challenge",
107-
"description": "Build a Solidity contract that generates a Merkle root and verifies leaf inclusion using proof. Submit the root hash as the answer.",
108-
"difficulty": "Medium",
109-
"tags": ["Solidity", "Merkle", "Security"],
110-
"validationType": "hash",
111-
"solutionHash": "0xdeadbeef123...",
112-
"testSuiteCID": "bafy...xyz",
113-
"createdBy": "0x1234abcd...",
114-
"createdAt": 1729849200
100+
"name": "Stego Sleuth",
101+
"description": "Proof of your ability to uncover secrets hidden in plain sight.",
102+
"image": "ipfs://<cid>",
103+
"task": {
104+
"title": "Steganography in the Image",
105+
"description": "A PNG file hides a message in its least significant bits. Extract it to find the secret number.",
106+
"difficulty": "Easy",
107+
"tags": ["stego", "forensics", "binary"],
108+
"createdBy": "0x1234abcd...",
109+
"createdAt": 1729849200,
110+
"requirements": ["steganography tools", "hex editor"],
111+
"resources": ["ipfs://<cid>"]
112+
}
115113
}
116-
```
117-
118-
You can upload this with:
119-
120-
* [Web3.Storage](https://web3.storage)
121-
* [NFT.Storage](https://nft.storage)
122-
* [Pinata](https://pinata.cloud)
123-
124-
Use returned CID in your smart contract.
125-
114+
```

0 commit comments

Comments
 (0)