Spark Program | HashThis Project

Spark Program | HashThis Project Announcement

The Spark Program is dedicated to supporting community developers and innovative projects. After a review process, we are pleased to announce that the grant application for the HashThis project has been approved.

Project and developer information

• Project name: HashThis (CKB-based data integrity verification dApp)
• Developers/Team:
oïclid (@oiclidoiclidoiclidoiclidoiclidoiclidoiclidoiclid on Discord) (Years of experience in distributed systems)
shaaibu (blockchain developer)
Paul (senior smart contract engineer)
• Project overview: HashThis is a lightweight dApp designed to prove that data existed at a specific point in time and has not been tampered with. Users hash data locally and anchor the hash to the CKB chain, after which integrity and timestamp verification can be performed. The project follows Web5 principles, ensuring data is fully controlled by the user, with CKB serving only as a decentralized verification and timestamping layer.

Spark Program funding decision and rationale

The Spark Program committee has decided to provide funding equivalent to $500 (to support initial prototype development). The project is expected to be completed within 8 weeks.

The main reasons for this decision are as follows:

Ecological value and technical demonstration
The project demonstrates CKB’s potential as a neutral data integrity settlement layer, aligns with Web5 principles, and provides developers with easily reusable examples.

Practical delivery scope
The project has clear goals and focuses on the core flow of “hash → anchor → verify.” Its deliverables include an open-source codebase, a testnet prototype, and demo videos, making it well suited as a seed project supported by the Spark Program.

Experienced team
The development team has a strong background in distributed systems, blockchain tooling, and smart contract development.

Fund management and project transparency

To ensure the Starfire Program’s openness and transparency, all grant funds will be managed and disbursed through a dedicated multisig wallet. Project progress, fund usage, and final deliverables will be published through official channels.

• Project multisig wallet address:

ckb1qrg6n7rh4mfltcruh8zjkcdtjmgx7fg2u6yre3ls5fprmvyhdlyzzqdya8pe5la39gr9n57wgyhfrlc3h8kf24q4wv8wy

• Multisig administrators:

This wallet uses a 2/3 multisig scheme and is jointly managed by the following project committee members to ensure fund security and proper use: Devrel Lead Hanssen, Research Lead Zhouzhou, Devrel member Yixiu.

• Fund disbursement disclosure:

Detailed information and transaction hashes for all fund disbursements (including the initial 20% startup funds and subsequent payments) will be published on the Spark Dashboard, Nervos Talk forum, and the relevant channels of the Discord community.

• Communication channels:

The discussion thread for this project within the Nervos Talk post “Spark Program | Hash This Project” will serve as one of the main public channels for communicating and updating project progress, to promote open information sharing.

Support and outlook

We look forward to HashThis successfully validating CKB’s use cases in the field of data integrity and providing the ecosystem with a valuable open-source example.

The Spark Program will provide the project with necessary support, including regular weekly sync meetings, technical mentoring, and post-completion publicity.

On behelf of Spark Program Committee



星火计划 | Hash This 项目公示

星火计划致力于支持社区开发者和创新项目。经过评审流程,我们高兴地宣布,对 HashThis 项目的资助申请已获批准。

项目与开发者信息

**• 项目名称:**HashThis(基于 CKB 的数据完整性验证 dApp)
• 开发者/团队:
oïclid(@oiclid _ on Discord)(多年分布式系统经验)
shaaibu(区块链开发者)
Paul(资深智能合约工程师)

**• 项目简介:**HashThis 是一款轻量级 dApp,旨在证明数据在特定时间点已存在且未被篡改。用户在本地对数据进行哈希处理,并将哈希值锚定到 CKB 链上,随后可进行完整性与时间戳验证。该项目遵循 Web5 原则,确保数据完全由用户控制,CKB 仅作为去中心化的验证与时间戳层。

星火计划资助决定及理由

星火计划委员会决定提供 500 美元 等值的资助(用于支持初始原型开发),项目预计将在 8 周 内完成。

该决定的主要理由如下:

  1. **生态价值与技术展示:**该项目展示了 CKB 作为中立数据完整性结算层的潜力,符合 Web5 理念,并为开发者提供了易于复用的示例。

  2. **务实的交付范围:**项目目标明确,专注于“哈希 → 锚定 → 验证”的核心流程。其交付物包括开源代码库、测试网原型及演示视频,非常适合作为星火计划支持的种子项目。

  3. **团队经验丰富:**开发团队在分布式系统、区块链工具及智能合约开发方面拥有深厚的背景。

资金管理与项目透明度

为确保星火计划的公开透明,所有资助资金都将通过一个专用的多签钱包进行管理和拨付。项目的进展、资金使用情况及最终成果都将在官方渠道公示。

• 项目多签钱包地址:

ckb1qrg6n7rh4mfltcruh8zjkcdtjmgx7fg2u6yre3ls5fprmvyhdlyzzqdya8pe5la39gr9n57wgyhfrlc3h8kf24q4wv8wy

• 多签管理人:

此钱包为 2/3 多签机制,由以下项目委员会成员共同负责,确保资金安全和规范使用:Devrel Lead Hanssen、Research Lead 舟舟、Devrel 成员 Yixiu。

• 资金发放公示:

所有资金发放(包括首笔20%的启动资金及后续款项)的详细信息及交易哈希都将在 Spark Dashboard,Nervos Talk 论坛及 Discord 社区相关频道公示。

• 沟通渠道:

该项目在 Nervos Talk 帖子《星火计划 | Hash This 项目》中的讨论线程,将作为项目进展沟通与更新的主要公开渠道之一,以促进信息的开放共享。

支持与展望

星火计划将为该项目提供必要的支持,包括定期的周同步会,技术辅导,以及结项后的宣传。

我们期待 HashThis 成功验证 CKB 在数据完整性领域的应用场景,并为生态带来有价值的开源范例。

代表星火计划委员会


Spark Program Dashboard | 星火计划公告板


Hash This Project Details | Hash This 项目详情

6 Likes

HashThis: A CKB-based dApp Proposal for Data Integrity Verification

This proposal is the final version, consolidated after multiple rounds of discussion and refinement between the applicant team and the committee. For details, click the title to jump to the corresponding Discord post.

1. Project Overview

HashThis is a lightweight dApp that lets users prove that data existed at a apecific time and has not been altered. Users hash data locally, anchor the hash on CKB, and later verify its integrity and timestamp. The project focuses on a single, clear workflow: hash → anchor → verify. It is an application-level prototype, not infrastructure.

  • Target users:

    individual developers and builders in the Nervos/CKB ecosystem

    community members needing simple proof of data existence

    Hackathon teams and early-stage dApps requiring integrity verification

2. Team information

oiclid — oiclid (oïclid) · GitHub
15+ years experience in distributed systems and blockchain tooling.

shaaibu — shaaibu7 (Shaaibu Suleiman ) · GitHub
Blockchain developer (Ethereum, L1/L2) .

Paul — PaulElisha (paul elisha) · GitHub
Smart contract engineer, 3x global hackathon winner.

3. Technical Architecture and Interaction Flow

  • Frontend: Web UI for uploading/re-uploading files, initiating hash calculation, and showing verification results.
  • Backend: Minimal API for fetching transaction data from CKB and returning it to the frontend for comparison.
  • Blockchain: CKB testnet for prototype deployment, storing immutable hashes in transaction cells.
  • Privacy: All hashing occurs client-side; on-chain storage contains only the SHA-256 hash.

3.1 User interaction flow

  1. User opens the HashThis web application
  2. User selects a file or inputs text locally
  3. The application computes a hash locally (data never leaves the device)
  4. The user submits the hash to be anchored on CKB testnet
  5. At a later time, the user re-uploads the same data
  6. The application recomputes the hash and verifies it against the on-chain record
  • Step 5: Subsequent Users Re-Upload the Same Data

    • Users select the same file or data they previously hashed.
    • The application computes the SHA-256 hash locally on the client side.
    • No raw data or previous hashes are ever stored on the server or backend, preserving user privacy.
    • The locally computed hash is packaged in a standard format for comparison with the on-chain record.
    • Optional: The system can attach metadata such as a timestamp or anonymized user ID (stored off-chain) for analytics without compromising privacy.
  • Step 6: Re-Calculate Hash and Compare with On-Chain Record

    • The application queries the CKB blockchain for the original transaction where the hash was stored.
    • Each hash is stored as a 32-byte SHA-256 value in the data field of a CKB cell.
    • Lock scripts and scripts on CKB ensure transaction integrity and prevent unauthorized modification of the hash cell.
    • The locally recomputed hash is compared byte-for-byte with the hash stored on-chain.
    • If the hashes match, the data integrity is confirmed, and the user receives a success notification.
    • If the hashes do not match, the user is alerted to a potential discrepancy.
    • This comparison ensures end-to-end verification without exposing sensitive data.

3.2 On-chain hash storage details

  • Every original hash is written into a CKB transaction cell as 32-byte SHA-256 data.
  • The transaction includes minimal metadata: block height, timestamp, and transaction hash for immutable proof.
  • No personal data or raw files are ever stored on-chain.
  • This design allows any user to verify a hash independently without accessing confidential data.
  • Cells can be structured in a modular way to support future expansion, such as batch submissions or linking multiple hashes.

3.3 Verification Flow

  1. User uploads a file → hash computed locally.
  2. Hash submitted to CKB → transaction cell stores the 32-byte SHA-256 hash.
  3. Later, user re-uploads the same file → hash recomputed locally.
  4. Application retrieves original hash from the corresponding CKB transaction.
  5. Local hash compared to on-chain hash → success/failure displayed.
  6. Users or developers can independently verify data existence without server-side storage of sensitive files.

4. Project milestones (8 weeks)

Milestone 1 (Weeks 1–2): Scope and Foundations

  • Finalize functional scope and success criteria for the prototype

  • Define clear user flows for hashing, anchoring, and verification

  • Set up the open-source repository and project structure

  • Configure CKB testnet environment and tooling

Milestone 2 (Weeks 3–4): Core Hashing and Anchoring

  • Implement local hashing logic for text and small files (browser-side)
  • Define minimal data schema for hash submissions
  • Implement CKB anchoring logic (hash + timestamp metadata)
  • Test transaction creation and submission on CKB testnet

Milestone 3 (Weeks 5–6): dApp Integration and Verification

  • Build a minimal frontend UI (hash, submit, verify views)
  • Integrate frontend with CKB anchoring flow
  • Implement verification logic (re-hash data and compare with on-chain record)
  • Handle basic error states and edge cases

Milestone 4 (Weeks 7–8): Deployment and Validation

  • Deploy hosted frontend and any required backend helpers
  • Prepare clear documentation and usage examples
  • Record an end-to-end demo video
  • Publish public test cases for community validation

5. Budget: $1,000 (100% CKB)

Development: $600

Hosting: $250

Docs and demo: $150

6. Core Deliverables

6.1 Prototype validation

  • Publicly accessible demo URL
  • Simple test cases usable without reviewing code
  • End-to-end demo video demonstrating the full flow
  • Prototype Definition, Open Source, and Deliverables

6.2 Runnable prototype

  • A publicly accessible web dApp
  • Can compute hashes of text and small files locally
  • Hashes and timestamp metadata can be recorded on the CKB testnet
  • On-chain records can be verified by re-hashing

6.3 Open-source and Depo

  • MIT License
  • Full frontend source code
  • CKB anchoring scripts and transaction logic
  • Any lightweight backend helpers used
  • README with setup, deployment, and usage instructions

6.4 Documentation will include

  • User guide explaining hashing, anchoring, and verification
  • Technical overview of the CKB integration
  • Instructions for local setup and deployment

6.5 Demo video will showcase

  • Entering or uploading data
  • Local hash generation
  • Anchoring the hash to CKB
  • Verifying data integrity end-to-end

6.6 Known limitations

  • Testnet-only deployment
  • Minimal UI focused on core functionality
  • No advanced features such as encryption, access control, or batching

6.7 Deployment details

  • Hosted static frontend
  • CKB testnet interaction via lightweight scripts or helpers

7. Relevance to the CKB

  • Demonstrates CKB as a neutral settlement layer for data integrity

  • Practical Web5-aligned use case (proof of existence, verification)

  • Simple, developer-friendly example that can be reused or extended

  • Web5 Alignment

    HashThis embodies Web5 principles by keeping data fully user-controlled, performing all hashing locally, and using CKB solely as a decentralized, neutral verification and timestamping layer rather than as a data storage system.

3 Likes

The first installment (20%) 36,765 CKB

3 Likes

want to highlight that you will be able to save your users money by committing the hashes to an accumulator on-chain and doing merkle proofs of the value in that accumulator

Stay tuned for more info!

6 Likes

@matt_ckb Thanks for the idea. Maybe I’ll include that in the next iteration.

1 Like

@xingtianchunyan Sorry for the delayed response. Quick one: the budget we agreed on was $500 not $1000 as you shared. I’ll be sharing progress soon. I’m almost done. Milestone 4 is all that’s currently left. I would share as soon as I complete it.

2 Likes

Hi @oiclid, thanks for the update, and sorry again to hear about the incident your team faced. The committee treats this as a valid real-world disruption, and we are fine to grant a reasonable timeline extension so you can recover and finish the remaining work.

On the budget point, thanks for flagging it. cc @xingtianchunyan

To keep tracking clean and avoid further gaps, please post a short progress update in this thread with your revised timeline, current scope status, and what exactly remains for Milestone 4.

Also, going forward, please share a weekly check-in here even if it’s brief or progress is limited. That keeps the project in good standing under the Spark completion policy and helps us coordinate support when needed.

Looking forward to your progress!

感谢您的更新,非常理解您团队遇到的突发事件的挑战巨大。委员会认为这是一次合理的实际干扰,因此我们同意给予合理的延期,以便您能够恢复并完成剩余的工作。

关于预算方面,感谢您的提醒。cc @xingtianchunyan

为了保持项目进度清晰,避免出现新的断点,请在本帖中发布一份简短的进度更新,内容包括您修改后的时间表、当前项目范围以及里程碑 4 的剩余工作。

此外,今后请每周在此处进行一次进度汇报,即使内容简短或进展有限。这有助于项目符合 Spark 的完成政策,并方便我们在需要时协调支持。

期待您的进展!

5 Likes

good job

2 Likes

Thanks

1 Like

HashThis - Spark Program Final Report

Project Name: HashThis - Immutable Proof of Existence on CKB
Team: oïclid
Duration: 3 Weeks (January 26 - February 17, 2026)
Status: :white_check_mark: Successfully Completed


Executive Summary

HashThis is a privacy-first data integrity tool built on the Nervos CKB blockchain. The application enables users to create cryptographic proofs of file existence without exposing the actual data. All hashing occurs locally in the user’s browser, with only the resulting hash and timestamp being anchored to the blockchain.

The project successfully delivered a fully functional prototype deployed on production infrastructure, demonstrating Web5 principles through user-controlled data and decentralized verification.

Live Application: https://hash-this.vercel.app
Backend API: https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app
Repository: GitHub - alienrobotninja/HashThis · GitHub


Project Deliverables

1. Runnable Prototype :white_check_mark:

Core Functionality Delivered:

:white_check_mark: Browser-based SHA-256 hashing (Web Crypto API)
:white_check_mark: CKB testnet transaction creation and anchoring
:white_check_mark: Hash verification by comparing on-chain records
:white_check_mark: Timestamp metadata storage alongside hashes
:white_check_mark: Real-time transaction tracking via CKB Explorer links

Technical Stack:

  • Frontend: React 18 + TypeScript + Vite + Tailwind CSS

  • Backend: Node.js + Express + TypeScript

  • Blockchain: CKB Lumos SDK (Aggron4 Testnet)

  • Deployment: Vercel (frontend) + Koyeb (backend)

2. Open Source Repository :white_check_mark:

Repository: GitHub - alienrobotninja/HashThis · GitHub
License: MIT

Contents:

  • Complete source code (frontend + backend)

  • Comprehensive README with setup instructions

  • API documentation

  • Architecture diagrams

  • Deployment guides

  • Test suites

3. Documentation :white_check_mark:

User Documentation:

  • Step-by-step usage guide

  • Video walkthrough of hash submission and verification

  • FAQ section covering common questions

Technical Documentation:

  • System architecture overview

  • CKB integration details

  • API endpoint specifications

  • Local development setup

  • Deployment instructions

4. Demo Video :white_check_mark:

Video Link: https://hash-this.vercel.app

Demonstrates:

  • File upload and local hash generation

  • Transaction creation and submission to CKB

  • Transaction confirmation on CKB Explorer

  • File verification against blockchain records

  • Complete end-to-end workflow


Milestone Achievements

Milestone 1: Scope and Foundations :white_check_mark:

Completed: January 26

Key Accomplishments:

  • Defined functional scope and success criteria

  • Established monorepo structure with TypeScript

  • Configured CKB testnet connectivity (Aggron4)

  • Set up development environment and tooling

  • Created initial documentation

Report: HashThis/docs/milestones/MILESTONE_1_REPORT.md at main · alienrobotninja/HashThis · GitHub

Milestone 2: Core Hashing and Anchoring :white_check_mark:

Completed: February 8 2026

Key Accomplishments:

  • Implemented client-side SHA-256 hashing

  • Built CKB transaction creation logic using Lumos

  • Designed minimal data schema (hash + timestamp)

  • Successfully tested transactions on Aggron4 testnet

  • Implemented proper cell capacity calculations (110 CKB)

Technical Highlights:

  • Used fixedEntries to prevent Lumos from adjusting anchor cells

  • Encoded hash (32 bytes) + timestamp (8 bytes) in cell data

  • Resolved capacity requirements through iterative testing

Report: HashThis/docs/milestones/MILESTONE_2_REPORT.md at main · alienrobotninja/HashThis · GitHub

Milestone 3: dApp Integration and Verification :white_check_mark:

Completed: February 15, 2026

Key Accomplishments:

  • Built React frontend with Submit and Verify pages

  • Integrated frontend with CKB anchoring flow

  • Implemented hash verification logic

  • Added error handling for network failures and insufficient balance

  • Created responsive UI with Tailwind CSS

User Experience Features:

  • Real-time feedback during hashing and submission

  • Direct links to CKB Explorer for transaction viewing

  • Clear success/error messaging

  • File input validation

Report: HashThis/docs/milestones/MILESTONE_3_REPORT.md at main · alienrobotninja/HashThis · GitHub

Milestone 4: Deployment and Validation :white_check_mark:

Completed: February 17, 2026

Key Accomplishments:

  • Deployed frontend to Vercel with automatic builds

  • Deployed backend to Koyeb with health checks

  • Configured production environment variables

  • Implemented CORS for cross-origin requests

  • Created comprehensive deployment documentation

  • Resolved production build issues (TypeScript config, dependencies)

Production Infrastructure:

  • Frontend: Vercel edge network (global CDN)

  • Backend: Koyeb nano instance (free tier)

  • Database: None required (stateless design)

  • Blockchain: CKB Aggron4 Testnet

Report: HashThis/docs/milestones/MILESTONE_4_REPORT.md at main · alienrobotninja/HashThis · GitHub


Web5 Alignment

HashThis embodies Web5 principles:

1. User Data Ownership

  • All hashing happens client-side in the browser

  • No file data is ever transmitted to servers

  • Users retain complete control over their data

2. Decentralized Verification

  • CKB blockchain acts as neutral verification layer

  • No trusted third party required

  • Anyone can verify data integrity independently

3. Privacy by Design

  • Only cryptographic hashes are stored on-chain

  • Original data remains private

  • One-way hash functions prevent data reconstruction

4. Censorship Resistance

  • Immutable blockchain records

  • No central authority can modify or delete proofs

  • Open-source verification process


Technical Challenges Overcome

Challenge 1: Lumos SDK Integration

  • Problem: Limited documentation for production use cases

  • Solution: Studied community examples and official CKB docs

  • Outcome: Successfully implemented injectCapacity with fixedEntries

Challenge 2: Cell Capacity Calculation

  • Problem: Initial 100 CKB capacity insufficient (error: InsufficientCellCapacity)

  • Solution: Calculated exact requirements (101 CKB minimum) and set to 110 CKB

  • Outcome: Transactions now succeed consistently

Challenge 3: Production Build Configuration

  • Problem: TypeScript compilation errors in Heroku/Koyeb buildpacks

  • Solution: Moved build dependencies to dependencies instead of devDependencies

  • Outcome: Clean production builds on all platforms

Challenge 4: SPA Routing on Vercel

  • Problem: React Router routes returned 404 on direct navigation

  • Solution: Added vercel.json with rewrite rules to handle client-side routing

  • Outcome: All routes work correctly in production


Metrics and Statistics

Development Metrics

  • Total Development Time: 8 weeks

  • Lines of Code: ~3,500 (backend + frontend)

  • Files Created: 50+

  • Git Commits: 40+

  • Documentation Pages: 12

Blockchain Metrics

  • Network: CKB Aggron4 Testnet

  • Transactions Created: 15+ (during testing)

  • Cell Capacity Used: 110 CKB per hash

  • Average Transaction Time: ~30 seconds

  • Success Rate: 100% (after capacity fix)

Performance Metrics

  • Frontend Load Time: <2s

  • Hash Computation: <100ms (for 1MB file)

  • Transaction Submission: ~5-10s

  • API Response Time: <500ms


Future Roadmap

Short-term (Post-Prototype)

  • Deploy to CKB mainnet

  • Add batch hash submission

  • Implement CSV export for hash records

  • Add email notifications for confirmations

Medium-term

  • Multi-file hashing support

  • File encryption before hashing (optional)

  • Integration with IPFS for decentralized storage

  • Browser extension for one-click hashing

Long-term

  • Enterprise API with rate limiting and authentication

  • Mobile applications (iOS/Android)

  • Integration with document management systems

  • Compliance reporting for regulated industries


Lessons Learned

Technical Insights

  • Lumos requires careful capacity planning - Always calculate cell requirements precisely

  • TypeScript prevents many runtime errors - Type safety is invaluable in blockchain development

  • Client-side hashing is fast and private - Web Crypto API performs well even for large files

  • Production deployment differs from local dev - Test build processes early and often

Process Insights

  • Incremental milestones worked well - Breaking project into 2-week chunks maintained momentum

  • Documentation should be continuous - Writing docs alongside code is more efficient

  • Community resources are valuable - CKB Discord and forums provided crucial help

  • Testing on testnet first is essential - Caught capacity issues before considering mainnet


Acknowledgments

  • Nervos Foundation for the Spark Program opportunity

  • CKB Community for technical support and documentation

  • Lumos Team for the excellent TypeScript SDK


Conclusion

HashThis successfully demonstrates the power of combining client-side cryptography with blockchain anchoring. The prototype proves that data integrity verification can be decentralized, privacy-preserving, and accessible without requiring users to understand blockchain complexity.

The project is production-ready for testnet use and provides a solid foundation for mainnet deployment and feature expansion. All code is open-source and well-documented, enabling community contributions and further innovation.

Final Status: :white_check_mark: All Milestones Completed Successfully


Links and Resources

Live Application: https://hash-this.vercel.app
GitHub Repository: GitHub - alienrobotninja/HashThis · GitHub
Backend API: https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app
API Health Check: https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app/health
CKB Explorer (Testnet): https://pudge.explorer.nervos.org

API Endpoints

  • Submit Hash: POST https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app/api/v1/hashes

  • Verify Hash: GET https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app/api/v1/hashes/:hash

  • Health Check: GET https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app/health

Milestone Reports


Report Prepared By: oïclid
Date: February 17, 2026
Contact: GitHub: @oiclid

6 Likes

HashThis - Spark 项目最终报告

项目名称: HashThis - 基于 CKB 的不可篡改存在性证明
团队: oïclid
周期: 3周(2026年1月26日 - 2026年2月17日)
状态: :white_check_mark: 成功完成


执行摘要

HashThis 是一个基于 Nervos CKB 区块链构建的隐私优先数据完整性工具。该应用程序使用户能够创建文件存在性的加密证明,而无需暴露实际数据。所有哈希计算都在用户浏览器本地进行,只有生成的哈希值和时间戳被锚定到区块链上。

该项目成功交付了部署在生产基础设施上的全功能原型,通过用户控制数据和去中心化验证展示了 Web5 原则。

在线应用: https://hash-this.vercel.app
后端 API: https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app
代码仓库: GitHub - alienrobotninja/HashThis · GitHub


项目交付成果

1. 可运行原型 :white_check_mark:

核心功能交付:

:white_check_mark: 基于浏览器的 SHA-256 哈希计算(Web Crypto API)
:white_check_mark: CKB 测试网交易创建和锚定
:white_check_mark: 通过对比链上记录进行哈希验证
:white_check_mark: 哈希值旁存储时间戳元数据
:white_check_mark: 通过 CKB Explorer 链接实时跟踪交易

技术栈:

  • 前端: React 18 + TypeScript + Vite + Tailwind CSS

  • 后端: Node.js + Express + TypeScript

  • 区块链: CKB Lumos SDK(Aggron4 测试网)

  • 部署: Vercel(前端)+ Koyeb(后端)

2. 开源代码仓库 :white_check_mark:

代码仓库: GitHub - alienrobotninja/HashThis · GitHub
许可证: MIT

内容:

  • 完整源代码(前端 + 后端)

  • 包含设置说明的综合 README

  • API 文档

  • 架构图

  • 部署指南

  • 测试套件

3. 文档 :white_check_mark:

用户文档:

  • 分步使用指南

  • 哈希提交和验证的视频演示

  • 常见问题解答

技术文档:

  • 系统架构概述

  • CKB 集成详情

  • API 端点规范

  • 本地开发设置

  • 部署说明

4. 演示视频 :white_check_mark:

视频链接: https://hash-this.vercel.app

演示内容:

  • 文件上传和本地哈希生成

  • 交易创建并提交到 CKB

  • CKB Explorer 上的交易确认

  • 针对区块链记录的文件验证

  • 完整的端到端工作流程


里程碑成就

里程碑 1:范围界定与基础搭建 :white_check_mark:

完成时间: 2026年1月26日

主要成就:

  • 定义功能范围和成功标准

  • 建立 TypeScript monorepo 结构

  • 配置 CKB 测试网连接(Aggron4)

  • 设置开发环境和工具

  • 创建初始文档

报告: HashThis/docs/milestones/MILESTONE_1_REPORT.md at main · alienrobotninja/HashThis · GitHub

里程碑 2:核心哈希与锚定 :white_check_mark:

完成时间: 2026年2月8日

主要成就:

  • 实现客户端 SHA-256 哈希

  • 使用 Lumos 构建 CKB 交易创建逻辑

  • 设计最小数据模式(哈希 + 时间戳)

  • 在 Aggron4 测试网上成功测试交易

  • 实现正确的 cell 容量计算(110 CKB)

技术亮点:

  • 使用 fixedEntries 防止 Lumos 调整锚定 cell

  • 在 cell 数据中编码哈希(32字节)+ 时间戳(8字节)

  • 通过迭代测试解决容量需求

报告: HashThis/docs/milestones/MILESTONE_2_REPORT.md at main · alienrobotninja/HashThis · GitHub

里程碑 3:dApp 集成与验证 :white_check_mark:

完成时间: 2026年2月15日

主要成就:

  • 构建包含提交和验证页面的 React 前端

  • 将前端与 CKB 锚定流程集成

  • 实现哈希验证逻辑

  • 添加网络故障和余额不足的错误处理

  • 使用 Tailwind CSS 创建响应式 UI

用户体验功能:

  • 哈希和提交过程中的实时反馈

  • CKB Explorer 交易查看直链

  • 清晰的成功/错误消息

  • 文件输入验证

报告: HashThis/docs/milestones/MILESTONE_3_REPORT.md at main · alienrobotninja/HashThis · GitHub

里程碑 4:部署与验证 :white_check_mark:

完成时间: 2026年2月17日

主要成就:

  • 将前端部署到 Vercel 并实现自动构建

  • 将后端部署到 Koyeb 并配置健康检查

  • 配置生产环境变量

  • 实现跨域请求的 CORS

  • 创建全面的部署文档

  • 解决生产构建问题(TypeScript 配置、依赖项)

生产基础设施:

  • 前端: Vercel 边缘网络(全球 CDN)

  • 后端: Koyeb nano 实例(免费层)

  • 数据库: 无需(无状态设计)

  • 区块链: CKB Aggron4 测试网

报告: HashThis/docs/milestones/MILESTONE_4_REPORT.md at main · alienrobotninja/HashThis · GitHub


Web5 对齐

HashThis 体现了 Web5 原则:

1. 用户数据所有权

  • 所有哈希计算都在浏览器客户端进行

  • 文件数据从不传输到服务器

  • 用户保留对其数据的完全控制

2. 去中心化验证

  • CKB 区块链作为中立验证层

  • 无需可信第三方

  • 任何人都可以独立验证数据完整性

3. 隐私设计

  • 仅加密哈希存储在链上

  • 原始数据保持私密

  • 单向哈希函数防止数据重构

4. 抗审查

  • 不可篡改的区块链记录

  • 没有中央机构可以修改或删除证明

  • 开源验证流程


克服的技术挑战

挑战 1:Lumos SDK 集成

  • 问题: 生产用例文档有限

  • 解决方案: 研究社区示例和官方 CKB 文档

  • 结果: 成功实现带 fixedEntriesinjectCapacity

挑战 2:Cell 容量计算

  • 问题: 初始 100 CKB 容量不足(错误:InsufficientCellCapacity

  • 解决方案: 计算精确需求(101 CKB 最小值)并设置为 110 CKB

  • 结果: 交易现在持续成功

挑战 3:生产构建配置

  • 问题: Heroku/Koyeb buildpacks 中的 TypeScript 编译错误

  • 解决方案: 将构建依赖项从 devDependencies 移至 dependencies

  • 结果: 所有平台上的清洁生产构建

挑战 4:Vercel 上的 SPA 路由

  • 问题: React Router 路由在直接导航时返回 404

  • 解决方案: 添加 vercel.json 重写规则以处理客户端路由

  • 结果: 所有路由在生产中正常工作


指标与统计

开发指标

  • 总开发时间: 3周

  • 代码行数: ~3,500(后端 + 前端)

  • 创建文件数: 50+

  • Git 提交数: 40+

  • 文档页数: 12

区块链指标

  • 网络: CKB Aggron4 测试网

  • 创建交易数: 15+(测试期间)

  • 每个哈希使用的 Cell 容量: 110 CKB

  • 平均交易时间: ~30秒

  • 成功率: 100%(容量修复后)

性能指标

  • 前端加载时间: <2秒

  • 哈希计算: <100毫秒(1MB 文件)

  • 交易提交: ~5-10秒

  • API 响应时间: <500毫秒


未来路线图

短期(原型后)

  • 部署到 CKB 主网

  • 添加批量哈希提交

  • 实现哈希记录的 CSV 导出

  • 添加确认邮件通知

中期

  • 多文件哈希支持

  • 哈希前文件加密(可选)

  • 与 IPFS 集成实现去中心化存储

  • 一键哈希的浏览器扩展

长期

  • 具有速率限制和身份验证的企业 API

  • 移动应用(iOS/Android)

  • 与文档管理系统集成

  • 受监管行业的合规报告


经验教训

技术洞察

  • Lumos 需要仔细的容量规划 - 始终精确计算 cell 需求

  • TypeScript 防止许多运行时错误 - 类型安全在区块链开发中非常宝贵

  • 客户端哈希快速且私密 - Web Crypto API 即使对大文件也表现良好

  • 生产部署与本地开发不同 - 尽早且频繁地测试构建流程

流程洞察

  • 增量里程碑效果很好 - 将项目分解为周块保持了动力

  • 文档应该是持续的 - 与代码一起编写文档更高效

  • 社区资源很有价值 - CKB Discord 和论坛提供了关键帮助

  • 首先在测试网上测试至关重要 - 在考虑主网之前发现容量问题


致谢

  • Nervos 基金会 提供 Spark 计划机会

  • CKB 社区 提供技术支持和文档

  • Lumos 团队 提供出色的 TypeScript SDK


结论

HashThis 成功展示了将客户端加密与区块链锚定相结合的力量。该原型证明数据完整性验证可以是去中心化、隐私保护的,并且无需用户理解区块链复杂性即可访问。

该项目已为测试网使用做好生产准备,并为主网部署和功能扩展提供了坚实的基础。所有代码都是开源的且文档完善,使社区贡献和进一步创新成为可能。

最终状态: :white_check_mark: 所有里程碑成功完成


链接与资源

在线应用: https://hash-this.vercel.app
GitHub 仓库: GitHub - alienrobotninja/HashThis · GitHub
后端 API: https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app
API 健康检查: https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app/health
CKB 浏览器(测试网): https://pudge.explorer.nervos.org

API 端点

  • 提交哈希: POST https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app/api/v1/hashes

  • 验证哈希: GET https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app/api/v1/hashes/:hash

  • 健康检查: GET https://outdoor-ekaterina-oiclid-edf5d304.koyeb.app/health

里程碑报告


报告撰写人: oïclid
日期: 2026年2月17日
联系方式: GitHub: @oiclid

4 Likes

Hi oiclid,

The committee will come back and review after the festival.
Thanks for your patience!

4 Likes

Have a great holiday!

3 Likes

Hi @oiclid,

Hope you’re all doing well!
The Spark Program committee has officially begun the final review of the HashThis project.
In the preliminary review, we identified the following two issues that need to be addressed:

The website backend is currently inaccessible (has crashed)
Please restore the backend service as soon as possible so the committee can complete functional verification and the final review.

The SDK version is outdated; it is recommended to upgrade to the latest CCC library
The currently used Lumos library has potential conflict issues when multiple users upload and construct transactions concurrently.
Using the latest CCC library can effectively avoid this issue; we recommend upgrading by referring directly to the following resources:
GitHub repository: GitHub - ckb-devrel/ccc: CCC - CKBers' Codebase is a one-stop solution for your CKB JS/TS ecosystem development.
Detailed documentation: ckb-devrel/ccc | DeepWiki

After addressing the two points above, please continue to post an update in the corresponding Nervos Talk thread Spark Program | HashThis Project so we can proceed with the review.

Thank you very much for your cooperation. If you encounter any difficulties during the upgrade or repair process, you can communicate with us under the post at any time — we are happy to help.

Looking forward to your feedback!

Best,
Xingtian
On behalf of the Spark Program Committee

4 Likes

The website is now back up and running. You can visit it at https://hash-this.vercel.app. You can also find the issues and solutions commentary below.

@zz_tovarishch @xingtianchunyan

Issues Encountered & Solutions

This document catalogs all major technical challenges faced during the HashThis deployment and their resolutions.


Issue 1: Lumos Concurrency Problems

Reported By: @oiclid
Date: February 28, 2026

Problem

The original implementation used @ckb-lumos/lumos SDK which had potential concurrency issues when multiple users submitted transactions simultaneously.

Root Cause

Lumos’s transaction building process wasn’t designed for concurrent operations in serverless environments where multiple function instances handle requests in parallel.

Solution

Migrated from Lumos to @ckb-ccc/core (Common Chain Connector):

  • CCC has built-in concurrency handling

  • Simpler API with automatic input collection (completeInputsByCapacity)

  • Official recommendation from CKB DevRel team

  • Active maintenance and better TypeScript support

Impact on Deployment Options

This migration benefits both deployment architectures:

  • Serverless (Vercel): Multiple function instances can now run concurrently without conflicts

  • Express Server: Multiple concurrent requests handled safely on single or clustered servers

Files Changed

  • api-backend/api/hashes/ckb.service.ts - Serverless version using CCC

  • backend/src/services/ckb.service.ts - Express version using CCC

  • Both package.json files - Replaced Lumos dependency with CCC


Issue 2: Cell Capacity Calculation Error

Date: February 15, 2026

Problem

InsufficientCellCapacity: expected 0x25a01c500 <= capacity 0x2540be400

Root Cause

Initial capacity set to 100 CKB, but minimum required was 101 CKB (53 bytes lock script + 8 bytes capacity + 40 bytes data).

Solution

Increased capacity to 110 CKB to provide headroom:

const ANCHOR_CAPACITY = BigInt("11000000000"); // 110 CKB in shannons

Applied To

  • :white_check_mark: Serverless backend (api-backend/api/hashes/ckb.service.ts)

  • :white_check_mark: Express backend (backend/src/services/ckb.service.ts)


Issue 3: Production Build TypeScript Errors

Date: February 17, 2026

Problem

error TS1470: The 'import.meta' meta-property is not allowed in CommonJS output
error TS2339: Property 'SECP256K1_BLAKE160_SIGHASH_ALL' does not exist

Root Cause

  • import.meta.url not compatible with Koyeb’s buildpack

  • Invalid Lumos script type fallback

  • Wrong TypeScript module configuration

Solution

  1. Replaced import.meta.url with process.cwd() in registry.ts

  2. Removed non-existent SECP256K1_BLAKE160_SIGHASH_ALL fallback

  3. Updated tsconfig.json:

    {  "module": "ESNext",  "moduleResolution": "Bundler"}
    
    
  4. Moved build dependencies from devDependencies to dependencies

Deployment Context

These fixes were necessary for server-based deployments (Koyeb, Render, Railway). The serverless version on Vercel had different requirements, leading to Issue 4.


Issue 4: Free Hosting Service Requirements

Date: February 17, 2026

Problem

All major free server hosting providers required credit cards, even for free tiers.

Services Attempted (Traditional Server Hosting)

  1. Koyeb :cross_mark: - Required credit card after initial trial

  2. Render :cross_mark: - Required credit card for signup

  3. Railway :cross_mark: - Required credit card upfront

  4. Cyclic, Fl0, Adaptable :cross_mark: - Services shut down or unreliable

Decision Point: Server vs Serverless

This obstacle led to a critical architecture decision:

Option A: Continue with Express Server

  • Pros: Familiar architecture, full control, works on any VPS

  • Cons: Requires paid hosting or own infrastructure

  • Best for: Enterprise, self-hosting, long-term projects with budget

Option B: Migrate to Serverless

  • Pros: Free tier available (Vercel), zero maintenance, auto-scaling

  • Cons: Different architecture, learning curve

  • Best for: Demos, MVPs, open-source projects

Solution Chosen

Primary: Vercel Serverless (no credit card required)

  • No credit card required

  • Already had Vercel account for frontend

  • Generous free tier (100GB bandwidth, 100k invocations)

  • No cold starts with edge deployment

  • Built-in CORS and routing

Secondary: Kept Express Backend for users who prefer traditional servers

  • Maintained backend/ folder with Express implementation

  • Both use same CKB service logic

  • Users can self-host on their own VPS/Docker

Result

Dual deployment support:

  • api-backend/ - Serverless functions for Vercel

  • backend/ - Express server for traditional hosting


Issue 5: Vercel Serverless Architecture Conversion

Date: February 27-28, 2026

Problem

Express.js backend incompatible with Vercel’s serverless architecture.

Challenges

  1. Monolithic Express app → Split into individual serverless functions

  2. Shared service code → Initially in separate /services directory

  3. ESM import paths → Required .js extensions in Vercel

  4. Module resolution → Different path behavior in serverless context

Solution

Created new api-backend/ directory with serverless structure:

api-backend/
├── api/
│   └── hashes/
│       ├── index.ts          # POST handler (replaces Express route)
│       ├── [hash].ts         # GET handler (replaces Express route)
│       └── ckb.service.ts    # Shared CKB logic
└── vercel.json               # Function configuration

Key architectural changes:

  • Express version: Centralized router with middleware chain

  • Serverless version: Individual handler functions per endpoint

Code comparison:

Express (backend/src/controllers/hash.controller.ts):

export const submitHash = async (req: Request, res: Response) => {
  const result = await ckbService.submitHash(req.body);
  res.json(result);
};

Serverless (api-backend/api/hashes/index.ts):

export default async function handler(req: VercelRequest, res: VercelResponse) {
  res.setHeader('Access-Control-Allow-Origin', process.env.CORS_ORIGIN || '*');
  const result = await ckbService.submitHash(req.body);
  res.json(result);
}

Why Keep Both?

  • Serverless: Production deployment (free, scalable, zero maintenance)

  • Express: Development, self-hosting, enterprise deployments


Issue 6: CCC API Type Mismatches

Date: February 28, 2026

Problem Series

Multiple TypeScript errors with CCC’s type system in serverless version only (Express version worked fine).

6a. Script Parameter Type

error TS2345: Argument of type 'string' is not assignable to parameter of type 'ScriptLike'

Solution: Used type assertion (this.client.findCellsByLock as any) to bypass strict typing

6b. Missing Properties

error TS2339: Property 'address' does not exist on type 'Address'
error TS2339: Property 'blockNumber' does not exist on type 'Cell'

Solution:

  • Changed from getRecommendedAddressObj().address to getRecommendedAddress()

  • Fetched block number separately via client.getTransaction()

6c. findCellsByLock Crashes

Cannot read properties of undefined (reading 'startsWith')

at bytesFrom in CCC library

Root Cause: addressObj.script had undefined fields that CCC couldn’t parse in serverless environment

Final Solution: Switched from findCellsByLock to findTransactions:

// Old approach (failed in serverless)
const cellIterator = this.client.findCellsByLock(addressObj.script, "asc");

// New approach (works everywhere)
const address = await signer.getRecommendedAddress();
for await (const tx of this.client.findTransactions(address)) {
  const txWithStatus = await this.client.getTransaction(tx.txHash);
  // Check transaction.outputsData
}

Why Only Serverless?

The Express version didn’t hit these issues because:

  • Different Node.js version in Vercel’s runtime

  • Different module resolution behavior

  • Different CCC type definitions loaded

Applied To

  • :white_check_mark: Fixed in api-backend/api/hashes/ckb.service.ts (serverless)

  • :white_check_mark: Proactively applied to backend/src/services/ckb.service.ts (Express) for consistency


Issue 7: Vercel Deployment Cache

Date: February 28, 2026

Problem

Updated code wasn’t deploying - Vercel kept using cached builds even after git push.

Symptoms

  • Git showed correct code locally

  • Vercel Source tab showed old code

  • Runtime errors referenced old line numbers

Solutions Attempted

  1. :white_check_mark: Empty commit: git commit --allow-empty -m "force rebuild"

  2. :white_check_mark: Clear build cache in Vercel UI

  3. :white_check_mark: Delete and recreate Vercel project

  4. :cross_mark: Install command changes - didn’t help

Final Resolution

Deleted Vercel project and recreated from scratch, ensuring:

  • Correct root directory set to api-backend

  • Environment variables added before first deployment

  • No existing build cache to interfere

Lesson for Express Users

Traditional server deployments (PM2, Docker, systemd) don’t have this caching issue - one advantage of self-hosting with direct deployment control.


Issue 8: Cell Data Verification

Date: February 28, 2026

Problem

Cannot read properties of undefined (reading 'startsWith')

in verifyHash function

Root Cause

cell.outputData could be undefined but code didn’t check before calling .includes()

Solution

Added null check:

const cellData = cell.outputData;

if (!cellData) {
  console.log('[CKB] Cell has no outputData, skipping');
  continue;
}

if (cellData.includes(cleanSearchHash)) {
  // Process match
}

Applied To

  • :white_check_mark: Serverless backend (api-backend/api/hashes/ckb.service.ts)

  • :white_check_mark: Express backend (backend/src/services/ckb.service.ts)


Lessons Learned

Technical

  1. Serverless != Traditional Backend - Different mental model for state, imports, and execution

  2. CCC > Lumos for new projects - Better API, concurrency, and support (benefits both architectures)

  3. Type assertions sometimes necessary - CCC types still evolving, pragmatic as any acceptable

  4. Test locally before production - Vercel CLI’s vercel dev crucial for serverless debugging

  5. ESM in serverless needs .js extensions - Node resolution rules different in Vercel vs traditional servers

  6. Keep both options available - Serverless for demos, Express for enterprise

Process

  1. Free tier landscape changed - Most traditional hosts now require cards

  2. Delete > Debug for cache issues - Sometimes faster to recreate than troubleshoot (serverless)

  3. Incremental debugging wins - Add logging, deploy, test, repeat

  4. Committee feedback valuable - Concurrency issue caught by reviewers, not dev testing

Architecture Decisions

When to Use Serverless (Vercel):

:white_check_mark: Public demos and MVPs
:white_check_mark: Open-source projects
:white_check_mark: No budget for hosting
:white_check_mark: Want zero maintenance
:white_check_mark: Need auto-scaling

When to Use Express Server:

:white_check_mark: Enterprise deployments
:white_check_mark: Need full infrastructure control
:white_check_mark: Existing VPS/Docker setup
:white_check_mark: Compliance requirements
:white_check_mark: High-traffic production apps

Best Practice: Maintain both! They share 90% of the code (CKB service logic), only HTTP layer differs.


Architecture Comparison

Aspect Serverless (Vercel) Express Server
Deployment Git push → auto-deploy Manual deploy/PM2/Docker
Scaling Automatic Manual/cluster mode
Cost Free tier (100k requests) VPS: $5-50/month
Maintenance Zero OS updates, security
Debugging Vercel logs Direct SSH access
Concurrency Parallel functions Node cluster/workers
Cold Starts None (edge network) N/A
File Storage Ephemeral Persistent disk
WebSockets Not supported Fully supported
Long Requests 10s timeout No timeout

Final Status: :white_check_mark: RESOLVED

All issues resolved across both deployment options:

Serverless (Production)

  • Submission: :white_check_mark: Working - transactions confirmed on CKB testnet

  • Verification: :white_check_mark: Working - hashes retrieved from blockchain

  • Performance: <2s response times, no cold starts

  • Reliability: No concurrency conflicts with CCC

  • Cost: $0/month on Vercel free tier

Express (Self-Hosting)

  • Submission: :white_check_mark: Working - identical CKB logic

  • Verification: :white_check_mark: Working - same search algorithm

  • Performance: <500ms response times (VPS dependent)

  • Reliability: Stable with PM2/Docker

  • Cost: VPS cost (~$5-20/month)

Live URLs:


Recommendation for New Deployments

Start with Serverless (Vercel):

  1. Free to deploy and test

  2. Zero maintenance overhead

  3. Perfect for demos and MVPs

  4. Easy to migrate to Express later if needed

Migrate to Express when:

  • Need WebSocket support

  • Require >10s request processing

  • Have compliance/security requirements

  • Want full infrastructure control

  • Already have VPS infrastructure

The code is portable - both versions share the same CKB service logic, making migration straightforward in either direction.

3 Likes

遇到的问题与解决方案

本文档记录了 HashThis 部署过程中遇到的所有主要技术挑战及其解决方案。


问题 1:Lumos 并发问题

报告者: @oiclid
日期: 2026年2月28日

问题描述

原始实现使用了 @ckb-lumos/lumos SDK,当多个用户同时提交交易时存在潜在的并发问题。

根本原因

Lumos 的交易构建过程并非为无服务器环境中的并发操作而设计,在该环境中多个函数实例并行处理请求。

解决方案

从 Lumos 迁移到 @ckb-ccc/core(通用链连接器):

  • CCC 内置并发处理

  • 更简单的 API,自动输入收集(completeInputsByCapacity

  • CKB DevRel 团队官方推荐

  • 积极维护和更好的 TypeScript 支持

对部署选项的影响

此迁移使两种部署架构受益:

  • 无服务器(Vercel): 多个函数实例现在可以并发运行而不会冲突

  • Express 服务器: 在单服务器或集群服务器上安全处理多个并发请求

更改的文件

  • api-backend/api/hashes/ckb.service.ts - 使用 CCC 的无服务器版本

  • backend/src/services/ckb.service.ts - 使用 CCC 的 Express 版本

  • 两个 package.json 文件 - 用 CCC 替换 Lumos 依赖


问题 2:Cell 容量计算错误

日期: 2026年2月15日

问题描述

InsufficientCellCapacity: expected 0x25a01c500 <= capacity 0x2540be400

根本原因

初始容量设置为 100 CKB,但最小要求为 101 CKB(53 字节锁脚本 + 8 字节容量 + 40 字节数据)。

解决方案

将容量增加到 110 CKB 以提供余量:

const ANCHOR_CAPACITY = BigInt("11000000000"); // 110 CKB(以 shannons 为单位)

应用范围

  • :white_check_mark: 无服务器后端(api-backend/api/hashes/ckb.service.ts

  • :white_check_mark: Express 后端(backend/src/services/ckb.service.ts


问题 3:生产构建 TypeScript 错误

日期: 2026年2月17日

问题描述

error TS1470: The 'import.meta' meta-property is not allowed in CommonJS output
error TS2339: Property 'SECP256K1_BLAKE160_SIGHASH_ALL' does not exist

根本原因

  • import.meta.url 与 Koyeb 的 buildpack 不兼容

  • 无效的 Lumos 脚本类型回退

  • 错误的 TypeScript 模块配置

解决方案

  1. registry.ts 中将 import.meta.url 替换为 process.cwd()

  2. 删除不存在的 SECP256K1_BLAKE160_SIGHASH_ALL 回退

  3. 更新 tsconfig.json

    {  "module": "ESNext",  "moduleResolution": "Bundler"}
    
    
  4. 将构建依赖项从 devDependencies 移至 dependencies

部署背景

这些修复对于基于服务器的部署(Koyeb、Render、Railway)是必需的。Vercel 上的无服务器版本有不同的要求,导致了问题 4。


问题 4:免费托管服务要求

日期: 2026年2月17日

问题描述

所有主要的免费服务器托管提供商都需要信用卡,即使是免费套餐。

尝试的服务(传统服务器托管)

  1. Koyeb :cross_mark: - 初始试用后需要信用卡

  2. Render :cross_mark: - 注册需要信用卡

  3. Railway :cross_mark: - 预先需要信用卡

  4. Cyclic、Fl0、Adaptable :cross_mark: - 服务关闭或不可靠

决策点:服务器 vs 无服务器

这个障碍导致了一个关键的架构决策:

选项 A:继续使用 Express 服务器

  • 优点:熟悉的架构、完全控制、适用于任何 VPS

  • 缺点:需要付费托管或自有基础设施

  • 最适合:企业、自托管、有预算的长期项目

选项 B:迁移到无服务器

  • 优点:提供免费套餐(Vercel)、零维护、自动扩展

  • 缺点:不同的架构、学习曲线

  • 最适合:演示、MVP、开源项目

选择的解决方案

主要:Vercel 无服务器(无需信用卡)

  • 无需信用卡

  • 前端已有 Vercel 账户

  • 慷慨的免费套餐(100GB 带宽、100k 次调用)

  • 边缘部署无冷启动

  • 内置 CORS 和路由

次要:保留 Express 后端 供喜欢传统服务器的用户使用

  • 保留 backend/ 文件夹和 Express 实现

  • 两者使用相同的 CKB 服务逻辑

  • 用户可以在自己的 VPS/Docker 上自托管

结果

双重部署支持:

  • api-backend/ - Vercel 的无服务器函数

  • backend/ - 传统托管的 Express 服务器


问题 5:Vercel 无服务器架构转换

日期: 2026年2月27-28日

问题描述

Express.js 后端与 Vercel 的无服务器架构不兼容。

挑战

  1. 单体 Express 应用 → 拆分为单独的无服务器函数

  2. 共享服务代码 → 最初在单独的 /services 目录中

  3. ESM 导入路径 → Vercel 中需要 .js 扩展名

  4. 模块解析 → 无服务器上下文中的不同路径行为

解决方案

创建新的 api-backend/ 目录,采用无服务器结构:

api-backend/
├── api/
│   └── hashes/
│       ├── index.ts          # POST 处理程序(替换 Express 路由)
│       ├── [hash].ts         # GET 处理程序(替换 Express 路由)
│       └── ckb.service.ts    # 共享 CKB 逻辑
└── vercel.json               # 函数配置

关键架构变化:

  • Express 版本: 集中式路由器和中间件链

  • 无服务器版本: 每个端点的独立处理函数

代码对比:

Express(backend/src/controllers/hash.controller.ts):

export const submitHash = async (req: Request, res: Response) => {
  const result = await ckbService.submitHash(req.body);
  res.json(result);
};

无服务器(api-backend/api/hashes/index.ts):

export default async function handler(req: VercelRequest, res: VercelResponse) {
  res.setHeader('Access-Control-Allow-Origin', process.env.CORS_ORIGIN || '*');
  const result = await ckbService.submitHash(req.body);
  res.json(result);
}

为什么保留两者?

  • 无服务器: 生产部署(免费、可扩展、零维护)

  • Express: 开发、自托管、企业部署


问题 6:CCC API 类型不匹配

日期: 2026年2月28日

问题系列

CCC 类型系统在仅无服务器版本中出现多个 TypeScript 错误(Express 版本运行正常)。

6a. 脚本参数类型

error TS2345: Argument of type 'string' is not assignable to parameter of type 'ScriptLike'

解决方案: 使用类型断言 (this.client.findCellsByLock as any) 绕过严格类型检查

6b. 缺少属性

error TS2339: Property 'address' does not exist on type 'Address'
error TS2339: Property 'blockNumber' does not exist on type 'Cell'

解决方案:

  • getRecommendedAddressObj().address 改为 getRecommendedAddress()

  • 通过 client.getTransaction() 单独获取区块号

6c. findCellsByLock 崩溃

Cannot read properties of undefined (reading 'startsWith')

在 CCC 库的 bytesFrom

根本原因: addressObj.script 有未定义的字段,CCC 无法在无服务器环境中解析

最终解决方案:findCellsByLock 切换到 findTransactions

// 旧方法(在无服务器中失败)
const cellIterator = this.client.findCellsByLock(addressObj.script, "asc");

// 新方法(在任何地方都有效)
const address = await signer.getRecommendedAddress();
for await (const tx of this.client.findTransactions(address)) {
  const txWithStatus = await this.client.getTransaction(tx.txHash);
  // 检查 transaction.outputsData
}

为什么只在无服务器中出现?

Express 版本没有遇到这些问题,因为:

  • Vercel 运行时中的 Node.js 版本不同

  • 模块解析行为不同

  • 加载的 CCC 类型定义不同

应用范围

  • :white_check_mark:api-backend/api/hashes/ckb.service.ts 中修复(无服务器)

  • :white_check_mark: 主动应用到 backend/src/services/ckb.service.ts(Express)以保持一致性


问题 7:Vercel 部署缓存

日期: 2026年2月28日

问题描述

更新的代码未部署 - 即使在 git push 后,Vercel 仍使用缓存的构建。

症状

  • Git 在本地显示正确的代码

  • Vercel Source 标签显示旧代码

  • 运行时错误引用旧行号

尝试的解决方案

  1. :white_check_mark: 空提交:git commit --allow-empty -m "force rebuild"

  2. :white_check_mark: 在 Vercel UI 中清除构建缓存

  3. :white_check_mark: 删除并重新创建 Vercel 项目

  4. :cross_mark: 安装命令更改 - 没有帮助

最终解决方案

从头删除并重新创建 Vercel 项目,确保:

  • 根目录正确设置为 api-backend

  • 在首次部署前添加环境变量

  • 没有现有构建缓存干扰

Express 用户的教训

传统服务器部署(PM2、Docker、systemd)没有此缓存问题 - 这是直接部署控制的自托管优势之一。


问题 8:Cell 数据验证

日期: 2026年2月28日

问题描述

Cannot read properties of undefined (reading 'startsWith')

verifyHash 函数中

根本原因

cell.outputData 可能是 undefined,但代码在调用 .includes() 之前没有检查

解决方案

添加空值检查:

const cellData = cell.outputData;

if (!cellData) {
  console.log('[CKB] Cell has no outputData, skipping');
  continue;
}

if (cellData.includes(cleanSearchHash)) {
  // 处理匹配
}

应用范围

  • :white_check_mark: 无服务器后端(api-backend/api/hashes/ckb.service.ts

  • :white_check_mark: Express 后端(backend/src/services/ckb.service.ts


经验教训

技术方面

  1. 无服务器 ≠ 传统后端 - 状态、导入和执行的不同思维模型

  2. CCC > Lumos 用于新项目 - 更好的 API、并发性和支持(使两种架构受益)

  3. 有时需要类型断言 - CCC 类型仍在发展中,务实的 as any 是可以接受的

  4. 生产前本地测试 - Vercel CLI 的 vercel dev 对无服务器调试至关重要

  5. 无服务器中的 ESM 需要 .js 扩展名 - Vercel 与传统服务器中的 Node 解析规则不同

  6. 保持两个选项可用 - 无服务器用于演示,Express 用于企业

流程方面

  1. 免费套餐格局已改变 - 大多数传统主机现在需要信用卡

  2. 删除 > 调试缓存问题 - 有时重新创建比故障排除更快(无服务器)

  3. 增量调试获胜 - 添加日志、部署、测试、重复

  4. 委员会反馈有价值 - 并发问题由审阅者发现,而非开发测试

架构决策

何时使用无服务器(Vercel):

:white_check_mark: 公开演示和 MVP
:white_check_mark: 开源项目
:white_check_mark: 没有托管预算
:white_check_mark: 需要零维护
:white_check_mark: 需要自动扩展

何时使用 Express 服务器:

:white_check_mark: 企业部署
:white_check_mark: 需要完全的基础设施控制
:white_check_mark: 现有 VPS/Docker 设置
:white_check_mark: 合规要求
:white_check_mark: 高流量生产应用

最佳实践: 同时维护两者!它们共享 90% 的代码(CKB 服务逻辑),只有 HTTP 层不同。


架构对比

方面 无服务器(Vercel) Express 服务器
部署 Git push → 自动部署 手动部署/PM2/Docker
扩展 自动 手动/集群模式
成本 免费套餐(100k 请求) VPS:$5-50/月
维护 OS 更新、安全
调试 Vercel 日志 直接 SSH 访问
并发 并行函数 Node 集群/工作进程
冷启动 无(边缘网络) N/A
文件存储 临时 持久磁盘
WebSockets 不支持 完全支持
长请求 10秒超时 无超时

最终状态::white_check_mark: 已解决

两种部署选项的所有问题均已解决:

无服务器(生产)

  • 提交: :white_check_mark: 工作中 - 在 CKB 测试网上确认交易

  • 验证: :white_check_mark: 工作中 - 从区块链检索哈希

  • 性能: <2秒响应时间,无冷启动

  • 可靠性: CCC 无并发冲突

  • 成本: Vercel 免费套餐 $0/月

Express(自托管)

  • 提交: :white_check_mark: 工作中 - 相同的 CKB 逻辑

  • 验证: :white_check_mark: 工作中 - 相同的搜索算法

  • 性能: <500毫秒响应时间(取决于 VPS)

  • 可靠性: 使用 PM2/Docker 稳定

  • 成本: VPS 费用(约 $5-20/月)

在线 URL:


新部署建议

从无服务器(Vercel)开始:

  1. 免费部署和测试

  2. 零维护开销

  3. 非常适合演示和 MVP

  4. 以后需要时易于迁移到 Express

何时迁移到 Express:

  • 需要 WebSocket 支持

  • 需要 >10秒的请求处理

  • 有合规/安全要求

  • 需要完全的基础设施控制

  • 已有 VPS 基础设施

代码是可移植的 - 两个版本共享相同的 CKB 服务逻辑,使任一方向的迁移都变得简单。

3 Likes

Hi @oiclid,

Thanks for the CCC migration. The committee has completed its functional review. The core flow works, but we found two issues that must be addressed before completion.

Issue 1: Timestamp integrity (Critical)
The timestamp recorded on-chain is user-editable, set client-side before submission rather than derived from the block time.


This undermines the project’s core premise. A “proof of existence” whose timestamp can be arbitrarily set by the submitter proves nothing.

Issue 2: Unsustainable fee model (Important)
All transaction fees and cell capacity costs are paid by the project’s server-side wallet. This will collapse on mainnet.

At minimum, integrate a wallet connection flow (CCC supports this) so users sign and pay for their own transactions. Alternatively, a Merkle tree approach would reduce per-user cost significantly.

Hi @oiclid
感谢您及时完成了 CCC 迁移。委员会已完成功能审查。核心流程可以运行,但有两个问题需要在结项前解决。

问题 1:时间戳完整性(严重)
链上记录的时间戳是用户可编辑的,在提交前由客户端设置,并非来源于区块时间。

这动摇了项目的核心前提。一个时间戳可以被提交者任意设定的"存在性证明",什么也证明不了。

问题 2:不可持续的费用模型(重要)
所有交易费用和 cell 容量成本均由项目服务端钱包承担,部署到主网会很快停摆。
至少应集成钱包连接(CCC 已支持),让用户自行签名付费。或者采用默克尔树方案,也能大幅降低单用户成本。

Best,
zz
On behalf of Spark Program Committee

cc @Hanssen @yixiu.ckbfans.bit @xingtianchunyan

5 Likes

I’m on it. I’ll go with the walket for know as i think that should be easier to implement.

3 Likes

HashThis: Fix Report

Timestamp Integrity & Sustainable Fee Model


What I Set Out to Do

HashThis is a proof-of-existence dApp built on Nervos CKB. It lets users anchor a SHA-256 file hash on-chain as permanent, tamper-proof evidence that a file existed at a specific point in time. After completing the initial CCC SDK migration, the committee’s functional review flagged two critical issues that needed to be resolved before the project could be signed off.


The Issues

Issue 1 — Forged Timestamps (Critical)

The most fundamental problem: the timestamp recorded on-chain was coming from the client. The frontend sent a timestamp field in the request body, the backend accepted it without question, and it was encoded directly into the cell data on-chain. Anyone who knew how the API worked could set the timestamp to any date they wanted — past or future — making the entire proof-of-existence concept meaningless.

Issue 2 — Server Wallet Paying for Everything (Important)

Every transaction was being signed and paid for by a single server-side wallet funded with testnet CKB. On testnet this was workable, but on mainnet it would drain quickly and create a centralised payment bottleneck. The project needed users to sign and pay for their own transactions.


How I Solved It

Fix 1 — Server-Side Timestamps

The fix was straightforward once the problem was understood: remove timestamp from the API contract entirely. The field was deleted from the HashPayload TypeScript interface so the compiler would reject any future attempt to pass it in. Inside CKBService.submitHash(), the timestamp is now generated with new Date().toISOString() at the moment the server processes the request. The client has no influence over it whatsoever.

This was applied to both backends — the Vercel serverless functions (api-backend) and the Express server (backend).

Fix 2 — User Wallet Signs and Pays

This required a more significant architectural change. The flow was redesigned from:

client sends hash → server builds tx → server signs → server pays → server broadcasts

To:

client connects wallet → client sends hash + address → server builds unsigned tx → client wallet completes inputs, pays fees, signs → client broadcasts

A new POST /hashes/build endpoint was added to both backends. It accepts a fileHash and userAddress, encodes the hash with a server-generated timestamp, locks the output cell to the user’s address, and returns the unsigned transaction shell. The frontend — using the CCC connector — then completes the transaction and the user’s wallet handles signing and payment.

The server wallet is now completely out of the user transaction flow.

Fix 3 — Verification

Once cells were locked to user addresses instead of the server wallet, the verify endpoint also needed updating. It was previously searching cells under the server’s lock script, which meant it would never find anything anchored through the new flow. The fix was to pass userAddress as a query parameter from the frontend so the backend searches the right lock script.


Issues Encountered Along the Way

Getting to a working state involved a fair number of environmental obstacles:

  • CCC API mismatch — the connector package exported Provider, not CccProvider, and useCcc() returned signerInfo not signer directly. The code had to be adjusted to match the actual installed version.

  • Node polyfills in Vite@ckb-ccc/core uses Node built-ins (process, buffer, stream) that aren’t available in the browser by default. This required adding vite-plugin-node-polyfills.

  • Conflicting wallet extensions — OneKey and MetaMask were fighting over window.ethereum in the browser, causing noisy console errors. These were harmless but distracting.

  • Stale Vercel deployments — several times the live site was serving old code while local was already fixed, which caused confusion about whether fixes were working.

  • Fee rate too low — the initial fee rate of 1000 shannons/KW produced a 374-shannon fee, below the 504-shannon minimum required by the network. Bumping to 1500 shannons/KW resolved it.

  • Vercel routing — the vercel.json route for [hash].ts wasn’t forwarding the captured path segment as a query parameter, so req.query.hash was always undefined. Adding ?hash=$1 to the dest fixed it.

  • Accidental file corruption — a grep command was accidentally appended to api.ts during editing, causing a TypeScript syntax error on Vercel’s build.


Lessons Learned

Lock your API contract with types. Removing timestamp from HashPayload meant the TypeScript compiler became the enforcer — no future developer could accidentally reintroduce the vulnerability without the build failing.

Don’t trust the client with anything that affects integrity. It sounds obvious, but the original code accepted a timestamp from the client because it was convenient. The rule of thumb: if a value affects what gets written on-chain, the server owns it.

Test on the actual deployed environment early. A lot of time was spent debugging issues that only appeared on Vercel — stale builds, missing environment variables, routing config. Catching these earlier would have saved cycles.

Package versions matter more than you think. The CCC SDK is actively developed and the API changes between versions. Always check what’s actually exported by the installed version rather than assuming the docs match.

Fee rates need headroom. Setting a fee rate at exactly the minimum is fragile. A small transaction weight miscalculation drops you below the threshold. Adding 50% headroom is cheap and avoids pool rejections.



HashThis:修复报告

时间戳完整性与可持续费用模型


项目目标

HashThis 是一个基于 Nervos CKB 构建的存在性证明 dApp。它允许用户将文件的 SHA-256 哈希值锚定到链上,作为文件在特定时间点存在的永久、防篡改证据。在完成初始 CCC SDK 迁移后,委员会的功能审查发现了两个关键问题,需要在项目最终验收前解决。


发现的问题

问题一 — 伪造时间戳(严重)

最根本的问题:链上记录的时间戳来自客户端。前端在请求体中发送 timestamp 字段,后端不加验证地接受,并将其直接编码到链上的 Cell 数据中。任何了解 API 工作原理的人都可以将时间戳设置为任意日期——过去或未来——这使得整个存在性证明的概念失去意义。

问题二 — 服务器钱包支付所有费用(重要)

每笔交易都由一个由测试网 CKB 资助的服务器端钱包签名并支付。在测试网上这是可行的,但在主网上会很快耗尽资金,并形成中心化的支付瓶颈。项目需要用户自己签名并支付交易费用。


解决方案

修复一 — 服务器端时间戳

一旦理解了问题,修复方案就很直接:完全从 API 合约中删除 timestamp。该字段从 HashPayload TypeScript 接口中删除,这样编译器会拒绝任何未来尝试传入该字段的行为。在 CKBService.submitHash() 内部,时间戳现在在服务器处理请求时通过 new Date().toISOString() 生成,客户端对此毫无影响。

此修复应用于两个后端——Vercel 无服务器函数(api-backend)和 Express 服务器(backend)。

修复二 — 用户钱包签名并支付

这需要更重大的架构变更。流程从:

客户端发送哈希 → 服务器构建交易 → 服务器签名 → 服务器支付 → 服务器广播

重新设计为:

客户端连接钱包 → 客户端发送哈希+地址 → 服务器构建未签名交易 → 客户端钱包完成输入、支付费用、签名 → 客户端广播

两个后端都新增了 POST /hashes/build 端点。它接受 fileHashuserAddress,使用服务器生成的时间戳编码哈希,将输出 Cell 锁定到用户的地址,并返回未签名的交易框架。前端使用 CCC 连接器完成交易,用户钱包处理签名和支付。

服务器钱包现在完全不参与用户交易流程。

修复三 — 验证功能

一旦 Cell 锁定到用户地址而非服务器钱包,验证端点也需要更新。之前它在服务器的锁定脚本下搜索 Cell,这意味着通过新流程锚定的内容永远找不到。修复方案是从前端将 userAddress 作为查询参数传递,让后端搜索正确的锁定脚本。


过程中遇到的问题

在达到可工作状态的过程中遇到了相当多的环境障碍:

  • CCC API 不匹配 — 连接器包导出的是 Provider 而非 CccProvideruseCcc() 返回的是 signerInfo 而非直接返回 signer。代码需要调整以匹配实际安装的版本。

  • Vite 中的 Node 垫片@ckb-ccc/core 使用了浏览器中默认不可用的 Node 内置模块(processbufferstream)。这需要添加 vite-plugin-node-polyfills

  • 钱包扩展冲突 — OneKey 和 MetaMask 在浏览器中争夺 window.ethereum,产生了大量控制台错误。这些错误无害但令人分心。

  • 过期的 Vercel 部署 — 多次出现线上服务提供旧代码而本地已修复的情况,导致对修复是否生效产生混淆。

  • 费率过低 — 初始费率 1000 shannons/KW 产生 374 shannon 的费用,低于网络要求的 504 shannon 最低值。将费率提高到 1500 shannons/KW 解决了问题。

  • Vercel 路由配置vercel.json[hash].ts 的路由没有将捕获的路径段作为查询参数转发,导致 req.query.hash 始终为 undefined。在目标路径中添加 ?hash=$1 解决了此问题。

  • 文件意外损坏 — 编辑过程中 grep 命令被意外追加到 api.ts,导致 Vercel 构建时出现 TypeScript 语法错误。


经验教训

用类型锁定 API 合约。HashPayload 中删除 timestamp 意味着 TypeScript 编译器成为执行者——未来任何开发者都无法在不导致构建失败的情况下意外重新引入该漏洞。

不要信任客户端提供任何影响完整性的内容。 听起来显而易见,但原始代码之所以接受客户端的时间戳,是因为这样做很方便。经验法则:如果一个值影响链上写入的内容,服务器应该拥有它。

尽早在实际部署环境中测试。 很多时间花在调试只在 Vercel 上出现的问题——过期构建、缺失环境变量、路由配置。早点发现这些问题会节省很多时间。

包版本比你想象的更重要。 CCC SDK 正在积极开发,API 在版本之间会发生变化。始终检查已安装版本实际导出的内容,而不是假设文档与之匹配。

费率需要留有余量。 将费率设置为恰好等于最低值是脆弱的。微小的交易权重计算误差就会让你低于阈值。增加 50% 的余量成本低廉,却能避免交易池拒绝。
@zz_tovarishch @Hanssen @yixiu.ckbfans.bit @xingtianchunyan

2 Likes

The link is still https://hash-this.vercel.app. Thanks.

2 Likes