Blockchain
Tamper-Evident Digital Udhaar (Credit) Ledger for a Kirana Store (Python, MySQL)
The shopkeeper's credit book rebuilt as a hash-chained ledger, where a torn page or an altered amount can no longer be hidden
- Python
- Flask
- MySQL
- +2
From field verification to bank credit, every instalment of a DBT-style farm subsidy leaves a hash-linked, independently checkable trail
Mapped to your syllabusUniversity of Madras CBCS 2023-24 · 320S61 Mini Project (Professional Competency Skill) · Semester 6UzhavanPay is an advanced BCA mini-project (University of Madras CBCS, slot 320S61, semester 6) that models the payment trail of a direct-benefit-transfer (DBT) farm-subsidy scheme — the pattern used by programmes such as PM-KISAN, where an instalment travels through field verification, sanction, a payment file and finally bank credit — and makes every step of that trail tamper-evident and independently verifiable.
The taluk office in the model has four roles: the field officer verifies a beneficiary and records the disbursement event; the taluk officer sanctions a batch; the disbursing officer generates the payment file and later imports the bank's credit acknowledgements; and the beneficiary checks status and can verify a receipt. Each disbursement event is hashed; each sanctioned batch is sealed into a Merkle tree whose root is written to an append-only anchor ledger — and, as an explicitly optional industry-standard extension, published to the Sepolia testnet through Web3j so the root exists outside the office's own database.
Given any receipt, the system can produce a Merkle inclusion proof: a handful of sibling hashes that lets a verifier confirm the payment belongs to the anchored batch without seeing anyone else's data.
The build uses the profile's own stack — Java (220C4A), MySQL (320C5B) and JSP/Servlets (320C5C) — with the Merkle tree and hash functions written in plain Java, plus JUnit tests for every proof. The design never stores Aadhaar or other government ID numbers: beneficiaries are internal codes with a masked bank reference.
Syllabus alignment
Farm-subsidy instalments disbursed through a taluk office travel through several hands — field verification, sanction, payment-file generation, bank credit — and every hand touches the same database. Because the database is the only record, a person with write access can alter an amount, substitute a bank reference, mark a paid instalment as failed, or insert a fake beneficiary after the fact, and no conventional application will ever notice. When beneficiaries or auditors question a payment, the office can only point at the same mutable table, so disputes end as arguments. A full blockchain network is the textbook answer but is impractical for a single office that needs no cryptocurrency.
What is needed is a disbursement trail that is append-only and self-proving: recording must be as easy as today, but any alteration must become detectable, each payment must be provable to belong to a sanctioned batch, and the proof must not depend on trusting the office's own database alone.
UzhavanPay is a semester-6 mini project that implements a tamper-evident disbursement trail for a taluk-level farm-subsidy scheme on the DBT pattern. Disbursement events (verify, sanction, payment file, bank credit) are hash-linked; sanctioned batches are sealed into Merkle trees whose roots are anchored in an append-only anchor store and optionally on a public testnet. A Merkle-proof service lets a beneficiary verify a receipt against the anchored root. The build uses Java Servlets/JSP, MySQL and JUnit.
India moves farm subsidies through DBT: the sanctioning office releases instalments, a bank credits them, and portals such as the PM-KISAN beneficiary-status page let farmers see where an instalment stands. The integrity of that trail depends on the office's own database. If a row is altered — an amount changed, a credit marked 'failed' after money actually moved, a beneficiary swapped — ordinary software notices nothing, and an audit must trust whatever the database currently says.
MessageDigest provides SHA-256; the Merkle builder is ~80 lines of plain Java; Web3j is one extra dependency used behind a feature flag. Tomcat, MySQL and JUnit run on any student laptop; the testnet option needs only an internet connection at anchoring time.In scope
Out of scope (v1)
The project uses an incremental model with weekly increments — the right fit for a 6-week mini project where each week must end in something demonstrable for the internal review.
| Week | Increment | Activities | Review deliverable |
|---|---|---|---|
| 1 | Requirements & registry | Study the DBT disbursement flow (PM-KISAN, PFMS documentation), finalise scope, ER diagram, schema, beneficiary/land registry module | Requirement list + ER |
| 2 | Event trail | Append-only event recording with SHA-256 linking; state machine; role-based login; JUnit tests for linking | Working trail demo |
| 3 | Batches & Merkle | Batch sanction service, binary Merkle builder (odd-leaf promotion), anchor table, duplicate-cycle checks | Sealed batch demo |
| 4 | Proofs & portal | Inclusion-proof generator and verifier, receipt QR, beneficiary status screens, payment-file export | Proof verification demo |
| 5 | Anchoring & audit | Web3j testnet anchoring (flagged, with simulation fallback), full-trail audit report, tamper test suite | Anchor + audit demo |
| 6 | Testing & report | Integration tests, black-box test-case tables, report writing, PPT, dry-run viva | Final submission |
Testing approach: JUnit unit tests for hash vectors, tree building (including 3-leaf and 5-leaf odd cases) and proof generation/verification; tamper tests that mutate stored rows and assert detection; black-box test cases per screen; and a scripted end-to-end demo from field verification to a verified receipt.
UzhavanPay follows a classic three-tier Java web architecture with the cryptographic services isolated in a plain-Java core library so they can be tested without a servlet container.
crypto package holds HashUtil (SHA-256, canonical bytes), MerkleTree (build, root, proof) and AnchorPublisher (Web3j or simulation) — all pure Java, no container dependencies.PreparedStatement everywhere; event, batch and anchor tables are append-only from the application.flowchart LR
B[Browser: officers / beneficiary] -->|HTTP| T[ Tomcat: Servlets + JSP ]
T --> W[Workflow state machine]
W --> DAO[JDBC DAOs - PreparedStatement]
DAO --> DB[(MySQL)]
W --> H[HashUtil - SHA-256 linking]
W --> M[MerkleTree builder]
M --> A[AnchorPublisher]
A -->|flag on| S[Sepolia via Web3j]
A -->|flag off| SIM[(Simulation anchor store)]
T --> P[Proof service: inclusion proofs]
P --> Mflowchart TD
R["Root: hash(h01 + h23)"] --> H01["h01 = hash(h0 + h1)"]
R --> H23["h23 = hash(h2 + h3)"]
H01 --> L0["h0: event 1 (verified payment)"]
H01 --> L1["h1: event 2 (verified payment)"]
H23 --> L2["h2: event 3 (verified payment)"]
H23 --> L3["h3: event 4 (verified payment)"]erDiagram
USER ||--o{ DISBURSEMENT_EVENT : acts
BENEFICIARY ||--o{ DISBURSEMENT_EVENT : "receives"
CYCLE ||--o{ DISBURSEMENT_EVENT : "covers"
BATCH ||--o{ DISBURSEMENT_EVENT : "seals as leaves"
BATCH ||--o| ANCHOR_RECORD : "is anchored by"
USER {
string id PK
string username UK
string passwordHash
string role
}
BENEFICIARY {
string code PK
string name
string village
string landAlias
string bankRefMasked
string status
}
CYCLE {
string id PK
string label
decimal amount
}
DISBURSEMENT_EVENT {
string id PK
string beneficiaryCode FK
string cycleId FK
string stage
decimal amount
string officerId FK
datetime at
string eventHash
string prevEventHash
string batchId FK
}
BATCH {
string id PK
string cycleId FK
string merkleRoot
int leafCount
datetime sanctionedAt
}
ANCHOR_RECORD {
string id PK
string batchId FK
string merkleRoot
string anchorType
string txRef
datetime anchoredAt
}flowchart LR
FO([Field Officer]) --"verification events"--> SYS((UzhavanPay<br/>Disbursement Trail))
TO([Taluk Officer]) --"sanction"--> SYS
DO([Disbursing Officer]) --"payment file, bank acks"--> SYS
BEN([Beneficiary]) --"status query, receipt proof"--> SYS
SYS --"sanctioned batches, audit reports"--> TO
SYS --"anchored roots"--> AN([Anchor: store / testnet])flowchart TD
FO([Field Officer]) --> P2["2.0 Record verification event"]
P2 <--> D3[(D3 Beneficiaries)]
P2 <--> D4[(D4 Disbursement Events)]
TO([Taluk Officer]) --> P3["3.0 Sanction batch + build Merkle tree"]
D4 --> P3
P3 --> D5[(D5 Batches)]
P3 --> P4["4.0 Publish anchor"]
P4 --> D6[(D6 Anchor Records)]
DO([Disbursing Officer]) --> P5["5.0 Payment file + bank acknowledgements"]
P5 <--> D4
BEN([Beneficiary]) --> P6["6.0 Status + receipt proof"]
D5 --> P6
D6 --> P6
D4 --> P6
U([Any officer]) --> P1["1.0 Authenticate + role check"]
P1 <--> D2[(D2 Users)]flowchart LR
FO([Field Officer])
TO([Taluk Officer])
DO([Disbursing Officer])
BEN([Beneficiary])
subgraph UP[UzhavanPay]
UC1(Login)
UC2(Verify beneficiary + record event)
UC3(Sanction batch and seal Merkle root)
UC4(Generate payment file)
UC5(Import bank credit acknowledgements)
UC6(View status and verify receipt proof)
UC7(Run full-trail audit)
UC8(Anchor root to testnet)
end
FO --- UC1 & UC2
TO --- UC1 & UC3 & UC7 & UC8
DO --- UC1 & UC4 & UC5
BEN --- UC6Module 01
CRUD for beneficiaries keyed by an internal code, with village, a land-parcel alias, masked bank reference and status; cycle definitions with per-instalment amounts; duplicate and eligibility checks (one instalment per beneficiary per cycle) enforced at insert time. No Aadhaar, account number or other government ID is ever stored, only the masked reference.
Module 02
Every workflow action writes an append-only event — VERIFIED, SANCTIONED, PAYMENT_FILED, CREDITED or FAILED — stamped with the acting officer, hashed with SHA-256 over a canonical byte format and linked to the previous event's hash. Illegal transitions (for example crediting an un-sanctioned event) are rejected by the state machine, and JDBC transactions keep the chain linear under concurrent officers.
Module 03
The taluk officer sanctions a batch of verified events; the builder hashes each event as a leaf, promotes the last hash when a level has an odd number of leaves, and stores the root with the batch. The anchor table is INSERT-only from the application — even the code that seals a batch cannot update a previously anchored root, which is the property the audit relies on.
Module 04
AnchorPublisher has two modes behind one flag: simulation mode writes the root to the local anchor store, and testnet mode posts it to Sepolia through Web3j and stores the transaction hash. The proof service answers a receipt query with the leaf hash and sibling hashes up the tree; the JSP verification page recomputes the root locally and shows PASS or FAIL against the anchored root.
Module 05
Generates a CSV payment file (masked references only) that stands in for the bank's interface, imports the returned acknowledgement CSV to mark events CREDITED or FAILED, and produces audit reports: batch summaries, events altered-after-the-fact (always zero unless a tamper test ran), and a full-trail recompute that pins the first broken hash.
Module 06
Login with salted PBKDF2 password hashing, session timeout, and role checks in a servlet filter (field/taluk/disbursing/auditor). All SQL uses PreparedStatement, the JSPs escape output to prevent XSS, receipt verification is rate-limited, and the whole security design is documented as a dedicated report section for the viva.
Slide 1
Tamper-Evident Farm-Subsidy Disbursement Trail
Slide 2
Context: How a Farm Subsidy Travels
Slide 3
Problem Statement
Slide 4
Proposed System
Slide 5
Objectives
Slide 6
Technology Stack
Slide 7
Merkle Trees: Batch Sealing and Proofs
Slide 8
System Architecture and Database
Slide 9
Screenshots / Live Demo
Slide 10
Testing
Slide 11
Security and Limitations
Slide 12
Conclusion and Future Scope
Bullets, speaker notes and the .pptx · ₹2,000
Read each answer, close it, and say it in your own words. Your viva will ask. Now you'll know.
A Merkle tree is a binary tree of hashes where leaves are event hashes and each parent is the hash of its children, ending in one root. A chain proves the whole history but any verification means recomputing everything, while a tree lets me prove one payment's inclusion with only log2(n) sibling hashes and without revealing the rest of the batch — which is exactly what a beneficiary receipt needs.
A blockchain is a distributed consensus system for mutually distrusting parties; a taluk office is a single authority whose real problem is insider tampering and external verifiability. Hash-linked events plus an anchored Merkle root deliver tamper-evidence and third-party verification, and the Web3j extension gives the root a home outside the office's database — the properties that matter — without running nodes or needing cryptocurrency, which no taluk office would operate.
Web3j is a Java library for talking to Ethereum clients. In testnet mode my AnchorPublisher builds a transaction whose data field carries the batch's Merkle root, signs it with a test-only wallet and submits it to Sepolia, storing the returned transaction hash in the anchor record. It is an extra because the University of Madras syllabus does not cover Ethereum — the core project runs entirely on the profile's Java/MySQL stack, and the flag can be off with simulation mode instead.
+12 more questions, with answers
Unlocks with the project · ₹2,000
Unlock for ₹2,000What to change before it goes anywhere near a submission. Skipping it is how the demo fails live.
Unlocks with the project · ₹2,000
Unlock for ₹2,000How to study it, adapt it and walk your examiner through it, step by step.
Unlocks with the project · ₹2,000
Unlock for ₹2,000OnlyProjects. (2026). Tamper-Evident Farm-Subsidy Disbursement Trail with Merkle-Batch Anchoring (Java, MySQL): BCA Blockchain project bundle [Educational resource]. https://onlyprojects.online/projects/bca-blockchain-farm-subsidy-disbursement-trail
Keep browsing
Same degree, same syllabus slot, different idea. Pick the one your guide will actually approve.
Blockchain
The shopkeeper's credit book rebuilt as a hash-chained ledger, where a torn page or an altered amount can no longer be hidden
Blockchain
Replacing the foreman's register in a monthly chit with a shared, tamper-evident ledger for contributions, auctions and payouts
Web Development
Room allocation, complaints and mess billing without the register
AI & Machine Learning
Predict tomorrow's air quality band for every Bengaluru monitoring station, before the morning commute
AI & Machine Learning
Forecast daily OPD crowds department by department, and plan the doctor roster before the Monday rush arrives
AI & Machine Learning
Turn a Soil Health Card into an explained, district-specific crop recommendation a small farmer can act on