លំហសិក្សាកម្ពុជា
V1.0
មេរៀនទី ៧ នេះផ្ដោតលើការរក្សាទុក Blockchain Data ទៅក្នុង CSV File។ នៅមេរៀនទី ៦ និស្សិតបានបង្កើត Blockchain សាមញ្ញដោយប្រើ Python List ដែលមាន Genesis Block និង Blocks ថ្មីៗ។ ប៉ុន្តែ Blockchain ដែលរក្សាទុកក្នុង Memory នឹងបាត់បង់នៅពេលកម្មវិធីបិទ។ ដូច្នេះ មេរៀននេះណែនាំពីរបៀប Save Blocks ទៅក្នុង blocks.csv, Load Blocks ត្រឡប់មកក្នុង Python, Save Transactions ទៅក្នុង transactions.csv, និង Convert List/Dictionary Data ទៅជា JSON String មុនដាក់ក្នុង CSV។ Python csv module គាំទ្រ reader, writer, DictReader, និង DictWriter សម្រាប់អាន និងសរសេរទិន្នន័យជា row ឬ dictionary form ។ ព្រោះ Block មាន transactions ជា List of Dictionaries យើងត្រូវប្រើ json.dumps() ដើម្បី serialize ទិន្នន័យនេះទៅជា JSON formatted string ហើយ json.loads() ដើម្បី convert ត្រឡប់មក Python object នៅពេល Load ពី CSV; Python documentation ក៏បញ្ជាក់ថា sort_keys=True អាចធ្វើឱ្យ dictionary keys ត្រូវបាន sort ដើម្បីជួយឱ្យ serialization មានលំដាប់ថេរ ។ មេរៀននេះជាជំហានសំខាន់សម្រាប់ Final Project ព្រោះវាធ្វើឱ្យ Blockchain Prototype អាចរក្សាទុក Records បានជាក់ស្តែង មុនបន្តទៅមេរៀនទី៨ ស្តីពី Blockchain Validation និង Tamper Detection។
| ចំណុច | ព័ត៌មាន |
|---|---|
| មុខវិជ្ជា | Blockchain Technology Using Python Console and CSV |
| មេរៀន | មេរៀនទី ៧ |
| ចំណងជើង | CSV-Based Blockchain Storage |
| ប្រធានបទសំខាន់ | Save Blocks, Load Blocks, Save Transactions, CSV Storage |
| កម្រិតនិស្សិត | Beginner to Intermediate |
| ភាសាសរសេរកម្មវិធី | Python |
| ប្រភេទកម្មវិធី | Console Application |
| Python Modules | csv, json, os, hashlib, datetime |
| លទ្ធផលរំពឹងទុក | និស្សិតអាច Save និង Load Blockchain Data ដោយប្រើ CSV |
| ទិសដៅ Project | Console-Based Blockchain Student Certificate Verification System |
បន្ទាប់ពីបញ្ចប់មេរៀននេះ និស្សិតគួរអាច៖
transactions.csv។
blocks.csv។
transactions ដែលជា List of Dictionaries ទៅជា JSON String មុន Save ទៅ CSV។
json.loads() ដើម្បី convert JSON String ត្រឡប់មកជា List។
នៅមេរៀនទី៦ និស្សិតបានបង្កើត Blockchain ដោយប្រើ Python List៖
blockchain = []
ប៉ុន្តែ List នេះស្ថិតនៅក្នុង Memory ប៉ុណ្ណោះ។ ពេលបិទកម្មវិធី ទិន្នន័យនឹងបាត់។ ដើម្បីធ្វើឱ្យ Project មានប្រយោជន៍ជាក់ស្តែង យើងត្រូវ Save Blockchain Data ទៅ File។
Flow សម្រាប់មេរៀនទី៧គឺ៖
Create Genesis Block↓Add Certificate Transactions↓Create New Block↓Save Block to blocks.csv↓Close Program↓Open Program Again↓Load Blockchain from blocks.csv↓View Blockchain Records

