准备环境
硬件与软件基础
硬件要求:普通家用/办公电脑(4GB以上内存,5GB以上剩余空间)
软件要求:
1. Node.js v18.17.0 LTS(含npm):直接从 https://nodejs.org/dist/v18.17.0/ 下载对应系统安装包,默认配置安装
2. Git:直接从 https://git-scm.com/downloads 下载对应系统安装包,默认配置安装
3. VS Code(推荐编辑器):从 https://code.visualstudio.com/ 下载
项目初始化
1. 创建空文件夹 `digital-archive-trace`,右键通过Git Bash打开
2. 初始化Node项目,一路回车确认:
```bash
npm init -y
```
3. 安装依赖:
```bash
npm install --save crypto-js express cors
```
crypto-js用于生成哈希值,express搭建轻量API,cors解决跨域问题
核心溯源逻辑实现
1. 定义区块数据结构
在项目根目录新建 `blockchain.js`,完整代码如下:
```javascript
const SHA256 = require('crypto-js/sha256');
// 定义单个区块类
class Block {
constructor(timestamp, archiveData, previousHash = '') {
this.timestamp = timestamp; // 操作时间戳
this.archiveData = archiveData; // 档案核心数据,格式见后续说明
this.previousHash = previousHash; // 上一个区块的哈希值
this.nonce = 0; // 工作量证明随机数
this.hash = this.calculateHash(); // 当前区块哈希值
}
// 计算哈希值的方法
calculateHash() {
return SHA256(this.previousHash + this.timestamp + JSON.stringify(this.archiveData) + this.nonce).toString();
}
// 简单工作量证明(难度设为前3位为0)
mineBlock(difficulty) {
while (this.hash.substring(0, difficulty) !== Array(difficulty + 1).join('0')) {
this.nonce++;
this.hash = this.calculateHash();
}
}
}
// 定义区块链类
class Blockchain {
constructor() {
this.chain = [this.createGenesisBlock()]; // 初始化创世区块
this.difficulty = 3; // 工作量证明难度
}
// 创建创世区块(没有上一个哈希)
createGenesisBlock() {
return new Block('2024-01-01T00:00:00.000Z', { archiveId: '00000000', operationType: 'system_init', operator: 'admin' }, '0');
}
// 获取最后一个区块
getLatestBlock() {
return this.chain[this.chain.length - 1];
}
// 添加新区块
addBlock(newBlock) {
newBlock.previousHash = this.getLatestBlock().hash;
newBlock.mineBlock(this.difficulty); // 先挖矿验证再添加
this.chain.push(newBlock);
}
// 验证区块链完整性
isChainValid() {
for (let i = 1; i < this.chain.length; i++) {
const currentBlock = this.chain[i];
const previousBlock = this.chain[i - 1];
// 检查当前区块哈希是否被篡改
if (currentBlock.hash !== currentBlock.calculateHash()) {
return false;
}
// 检查当前区块的上一个哈希是否等于上一个区块的哈希
if (currentBlock.previousHash !== previousBlock.hash) {
return false;
}
}
return true;
}
// 根据档案ID查询完整溯源链
getTraceByArchiveId(archiveId) {
return this.chain.filter(block => block.archiveData.archiveId === archiveId).reverse();
}
}
module.exports = Blockchain;
```
2. 搭建API服务
在项目根目录新建 `server.js`,完整代码如下:
```javascript
const express = require('express');
const cors = require('cors');
const Blockchain = require('./blockchain');
const app = express();
const PORT = 3000;
const archiveChain = new Blockchain(); // 实例化区块链
app.use(cors());
app.use(express.json()); // 解析JSON请求体
// 1. 新增档案操作(上链)
app.post('/api/upload-operation', (req, res) => {
const { archiveId, operationType, operator, operationDetail } = req.body;
// 简单必填项校验
if (!archiveId || !operationType || !operator) {
return res.status(400).json({ success: false, message: 'archiveId、operationType、operator为必填项' });
}
const newBlock = new Block(
new Date().toISOString(),
{ archiveId, operationType, operator, operationDetail: operationDetail || '' }
);
archiveChain.addBlock(newBlock);
res.status(201).json({ success: true, block: newBlock });
});
// 2. 查询档案ID完整溯源
app.get('/api/trace/:archiveId', (req, res) => {
const { archiveId } = req.params;
const traceData = archiveChain.getTraceByArchiveId(archiveId);
if (traceData.length === 0) {
return res.status(404).json({ success: false, message: '未找到该档案的溯源信息' });
}
res.status(200).json({ success: true, traceData, isChainValid: archiveChain.isChainValid() });
});
// 3. 查看完整区块链
app.get('/api/chain', (req, res) => {
res.status(200).json({ success: true, chain: archiveChain.chain, isChainValid: archiveChain.isChainValid() });
});
// 启动服务
app.listen(PORT, () => {
console.log(`数字档案溯源API服务已启动,地址:http://localhost:${PORT}`);
});
```
快速测试与落地
1. 启动API服务
在Git Bash中执行:
```bash
node server.js
```
看到「数字档案溯源API服务已启动,地址:http://localhost:3000」即为成功
2. 使用Postman/VS Code REST Client测试
推荐使用VS Code REST Client(插件ID:humao.rest-client),新建 `test.http` 文件,完整测试代码如下:
```http
1. 新增档案创建操作
POST http://localhost:3000/api/upload-operation
Content-Type: application/json
{
"archiveId": "DOC20240601001",
"operationType": "create",
"operator": "李小明",
"operationDetail": "创建员工入职档案,包含身份证扫描件、劳动合同"
}
2. 新增档案归档操作
POST http://localhost:3000/api/upload-operation
Content-Type: application/json
{
"archiveId": "DOC20240601001",
"operationType": "archive",
"operator": "张小红",
"operationDetail": "完成档案完整性校验,归档至3号档案柜第1层"
}
3. 新增档案借阅操作
POST http://localhost:3000/api/upload-operation
Content-Type: application/json
{
"archiveId": "DOC20240601001",
"operationType": "borrow",
"operator": "王经理",
"operationDetail": "借阅用于2024年度绩效考核"
}
4. 查询DOC20240601001的完整溯源链
GET http://localhost:3000/api/trace/DOC20240601001
5. 查看完整区块链
GET http://localhost:3000/api/chain
```
测试时,点击每个请求前的「Send Request」即可,VS Code右侧会显示返回结果
3. 零门槛简易前端展示
如果需要基础的溯源查询界面,在项目根目录新建 `index.html`,完整代码如下:
```html
数字档案简易溯源查询
数字档案简易溯源查询
```
保存后直接在浏览器打开 `index.html`,输入测试用的档案ID即可查询
扩展优化方向(可选)
1. 数据持久化:当前数据存储在内存中,重启服务会清空,可使用LevelDB(`npm install --save level`)存储区块链
2. 权限控制:新增JWT验证模块,只有授权用户才能上传操作
3. 工作量证明优化:根据实际需求调整难度,或改用联盟链共识机制(如PBFT)