锚定服务¶
本文是英文版本的参考译文,更新于2026年10月25日。如有差异,以英文原文为准。标识符和代码块(包括注释)均保留原文。
用于将 Citizenship Bundle 哈希锚定到 L2 区块链(Base、Arbitrum、Optimism)的 HTTP 服务,可单独锚定,也可在 Merkle 根下批量锚定。目前它只在本地记录这些哈希(见下方说明)。
尚未实现链上提交。 哈希和批次根在本地记录,带有
tx_hash: null和onchain: false;服务绝不会伪造交易哈希。ANCHOR_RPC_URL、ANCHOR_PRIVATE_KEY和ANCHOR_CONTRACT尚未使用。状态保存在内存中 (参见持久化)。
快速开始¶
# Start the service, from the repo root after installing the root dependencies
node services/anchor/index.js
# Or with Docker, from the repo root
docker compose -f docker/docker-compose.yml up anchor
服务默认监听 http://localhost:3001。
端点¶
GET /health¶
服务健康检查。
total_anchored 统计本地记录,每批一条,而非哈希数量。健康响应并不说明存在任何链上操作。
POST /anchor¶
提交待锚定的 bundle 哈希:sha256: 后接64个小写十六进制字符(前缀可选)。其他格式或超过1 MB的请求体会得到400响应。
curl -X POST http://localhost:3001/anchor \
-H "Content-Type: application/json" \
-d '{"bundle_hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"}'
单独模式 — 立即在本地记录哈希:anchored: true 表示此服务已记录,并不表示已经上链(onchain: false、tx_hash: null):
{
"anchored": true,
"hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"count": 1,
"timestamp": "2025-01-01T00:00:00.000Z",
"tx_hash": null,
"onchain": false,
"chain": "base"
}
批处理模式 — 接受并入队(HTTP 202):
{
"accepted": true,
"bundle_hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"position": 3,
"hint": "Will be anchored in next batch (interval: 60000ms)"
}
GET /status/:hash¶
查询已锚定哈希的状态。
curl http://localhost:3001/status/sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
{
"anchored": true,
"hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"count": 1,
"timestamp": "2025-01-01T00:00:00.000Z",
"tx_hash": null,
"onchain": false,
"chain": "base"
}
尚未锚定但仍在等待时:
只能按记录中保存的哈希查到该记录。在单独模式或仅含一个哈希的批次中,它就是提交的哈希(带 sha256: 前缀)。对于含多个哈希的批次,只保存其 Merkle 根,因此查询每个原始哈希会得到 {"anchored": false, "pending": false};尚无针对每个哈希的包含证明。仍在等待时,哈希按提交时的形式匹配(带前缀或不带前缀)。记录保存在内存中,重启会丢失。
GET /anchored¶
列出所有锚定记录。
{
"records": [
{ "hash": "sha256:...", "count": 1, "timestamp": "...", "tx_hash": null, "onchain": false, "chain": "base" }
]
}
POST /flush¶
强制处理待执行批次(仅限批处理模式)。需要运营方令牌;未配置 OPERATOR_TOKEN 时,此端点保持锁定(401)。
配置¶
环境变量¶
| 变量 | 默认值 | 描述 |
|---|---|---|
PORT |
3001 |
HTTP 端口 |
ANCHOR_MODE |
"batch" |
锚定模式:"individual" 或 "batch" |
BATCH_INTERVAL_MS |
60000 |
自动处理间隔,单位为毫秒(批处理模式) |
ANCHOR_RPC_URL |
— | L2 节点的 JSON-RPC URL(尚未使用;设置时会记录警告) |
ANCHOR_PRIVATE_KEY |
— | 用于签署交易的钱包私钥(尚未使用) |
ANCHOR_CONTRACT |
— | 已部署 DCPAnchor 合约的地址(尚未使用) |
ANCHOR_CHAIN |
"base" |
链标识符 |
OPERATOR_TOKEN |
— | POST /flush 的 Bearer 令牌。未设置时锁定 |
运行模式¶
单独模式(ANCHOR_MODE=individual): 每个哈希立即获得独立的本地记录。接入链上提交后,每个哈希预计对应一笔独立交易。
批处理模式(ANCHOR_MODE=batch): 累积哈希,每隔 BATCH_INTERVAL_MS 毫秒将其记录为一个 Merkle 根,也可以通过 POST /flush 立即处理。接入链上提交后,每个批次预计对应一笔交易。
与 DCPAnchor.sol 集成¶
接入后,服务将与 DCPAnchor.sol 智能合约交互:
- 单独模式: 调用
anchorBundle(bytes32 bundleHash) - 批处理模式: 计算待处理哈希的 Merkle 根,并调用
anchorBatch(bytes32 merkleRoot, uint256 count)
合约详情请参阅 contracts/ethereum/README.md。
开发¶
# Start in development mode, from the repo root
PORT=3001 ANCHOR_MODE=batch node services/anchor/index.js
# Test with curl
curl http://localhost:3001/health
curl -X POST http://localhost:3001/anchor \
-H "Content-Type: application/json" \
-d '{"bundle_hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"}'
许可证¶
Apache-2.0