Skip to content

DestroyerAlpha/Blockchain2.0

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Blockchain2.0

Team Members

  • Duy The Dang(dtd2125)
  • Shivam Chaturvedi (sc5588)
  • Angela Peng (ap4636)
  • Luigi Liu (ll3840)

📁 Project Structure

DemoApp

Project Structure

DemoApp/
├── init.py             # Package marker
├── script.js           # Frontend logic (for 1 client)
├── scriptv2.js         # Frontend logic (for use if want to test another client)
├── style.css           # Styles for wallet UI
├── wallet_api.py       # Flask backend API for wallet interaction
├── wallet_ui.html      # Wallet UI (for 1 client)
├── wallet_ui_v2.html   # Wallet UI (for use if want to test another client)
├── wallet.py           # Wallet logic (includes WalletApp)

Features:

  • Generate and use a new wallet key pair
  • View public wallet address
  • View live balance (via polling)
  • Send signed transactions
  • View blockchain blocks and transactions
  • Simple modal UI for transaction details

Requirements

  • Python 3.8+
  • Flask (backend)
  • requests (for inter-service HTTP)
  • Bootstrap 5 (for frontend UI)

🏗️ Blockchain Core

Directory Layout

blockchain/
├── **init**.py        # Package marker
├── block.py           # Block structure & proof‑of‑work logic
├── blockchain.py      # Chain management, validation, fork resolution
├── node.py            # High‑level node that ties P2P, mempool & mining
└── utils.py           # Helper functions (hashing, timestamps, etc.)

Key Components

File Main Classes / Functions Responsibilities
block.py Block ‑ Immutable record containing index, prev_hash, timestamp, nonce, transactions, and hash
‑ Implements mine() (incrementing nonce until hash meets difficulty)
‑ Provides is_valid() for self‑validation
blockchain.py Blockchain ‑ Maintains the canonical chain and orphan branches
‑ Validates and appends blocks, resolves forks (longest‑valid‑chain rule)
‑ Tracks current mempool and exposes add_new_transaction() / mine_pending_transactions()
‑ Utility methods: get_main_chain(), get_balance(addr)
node.py BlockchainNode ‑ Combines a Blockchain instance with a P2PNode
‑ Background threads for mining and for receiving network data
‑ Broadcasts newly mined / received blocks, adds incoming transactions to mempool
utils.py current_ts(), hashing helpers, TxType enum ‑ Simple utility layer so core classes stay focused

Data Flow

  1. Transaction creation (from DemoApp or other peers) → added to mempool.

  2. Mining loop (node._mine_loop):

    • pulls pending transactions, builds a candidate Block, runs PoW via Block.mine().
    • upon success, broadcasts the block to peers.
  3. Block reception (node.receive_network_data):

    • validates block; if valid and builds a longer chain, inserts into Blockchain.
    • If the block originates a fork, side‑chains are tracked and pruned when they fall ≥6 blocks behind.

Proof‑of‑Work

  • difficulty = number of leading zeros required in SHA‑256 block hash.
  • Adjustable when instantiating Blockchain(difficulty=…) or BlockchainNode.

Typical Usage

from blockchain.blockchain import Blockchain
from transactions.transaction import Transaction, TxType
from crypto.key\_pair import KeyPair

bc = Blockchain(difficulty=2)
alice, bob = KeyPair(), KeyPair()

# Mint coins to Alice

mint = Transaction(TxType.ASSIGN, sender="", recipient=alice.public, amount=10); mint.sign(alice)
bc.add\_new\_transaction(mint); bc.mine\_pending\_transactions()

# Transfer

pay = Transaction(TxType.TRANSFER, sender=alice.public, recipient=bob.public, amount=3); pay.sign(alice)
bc.add\_new\_transaction(pay); bc.mine\_pending\_transactions()

print("Alice:", bc.get\_balance(alice.public))  # -> 7
print("Bob:",   bc.get\_balance(bob.public))    # -> 3

Note: networking is optional—running Blockchain in isolation is perfect for unit tests or demos; add BlockchainNode when you need peer discovery and block propagation.

Add a more detailed directory map for p2p and blockchain here once implementation stabilises.


WalletApp

The WalletApp class under DemoApp/wallet.py handles key wallet operations:

Method Description
get_public_key_str() Returns the public key as a string (used as the wallet address).
sign_transaction(message: dict) Signs the basic transaction payload using the private key.
create_transaction(recipient, amount, sign=True) Builds a transaction to the given recipient and optionally signs it.
compute_txid(tx: dict) Computes a SHA-256 hash of the transaction data, excluding the signature.

API Endpoints (Backend)

DemoApp/wallet_api.py

Endpoint Method Description
/wallet/address GET Fetch the wallet's public key
/transaction/send POST Send a transaction to the blockchain
/blockchain GET Retrieve the current blockchain
/connect POST Register this wallet with the network

How to start the backend?

For testing purposes, we have encapsulated the starting of all the nodes under a single application layer. All these nodes are running under different ports but the same process. While this might not be how it would be done ideally, we did this for ease of testing locally.
Command:
python3 -m application.application <application_ip> <application_port> <tracker_ip> <tracker_port> <list_of_blockchain_node_ip_and_ports>

How to Run

  1. Start the blockchain backend (port 60000)
  2. Start the wallet API (Flask app on port 5050)
cd DemoApp
python3 wallet_api.py 5050
  1. Open http://localhost:8080/wallet_ui.html in your browser after running the following command
cd DemoApp
python3 -m http.server 8080

Example Transaction (JS Console)

// Send 5 BTC to another address
fetch("http://localhost:5050/transaction/send", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    to: "recipient_public_key_here",
    amount: 5,
    sign: true
  })
}).then(res => res.json()).then(console.log);

Important Note on Wallet Connection Handling

The app is designed to connect the wallet to the blockchain only once per session using a flag stored in the browser's localStorage:

localStorage.setItem("cw_connected_once", "true");

This prevents repeated /connect requests on each page reload. However, if you manually restart the backend server (e.g., using Ctrl+C and restarting Flask), the browser is not aware of it, and the connection flag will persist.

To reconnect after restarting the backend, open DevTools in your browser and manually remove the cw_connected_once item from localStorage:

  1. Open DevTools (F12 or right-click → Inspect)
  2. Go to the Application tab
  3. Under Storage → Local Storage, select your app’s URL
  4. Find and delete the cw_connected_once key
  5. Refresh the page

This will force the wallet to re-send the connection request.

Also Note: This is a demo app. Wallet keys are not persisted across sessions. In a real system, we'd want secure key storage, transaction validation, and persistent nodes.

P2P Implementation

Check the main section of p2p/p2p_node.py and p2p/p2p_tracker.py for instructions on running tests for P2P implementation.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •