简介:这是一套基于Python开发的农产品溯源仿真系统源码,面向高校计算机、农业信息化相关专业学生及初中级Python开发者,聚焦区块链前序环节——利用加密技术实现农产品全链条数据可信存证与可追溯验证。系统采用Flask构建轻量级后端服务,集成AES/RSA等加密解密模块,并支持MySQL持久化存储,涵盖数据采集模拟(uploadData.py)、商品管理(commodity.py)、配置中心(settings.py)等核心功能,适合作为课程设计、毕业设计或小型溯源原型开发参考。资源共18999个文件,主体为5703个Python源码(.py)与5476个编译字节码(.pyc),辅以1228个国际化翻译文件(.po/.mo)、1064个前端交互脚本(.js)及157个HTML模板,压缩包大小78.83MB。已有352人学习下载,提供完整目录结构、局域网部署说明及温湿度模拟上传接口,含典型错误配置提示与IP/数据库参数修改指引,便于快速上手调试与二次开发。
1. 为什么用 Python 加密技术做农产品溯源仿真,不是“炫技”而是刚需
你手里的那盒鸡蛋,扫码显示“某县生态农场直供”,但后台数据库没加密、溯源链路可被人工覆盖、批次号生成靠时间戳硬编码——这种系统在真实监管抽查中一查就穿帮。Python 基于加密技术的农产品溯源仿真系统,核心不是造一个能点开看的网页,而是构建一条不可抵赖、不可篡改、可验证时序的数据链路。它用 SHA-256 做批次指纹固化、用 RSA 非对称加密保护关键操作权限、用 HMAC-SHA256 验证流转环节数据完整性,最后在本地模拟从种植、采收、分拣、仓储到物流的全节点行为。适合农业信息化团队做方案预演,也适合高校课程设计验证密码学在实体供应链中的落地约束——比如:当分拣员手机端提交一次“包装完成”,系统必须拒绝重复提交、拒绝伪造时间戳、拒绝非授权账号签名。这不是写个 CRUD 就能交差的项目,它逼你把hashlib、cryptography、datetime和状态机逻辑拧在一起,才能跑出一条像样的溯源路径。
2. 用 cryptography 库实现三重加密防护:签名、验签与防篡改
农产品溯源最怕什么?不是数据丢了,而是数据被悄悄改了——比如把“农药残留检测:合格”改成“未检测”,或者把“冷链温度:2℃~8℃”改成“常温运输”。单纯用数据库主键或时间戳做校验毫无意义。我们必须让每条记录自带“数字指纹”,且这个指纹只能由可信角色生成、所有节点都能独立验证。cryptography 库是当前 Python 生态中最稳妥的选择,它不依赖 OpenSSL 动态链接(避免 Windows 下 DLL 冲突),API 明确区分对称/非对称/哈希场景,且已通过 FIPS 140-2 合规性审计。
2.1 生成并持久化 RSA 密钥对:为农场、加工厂、物流中心分配身份
溯源系统里不同角色拥有不同操作权限:农场只能提交种植和采收数据,加工厂可添加质检和包装信息,物流中心仅能更新运输温湿度和签收状态。我们用 RSA 非对称加密为每个角色生成唯一密钥对,私钥本地保存(绝不上传),公钥注入系统全局配置。这样,当农场提交一条“采收记录”时,必须用其私钥签名;其他节点收到后,用农场公钥验签——验不过,直接丢弃。
from cryptography.hazmat.primitives.asymmetric import rsa, padding from cryptography.hazmat.primitives import hashes, serialization # 为“XX县生态农场”生成 2048 位 RSA 密钥对 private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, ) public_key = private_key.public_key() # 保存私钥(需严格权限控制:chmod 600) with open("farm_private_key.pem", "wb") as f: f.write(private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() # 生产环境应使用 PasswordBasedKeyDerivation )) # 保存公钥(可公开分发) with open("farm_public_key.pem", "wb") as f: f.write(public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ))提示:
encryption_algorithm=serialization.NoEncryption()仅用于本地仿真调试。真实部署必须改用PBKDF2HMAC并设置强密码,否则私钥文件等于裸奔。密钥文件路径建议统一放在config/keys/目录下,代码中通过环境变量KEY_DIR指定根路径,避免硬编码。
2.2 用 HMAC-SHA256 构建环节级数据指纹:确保单条记录不被局部篡改
RSA 签名解决的是“谁提交的”,但无法防止同一角色反复修改同一条记录。例如,农场今天填了“采收时间:2024-05-20 08:30”,明天又偷偷改成“2024-05-19 15:00”。我们需要给每条记录附加一个基于内容+时间+前序哈希的 HMAC 值,形成链式防篡改结构。
import hmac import hashlib import json from datetime import datetime def generate_record_hmac(record_data: dict, secret_key: bytes, prev_hash: str = "") -> str: """ 为单条溯源记录生成 HMAC-SHA256 指纹 record_data: 包含 crop_id, stage, operator, timestamp, details 的字典 secret_key: 当前环节共享密钥(如农场环节密钥为 b"farm_stage_key_2024") prev_hash: 上一环节的 record_hmac 值,首次为空字符串 """ # 强制标准化时间格式,避免时区/微秒导致哈希不一致 if "timestamp" in record_data: record_data["timestamp"] = datetime.fromisoformat( record_data["timestamp"] ).strftime("%Y-%m-%d %H:%M:%S") # 拼接结构化数据(非简单 json.dumps,要保证字段顺序稳定) data_str = "|".join([ str(record_data.get("crop_id", "")), str(record_data.get("stage", "")), str(record_data.get("operator", "")), str(record_data.get("timestamp", "")), json.dumps(record_data.get("details", {}), sort_keys=True), prev_hash ]) return hmac.new( secret_key, data_str.encode("utf-8"), hashlib.sha256 ).hexdigest() # 示例:生成第一条种植记录的 HMAC plant_record = { "crop_id": "EGG-2024-001", "stage": "planting", "operator": "farmer_zhang", "timestamp": "2024-05-10T09:15:22", "details": {"soil_ph": 6.8, "seed_variety": "Lohmann Brown"} } hmac_value = generate_record_hmac(plant_record, b"farm_stage_key_2024") print(hmac_value) # 输出 64 位十六进制字符串,如 'a1b2c3...f8e9'参数说明:
prev_hash是上一环节的 HMAC 值,首次调用传空字符串。sort_keys=True确保 JSON 字段顺序固定,否则相同内容因字典键序不同产生不同哈希。secret_key必须按环节隔离(农场用 farm_key,加工用 process_key),不能全系统共用一个密钥,否则任一环节密钥泄露即全链崩塌。
2.3 用 SHA-256 批次指纹固化:让“一箱鸡蛋”拥有不可复制的数字身份证
最终消费者扫码看到的,不是一个长列表,而是一个简短批次码(如EGG-2024-001-7F2A)。这个后缀7F2A就是整条溯源链的 SHA-256 哈希截断值。它由所有环节 HMAC 值按顺序拼接后计算得出,任何一环数据变动,都会导致最终批次指纹巨变。
def calculate_batch_fingerprint(hmac_list: list) -> str: """ 根据所有环节 HMAC 列表生成最终批次指纹(取前 4 字节十六进制) hmac_list: ["hmac1", "hmac2", "hmac3", ...] """ full_chain = "|".join(hmac_list).encode("utf-8") full_hash = hashlib.sha256(full_chain).hexdigest() return full_hash[:4].upper() # 截取前 4 字符,大写,如 '7F2A' # 假设我们有 3 个环节的 HMAC hmacs = [ "a1b2c3d4e5f6...1234", # 种植 "b2c3d4e5f6a1...2345", # 采收 "c3d4e5f6a1b2...3456" # 包装 ] batch_suffix = calculate_batch_fingerprint(hmacs) print(f"批次码:EGG-2024-001-{batch_suffix}") # EGG-2024-001-7F2A注意:
calculate_batch_fingerprint必须在所有环节数据确认无误后,由可信中心节点(如监管平台)统一调用。不能由任一环节自行计算并声称“这是最终码”,否则失去防抵赖意义。仿真系统中,该函数通常放在batch_manager.py中,由simulate_full_trace()主流程最后触发。
3. 构建可验证的溯源链路:从种植到物流的六节点状态机仿真
光有加密不够,还得让数据按真实业务流走。我们定义六个标准节点:planting(种植)、harvesting(采收)、processing(初加工)、quality_check(质检)、packing(包装)、logistics(物流)。每个节点有明确输入约束、操作者权限、时间窗口和输出格式。仿真系统不是随机生成数据,而是按状态机规则驱动——只有前序节点完成,后续节点才可激活;每个节点提交的数据必须包含前序 HMAC,否则拒绝入库。
3.1 定义状态机 Schema 与校验规则
我们用 Pythondataclass描述每个节点的强制字段,并内置校验逻辑。重点在于validate_transition()方法:它检查新记录是否满足“只能由合法角色在合理时间提交”、“是否携带正确前序 HMAC”。
from dataclasses import dataclass from datetime import datetime, timedelta import re @dataclass class TraceNode: crop_id: str stage: str # 必须是预定义枚举值 operator: str timestamp: str # ISO 格式字符串 prev_hmac: str # 前一环节 HMAC,首环节为空字符串 details: dict current_hmac: str # 本环节计算出的 HMAC def __post_init__(self): # 强制时间格式校验 try: dt = datetime.fromisoformat(self.timestamp.replace("Z", "+00:00")) # 限制时间不能早于 2020 年,不能晚于当前时间 + 1 小时(防设备时钟错误) if dt.year < 2020 or dt > datetime.now() + timedelta(hours=1): raise ValueError("timestamp out of valid range") except ValueError as e: raise ValueError(f"Invalid timestamp format or value: {self.timestamp}") from e # 角色命名规范:必须含 _role 后缀,如 farmer_zhang、inspector_li if not re.match(r"^[a-z]+_[a-z]+$", self.operator): raise ValueError(f"operator name '{self.operator}' must be lowercase with underscore") def validate_transition(self, previous_node: 'TraceNode' = None) -> bool: """校验本节点是否可从前一节点合法过渡""" # 首环节:prev_hmac 必须为空 if self.stage == "planting": if self.prev_hmac != "": raise ValueError("planting stage must have empty prev_hmac") return True # 非首环节:必须提供前序节点,且 prev_hmac 匹配其 current_hmac if previous_node is None: raise ValueError(f"stage '{self.stage}' requires previous node") if self.prev_hmac != previous_node.current_hmac: raise ValueError( f"prev_hmac mismatch: expected {previous_node.current_hmac}, got {self.prev_hmac}" ) # 时间约束:后一环节时间必须晚于前一环节(允许最多 1 分钟误差,防设备不同步) prev_dt = datetime.fromisoformat(previous_node.timestamp.replace("Z", "+00:00")) curr_dt = datetime.fromisoformat(self.timestamp.replace("Z", "+00:00")) if curr_dt < prev_dt - timedelta(minutes=1): raise ValueError(f"timestamp violation: {self.timestamp} < {previous_node.timestamp}") return True # 使用示例 try: planting = TraceNode( crop_id="EGG-2024-001", stage="planting", operator="farmer_zhang", timestamp="2024-05-10T09:15:22", prev_hmac="", details={"soil_ph": 6.8}, current_hmac="a1b2c3..." # 此处应为实际计算值 ) harvesting = TraceNode( crop_id="EGG-2024-001", stage="harvesting", operator="farmer_wang", timestamp="2024-05-20T07:30:15", prev_hmac=planting.current_hmac, # 关键:必须匹配 details={"weight_kg": 125.5}, current_hmac="b2c3d4..." ) harvesting.validate_transition(planting) # 返回 True,表示过渡合法 except ValueError as e: print(f"Transition failed: {e}")逻辑说明:
validate_transition()不是装饰器或钩子,而是显式调用的校验方法。在仿真主流程中,每生成一个新节点,都必须传入上一节点实例进行校验。失败则抛出ValueError,由上层捕获并记录为“非法操作事件”,这比静默忽略更能暴露流程漏洞。
3.2 用 Faker 生成符合农业场景的仿真数据
真实农产品数据有强领域特征:作物 ID 带品类前缀(EGG-,RICE-,APPLE-),操作员姓名需符合地域习惯(华东多“张”“李”,西南多“王”“陈”),质检结果含国标代号(GB/T 20014.12-2013),温湿度单位固定。用Faker库配合自定义 provider,可生成高保真测试数据。
from faker import Faker from faker.providers import BaseProvider class AgriculturalProvider(BaseProvider): def crop_id(self, prefix: str = "EGG") -> str: year = self.random_int(min=2020, max=2025) seq = str(self.random_int(min=1, max=9999)).zfill(4) return f"{prefix}-{year}-{seq}" def operator_name(self, region: str = "east") -> str: last_names = { "east": ["张", "李", "王", "刘", "陈"], "southwest": ["王", "陈", "李", "杨", "黄"] } first_names = ["伟", "芳", "娜", "敏", "静", "丽", "良", "军", "林", "杰"] return f"{self.random_element(last_names[region])}_{self.random_element(first_names)}" def quality_standard(self) -> str: standards = ["GB/T 20014.12-2013", "NY/T 761-2008", "GB 2763-2021"] return self.random_element(standards) fake = Faker("zh_CN") fake.add_provider(AgriculturalProvider) # 生成一条高仿真质检记录 qc_record = { "crop_id": fake.crop_id("APPLE"), "stage": "quality_check", "operator": fake.operator_name("southwest"), "timestamp": fake.date_time_between(start_date="-30d", end_date="now").isoformat(), "prev_hmac": "previous_hmac_here", "details": { "standard": fake.quality_standard(), "pesticide_residue": round(fake.pyfloat(min_value=0.0, max_value=0.5), 3), "microbial_count": fake.pyint(min_value=100, max_value=5000) } } print(qc_record) # {'crop_id': 'APPLE-2024-1234', 'stage': 'quality_check', 'operator': '王_芳', ...}参数说明:
fake.add_provider(AgriculturalProvider)注册自定义规则;fake.crop_id("APPLE")生成苹果品类 ID;fake.operator_name("southwest")生成西南地区风格姓名。所有生成数据均通过TraceNode构造函数校验,确保格式合规。
3.3 运行完整仿真流程:simulate_full_trace()函数详解
把加密、状态机、数据生成串起来,就是simulate_full_trace()。它接受作物品类、起始时间、环节数等参数,自动调用各环节生成器,逐节点校验并计算 HMAC,最后输出完整溯源链和批次码。
def simulate_full_trace( crop_type: str = "EGG", start_time: str = None, num_stages: int = 6, key_dir: str = "config/keys" ) -> dict: """ 执行一次完整的农产品溯源链路仿真 返回包含所有节点、HMAC 链、批次码的字典 """ if start_time is None: start_time = datetime.now().isoformat() # 加载各环节密钥(生产环境应从安全存储读取) stage_keys = { "planting": open(f"{key_dir}/farm_stage_key.bin", "rb").read(), "harvesting": open(f"{key_dir}/farm_stage_key.bin", "rb").read(), # 农场环节共用 "processing": open(f"{key_dir}/process_stage_key.bin", "rb").read(), "quality_check": open(f"{key_dir}/inspect_stage_key.bin", "rb").read(), "packing": open(f"{key_dir}/pack_stage_key.bin", "rb").read(), "logistics": open(f"{key_dir}/logis_stage_key.bin", "rb").read() } stages = ["planting", "harvesting", "processing", "quality_check", "packing", "logistics"][:num_stages] nodes = [] hmac_list = [] for i, stage in enumerate(stages): # 生成本环节基础数据 if stage == "planting": base_data = { "crop_id": fake.crop_id(crop_type), "stage": stage, "operator": fake.operator_name("east"), "timestamp": start_time, "prev_hmac": "", "details": {"soil_ph": round(fake.pyfloat(min_value=5.5, max_value=7.5), 1)} } elif stage == "harvesting": base_data = { "crop_id": nodes[-1].crop_id, "stage": stage, "operator": fake.operator_name("east"), "timestamp": (datetime.fromisoformat(start_time) + timedelta(days=10)).isoformat(), "prev_hmac": nodes[-1].current_hmac, "details": {"weight_kg": fake.pyfloat(min_value=100.0, max_value=200.0)} } else: # 其他环节逻辑类似,略去以保持篇幅 pass # 计算当前 HMAC current_hmac = generate_record_hmac( base_data, stage_keys[stage], base_data["prev_hmac"] ) # 构建节点实例 node = TraceNode( crop_id=base_data["crop_id"], stage=base_data["stage"], operator=base_data["operator"], timestamp=base_data["timestamp"], prev_hmac=base_data["prev_hmac"], details=base_data["details"], current_hmac=current_hmac ) # 校验状态转移 if i > 0: node.validate_transition(nodes[-1]) nodes.append(node) hmac_list.append(current_hmac) # 生成最终批次码 batch_suffix = calculate_batch_fingerprint(hmac_list) batch_code = f"{nodes[0].crop_id}-{batch_suffix}" return { "batch_code": batch_code, "trace_nodes": [n.__dict__ for n in nodes], # 转为字典便于序列化 "hmac_chain": hmac_list, "full_hash": hashlib.sha256("|".join(hmac_list).encode()).hexdigest() } # 执行仿真 result = simulate_full_trace(crop_type="RICE", num_stages=4) print(f"批次码:{result['batch_code']}") print(f"共 {len(result['trace_nodes'])} 个环节")关键点:
simulate_full_trace()是整个仿真的心脏。它不返回 HTML 或图表,而是返回纯 Python 字典,包含所有可验证字段。这意味着你可以把它嵌入 Flask API、存入 SQLite、或导出为 JSON 供前端渲染——但加密和校验逻辑完全在 Python 层闭环,不依赖任何外部服务。
4. 验证与反演:用独立脚本校验任意溯源链的有效性
仿真系统产出的数据,必须能被第三方独立验证。我们提供verify_trace.py脚本,它不依赖原始密钥文件,只用公开的公钥和规则,就能判断一条溯源链是否被篡改、是否符合时序、是否所有 HMAC 连续有效。这才是“可验证”的真正含义。
4.1 编写verify_trace.py:三步校验法
该脚本接收一个 JSON 文件路径(含trace_nodes数组),执行以下三步:
- 结构校验:检查每个节点是否符合
TraceNode字段要求(用dataclass的__post_init__逻辑复现); - 链路校验:遍历节点,用
validate_transition()逐对校验时序与 HMAC 连续性; - 批次校验:提取所有
current_hmac,用calculate_batch_fingerprint()重新计算批次码,与batch_code字段比对。
# verify_trace.py 使用方式 python verify_trace.py --input trace_output.json# verify_trace.py 核心逻辑(简化版) import sys import json import argparse from datetime import datetime from typing import List, Dict def load_trace_json(file_path: str) -> Dict: with open(file_path, "r", encoding="utf-8") as f: return json.load(f) def validate_structure(node_dict: Dict) -> bool: """复现 TraceNode.__post_init__ 的校验逻辑""" try: dt = datetime.fromisoformat(node_dict["timestamp"].replace("Z", "+00:00")) if dt.year < 2020 or dt > datetime.now() + timedelta(hours=1): return False if not isinstance(node_dict["details"], dict): return False return True except: return False def validate_chain(nodes: List[Dict]) -> bool: """复现 validate_transition 的链路校验""" for i in range(1, len(nodes)): curr = nodes[i] prev = nodes[i-1] # 检查 prev_hmac 是否匹配上一节点 current_hmac if curr["prev_hmac"] != prev["current_hmac"]: print(f"❌ HMAC break at index {i}: expected {prev['current_hmac']}, got {curr['prev_hmac']}") return False # 检查时间是否倒流 curr_dt = datetime.fromisoformat(curr["timestamp"].replace("Z", "+00:00")) prev_dt = datetime.fromisoformat(prev["timestamp"].replace("Z", "+00:00")) if curr_dt < prev_dt - timedelta(minutes=1): print(f"❌ Time reversal at index {i}: {curr['timestamp']} < {prev['timestamp']}") return False return True def verify_batch_code(nodes: List[Dict], batch_code: str) -> bool: """校验批次码是否由当前 HMAC 链生成""" hmacs = [n["current_hmac"] for n in nodes] expected_suffix = calculate_batch_fingerprint(hmacs) expected_code = f"{nodes[0]['crop_id']}-{expected_suffix}" if batch_code != expected_code: print(f"❌ Batch code mismatch: expected {expected_code}, got {batch_code}") return False return True if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--input", required=True, help="Path to trace JSON file") args = parser.parse_args() data = load_trace_json(args.input) nodes = data["trace_nodes"] batch_code = data["batch_code"] print("🔍 Starting verification...") if not all(validate_structure(n) for n in nodes): print("❌ Structure validation failed") sys.exit(1) if not validate_chain(nodes): print("❌ Chain validation failed") sys.exit(1) if not verify_batch_code(nodes, batch_code): print("❌ Batch code validation failed") sys.exit(1) print("✅ All verifications passed. This trace is cryptographically sound.")提示:
verify_trace.py必须与主仿真代码使用完全相同的calculate_batch_fingerprint和generate_record_hmac实现。任何细微差异(如sort_keys参数、时间格式化方式)都会导致校验失败。建议将这些函数抽离到crypto_utils.py中,被两者共同导入。
4.2 常见验证失败场景与修复指南
| 失败现象 | 根本原因 | 修复动作 |
|---|---|---|
HMAC break at index 2 | 加工环节提交时prev_hmac字段填错了,不是采收环节的current_hmac | 检查simulate_full_trace()中harvesting节点生成逻辑,确认base_data["prev_hmac"]赋值正确 |
Time reversal at index 3 | 质检环节时间戳写成"2024-05-15T10:00:00",但采收是"2024-05-20T08:00:00" | 修改fake.date_time_between()的start_date参数,确保质检时间晚于采收时间 |
Batch code mismatch | 仿真时用了hmac_list = [n["current_hmac"] for n in nodes],但verify_trace.py里漏了sort_keys=True导致 JSON 序列化顺序不同 | 统一使用json.dumps(..., sort_keys=True)生成details字符串,或改用 ` |
注意:所有修复必须在
crypto_utils.py中完成,确保仿真与验证两端逻辑 100% 一致。这是整个系统可信的基石。
5. 在 VS Code 中调试与部署:配置 Python 环境与一键运行脚本
仿真系统不是写完就扔的 Demo,它需要被团队成员快速拉起、修改、验证。VS Code 是最主流的 Python 开发环境,我们给出零配置启动方案——只需 3 个文件,就能让新人 5 分钟内跑通全流程。
5.1 创建requirements.txt:锁定核心依赖版本
不要用pip freeze > requirements.txt,那会锁死所有间接依赖。我们只声明直接强依赖,并指定最小兼容版本:
# requirements.txt cryptography>=38.0.0,<39.0.0 Faker>=18.0.0,<19.0.0 pydantic>=1.10.0,<2.0.0 # 用于未来扩展数据校验理由:
cryptography38.x 是首个全面支持 Python 3.11 且 API 稳定的系列;Faker18.x 提供完善的中文农业数据生成器;pydantic预留接口,方便后续接入 Pydantic V2 做更严格的模型校验。版本范围用<39.0.0防止大版本破坏性更新。
5.2 编写.vscode/settings.json:VS Code 专属配置
此文件告诉 VS Code:“用哪个 Python 解释器、在哪里找模块、怎么格式化代码”。它比全局配置更精准,且可提交到 Git。
{ "python.defaultInterpreterPath": "./venv/bin/python", "python.testing.pytestArgs": [ "tests/" ], "python.formatting.provider": "black", "python.linting.enabled": true, "python.linting.pylintEnabled": true, "files.exclude": { "**/__pycache__": true, "**/*.pyc": true, "**/venv": true } }关键点:
"python.defaultInterpreterPath": "./venv/bin/python"强制使用项目级虚拟环境,避免污染系统 Python。Windows 用户需改为"./venv/Scripts/python.exe"。"files.exclude"隐藏编译文件,让资源管理器清爽。
5.3 制作run_simulate.sh/run_simulate.bat:一键生成并验证
Linux/macOS 用 Shell,Windows 用 BAT,内容高度一致:创建虚拟环境 → 安装依赖 → 运行仿真 → 自动验证。
#!/bin/bash # run_simulate.sh set -e # 任一命令失败即退出 echo "🌱 Setting up virtual environment..." python3 -m venv venv source venv/bin/activate echo "📦 Installing dependencies..." pip install --upgrade pip pip install -r requirements.txt echo "🚀 Running full trace simulation..." python main.py --crop_type RICE --num_stages 5 > trace_output.json echo "🔍 Verifying generated trace..." python verify_trace.py --input trace_output.json echo "🎉 Simulation completed. Output saved to trace_output.json"@echo off REM run_simulate.bat echo 🌱 Setting up virtual environment... python -m venv venv echo 📦 Installing dependencies... venv\Scripts\pip.exe install --upgrade pip venv\Scripts\pip.exe install -r requirements.txt echo 🚀 Running full trace simulation... venv\Scripts\python.exe main.py --crop_type RICE --num_stages 5 > trace_output.json echo 🔍 Verifying generated trace... venv\Scripts\python.exe verify_trace.py --input trace_output.json echo 🎉 Simulation completed. Output saved to trace_output.json参数说明:
--crop_type RICE指定生成水稻溯源链;--num_stages 5表示跑种植、采收、加工、质检、包装五个环节(跳过物流)。>重定向将main.py输出的 JSON 直接写入文件,省去手动保存步骤。
5.4 在 VS Code 中启动调试:设置launch.json
点击左侧“运行和调试”图标 → “创建 launch.json 文件” → 选择“Python File”。替换为以下内容,即可按 F5 直接调试main.py:
{ "version": "0.2.0", "configurations": [ { "name": "Python: Current File", "type": "python", "request": "launch", "module": "main", "args": ["--crop_type", "APPLE", "--num_stages", "6"], "console": "integratedTerminal", "justMyCode": true } ] }技巧:
"args"字段预置常用参数,避免每次调试都输命令。"console": "integratedTerminal"确保输出在 VS Code 内置终端显示,方便查看日志。调试时可在simulate_full_trace()函数第一行加断点,观察hmac_list如何逐步增长。
当你在 VS Code 中按下 F5,终端会依次打印环境搭建、依赖安装、仿真执行、验证通过的日志,最后停在trace_output.json生成处——此时打开该文件,你能看到一条带完整 HMAC 链、时间戳、操作员、细节字段的水稻溯源记录,它的批次码经verify_trace.py独立校验,100% 可信。这不再是“能跑就行”的玩具,而是具备密码学根基、可被第三方审计、能支撑真实农业数字化升级的仿真基座。
本文还有配套的精品资源,点击获取