Skip to content

Anis017/Blockchain-

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation


🕺 Project 2025 – A Semi-Decentralized Blockchain for Dancing Stickman

INFOB301 — University of Namur
Language: Rust 🦀
Purpose: Use blockchain and Proof-of-Work to reach consensus on a dancing stickman’s moves.


📖 Overview

Project 2025 is a university assignment designed to implement a semi-decentralized blockchain system in Rust, with a quirky but educational twist: miners compete to build a dance sequence for a virtual stickman, where each block contributes a single dance move (Y, M, C, or A).

The system includes:

  • A centralized server acting as the shared source of truth
  • Multiple clients (miners) that independently build and extend the blockchain
  • A blockchain tree, allowing forks and using the longest chain rule to determine consensus

🧩 Project Components

1. 💻 Client (Miner)

Located in the miner/ directory.

Responsibilities:

  • Mining new blocks using Proof-of-Work (PoW)
  • Building the blockchain tree
  • Interacting with the central server to fetch and submit blocks

2. 🖥️ Server

Located in the server/ directory.

Responsibilities:

  • Store all submitted blocks
  • Validate basic correctness (PoW & uniqueness)
  • Provide all known blocks to clients

🧠 Key Concepts to Understand


1. 📦 Blockchain Basics

Each block includes:

  • parent_hash: SHA256 hash of the parent block (empty for genesis)
  • miner: Name of the miner that created the block
  • nonce: A random value used in PoW
  • dancemove: Integer (1–4) representing the moves Y, M, C, A

Genesis Block:

  • Must have an empty parent_hash
  • Must have the miner name "Genesis"
  • Must pass the PoW check

Blockchain:

  • Represented as a tree (not just a chain)
  • Multiple branches (forks) allowed
  • The longest valid chain determines the winning sequence

2. 🧮 Proof-of-Work (PoW)

Miners must find a nonce so that the SHA256 hash of the block has the first N bits set to 0, where N is the difficulty (default is 25).

Why?

  • Prevents spam
  • Ensures fairness through computational effort
  • Ensures only well-formed blocks are added

Where?

  • Implemented in solve_block (in block.rs), using random nonces until the hash meets the difficulty

3. 🔒 SHA256 Hashing

Each block's unique identifier is its SHA256 hash, computed from:

  • parent_hash
  • miner
  • nonce
  • dancemove

Purpose:

  • Serves as a fingerprint for each block
  • Enables block linking via parent_hash

Where?

  • Implemented in hash_block (in block.rs), using a top-down concatenation order

4. ✅ Block Validation

Rules:

  • Genesis blocks: Must have parent_hash = "", miner = "Genesis", and valid PoW
  • Non-genesis blocks:
    • miner ≠ "Genesis" or "changemeyoufool"
    • dancemove ∈ {1, 2, 3, 4}
    • Must pass PoW

Why?

  • Prevents invalid data from entering the blockchain
  • Ensures dance moves are valid and blocks are unique

Where?

  • Implemented in is_block_valid and is_genesis (in block.rs)

5. 🌲 Blockchain Tree Structure

The blockchain is represented as a tree using the TreeNode struct from simpletree.rs.

Purpose:

  • Supports multiple forks
  • Enables traversal and analysis
  • Allows miners to build on forks

How?

  • Each node = 1 block
  • Children are blocks whose parent_hash matches the current block’s hash

Where?

  • Blockchain logic is in Blockchain struct (in miner.rs)
  • Tree handling is provided by TreeNode<Block>

6. 🔄 Client–Server Interaction

Server

  • Accepts blocks: POST /postblock
  • Returns all blocks: GET /blocks
  • Performs basic validation: PoW & uniqueness

Client (Miner)

  • Syncs with the server
  • Builds a local blockchain tree
  • Mines on the longest chain tip
  • Submits mined blocks to the server

Why?

  • Ensures consistency among all miners
  • Prevents duplication
  • Allows central authority to track global state

Where?

  • network.rs handles communication (via reqwest::blocking)
  • Integrated into mining loop in miner.rs

7. ⛏️ Mining Process

The mining logic includes three concurrent threads:

Thread Role
Network Periodically fetches new blocks from the server
Mining Mines new blocks on the tip of the longest chain
Main Updates blockchain and forwards tips to mining thread

Steps:

  1. Fetch blocks
  2. Rebuild blockchain tree
  3. Find tip of longest chain
  4. Mine a new block
  5. Submit it to the server

Where?

  • Implemented in mine function (in miner.rs)

8. 🥇 Longest Chain Rule

