A Bitcoin-style blockchain engine built from scratch in Java, implementing the complete UTXO transaction lifecycle β from coinbase issuance through fee-prioritized mempool staging, PoW mining, dynamic difficulty retargeting, and 2-node P2P consensus via Java Sockets. Every design decision mirrors a real Bitcoin mechanic.
| Feature | Status |
|---|---|
| UTXO Transaction Model | β |
| ECDSA Wallets (BouncyCastle) | β |
| Satoshi-Denomination Integers | β |
| Proof-of-Work Mining | β |
| Merkle Root Integrity | β |
| Mempool with Fee Prioritization | β |
| Coinbase Transaction + Mining Reward | β |
| Transaction Fee Market | β |
| Dynamic Difficulty Retargeting | β |
| Per-Block Difficulty Snapshot | β |
| Full Chain Validation | β |
| 2-Node P2P Network (Java Sockets) | β |
| 4-Layer Architecture (SRP) | β |
- ECDSA key pair generation via BouncyCastle (
prime192v1curve) - Private key signing + public key verification per transaction
- Fee field included in signed data β prevents miner from tampering fee after signing
- Base64 key encoding via
StringUtilcrypto layer
- Full Bitcoin-style Unspent Transaction Output model
- Dynamic balance calculated by scanning UTXO map β no stored balance field
- Double-spend prevention: spent inputs removed from global UTXO set atomically
- Input-output equality enforced:
inputsValue = outputsValue + fee - Change outputs automatically returned to sender
- All coin values stored as
longintegers (satoshis) β neverfloatordouble - 1 NoobCoin = 100,000,000 satoshis β identical to Bitcoin's unit model
- Eliminates floating-point precision errors (
0.1f + 0.2f = 0.30000001in Java) - Display conversion via
StringUtil.toCoins()β satoshis βx.xxxxxxxxstring
- Transactions submitted via
sendFunds()enter a global pending pool - Miner sorts mempool descending by fee before packing a block
- Highest-fee transactions confirmed first β replicates Bitcoin's economic incentive
- Miner income =
miningReward + sum(all fees in block) - Mempool cleared atomically after successful mine
Coinbase TX (block reward + fees β miner)
β
Wallet.sendFunds(recipient, value, fee) β Mempool
β
MiningEngine.mineNextBlock() β sort by fee β pack block
β
PoW solved β broadcast to peers β peers validate β append
β
UTXO set updated β mempool cleared
- Difficulty stored per block at mine time β not read from global state
- Every
retargetIntervalblocks: compares actual vs target mine time - Increases difficulty if blocks mined too fast, decreases if too slow
- Per-block snapshot fixes mid-chain retarget validation bug: blocks mined at difficulty 3 are validated against 3, not current difficulty 4
- Merkle root computed from all transaction IDs in a block
- Stored in block header, included in
calculateHash() - Updated on every
addTransaction()andaddCoinbase()call - Any tampered transaction changes the root β breaks block hash β detected by validator
- Hash chain integrity:
previousHashmust match prior block'shash - Per-block hash recalculation verified against stored hash
- Each block validated against its own stored difficulty β not global
- ECDSA signature verification on every non-coinbase transaction
- Conservation law:
inputsValue = outputsValue + feechecked per TX - UTXO reference validation: every input must reference an existing unspent output
- Coinbase skipped correctly (index 0, null sender)
- Each
Noderuns aServerSocketlistener on its own port (background thread) - Mined blocks serialized via
ObjectOutputStreamand broadcast to all peers - Receiving node validates before appending:
previousHashmatches local chain tip- Hash satisfies stored difficulty
- Recalculated hash matches stored hash
- All transaction signatures valid
synchronized receiveBlock()prevents race condition on concurrent broadcasts- Retry logic (3 attempts) handles peer startup delay
- Shutdown hook calls
network.stopAll()on JVM exit β noConnection refusederrors
Wallet β sendFunds() β Mempool (fee-sorted) β MiningEngine.mineNextBlock()
β Block (Coinbase + TXs) β PoW β broadcast via Node β peer validates
β appended to local chain β ChainValidator.isChainValid()
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LAYER 1 Β· PRESENTATION β
β β
β Dashboard.java β
β Swing GUI Β· live balances Β· mempool count Β· difficulty β
β block height Β· send/mine/validate controls Β· activity log β
βββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β reads BlockchainState Β· calls MiningEngine
β calls ChainValidator Β· holds Node refs
βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ
β LAYER 2 Β· ORCHESTRATION β
β β
β Noob.java β
β main() only Β· genesis bootstrap Β· simulation sequence β
β wires wallets β network β GUI Β· shutdown hook β
ββββββββ¬βββββββββββββββββ¬βββββββββββββββββββ¬βββββββββββββββββββββ β
β β β
βΌ βΌ βΌ
βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββββββββββββ
β LAYER 3 Β· SERVICES (business logic β no shared state) β
βββββββββββββββ€ βββββββββββββββ€ βββββββββββββββββββββββββββββββββ€
βBlockchainS..β βMiningEngine β β ChainValidator β
β β β β β β
β blockchain[]β βmineNextBlockβ β isChainValid() β
β UTXOs map β βcreateCoinbase β tempUTXOs replay β
β mempool[] β βsortByFee β β 4-rule validation: β
β walletA/B β βadjustDiff.. β β hash Β· chain Β· PoW Β· UTXO β
β difficulty β βfee aggregat.β β read-only Β· no side effects β
β constants β β β β β
ββββββββ¬βββββββ ββββββββ¬βββββββ βββββββββββββββββββββββββββββββββ
β β
β ββββββββββ
β β
ββββββββΌββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LAYER 3b Β· NETWORK (P2P β runs on background threads) β
β β
β NetworkManager.java Node.java β
β createNode() Β· connectPeers ServerSocket listener β
β seedAll() Β· startAll() synchronized receiveBlock() β
β stopAll() Β· consensus check broadcast() Β· retry logic β
β Facade over Node instances localBlockchain Β· localUTXOs β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββ
β LAYER 4 Β· CORE DATA (data classes + crypto utility) β
β β
β Block Transaction TransactionInput β
β hash chain UTXO lifecycle UTXO pointer β
β nonce Β· PoW sign Β· verify two-phase resolve β
β merkleRoot conservation law double-spend guard β
β per-block diff Merkle tree β
β β
β TransactionOutput Wallet StringUtil β
β UTXO data class ECDSA keypair SHA-256 Β· ECDSA β
β isMine() Β· ID getBalance() Base64 Β· toCoins() β
β satoshi value sendFunds() crypto utility belt β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
src/
βββ Noob.java β Orchestration: genesis, simulation, network wiring
βββ BlockchainState.java β All global state: chain, UTXOs, mempool, params
βββ MiningEngine.java β PoW mining, coinbase, fee aggregation, difficulty retarget
βββ ChainValidator.java β Full chain validation β reads state, never writes
βββ Node.java β P2P node: ServerSocket listener, broadcast, consensus
βββ NetworkManager.java β Creates nodes, wires peers, seeds genesis, startAll/stopAll
βββ Block.java β Block: hash chain, nonce, merkle root, per-block difficulty
βββ Transaction.java β UTXO TX: inputs, outputs, fee, signing, merkle tree
βββ TransactionInput.java β UTXO input reference pointer
βββ TransactionOutput.java β UTXO output: recipient, value (satoshis), ID
βββ Wallet.java β ECDSA keypair, balance scan, sendFunds(value, fee)
βββ StringUtil.java β SHA-256, ECDSA sign/verify, Base64, toCoins()
- Java JDK 17+
- BouncyCastle
bcprov-jdk15on-1.70
## How to Run
```bash
# 1. Clone
git clone https://github.com/Gaurav77Kumar/Basic-BlockChain
cd Basic-BlockChain
# 2. Install dependencies
mvn install
# 3. Run simulation
mvn exec:java -Dexec.mainClass="Noob"
prints full P2P lifecycle to console
Block Mined!!! : 000429f7a717c22b...
Node 1 β localhost:6002 β
Node 2 accepted. Local height: 2
Node-1: height=2 | Node-2: height=2 | IN SYNC β
WalletB β WalletA: 20 coins
Coinbase: 10.20000000 coins β miner (reward + fees)
Block Mined!!! : 00070995ef15e864...
Node-1: height=3 | Node-2: height=3 | IN SYNC β
Difficulty retarget β Expected: 2003ms | Actual: 1931ms
Difficulty stays the same: 3
Chain height: 4 | Difficulty: 3 | Mempool: 0
Wallet A: 100.00000000 | Wallet B: 30.00000000
Blockchain valid β 4 blocks checked.
Shutting down P2P nodes...
Process finished with exit code 0

