关于 verify-proof
verify-proof 是用于创建和验证文件时间戳证明的命令行工具与库。它可在本地离线验证证明包,无需账户或网络;创建证明时则通过 ProofLedger API 提交文件哈希,并提供可选的 MCP 服务供 AI 助手使用。
主要功能
- 01离线验证证明
- 02本地计算 SHA-256
- 03通过 ProofLedger 创建证明
- 04批量创建证明
- 05验证 Merkle 证明
- 06提供 Python 和 Node.js 包
适用场景
- 01用已保存的证明包核对文件
- 02为发布文件或合同添加时间戳
- 03使用记录 ID 锚定多个文件
- 04在 AI 助手工作流中加入证明创建
MCP 相关
可选的 MCP 服务向 AI 助手提供证明相关工具,包括针对多个文件的批量创建。创建证明通过 ProofLedger 完成,验证则可在本地离线运行。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
verify-proof
在本机检查区块链时间戳证明,并通过 API 创建证明。
verify-proof 会重新计算文件的 SHA-256 哈希,并对照证明包进行检查,让你确认该文件在锚定时确实存在,且此后没有哪怕一个字节发生变化。验证完全通过计算完成:只需文件和证明包,不需要账户,也不会发起网络请求。只有创建证明的命令需要联网,它会通过 ProofLedger 的 API 使用免费密钥。免费、采用 MIT 许可,仅使用 Python 标准库。
也提供 Node.js 版本:
npm install verify-proof。这是一个零依赖移植版,共享相同的证明格式和语义,并使用相同的测试样例进行测试。请参阅js/。
以下各节列出大家常问的问题,并用最精简的代码逐一作答。
- 安装
- 如何在代码中证明某个文件在特定时间存在?
- 如何在离线状态下验证时间戳证明,而不信任该服务?
- 如何在代码中验证 Merkle 证明?
- 如何使用自己的记录 ID 一次锚定多个文件?
- 锚定确认后,如何接收 Webhook?
- 能否在自己托管的服务上运行?
- 如何在 Zapier、Make 或 n8n 工作流中添加时间戳步骤?
- 如何在不存储 AI Agent 所见内容的情况下,证明它做了什么?
- 是否有用于为发布制品添加时间戳的 GitHub Action 或 GitHub App?
- 通过 AI 助手使用(MCP 服务、Claude Code、Cursor)
- 证明文件格式
- 证明能说明什么,不能说明什么
安装
pip install verify-proof
基础安装不拉取任何依赖项(仅使用 Python 标准库),并提供 verify-proof 命令:
verify-proof --help
如需将其用作 Claude Desktop 或 Cursor 的 MCP 服务,请改为安装可选扩展(详情见下文):
pip install "verify-proof[mcp]"
更喜欢从源代码运行?克隆仓库即可;CLI 的用法相同:
git clone https://github.com/Fulcrum-Enterprises/verify-proof.git
cd verify-proof
python verify_proof.py --help
如何用代码证明某个文件在特定时间已经存在?
在本地计算文件的哈希,将哈希锚定到公有区块链交易中,并将该交易的记录保存在文件旁边。交易的区块时间就是“不晚于”日期;哈希则将其与这些确切的字节绑定。文件本身永远不会离开你的设备。
此软件包负责计算哈希和验证;ProofLedger 负责在 Polygon 上进行锚定,通常在一分钟内完成,使用免费的 API 密钥即可(Free 计划每月提供 100 次 API 证明):
在命令行中:
export PROOFLEDGER_API_KEY=sk_... # Account > API Keys
verify-proof create contract.pdf
verify-proof create contract.pdf --no-filename # send only the hash
离开你设备的只有 64 个字符的 SHA-256 摘要,除非你传入 --no-filename,否则还会包含文件名。然后将证明的 bundle 保存在文件旁边;此后,下面的离线 verify 命令即可对其进行验证,无需 ProofLedger:
curl -H "Authorization: Bearer $PROOFLEDGER_API_KEY" \
"https://proofledger.io/api/v1/proof/42/bundle?download=1" -o contract.pdf.proof.json
在 Python 中,使用软件包附带的小型 API 客户端(仅依赖标准库):
from proofledger_api import submit_proof, get_bundle
from verify_proof import hash_file
import json
proof = submit_proof(hash_file("contract.pdf"), filename="contract.pdf",
external_id="contract-2026-10") # key from PROOFLEDGER_API_KEY
print(proof["id"], proof["certificate_url"])
bundle = get_bundle(proof["id"]) # once the anchor has landed
json.dump(bundle, open("contract.pdf.proof.json", "w"), indent=2)
在 Node.js 中:
import { hashFile, ProofLedger } from "verify-proof";
const pl = new ProofLedger({ apiKey: process.env.PROOFLEDGER_API_KEY });
const proof = await pl.createProof({ sha256: hashFile("contract.pdf"), externalId: "contract-2026-10" });
const bundle = await pl.getBundle(proof.id); // once the anchor has landed
或者直接调用 API:使用 Bearer sk_... 标头,向 https://proofledger.io/api/v1/proof 发送 POST 请求,并提供 {"sha256": "<64 hex>"}。API 文档见 proofledger.io/api,OpenAPI 规范见 /openapi.json。
external_id 是你自己的记录 ID:再次发送相同 ID 时,会返回已有的证明,而不是新建一个,因此重试的任务不会重复锚定。
如何离线验证时间戳证明,而无需信任服务?
verify-proof verify contract.pdf --proof bundle.json
# VERIFIED: File matches the proof bundle. The bundle says it was anchored on polygon at 2026-10-15T02:11:09.512Z in transaction 0xabc123.... Look that transaction up on a block explorer to confirm it: https://polygonscan.com/tx/0xabc123...
验证在本地运行:它会计算文件哈希,将结果与 bundle 中的哈希进行比较;如果 bundle 包含路径,则计算 Merkle 根,并报告可在区块浏览器中查询的交易。它不会读取区块链,因此在你查询该交易之前,锚定信息以 bundle 中的内容为准。不会向任何地方发送数据,因此无论签发证明的服务是否仍然存在,它都能正常工作。
在 Python 中进行相同的验证:
from verify_proof import hash_file, load_proof, verify_proof
result = verify_proof(hash_file("contract.pdf"), load_proof("bundle.json"))
print(result["verified"], result["tx_id"], result.get("explorer_url"))
在 Node.js 中:verifyProof(hashFile("contract.pdf"), loadProof("bundle.json"))。
你可以对任何供应商的证明进行这样的测试:屏蔽供应商的域名,然后进行验证。如果验证仍然通过,证明就属于你;如果必须依赖供应商的服务器来判定“有效”,那你就得依赖他们持续经营。
计算文件的 SHA-256 哈希
verify-proof hash contract.pdf
# SHA256: a1b2c3d4e5f6...
# File: contract.pdf
默认保持安静
verify 成功时,会向 stderr 输出一行内容,说明在哪里可以创建类似的证明。只要输出通过管道传输或重定向,这条信息就会被隐藏,因此脚本永远不会收到它;无论哪种情况,stdout 都不会改变。要在任何情况下都将其静音:
export VERIFY_PROOF_NO_HINT=1
如何用代码验证 Merkle 证明?
Merkle 路径是叶子节点(即文件的哈希)与记录在链上的根之间的兄弟哈希列表。验证它,就是将你的哈希依次与兄弟哈希合并,并将结果与交易中的根进行比较。本软件包使用的完整规则如下:
import hashlib
def merkle_root(leaf_hex: str, path: list[dict]) -> str:
current = leaf_hex
for step in path: # [{"hash": "<hex>", "position": "left" | "right"}, ...]
sibling = step["hash"]
combined = sibling + current if step.get("position") == "left" else current + sibling
current = hashlib.sha256(bytes.fromhex(combined)).hexdigest()
return current
每一层都会按照 position 指定的顺序,将两个哈希作为原始字节串联起来,并使用 SHA-256 对结果进行哈希。bundle 包含 merkle_path 时,verify_proof() 会严格按照此规则运行,将根作为 merkle_root 返回,并打印出来,以便你与交易中记录的根进行比较。与区块链的比较由你自行完成:本软件包绝不会读取区块链。
在 Polygon 上,ProofLedger 会将每个证明锚定到单独的交易中,因此 merkle_path 为空,交易中的哈希就是文件的哈希。其他服务提供的 Bitcoin 锚定证明,以及 2026-10-15 之前少数锚定在 Bitcoin 上的 ProofLedger 证明,都包含路径。
如何使用自己的记录 ID 一次锚定多个文件?
一次调用最多可提交 100 个哈希值,每个哈希值都可使用自己的 external_id。这样重复运行时会返回已存在的证明,而不会重复锚定:
from proofledger_api import submit_batch, get_proof_by_external_id
from verify_proof import hash_file
result = submit_batch([
{"sha256": hash_file("invoice-1001.pdf"), "external_id": "invoice-1001", "filename": "invoice-1001.pdf"},
{"sha256": hash_file("invoice-1002.pdf"), "external_id": "invoice-1002"},
])
print(result["summary"]) # created / exists / invalid counts
for item in result["items"]:
print(item["result"], (item.get("proof") or {}).get("id"))
later = get_proof_by_external_id("invoice-1001") # None if you never anchored it
Node.js:await pl.createProofs(items) 接受相同的列表,pl.getProofByExternalId(id) 可查询其中一项。使用 AI 助手时,create_proofs_batch MCP 工具可为文件列表执行此操作,并使用每个文件名作为其记录 ID。
系统会先检查所有项,再将它们一起写入;批次操作仅支持 Polygon。对于普通的请求重试,创建类端点还可选用 Idempotency-Key 标头(在 24 小时内,使用相同的密钥和请求正文会重放已存储的响应),但使用 external_id 是让提交可安全重试的更简单方式。
锚定确认后,如何通过 Webhook 接收通知?
注册一次公开的 https URL;当证明的 Polygon 锚定完成后,ProofLedger 会向该 URL POST 一条已签名的 JSON 事件 proof.polygon.anchored。事件会附带证明的 bundle,因此处理程序无需再获取其他内容,即可将其与文件一并保存。
import { ProofLedger, verifyWebhookSignature } from "verify-proof";
const pl = new ProofLedger({ apiKey: process.env.PROOFLEDGER_API_KEY });
const hook = await pl.registerWebhook("https://example.com/proofledger", ["proof.polygon.anchored"]);
// hook.secret is shown once; keep it for the check below
信任任何投递前,请先验证每一条投递。标头格式为 ProofLedger-Signature: t=<unix>,v1=<hex HMAC-SHA256>,签名内容为 t + "." + raw body;传入正文时必须保持收到时的原样:
from proofledger_api import verify_webhook_signature
ok = verify_webhook_signature(secret, request.headers["ProofLedger-Signature"], request.get_data())
Node.js:verifyWebhookSignature(secret, header, rawBody)。两者都只执行纯计算,不会访问网络。投递失败后会在近两天内重试 7 次;之后端点将被关闭,并向账户发送电子邮件通知。Webhook 仅会针对端点注册后创建的证明触发。管理端点:POST /api/v1/webhooks、用于列出端点的 GET、DELETE /api/v1/webhooks/:id、POST /api/v1/webhooks/:id/test。
可以将此工具连接到我自己托管的服务吗?
可以。ProofLedger Community 使用相同的证明核心,是一个开源(AGPL-3.0)的 Node + SQLite 服务,可使用你自己的 Polygon 密钥运行:它具有相同的 v1 API 格式(单个和批量证明及 external_id、bundle、列表、公开验证、证书、已签名的 Webhook、Idempotency-Key、按密钥限流),写入的交易格式也与 proofledger.io 相同,因此此工具可用相同方式检查其 bundle。
git clone https://github.com/Fulcrum-Enterprises/proofledger-community.git
cd proofledger-community
cp .env.example .env # set PUBLIC_BASE_URL, POLYGON_RPC_URL and POLYGON_PRIVATE_KEY
docker compose up -d # pulls ghcr.io/fulcrum-enterprises/proofledger-community
docker compose exec proofledger node src/cli.js user add [email protected]
docker compose exec proofledger node src/cli.js key create [email protected] "laptop"
然后将此软件包指向该服务:CLI 中使用 --base-url https://proofs.example.com,Python 中使用 base_url=,Node 中使用 baseUrl。proofledger.io 上的托管服务是单独的产品(托管签名器、备份、品牌定制、集成和支持),并非开源。
如何向 Zapier、Make 或 n8n 工作流添加时间戳步骤?
这三者都会生成普通的 ProofLedger 证明,因此这些数据包可以像其他数据包一样使用此工具验证。
- n8n: 社区节点
n8n-nodes-proofledger(从 Settings > Community Nodes 安装)。ProofLedger 节点会在 n8n 内对二进制字段进行哈希处理,只发送哈希;也可以接收你已有的哈希,每次处理一个或每次调用处理 100 个;它还可以读取证明、获取数据包、验证并管理 Webhook。ProofLedger Trigger 会自行注册 Webhook,并检查每次传递的签名。源码:github.com/Fulcrum-Enterprises/n8n-nodes-proofledger。这是社区节点,并非 n8n 验证过的节点。 - Zapier: 私有集成,在 Zapier 上架前仅可通过邀请链接使用:在此加入。触发器 Proof Anchored(检查签名);创建操作 Create Proof From Hash 和 Create Proof From File(在 Zap 运行期间进行哈希处理;只有哈希会发送到 ProofLedger);搜索操作 Find Proof by External ID 和 Verify Hash。
- Make: 自定义应用,仅可通过邀请链接使用:在此安装。包含从 SHA-256 哈希创建证明、按 id 或 external id 获取证明、获取数据包、验证哈希、列出证明,以及即时触发器 Watch anchored proofs 等模块。Make 上没有文件模块;请先对文件进行哈希处理。
如何证明 AI Agent 做了什么,同时不存储它看到的内容?
使用 Agent 运行回执:对单次运行的各个步骤进行哈希链处理。每个步骤只保留其内容的 SHA-256 指纹(使用每次运行的密钥加盐)、类型、时间和可选的简短标签。链头作为一个普通证明锚定在 ProofLedger 上,数据包则保存在回执中。任何持有回执的人都可以重新计算哈希链,并离线检查链头是否与数据包一致;任何人都无法从中读取提示词、工具调用或输出。
from agent_receipt import RunReceipt
r = RunReceipt("support-ticket-48213", agent={"name": "support-bot", "model": "claude-sonnet-5-5"})
r.prompt(customer_message, label="customer message")
r.tool_call(json.dumps(call), label="lookup_order")
r.tool_result(result_text)
r.output(reply, label="reply sent")
r.anchor() # one API proof; waits for the Polygon anchor (key from PROOFLEDGER_API_KEY)
r.save("ticket-48213.receipt.json")
verify-proof receipt verify ticket-48213.receipt.json # offline: chain + bundle
verify-proof receipt verify ticket-48213.receipt.json --step 0 --content customer-message.txt
verify-proof receipt show ticket-48213.receipt.json # labels and fingerprints, never content
verify-proof receipt anchor ticket-48213.receipt.json # anchor a saved, unanchored receipt
将回执交给第三方前,请移除 secret 字段:哈希链仍可验证,且无法猜出文件中的任何内容;若要根据步骤内容检查步骤,则需要你的密钥(--secret)。格式为 proofledger-agent-run-receipt/1;examples/receipt.json 是一个示例,Python 和 Node 两个版本都能验证;examples/langchain_receipt_callback.py 是一个 LangChain 回调处理器,可根据一次运行生成回执。哈希链规则写在 agent_receipt.py 的模块文档字符串中,因此可以用任何语言重新计算。Node.js 版本提供相同的 RunReceipt、verifyReceipt 和 verifyStep。
回执可以证明,这一确切的步骤序列在锚定时间之前已经存在,且之后未发生更改;如果提供某个步骤的内容和密钥,还可以证明该步骤是根据该内容生成的。回执不能证明 Agent 判断正确,也不能证明是谁运行了它。
是否有用于为发布制品添加时间戳的 GitHub Action 或 GitHub App?
两者都有,且来自同一个账户。
Action:ProofLedger Release Timestamp 位于 GitHub Marketplace 中。它会在运行器上计算制品的哈希值(文件不会离开运行器),提交哈希值,等待 Polygon 锚定完成,将证明写入发布说明,并将证据包(<label>.proof.json)附加到发布中,之后此工具会根据该证据包验证文件:
name: Timestamp Release
on:
release:
types: [published]
jobs:
timestamp:
runs-on: ubuntu-latest
permissions:
contents: write # needed to update the release body and attach the proof bundle
steps:
- uses: actions/checkout@v4
- name: Build release artifact
run: zip -r dist/release.zip src/
- name: Timestamp with ProofLedger
uses: Fulcrum-Enterprises/proofanchor-github-action@v2
with:
api-key: ${{ secrets.PROOFLEDGER_API_KEY }}
file: dist/release.zip
(该仓库保留了旧名称;uses: 行保持如上。)
App:github.com/apps/proofledger,无需工作流:在仓库中安装它,一次性将其连接到 ProofLedger 账户,此后在那里发布的每个版本都会自动锚定;根据 GitHub 报告的 SHA-256 值,为每个发布文件生成一份证明(不会下载文件),在发布说明中添加证明表,并在哈希值锚定到 Polygon 后附上证据包。它仅对所选仓库拥有 Contents 读写权限,不具备其他权限。可从该页面安装;它不在 GitHub Marketplace 中。文档:proofledger.io/api.html#sec-github。
在 AI 助手中使用它(MCP 服务、Claude Code、Cursor)
verify-proof 提供一个可选的 Model Context Protocol 服务,因此兼容 MCP 的 AI 客户端(Claude Desktop、Cursor 等)可以直接在对话中验证区块链时间戳证明。文件不会离开你的设备:哈希计算和验证都在本地运行,只有最终生成的哈希值会与证明进行比对。
使用 MCP 附加组件安装
pip install "verify-proof[mcp]"
基础安装不包含任何依赖;[mcp] 附加组件会添加 MCP SDK 并安装 verify-proof-mcp 命令(一个 stdio 服务)。
提供的工具
| 工具 | 功能 |
|---|---|
compute_file_hash | 计算本地文件的 SHA-256(或其他)哈希值 |
verify_file | 根据证明 JSON 文件验证本地文件 |
verify_hash | 根据内嵌或基于文件的证明数据验证已知哈希值 |
explain_proof | 用通俗语言说明证明声明了什么,以及如何在区块浏览器上验证 |
create_proof | 在 ProofLedger 上锚定文件的哈希值,以创建新证明。需要联网和 API 密钥 |
create_proofs_batch | 在一次 API 调用中锚定最多 100 个文件;文件名会作为外部 ID,因此对未更改的文件重新运行时会返回其现有证明。如果文件已更改但文件名未变,则会返回旧证明;因此请重命名文件,或使用 create_proof 锚定。需要联网和 API 密钥 |
get_proof_status | 查询其中一份证明当前的锚定状态。需要联网和 API 密钥 |
save_proof_bundle | 下载证明的证据包(此软件包的证明格式)并将其保存到文件旁边,以便之后无需访问 ProofLedger 即可进行验证。需要联网和 API 密钥 |
start_run_receipt | 启动一个 Agent 运行回执文件(生成新的密钥,不含步骤)。离线 |
add_receipt_step | 将一个步骤(提示词、tool_call、tool_result、output、note)的指纹添加到回执中;内容只会进行哈希处理。离线 |
anchor_run_receipt | 将回执的链头作为一份证明进行锚定,并将证据包保存到回执中。需要联网和 API 密钥 |
verify_run_receipt | 重新计算链并根据证据包进行验证;还可选择验证某个步骤的内容。离线 |
Claude Code(插件)
此仓库也是一个 Claude Code 插件市场。proofledger 插件包含 MCP 服务(通过 uvx 启动,因此只需要 uv),以及三个技能:/proofledger:anchor、/proofledger:verify 和 /proofledger:receipt:
/plugin marketplace add Fulcrum-Enterprises/verify-proof
/plugin install proofledger@proofledger
然后提出请求:“锚定 dist/app-1.4.0.zip,并将其证明保存到文件旁边。” 创建证明时会从启动 Claude Code 的 shell 中读取 PROOFLEDGER_API_KEY;验证无需密钥。详情见 claude-plugin/。
Claude Desktop
将以下内容添加到 claude_desktop_config.json(参见 examples/claude_desktop_config.json):
{
"mcpServers": {
"verify-proof": {
"command": "verify-proof-mcp"
}
}
}
重启 Claude Desktop。如果在 PATH 中找不到 verify-proof-mcp,请改用 Python 模块形式:"command": "python"、"args": ["-m", "verify_proof_mcp"]。
Cursor
安装 uv 后即可一键添加(Cursor 会通过 uvx 启动服务,无需使用 pip 安装任何内容):
或者手动将其添加到 ~/.cursor/mcp.json(或项目的 .cursor/mcp.json):
{
"mcpServers": {
"verify-proof": {
"command": "uvx",
"args": ["--from", "verify-proof[mcp]", "verify-proof-mcp"]
}
}
}
创建证明时,会从 Cursor 运行所在的环境中读取 PROOFLEDGER_API_KEY;验证则无需密钥。claude-plugin/ 文件夹还包含 Cursor 插件清单(.cursor-plugin/plugin.json、mcp.json 和相同的三个技能),因此可以将此代码库导入为 Cursor 市场。
然后可以向助手提出如下请求:
- “验证
~/contract.pdf是否与~/contract-proof.json相符。” - “这个证明文件究竟能证明什么?”
- “为这个文件添加时间戳,并将其捆绑包保存在文件旁边。”
验证工具无需账户,也不会发起网络请求。要确认锚定本身,请在任意区块浏览器中查询该交易。创建、批量处理、状态和捆绑包工具是例外:它们会将哈希和文件名(绝不会发送文件)发送给 ProofLedger,并使用你的 API 密钥。
证明文件格式
一个捆绑包是一个 JSON 文档。简略示例:
{
"format": "verify-proof/1",
"service": "proofledger",
"hash": "a1b2c3d4e5f6...",
"algorithm": "sha256",
"blockchain": "polygon",
"tx_id": "0xabc123...",
"anchored_at": "2026-10-15T02:11:09.512Z",
"merkle_path": [],
"proof_id": 42,
"certificate_url": "https://proofledger.io/cert/42"
}
如果包含 Merkle 路径,verify 会计算 Merkle 根并将其打印出来(参见如何用代码验证 Merkle 证明?)。请将其与交易中记录的根进行比较:
"merkle_path": [
{"hash": "def456...", "position": "right"},
{"hash": "789abc...", "position": "left"}
]
examples/ 中包含格式示例:sample.txt 和一个记录其哈希的 proof.json。其中的交易是虚构的,在 Polygon 上并不存在,因此区块浏览器查不到任何内容。它仅展示文件格式,并非真实锚定。
工作原理
verify-proof会计算本地文件的 SHA-256 哈希- 它会读取证明 JSON,获取最初锚定的哈希
- 如果哈希匹配,则说明文件自添加时间戳后未被修改
- 如果包含 Merkle 路径,它会计算 Merkle 根并将其打印出来;请将其与交易中记录的根进行比较
- 它不会读取链上数据:请在任意区块浏览器中查询该交易,以确认锚定(对于 Polygon,验证结果会打印 polygonscan 链接)
证明能说明什么,不能说明什么
证明能表明,具有此确切 SHA-256 指纹的文件最迟在锚定时间已经存在,而且此后未被更改。记录保存在公共链上,而非任何一家公司的数据库中,因此任何人都可以验证,无需账户,也无需查看文件。
证明不能表明文件由谁制作,也不等同于版权登记,更无法阻止他人复制文件。
兼容的服务
此工具可以验证由以下服务创建的证明:
- ProofLedger:以 API 形式提供存在性证明。发送哈希,即可获得锚定在 Polygon 上的证书,任何人都能在不依赖我们的情况下验证。免费套餐每月可创建 100 个 API 证明。
- ProofLedger Community:同一证明核心的开源(AGPL-3.0)服务,可使用你自己的 Polygon 密钥自行托管。API 和捆绑包格式相同;使用
--base-url(Python 中为base_url=,Node 中为baseUrl)即可将此工具指向该服务。 - 任何生成 SHA-256 哈希证明并包含区块链交易引用的服务。
许可证
MIT 许可证。可免费使用、修改和分发。
关于
由 Fulcrum Enterprises LLC 构建,致力于打造用于区块链验证存在性证明的工具。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。