At any time, the valid chain with the most blocks is considered the winner.

  • Winning dance sequence = moves in the longest valid chain
  • Forks can happen but only one chain will dominate

How?

  • find_longest_chain_tip recursively searches for the deepest leaf

Why?

  • Enforces consensus
  • Encourages honest mining

📁 Project Structure and Logic


📂 miner/src/block.rs

Purpose: Defines block structure, hashing, validation, and PoW.

Key Structures:

  • Block: Struct with fields: parent_hash, miner, nonce, dancemove
  • DanceMove: Enum (Y=1, M=2, C=3, A=4)

Important Methods:

  • new(): Creates a new block
  • hash_block(): Computes SHA256 hash of the block
  • solve_block(): Mines the block by finding a valid nonce
  • pow_check(): Verifies if a hash meets PoW difficulty
  • is_block_valid(): Applies validation rules
  • is_genesis(): Checks if a block is a valid genesis block
  • is_parent(): Checks parent-child relation via hash

Design Choices:

  • PoW check: Uses full-byte + bitwise logic for performance
  • Random nonces: Generated using RngCore for PoW efficiency
  • Validation split: Genesis and non-genesis treated separately

📂 miner/src/miner.rs

Purpose: Defines blockchain structure, mining process, and CLI entry point.

Key Structures:

  • Blockchain: Holds a TreeNode<Block> to manage tree

Functions:

  • new_from_genesis(): Starts a blockchain from genesis
  • new_from_genesis_and_vec(): Reconstructs blockchain from blocks
  • mine(): Handles mining with three threads
  • find_longest_chain_tip(): Finds the deepest leaf node
  • main(): CLI interface with two commands:
    • mine: Starts mining
    • print: Displays blockchain

Design Choices:

  • Threading: Uses std::sync::mpsc channels for safe communication
  • Genesis strategy: Creates or selects a genesis block from server
  • Chain updates: Iteratively inserts blocks, rechecking orphans
  • Visual output: Tree printed using print_tree()

📂 miner/src/network.rs

Purpose: Handles communication with the server.

Key Structure:

  • NetworkConnector: Uses channels to send/receive blocks

Key Methods:

  • sync(): Periodically pulls/pushes blocks from/to server
  • get_blocks(): Fetches all blocks via GET /blocks

Design Choices:

  • Blocking networking: Uses reqwest::blocking for simplicity
  • Rate limiting: 1 request/sec to comply with project rules
  • Fault tolerance: Continues running on network failure

📂 miner/src/simpletree.rs

Purpose: Provides generic tree structure for blockchain.

Key Elements:

  • TreeNode<T>: Node with children
  • Parenting trait: Lets nodes identify valid parents

Methods:

  • insert, depth, look_for_parent, etc.

Design Choices:

  • DFS lookup: Efficient parent matching
  • Reusability: Can be applied to any structure implementing Parenting

📂 miner/src/lib.rs

Purpose: Exposes block and simpletree modules for use in miner.rs

Design:

Minimal glue code

  • Improves module organization

📄 miner/Cargo.toml

Lists all dependencies:

serde = "1.0"
serde_derive = "1.0"
rand = "0.8"
sha2 = "0.10"
clap = "3.2"
reqwest = { version = "0.11", features = ["blocking", "json"] }

📂 server/src/main.rs

Purpose: Implements centralized HTTP server with basic block validation.

Key Logic:

  • Uses rouille for HTTP endpoints:
    • GET /blocks: Returns all stored blocks
    • POST /postblock: Accepts a new block

Storage:

  • In-memory HashMap using nonce as key

Validation:

  • Verifies PoW
  • Rejects duplicate nonces

📄 server/Cargo.toml

rouille = "3.0"
clap = "3.2"
serde = { version = "1.0", features = ["derive"] }

🧪 Testing

Run unit tests:

cd miner
cargo test

Tests cover:

  • Genesis block validation
  • PoW edge cases
  • Blockchain reconstruction
  • Forks, orphans, and duplicates

🚀 How to Run the Project

1. Install Rust

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

2. Run the Server

cd server
cargo run

Optional:

cargo run -- -a 127.0.0.1 -p 8080 -d 10

3. Run the Miner

cd miner
cargo run -- mine -d 10 -m YourMinerName

Print the blockchain:

cargo run -- print -d 10

🌱 Future Improvements

  • Async networking (via tokio)
  • Protocol attacks for bonus marks
  • Improved multiple genesis handling
  • Persistent storage on the server

🛡 License

This project is intended only for educational purposes and not for production.
Use at your own risk.


🙌 Authors & Acknowledgments

Created as part of INFOB301 at Université de Namur
All logic and implementation decisions align with course specifications.


About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages