一个基于 Node.js/Express 的极简 OTS(OpenTimestamps)HTTP 服务:接受任意 JSON 数据,内存中计算 SHA‑256,向 OTS 日历申请时间戳,并仅持久化“哈希值 + .ots 证明文件”。不保存任何原始数据。
- 隐私模型:Hash-only(零原文存储),详见 SECURITY.md
- 主要依赖:express、javascript-opentimestamps、helmet、morgan、express-rate-limit
- 存储目录:storage/proofs/{SHA256}.ots(可通过 .env 覆盖)
基于 Node.js/Express 的极简 OTS 服务:仅在内存中对输入做 SHA‑256,向 OTS 日历申请时间戳,并只持久化“哈希值 + .ots 证明文件”。不保存任何原始数据(隐私优先)。
- 隐私模型:Hash-only(零原文存储),详见
SECURITY.md - 依赖:express、javascript-opentimestamps、helmet、morgan、express-rate-limit
- 存储:
storage/proofs/{SHA256}.ots(可通过.env覆盖)
- 安装依赖
npm install- 可选:配置环境
Copy-Item .env.example .env
# 按需修改 .env(例如 PORT、PROOF_DIR、OTS_CALENDAR_URLS 等)- 启动服务
npm run dev # 开发(自动重启)
# 或
npm start # 直接启动- 一键 E2E(Windows 本地)
# 健康检查
Invoke-RestMethod -Uri http://localhost:3000/health -Method GET | ConvertTo-Json -Depth 10
# 创建时间戳
$r = Invoke-RestMethod -Uri http://localhost:3000/ots/timestamp -Method POST -ContentType "application/json" -Body '{"data":"Hello OTS"}'
$hash = $r.hash
# 校验 / 信息 / 下载 / 升级
Invoke-RestMethod -Uri "http://localhost:3000/ots/verify?hash=$hash" -Method GET | ConvertTo-Json -Depth 10
Invoke-RestMethod -Uri "http://localhost:3000/ots/info/$hash" -Method GET | ConvertTo-Json -Depth 10
Invoke-WebRequest -Uri "http://localhost:3000/ots/proof/$hash" -OutFile ".\$hash.ots"
Invoke-RestMethod -Uri "http://localhost:3000/ots/upgrade/$hash" -Method POST | ConvertTo-Json -Depth 10
# 或运行脚本
./scripts/e2e-smoke.ps1- POST
/ots/timestamp- Body:
{ data: any } - Resp:
{ success, hash, proof: { id,file,status,size }, createdAt }
- Body:
- GET
/ots/verify?hash=<64-hex>- Resp:
{ success, valid, status, timestamp?, attestations?, verifiedAt }
- Resp:
- GET
/ots/proof/:hash→ 下载二进制.ots - GET
/ots/info/:hash→{ success, hash, timestamp?, size, status, info } - POST
/ots/upgrade/:hash→ 升级证明(更大.ots即表示有新佐证)
- 永不持久化或日志记录原始数据(
req.body.data) - 仅保存 64 位十六进制哈希与
.ots证明文件 - 一切文件 IO/校验前先
isValidHash()校验输入 - 生产模式对外错误信息脱敏(内部日志包含详情)
参考 .env.example:
PORT/NODE_ENV/API_VERSIONJSON_LIMIT:请求体大小限制(默认 256kb)RATE_LIMIT_READ_MAX/RATE_LIMIT_WRITE_MAX:15 分钟窗口PROOF_DIR:证明目录(默认./storage/proofs)OTS_CALENDAR_URLS:逗号分隔(默认 alice/bob/finney)OTS_STAMP_TIMEOUT_MS/OTS_STAMP_RETRIESOTS_UPGRADE_TIMEOUT_MS/OTS_UPGRADE_RETRIES
OTS-SDK/
├─ server.js # 入口:helmet/cors/json/urlencoded/morgan + 路由挂载
├─ routes/
│ └─ api.js # 演示 CRUD,与 OTS 无关
├─ src/
│ ├─ routes/ots.js # OTS 端点:timestamp/verify/proof/info/upgrade
│ └─ ots/
│ ├─ hash.js # SHA‑256、哈希校验
│ ├─ provider.js # 生成/升级/读取/存在性;.env 覆盖/超时/重试
│ └─ verify.js # 反序列化、fromHash、verify/info
├─ storage/proofs/ # 证明目录;文件名 {hash}.ots(已在 .gitignore)
├─ scripts/
│ ├─ e2e-smoke.ps1 # Windows 一键冒烟
│ └─ e2e-smoke.js # Node 冒烟(用于 CI / 本地)
├─ .env.example
└─ SECURITY.md
- 本地:服务运行后可执行
npm run e2e(调用scripts/e2e-smoke.js) - CI:已提供
.github/workflows/ci.yml,自动启动服务并跑端到端冒烟
/verify返回pending是正常现象:上链确权需要时间;稍后用/upgrade可获取新佐证- 建议客户端自行计算 SHA‑256 并只上传哈希(更省带宽/隐私更强)
MIT
curl -X PUT http://localhost:3000/api/items/1 -H "Content-Type: application/json" -d '{"name":"Updated"}'
This API implements hash-only storage for maximum privacy:
✅ **What IS Stored:**curl -X DELETE http://localhost:3000/api/items/1
-
SHA256 hash (64 hex characters)```
-
OTS proof file (.ots format)
-
Timestamp metadata (creation time, status)### 使用 PowerShell Invoke-WebRequest
❌ What is NOT Stored:```powershell
-
Original request data# GET 请求
-
User-provided contentInvoke-WebRequest -Uri http://localhost:3000/api/items | Select-Object -Expand Content
-
Raw documents or text
-
Any personally identifiable information# POST 请求
$body = @{
description = "Test description"
Client submits data → Hash computed in memory → Proof created → Original data discarded
↓Invoke-WebRequest -Uri http://localhost:3000/api/items -Method POST -Body $body -ContentType "application/json"
Only hash + proof stored to disk```
-
Privacy: Original data never leaves the user's control
-
Security: Server compromise cannot reveal timestamped content在
routes/api.js中使用 Express Router 添加新路由: -
Compliance: No sensitive data retention concerns
-
Trust: Users can verify this behavior by inspecting the code```javascript
// GET /api/users
For more details, see SECURITY.mdrouter.get('/users', (req, res) => {
res.json({
data: users
OTS-SDK/});
├── src/
│ ├── ots/// POST /api/users
│ │ ├── hash.js # SHA256 hashing utilitiesrouter.post('/users', (req, res) => {
│ │ ├── provider.js # OTS provider integration const newUser = {
│ │ └── verify.js # Proof verification logic id: Date.now(),
│ └── routes/ ...req.body
│ └── ots.js # API route handlers };
├── storage/ users.push(newUser);
│ └── proofs/ # OTS proof files storage res.status(201).json({
├── server.js # Express server entry point success: true,
├── package.json # Dependencies and scripts data: newUser
├── README.md # This file });
└── SECURITY.md # Security policy documentation});
Create a timestamp:```javascript
curl -X POST http://localhost:3000/ots/timestamp \app.use((req, res, next) => {
-H "Content-Type: application/json" \ console.log(`${req.method} ${req.path}`);
-d '{"data": "Hello, World!"}' next();
```});
**Verify a timestamp:**// 身份验证中间件
```bashconst authMiddleware = (req, res, next) => {
curl "http://localhost:3000/ots/verify?hash=dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f" const token = req.headers['authorization'];
``` if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
**Download proof:** }
```bash // 验证 token
curl -O "http://localhost:3000/ots/proof/dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f" next();
```};
### Using JavaScript// 应用到特定路由
app.use('/api/protected', authMiddleware);
```javascript```
// Create timestamp
const response = await fetch('http://localhost:3000/ots/timestamp', {### 集成数据库
method: 'POST',
headers: { 'Content-Type': 'application/json' },替换内存存储为真实数据库(如 MongoDB、PostgreSQL):
body: JSON.stringify({ data: 'My important document' })
});**MongoDB 示例:**
const result = await response.json();```javascript
console.log('Hash:', result.hash);// 安装依赖
console.log('Proof ID:', result.proof.id);// npm install mongoose
// Verify timestamp// 在 server.js 中连接数据库
const verifyResponse = await fetch(const mongoose = require('mongoose');
`http://localhost:3000/ots/verify?hash=${result.hash}`mongoose.connect('mongodb://localhost:27017/mydb');
);
const verification = await verifyResponse.json();// 创建模型 models/Item.js
console.log('Valid:', verification.valid);const mongoose = require('mongoose');
```const itemSchema = new mongoose.Schema({
name: { type: String, required: true },
## 🛠️ Configuration description: String
});
### Environment Variablesmodule.exports = mongoose.model('Item', itemSchema);
Create a `.env` file in the root directory:// 在 routes/api.js 中使用
const Item = require('../models/Item');
```env
# Server Configurationrouter.get('/items', async (req, res) => {
PORT=3000 try {
NODE_ENV=development const items = await Item.find();
API_VERSION=v1 res.json({ success: true, data: items });
} catch (error) {
# Future: Add OTS calendar server URLs res.status(500).json({ error: error.message });
# OTS_CALENDAR_URLS=https://alice.btc.calendar.opentimestamps.org,https://bob.btc.calendar.opentimestamps.org }
```});
-
SHA256 hashing utilitiesExpress.js 拥有丰富的中间件生态:
-
Mock OTS proof generation
-
Proof storage system```javascript
-
REST API endpoints// 压缩响应
-
Privacy-first architectureconst compression = require('compression');
app.use(compression());
-
Integrate
opentimestampsnpm package// 限流 -
Connect to real OTS calendar serversconst rateLimit = require('express-rate-limit');
-
Support Bitcoin blockchain attestationsconst limiter = rateLimit({
-
Automatic proof upgrades (pending → confirmed) windowMs: 15 * 60 * 1000, // 15 分钟
-
Multiple calendar server redundancy max: 100 // 限制 100 个请求
});
-
Batch timestamping API
-
Proof upgrade scheduling// Cookie 解析
-
Webhook notifications for confirmationsconst cookieParser = require('cookie-parser');
-
Rate limiting and API keysapp.use(cookieParser());
-
Proof expiration/cleanup policies
// 文件上传
-
JavaScript/TypeScript SDKconst upload = multer({ dest: 'uploads/' });
-
Python client libraryapp.post('/upload', upload.single('file'), (req, res) => {
-
CLI tool for command-line usage res.json({ file: req.file });
-
Browser extension});
### Phase 5: Blockchain Integration
- [ ] **ICL (Inter-Chain Link)** support for cross-chain timestamps## 环境变量
- [ ] **ICS (Inter-Chain Service)** integration for DeFi applications
- [ ] Multi-blockchain attestation (Bitcoin, Ethereum, etc.)| 变量 | 说明 | 默认值 |
- [ ] Smart contract verification endpoints|------|------|--------|
- [ ] Decentralized proof storage options| PORT | 服务器端口 | 3000 |
| NODE_ENV | 运行环境 | development |
### Phase 6: Enterprise Features| API_VERSION | API 版本 | v1 |
- [ ] Multi-tenancy support
- [ ] Custom calendar servers## 许可证
- [ ] High-availability deployment guides
- [ ] Monitoring and analytics dashboardMIT
- [ ] S3/IPFS backup for proof files
## 🤝 Contributing
Contributions are welcome! Please follow these steps:
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
### Development Guidelines
- Follow existing code style
- Add comments for complex logic
- Update documentation for API changes
- Maintain security-first principles (no raw data storage)
- Write tests for new features
## 📄 License
MIT License
Copyright (c) 2025 OTS-SDK Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## 📞 Support
- **Issues**: [GitHub Issues](https://github.com/your-username/OTS-SDK/issues)
- **Documentation**: [API Docs](https://github.com/your-username/OTS-SDK/wiki)
- **Security**: See [SECURITY.md](./SECURITY.md)
## 🔗 Resources
- [OpenTimestamps Official Site](https://opentimestamps.org/)
- [OpenTimestamps GitHub](https://github.com/opentimestamps)
- [Bitcoin Blockchain](https://bitcoin.org/)
- [SHA-256 Algorithm](https://en.wikipedia.org/wiki/SHA-2)
---
**Built with ❤️ for the decentralized future**