រូបភាពនេះគួរបង្ហាញថា Blockchain ដែលរក្សាទុកជា Python List អាចត្រូវបាន Save ទៅក្នុង CSV File។ វាជួយឱ្យនិស្សិតយល់ថា CSV Storage ធ្វើឱ្យ Blockchain Data មិនបាត់បង់បន្ទាប់ពីកម្មវិធីបិទ។
Data Persistence មានន័យថា ទិន្នន័យនៅតែរក្សាទុក បើទោះបីកម្មវិធីបិទ ឬកុំព្យូទ័រត្រូវបាន Restart ក៏ដោយ។ នៅក្នុង Python Program ធម្មតា ទិន្នន័យដែលរក្សាទុកក្នុង Variable ឬ List មានជីវិតត្រឹមតែពេល Program កំពុងដំណើរការ។
ឧទាហរណ៍៖
blockchain = []
បើកម្មវិធីបិទ blockchain នឹងបាត់។ ដូច្នេះយើងត្រូវប្រើ File Storage ដូចជា CSV, JSON, SQLite ឬ Database។ ក្នុង Course នេះ យើងប្រើ CSV ព្រោះងាយស្រួលសម្រាប់ Beginner និងអាចបើកមើលដោយ Excel បាន។
សម្រាប់ Final Project យើងអាចប្រើ CSV Files ចម្បងៗដូចខាងក្រោម៖
| CSV File | Purpose |
|---|---|
certificates.csv | Store original certificate records |
transactions.csv | Store certificate transactions |
blocks.csv | Store blockchain blocks |
verification_logs.csv | Store verification attempts |
audit_logs.csv | Store important system actions |
ក្នុងមេរៀនទី៧នេះ យើងផ្ដោតលើ transactions.csv និង blocks.csv ជាមុន។

រូបភាពនេះគួរបង្ហាញ CSV Files ដែលត្រូវប្រើក្នុង Final Project ដូចជា certificates.csv, transactions.csv, blocks.csv, verification_logs.csv, និង audit_logs.csv។ វាជួយឱ្យនិស្សិតមើលឃើញថា Project មួយត្រូវការការបែងចែក File តាមតួនាទីទិន្នន័យ។
Block មួយមាន Field transactions ដែលជាទម្រង់ List of Dictionaries។ ឧទាហរណ៍៖
transactions = [ { "transaction_id": "TX-0001", "certificate_id": "CERT-FDE-001", "student_name": "Sok Dara", "status": "Valid" } ]
CSV ជាទម្រង់តារាង rows និង columns។ វាមិនអាចរក្សាទុក Python List ឬ Dictionary ជា object ពិតៗបានទេ។ ដូច្នេះយើងត្រូវ Convert List/Dictionary ទៅជា Text មុន Save។ JSON គឺជាទម្រង់សមស្របសម្រាប់ករណីនេះ។
json.dumps(transactions)
ពេល Load ពី CSV វិញ យើងប្រើ៖
json.loads(row["transactions"])
Python JSON documentation បញ្ជាក់ថា json.dump() និង json.dumps() ប្រើសម្រាប់ serialize Python objects ទៅជា JSON formatted data ហើយ json.loads() ប្រើសម្រាប់ deserialize JSON string ត្រឡប់មកជា Python object ។

រូបភាពនេះគួរបង្ហាញថា List of Transactions ត្រូវបាន Convert ទៅជា JSON Text មុន Save ទៅក្នុង CSV។ ពេល Load វិញ JSON Text ត្រូវបាន Convert ត្រឡប់មកជា Python List ដោយប្រើ json.loads()។
transactions.csvtransactions.csv| Field | Description |
|---|---|
transaction_id | Unique transaction ID |
certificate_id | Certificate ID |
student_name | Student name |
program | Study program |
certificate_title | Certificate title |
issue_date | Certificate issue date |
status | Valid, Invalid, or Revoked |
certificate_hash | SHA-256 hash of certificate record |
transactions.csvtransaction_id,certificate_id,student_name,program,certificate_title,issue_date,status,certificate_hash TX-0001,CERT-FDE-001,Sok Dara,Digital Economy,Blockchain Technology Completion,2026-08-25,Valid,a3f1c6d7e8b9f01a
បង្កើត Function សម្រាប់ Save Certificate Transaction ទៅក្នុង transactions.csv។
import csv import os TRANSACTION_FILE = "transactions.csv" transaction_fields = [ "transaction_id", "certificate_id", "student_name", "program", "certificate_title", "issue_date", "status", "certificate_hash" ] def create_transaction_file(): if not os.path.exists(TRANSACTION_FILE): with open(TRANSACTION_FILE, "w", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=transaction_fields) writer.writeheader() def save_transaction(transaction): create_transaction_file() with open(TRANSACTION_FILE, "a", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=transaction_fields) writer.writerow(transaction) print("Transaction saved to CSV successfully.")
create_transaction_file() បង្កើត CSV File ប្រសិនបើមិនទាន់មាន។
csv.DictWriter() សរសេរ Dictionary ទៅ CSV។
writer.writeheader() សរសេរ Header Row។
writer.writerow(transaction) សរសេរ Transaction មួយ Row។
newline="" ជួយកាត់បន្ថយបញ្ហាបន្ទាត់ទទេនៅក្នុង CSV។
Python csv documentation បញ្ជាក់ថា DictWriter អាច map dictionaries ទៅ output rows ដោយប្រើ fieldnames ដែលបានកំណត់ ។
blocks.csvblocks.csv| Field | Description |
|---|---|
index | Block index |
timestamp | Block creation time |
transactions | JSON text of transaction list |
previous_hash | Hash of the previous block |
nonce | Number used for proof-of-work practice |
hash | Current block hash |
blocks.csvindex,timestamp,transactions,previous_hash,nonce,hash 0,2026-08-25 23:00:00,[],0,0,3f8a7c2e6b4d... 1,2026-08-25 23:05:12,"[{""transaction_id"": ""TX-0001"", ""certificate_id"": ""CERT-FDE-001""}]",3f8a7c2e6b4d...,0,7b9c2d1e6f8a...

