在开始构建基于区块链的档案管理系统之前,我们需要准备一个干净且隔离的Python开发环境。本系统将使用Python作为主要开发语言,利用Flask框架搭建Web服务,并使用Python内置库进行加密哈希计算,确保无需安装复杂的区块链节点即可实现核心逻辑。
请确保你的系统中已经安装了Python 3.8或更高版本。你可以通过在终端输入以下命令来检查版本:
python --version
接下来,我们需要安装Flask框架。打开终端或命令行工具,执行以下命令进行全局安装或虚拟环境安装:
pip install flask
为了保持项目的整洁,建议创建一个专门的目录用于存放本项目的代码。执行以下命令创建目录并进入:
mkdir blockchain-archive
cd blockchain-archive
在该目录下,我们将创建三个核心文件:blockchain.py(负责区块链核心逻辑)、app.py(负责Web接口与文件处理)以及一个用于存储链上数据的chain.json文件(系统运行时会自动生成)。
区块链的核心在于区块的结构和链的验证机制。我们需要创建一个Block类来存储档案信息,以及一个Blockchain类来管理链的生成和验证。
请在项目根目录下创建一个名为blockchain.py的文件,并写入以下完整代码。这段代码实现了区块结构、创世区块生成、哈希计算以及整个链的完整性验证逻辑。
```python import hashlib import json from time import time class Block: def __init__(self, index, timestamp, data, previous_hash): self.index = index self.timestamp = timestamp self.data = data 这里存储档案的元数据(文件名、文件Hash等) self.previous_hash = previous_hash self.hash = self.calculate_hash() def calculate_hash(self): 计算区块哈希值,包含索引、时间戳、数据和前一个区块的哈希 block_string = f"{self.index}{self.timestamp}{self.data}{self.previous_hash}" return hashlib.sha256(block_string.encode()).hexdigest() class Blockchain: def __init__(self): self.chain = [] self.load_chain() 尝试加载已有链,如果没有则创建创世区块 if len(self.chain) == 0: self.create_genesis_block() def create_genesis_block(self): 创建创世区块 genesis_block = Block(0, time(), "Genesis Block", "0") self.chain.append(genesis_block) self.save_chain() def get_latest_block(self): return self.chain[-1] def add_block(self, new_data): 添加新区块,包含档案数据 latest_block = self.get_latest_block() new_block = Block(latest_block.index + 1, time(), new_data, latest_block.hash) self.chain.append(new_block) self.save_chain() return new_block def is_chain_valid(self): 验证链的完整性:检查每个区块的哈希是否正确,以及前后区块链接是否正确 for i in range(1, len(self.chain)): current_block = self.chain[i] previous_block = self.chain[i - 1] 重新计算当前区块哈希,比对存储值 if current_block.hash != current_block.calculate_hash(): return False 检查previous_hash字段是否指向前一个区块的hash if current_block.previous_hash != previous_block.hash: return False return True def save_chain(self): 将链保存到JSON文件中,实现持久化 chain_data = [] for block in self.chain: chain_data.append({ "index": block.index, "timestamp": block.timestamp, "data": block.data, "previous_hash": block.previous_hash, "hash": block.hash }) with open('chain.json', 'w') as f: json.dump(chain_data, f, indent=4) def load_chain(self): 从JSON文件加载链 try: with open('chain.json', 'r') as f: chain_data = json.load(f) self.chain = [] for data in chain_data: block = Block(data['index'], data['timestamp'], data['data'], data['previous_hash']) 强制覆盖计算出的hash,确保加载一致 block.hash = data['hash'] self.chain.append(block) except (FileNotFoundError, json.JSONDecodeError): self.chain = [] ```有了核心的区块链逻辑后,我们需要通过Web接口允许用户上传档案,并自动计算上链。我们将使用Flask处理HTTP请求,并计算上传文件的SHA-256哈希值作为档案的唯一指纹存入区块链。
在项目根目录下创建app.py文件,并写入以下代码。此代码包含了文件上传接口、链查询接口和验证接口。
```python from flask import Flask, request, jsonify, render_template_string from blockchain import Blockchain import hashlib import os app = Flask(__name__) blockchain = Blockchain() 简单的HTML前端模板,用于测试上传 HTML_TEMPLATE = """文件名: {file.filename}
文件指纹 (SHA256): {file_hash}
区块索引: {new_block.index}

区块哈希: {new_block.hash}
返回首页 """ @app.route('/chain', methods=['GET']) def get_chain(): 返回完整的区块链数据用于查看 response = { "chain": [], "length": len(blockchain.chain) } for block in blockchain.chain: response["chain"].append({ "index": block.index, "timestamp": block.timestamp, "data": block.data, "previous_hash": block.previous_hash, "hash": block.hash }) return jsonify(response) @app.route('/validate', methods=['GET']) def validate_chain(): is_valid = blockchain.is_chain_valid() if is_valid: return "验证结果:区块链数据完整,未被篡改。返回" else: return "验证结果:警告!检测到数据被篡改!返回" if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True) ```代码编写完成后,我们可以直接启动系统进行测试。确保当前终端位于项目目录下,执行以下命令启动Flask服务:
python app.py
启动成功后,终端会显示服务运行在5000端口。此时,打开浏览器,在地址栏输入:
http://localhost:5000
你将看到一个简洁的上传页面。
点击“选择文件”,上传任意一个本地文件(例如一份PDF合同或一张图片)。点击“上传”按钮后,系统会自动计算文件的哈希值,并将其打包进一个新的区块中。页面会返回上传成功的信息,并显示该文件的SHA256指纹和所在区块的哈希值。这个指纹就是该档案在区块链上的唯一身份证。
回到首页,点击“查看区块链数据”链接。浏览器将以JSON格式展示当前的区块链结构。你可以看到从创世区块(索引0)开始,到你刚才上传的档案区块(索引1)的所有数据。请注意观察每个区块中的previous_hash字段,它完美地指向前一个区块的hash,形成了不可断裂的链条。
为了证明区块链在档案管理中的核心价值,我们需要进行一次“破坏性测试”。我们将手动修改底层数据库文件,模拟黑客攻击或数据意外损坏,然后通过系统的验证功能来检测异常。
停止正在运行的Python服务(在终端按Ctrl+C)。使用任意文本编辑器打开项目目录下的chain.json文件。
找到索引为1的区块(即你刚才上传的档案区块),将"data"字段下的"filename"修改为另一个名字,或者修改"file_hash"中的任意一个字符。保存文件并关闭编辑器。
重新启动服务:
python app.py
再次访问浏览器,点击首页的“验证数据完整性”链接。由于我们修改了区块内容,但未重新计算该区块的哈希值(或者修改了哈希值导致前后链接断裂),系统会立即检测到异常。页面将显示红色的警告信息:“验证结果:警告!检测到数据被篡改!”。
这个实验直观地展示了区块链技术如何保障档案的安全。任何对历史档案数据的微小修改,都会导致哈希值变化,进而破坏链条的连续性,从而被系统自动识别。这对于需要长期保存、不可篡改的电子档案(如合同、学历证明、审计日志)来说,是一项至关重要的底层技术保障。