រូបភាពនេះគួរបង្ហាញ blocks.csv ជាតារាងដែលមាន index, timestamp, transactions, previous_hash, nonce, និង hash។ Field transactions ត្រូវបង្ហាញជា JSON Text ព្រោះវាមាន List of Dictionaries។
បង្កើត Function សម្រាប់ Save Block ទៅក្នុង blocks.csv។
import csv import json import os BLOCK_FILE = "blocks.csv" block_fields = [ "index", "timestamp", "transactions", "previous_hash", "nonce", "hash" ] def create_block_file(): if not os.path.exists(BLOCK_FILE): with open(BLOCK_FILE, "w", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=block_fields) writer.writeheader() def save_block(block): create_block_file() block_row = { "index": block["index"], "timestamp": block["timestamp"], "transactions": json.dumps(block["transactions"], sort_keys=True), "previous_hash": block["previous_hash"], "nonce": block["nonce"], "hash": block["hash"] } with open(BLOCK_FILE, "a", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=block_fields) writer.writerow(block_row) print("Block saved to CSV successfully.")
Function save_block(block) មិនសរសេរ Block Dictionary ដោយផ្ទាល់ទេ។ វាបង្កើត block_row ជាមុន ដើម្បី Convert transactions ទៅ JSON Text។ បន្ទាប់មកវា Save block_row ទៅ CSV។
បង្កើត Function សម្រាប់ Load Blockchain ពី blocks.csv ត្រឡប់មកជា Python List។
import csv import json import os BLOCK_FILE = "blocks.csv" def load_blocks(): blockchain = [] if not os.path.exists(BLOCK_FILE): print("No blocks.csv file found.") return blockchain with open(BLOCK_FILE, "r", encoding="utf-8") as file: reader = csv.DictReader(file) for row in reader: block = { "index": int(row["index"]), "timestamp": row["timestamp"], "transactions": json.loads(row["transactions"]), "previous_hash": row["previous_hash"], "nonce": int(row["nonce"]), "hash": row["hash"] } blockchain.append(block) return blockchain
csv.DictReader(file) អាន row ជា dictionary។
int(row["index"]) Convert index ពី string ទៅ integer។
json.loads(row["transactions"]) Convert JSON Text ត្រឡប់មកជា Python List។
blockchain.append(block) បន្ថែម Block ទៅ Blockchain List។

រូបភាពនេះគួរបង្ហាញថា Python Program អាន blocks.csv, Convert transactions ពី JSON Text ទៅ Python List, ហើយ rebuild Blockchain List។ វាជួយឱ្យនិស្សិតយល់ពីការបិទ និងបើក Program ឡើងវិញដោយមិនបាត់ Blockchain Data។
បង្កើត Blockchain សាមញ្ញ Save ទៅ CSV ហើយ Load ត្រឡប់មកវិញ។
from datetime import datetime import hashlib import json import csv import os BLOCK_FILE = "blocks.csv" block_fields = [ "index", "timestamp", "transactions", "previous_hash", "nonce", "hash" ] def generate_hash(data): data_string = json.dumps(data, sort_keys=True) return hashlib.sha256(data_string.encode("utf-8")).hexdigest() def create_block(index, transactions, previous_hash): block = { "index": index, "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "transactions": transactions, "previous_hash": previous_hash, "nonce": 0 } block["hash"] = generate_hash(block) return block def create_block_file(): if not os.path.exists(BLOCK_FILE): with open(BLOCK_FILE, "w", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=block_fields) writer.writeheader() def save_block(block): create_block_file() block_row = { "index": block["index"], "timestamp": block["timestamp"], "transactions": json.dumps(block["transactions"], sort_keys=True), "previous_hash": block["previous_hash"], "nonce": block["nonce"], "hash": block["hash"] } with open(BLOCK_FILE, "a", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=block_fields) writer.writerow(block_row) def load_blocks(): blockchain = [] if not os.path.exists(BLOCK_FILE): return blockchain with open(BLOCK_FILE, "r", encoding="utf-8") as file: reader = csv.DictReader(file) for row in reader: block = { "index": int(row["index"]), "timestamp": row["timestamp"], "transactions": json.loads(row["transactions"]), "previous_hash": row["previous_hash"], "nonce": int(row["nonce"]), "hash": row["hash"] } blockchain.append(block) return blockchain genesis_block = create_block(0, [], "0") save_block(genesis_block) transactions = [ { "transaction_id": "TX-0001", "certificate_id": "CERT-FDE-001", "student_name": "Sok Dara", "status": "Valid" } ] block_1 = create_block(1, transactions, genesis_block["hash"]) save_block(block_1) loaded_blockchain = load_blocks() print("=== Loaded Blockchain ===") for block in loaded_blockchain: print("-----------------------------") print("Index:", block["index"]) print("Timestamp:", block["timestamp"]) print("Previous Hash:", block["previous_hash"]) print("Hash:", block["hash"]) print("Transactions:", block["transactions"])
នៅពេល Run Program ច្រើនដង វាអាច Save Genesis Block ឬ Block ដូចគ្នាចូល CSV ច្រើនដង។ ដើម្បីការពារ យើងអាចមាន Function ពិនិត្យថា blocks.csv មាន Records រួចឬនៅ។
def block_file_has_data(): if not os.path.exists(BLOCK_FILE): return False with open(BLOCK_FILE, "r", encoding="utf-8") as file: reader = csv.DictReader(file) for row in reader: return True return False
ប្រសិនបើ File មាន Data រួច យើងគួរ Load Blockchain ពី CSV ជាជម្រើសដំបូង មិនមែនបង្កើត Genesis Block ថ្មីរាល់ពេលទេ។
def show_menu(): print("\n=== CSV-Based Blockchain Storage ===") print("1. Load Blockchain from CSV") print("2. Add New Block") print("3. View Blockchain") print("4. Exit")
Menu នេះអាចភ្ជាប់ជាមួយ Functions ខាងក្រោម៖
blockchain = load_blocks() while True: show_menu() choice = input("Choose option: ") if choice == "1": blockchain = load_blocks() print("Blockchain loaded successfully.") elif choice == "2": if len(blockchain) == 0: genesis_block = create_block(0, [], "0") blockchain.append(genesis_block) save_block(genesis_block) transaction = { "transaction_id": input("Transaction ID: "), "certificate_id": input("Certificate ID: "), "student_name": input("Student Name: "), "status": input("Status: ") } previous_hash = blockchain[-1]["hash"] new_block = create_block(len(blockchain), [transaction], previous_hash) blockchain.append(new_block) save_block(new_block) print("New block added and saved.") elif choice == "3": for block in blockchain: print(block) elif choice == "4": print("Goodbye!") break else: print("Invalid choice.")

រូបភាពនេះគួរបង្ហាញ Console Menu ដែលមាន Load Blockchain, Add New Block, View Blockchain និង Exit។ វាជួយឱ្យនិស្សិតយល់ថា CSV Storage អាចភ្ជាប់ជាមួយ Console Application ដើម្បីក្លាយជាប្រព័ន្ធ Prototype មួយ។
| Problem | Cause | Solution |
|---|---|---|
blocks.csv not found | File not created yet | Use create_block_file() |
| Transactions show as text only | JSON not converted back | Use json.loads() |
| Duplicate genesis blocks | Program creates genesis every run | Check if file already has data |
| Hash changes unexpectedly | Inconsistent data format | Use json.dumps(..., sort_keys=True) |
| CSV unreadable | Broken quotes or commas | Use csv.DictWriter, not manual string writing |
| Index becomes text | CSV stores values as string | Convert with int() |

រូបភាពនេះគួរបង្ហាញ Workflow ពេញលេញពី Create Block → Save to CSV → Close Program → Load from CSV → View Blockchain។ វាជារូបភាពសង្ខេបសម្រាប់មេរៀនទី៧ទាំងមូល។
គ្រូអាចប្រើសំណួរខាងក្រោម៖
transactions ត្រូវ Convert ទៅ JSON Text?
json.loads() មានតួនាទីអ្វីនៅពេល Load Blocks?
blocks.csv មាន Fields សំខាន់ៗអ្វីខ្លះ?
សរសេរចម្លើយខ្លី ៥–៧ បន្ទាត់៖
ហេតុអ្វីការរក្សាទុក Blockchain Data ក្នុង CSV File ជាជំហានសំខាន់សម្រាប់ Final Project?
ចម្លើយគួររួមបញ្ចូលគំនិត៖
transactions.csvបង្កើត Function create_transaction_file() ដែលបង្កើត transactions.csv មាន Header Row ត្រឹមត្រូវ។
បង្កើត Function save_transaction(transaction) ដើម្បី Save Transaction Dictionary មួយទៅ CSV។
blocks.csvបង្កើត Function create_block_file() ដែលបង្កើត blocks.csv មាន Fields៖
index,timestamp,transactions,previous_hash,nonce,hash
បង្កើត Function save_block(block) ដែល Save Block Dictionary មួយទៅ blocks.csv។ ត្រូវ Convert transactions ទៅ JSON Text មុន Save។
បង្កើត Function load_blocks() ដែលអាន blocks.csv ហើយ return blockchain ជា List of Blocks។
បង្កើត Console Menu ដែលមាន៖
1. Load Blockchain from CSV 2. Add New Block 3. View Blockchain 4. Exit
បន្ថែម Logic ដើម្បីពិនិត្យថា blocks.csv មាន Data រួចឬនៅ មុនបង្កើត Genesis Block ថ្មី។
បង្កើតកម្មវិធី Python Console មួយឈ្មោះ៖
csv_blockchain_storage.py
កម្មវិធីត្រូវមាន៖
generate_hash(data)
create_block(index, transactions, previous_hash)
create_block_file()
save_block(block)
load_blocks()
show_menu()
view_blockchain(blockchain)
blocks.csv
json.loads()
blocks.csv និង Console Output
បន្ទាប់ពីបញ្ចប់មេរៀនទី៧ និស្សិតគួរមាន៖
csv.DictWriter និង csv.DictReader។
json.dumps() និង json.loads()។
transactions.csv និង blocks.csv។
CSV Storage គឺជាជំហានសំខាន់សម្រាប់ធ្វើឱ្យ Blockchain Prototype មានទម្រង់ជាក់ស្តែង។ នៅមេរៀនទី៦ Blockchain មានត្រឹម Memory ប៉ុណ្ណោះ។ នៅមេរៀនទី៧ Blockchain អាច Save និង Load បាន។ នេះជាការផ្លាស់ប្តូរពី temporary program ទៅជា file-based system prototype។
ឯកសារមានឈ្មោះថា blocks.csv ក្នុង Excel ឬ Text Editor ដើម្បីឱ្យនិស្សិតឃើញថា Blocks ត្រូវបាន Save ពិតប្រាកដ។ គ្រូក៏គួរបញ្ជាក់ថា CSV មិនមែនជា Database ពេញលេញទេ ប៉ុន្តែវាសមស្របសម្រាប់ការរៀន Concept និងការបង្កើត Prototype ដំបូង។
| Figure | កន្លែងបញ្ចូល | គោលបំណង |
|---|---|---|
| Figure 1 | ផ្នែក ៣ | បង្ហាញ Blockchain List ទៅ CSV Storage |
| Figure 2 | ផ្នែក ៥ | បង្ហាញ CSV Files ដែលប្រើក្នុង Project |
| Figure 3 | ផ្នែក ៦ | បង្ហាញ Convert Transactions List ទៅ JSON Text |
| Figure 4 | ផ្នែក ៩ | បង្ហាញ Block Data Stored in blocks.csv |
| Figure 5 | ផ្នែក ១១ | បង្ហាញ Load Blockchain ពី blocks.csv |
| Figure 6 | ផ្នែក ១៤ | បង្ហាញ CSV-Based Blockchain Storage Menu |
| Figure 7 | ផ្នែក ១៥ | បង្ហាញ Save and Load Blockchain Data Workflow |
[1] Python Software Foundation, “csv — CSV File Reading and Writing,” Python 3.14 Documentation, 2026.
[2] Python Software Foundation, “json — JSON encoder and decoder,” Python 3.14 Documentation, 2026.
[3] D. Yaga, P. Mell, N. Roby, and K. Scarfone, “Blockchain Technology Overview,” National Institute of Standards and Technology, NISTIR 8202, 2018, doi: 10.6028/NIST.IR.8202.
[4] Python Software Foundation, “hashlib — Secure hashes and message digests,” Python 3 Documentation, 2026.
មតិយោបល់ 0