news 2026/9/17 5:14:07

Aptos Keyless Pepper Service 开发指南:本地运行、Firestore 集成与客户端交互实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Aptos Keyless Pepper Service 开发指南:本地运行、Firestore 集成与客户端交互实战

Aptos Keyless Pepper Service 开发指南:本地运行、Firestore 集成与客户端交互实战

【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core

导读

本文是 Aptos 仓库中 keyless/pepper/README.md 的深度开发指南,围绕Pepper Service(无密钥账户方案中的关键服务)与其 Rust 示例客户端展开。通过本文,你将掌握 Pepper Service 的本地开发模式启动、Firestore 模拟器集成、完整的命令行参数含义、REST API 端点与客户端交互流程,并结合仓库源码理解其 VUF 密钥管理与启动自检机制,为二次开发或接入 keyless 账户体系打下基础。

一、Pepper Service 是什么

在 Aptos 的无密钥(keyless)账户方案中,Pepper Service扮演"pepper"(胡椒盐)生成与签名的可信第三方角色:它接收携带 OIDC JWT 的 pepper 请求,验证后将 JWT 中的身份信息(issuer、sub、aud 等)与一个随机 blinder 一起映射到一个确定性的 pepper 值,并基于该值派生账户地址,为临时公钥签署ephemeral signature。这样用户既可以通过 OAuth 身份登录,又不需要在链上直接暴露 JWT 原始信息。

本目录包含两大组成部分:

  • Pepper Service:位于 keyless/pepper/service,一个基于 Rust + Hyper 的 HTTP 服务,是本文的绝对主体;
  • Pepper Client 示例:位于 keyless/pepper/example-client-rust,一个 Rust 实现的交互式控制台客户端,用于演示完整用户流程。README 特别提示:如果你是前端开发者,可以直接以该 Client 示例为参考,理解如何与 Pepper Service API 交互。

两者共享的公共类型(PepperInputPepperRequestPepperResponse、VUF 实现、账户恢复数据库抽象等)位于 keyless/pepper/common。

二、本地开发模式快速启动

README 推荐的最简启动方式是直接使用仓库内的示例脚本。整个流程只需要两个终端窗口。

2.1 启动 Pepper Service

cd keyless/pepper/scripts ./start-pepper-service.sh

该脚本会在前台运行 Pepper Service,监听8000 端口(即request_handler.rs中定义的DEFAULT_PEPPER_SERVICE_PORT: u16 = 8000),并处于本地开发模式。本地开发模式的三个关键特性:

  • 使用临时文件型数据库TestAccountRecoveryDB)代替 Firestore,不产生任何持久化数据;
  • 连接 Aptosdevnet拉取链上资源(Groth16 验证密钥与 keyless 配置);
  • 跳过生产环境的常量时间标量乘法校验(详见下文"启动自检"小节)。

从脚本源码可以看到实际执行的命令(start-pepper-service.sh):

cargo run -p aptos-keyless-pepper-service -- \ --local-development-mode \ --expected-derived-pepper-on-startup=${EXPECTED_DERIVED_PEPPER_ON_STARTUP} \ --expected-vuf-pubkey-on-startup=${EXPECTED_VUF_PUBKEY_ON_STARTUP} \ --on-chain-groth16-vk-url=${ON_CHAIN_GROTH16_VK_URL} \ --on-chain-keyless-config-url=${ON_CHAIN_KEYLESS_CONFIG_URL} \ --vuf-private-key-seed-hex=${VUF_KEY_SEED_HEX}

脚本内置的测试用常量值得关注:

常量说明
VUF_KEY_SEED_HEXf的 64 位十六进制测试专用 VUF 私钥种子,生产环境必须更换
EXPECTED_VUF_PUBKEY_ON_STARTUPb601ec18...开头的公钥与该种子对应的期望 VUF 公钥,用于启动校验
EXPECTED_DERIVED_PEPPER_ON_STARTUP72c147eb...期望的派生 pepper 值,用于启动校验
ON_CHAIN_GROTH16_VK_URLhttps://fullnode.devnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::keyless_account::Groth16VerificationKeydevnet 上的 Groth16 验证密钥资源
ON_CHAIN_KEYLESS_CONFIG_URLhttps://fullnode.devnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::keyless_account::Configurationdevnet 上的 keyless 配置资源

注意:Pepper Service 在前台运行,整个交互过程中必须保持该终端窗口开启。

2.2 启动 Pepper Client 示例

保持服务端终端运行,另开一个终端执行:

cd keyless/pepper/scripts ./start-pepper-client.sh

脚本实际执行(start-pepper-client.sh):

cargo run -p aptos-keyless-pepper-example-client-rust -- --pepper-service-url="http://localhost:8000"

Pepper Client 是交互式控制台程序,会依次调用 Pepper Service 的多个 API 端点演示完整用户流程,需要你按提示手动完成一次会话(例如通过 Google OAuth Playground 获取带 nonce 的 JWT 后粘贴给客户端)。其完整流程定义在 example-client-rust/src/lib.rs 的run_client_example中,共包含以下步骤:

  1. 获取验证公钥:调用/v0/vuf-pub-key端点拉取 VUF 验证公钥;
  2. 生成 blinder 与临时密钥:生成 31 字节 blinder、临时公钥与临时密钥过期时间;
  3. 构造 OAuth nonce:将 blinder、过期时间与临时公钥绑定生成 nonce 字符串;
  4. 获取带 nonce 的 JWT:引导用户在 Google Playground 完成授权,获取包含该 nonce 的 JWT;
  5. 请求 pepper:调用/v0/fetch端点,提交PepperRequest(含 JWT、blinder、临时公钥、过期时间);
  6. 请求签名:调用/v0/signature端点,获取服务端对临时密钥的签名。

在本地开发模式下,客户端使用内置的测试 JWT 与默认sub作为 UID key,无需真实登录即可跑通全流程。

三、Firestore Emulator 集成模式

如果你的目标是贴近生产环境、测试账户恢复数据库的读写行为,README 提供了完整的 Firestore Emulator 方案。与本地开发模式的核心区别在于:账号恢复数据库从临时内存库切换为 Firestore,同时服务不再处于--local-development-mode

3.1 前置条件

要使用 Firestore 数据库运行 Pepper Service,需要准备两项 GCP 资源(均可通过 GCP Console 完成):

  1. GCP Project:一个已创建好的 GCP 项目;
  2. Service Account:一个具有 Firestore 访问权限的服务账号,并下载其JSON 格式的凭据文件(即GOOGLE_APPLICATION_CREDENTIALS指向的文件)。

3.2 启动 Firestore Emulator

cd keyless/pepper/scripts ./start-firestore-emulator.sh 8081

脚本参数:

  • <FIRESTORE_PORT>:Firestore 模拟器的监听端口。

执行后模拟器将运行在8081 端口,同样在前台运行,需保持该终端开启。脚本底层命令是gcloud emulators firestore start --host-port=localhost:${FIRESTORE_PORT}(见 start-firestore-emulator.sh),因此需要本机已安装并登录gcloudCLI。

3.3 停止 Firestore Emulator

cd keyless/pepper/scripts ./stop-firestore-emulator.sh 8081

脚本参数:

  • <FIRESTORE_PORT>:正在运行的 Firestore 模拟器端口。

停止时务必输入正确的端口号,脚本会通过lsof -t -i:<port>找到占用该端口的进程并强制结束(见 stop-firestore-emulator.sh)。请谨慎确认没有其他服务复用该端口。

3.4 使用 Firestore 启动 Pepper Service

cd keyless/pepper/scripts ./start-pepper-service-with-firestore.sh <FIRESTORE_EMULATOR_HOST> <GOOGLE_APPLICATION_CREDENTIALS> <GOOGLE_PROJECT_ID>

三个参数的说明:

参数示例含义
<FIRESTORE_EMULATOR_HOST>http://localhost:8081Firestore 模拟器的主机与端口
<GOOGLE_APPLICATION_CREDENTIALS>/path/to/credential.json服务账号凭据文件(JSON)路径
<GOOGLE_PROJECT_ID>my-gcp-projectGCP 项目 ID

从脚本源码(start-pepper-service-with-firestore.sh)可以看到,该模式还会:

  • FIRESTORE_EMULATOR_HOSTGOOGLE_APPLICATION_CREDENTIALS导出为环境变量;
  • 使用模拟器默认数据库 ID(default)
  • 配置账户恢复管理器(Account Recovery Manager),脚本内置了 Google 示例:
export ACCOUNT_MANAGER_0_ISSUER=https://accounts.google.com export ACCOUNT_MANAGER_0_AUD=407408718192.apps.googleusercontent.com

如需支持更多 OAuth 提供商,可依注释追加(Facebook、Apple 等):

# export ACCOUNT_MANAGER_1_ISSUER=https://www.facebook.com # export ACCOUNT_MANAGER_1_AUD=999999999.apps.fbusercontent.com # export ACCOUNT_MANAGER_2_ISSUER=https://appleid.apple.com # export ACCOUNT_MANAGER_2_AUD=88888888.apps.appleusercontent.com

该模式下实际运行的命令不再带--local-development-mode,而是显式传入 Firestore 参数:

cargo run -p aptos-keyless-pepper-service -- \ --expected-derived-pepper-on-startup=${EXPECTED_DERIVED_PEPPER_ON_STARTUP} \ --expected-vuf-pubkey-on-startup=${EXPECTED_VUF_PUBKEY_ON_STARTUP} \ --google-project-id=${GOOGLE_PROJECT_ID} \ --firestore-database-id=${FIRESTORE_DATABASE_ID} \ --on-chain-groth16-vk-url=${ON_CHAIN_GROTH16_VK_URL} \ --on-chain-keyless-config-url=${ON_CHAIN_KEYLESS_CONFIG_URL} \ --vuf-private-key-seed-hex=${VUF_KEY_SEED_HEX}

3.5 使用 Firestore 启动 Pepper Client

cd keyless/pepper/scripts ./start-pepper-client-with-firestore.sh <FIRESTORE_EMULATOR_HOST> <GOOGLE_APPLICATION_CREDENTIALS> <PEPPER_SERVICE_URL> <GOOGLE_PROJECT_ID> <FIRESTORE_DATABASE_ID>

五个参数说明:

参数示例含义
<FIRESTORE_EMULATOR_HOST>http://localhost:8081Firestore 模拟器主机与端口
<GOOGLE_APPLICATION_CREDENTIALS>/path/to/credential.json服务账号凭据文件(JSON)路径
<PEPPER_SERVICE_URL>http://localhost:8000Pepper Service 主机与端口
<GOOGLE_PROJECT_ID>my-gcp-projectGCP 项目 ID
<FIRESTORE_DATABASE_ID>(default)Firestore 数据库 ID

客户端对应的底层命令(start-pepper-client-with-firestore.sh):

cargo run -p aptos-keyless-pepper-example-client-rust -- \ --pepper-service-url=${PEPPER_SERVICE_URL} \ --firestore-google-project-id=${GOOGLE_PROJECT_ID} \ --firestore-database-id=${FIRESTORE_DATABASE_ID}

该模式下客户端会额外把FIRESTORE_EMULATOR_HOSTGOOGLE_APPLICATION_CREDENTIALS导出为环境变量,以便在完整流程中读写 Firestore 中的账户恢复记录(默认集合名为accounts,定义于客户端源码的DEFAULT_FIRESTORE_COLLECTION)。

四、服务端命令行参数全解(源码级)

Pepper Service 的全部启动参数由 service/src/main.rs 中基于clapArgs结构定义,是理解服务行为的一手资料:

参数类型/默认值说明
--local-development-modebool,默认 false使用测试账户恢复数据库(TestAccountRecoveryDB),与firestore_database_id/google_project_id互斥
--firestore-database-idOption<String>Firestore 数据库 ID,非本地模式必填,且必须与google_project_id同时出现
--google-project-idOption<String>GCP 项目 ID,非本地模式必填
--vuf-private-key-seed-hexOption<String>十六进制 VUF 私钥种子(用于派生私钥),与vuf_private_key_hex二选一
--vuf-private-key-hexOption<String>直接提供十六进制 VUF 私钥,与vuf_private_key_seed_hex二选一
--expected-vuf-pubkey-on-startupOption<String>启动时校验 VUF 公钥与期望值一致,防止用错密钥对
--expected-derived-pepper-on-startupOption<String>启动时用固定输入派生 pepper 并与期望值比对,保证派生逻辑前后兼容
--on-chain-groth16-vk-urlOption<String>拉取链上 Groth16 验证密钥的 REST 地址
--on-chain-keyless-config-urlOption<String>拉取链上 keyless 配置的 REST 地址
--pepper-service-portu16,默认 8000Pepper Service 监听端口
--account-recovery-managersVec允许在处理 pepper 请求时覆盖 JWTaud声明的账户恢复管理器列表
--disable-async-db-updatesbool,默认 false关闭账户恢复数据库的异步更新(默认异步,避免阻塞请求处理)
--resource-fetch-headersVec<HttpHeader>拉取链上资源时附加的 HTTP 头,适用于内部 API 网关鉴权
--jwk-issuers-overrideVec<JWKIssuer>额外监控的 JWK URL 列表,也可覆盖默认发行者的 JWK 地址

除 CLI 参数外,main.rs还支持两个环境变量注入的配置:

  • INTERNAL_NODE_API:若设置,则作为链上资源拉取的 base URL,自动拼接/v1/accounts/0x1/resource/0x1::keyless_account::Groth16VerificationKey...::Configuration两个路径,覆盖对应 CLI 参数;
  • INTERNAL_NODE_API_HEADER_<i>_NAME/INTERNAL_NODE_API_HEADER_<i>_VALUE:成对设置,追加到资源拉取请求头。

五、HTTP API 端点一览

Pepper Service 的全部端点集中定义在 service/src/request_handler.rs:

路径用途
/about服务基本信息
/v0/fetch提交 pepper 请求,获取派生 pepper 与账户地址(核心流程)
/v0/signature为临时公钥签发 ephemeral signature
/v0/verify验证 pepper / 签名
/v0/delegated-fetch委托模式下的 pepper 获取
/v0/vuf-pub-key返回 VUF 验证公钥
/cached/groth16-vk缓存的链上 Groth16 验证密钥
/cached/jwk缓存的 JWK(JSON Web Key)
/cached/keyless-config缓存的链上 keyless 配置

其中/cached/*三个端点由后台的start_cached_resource_fetcher周期拉取并缓存,/v0/*端点由request_handler::handle_request统一分发到dedicated_handlers中的各个处理器(V0FetchHandlerV0SignatureHandlerV0VerifyHandlerV0DelegatedFetchHandler等,见 service/src/dedicated_handlers/handlers.rs)。请求体以 JSON 反序列化(serde_json),非法请求返回 400,内部异常统一返回 500。

六、启动自检:VUF 密钥与派生逻辑的一致性保障

main.rsverify_critical_service_invariants在服务启动时执行三道关键检查,任何一项失败都会直接 panic,防止错误配置上线:

  1. 常量时间标量乘法校验(生产模式):使用 dudect 统计测试(ctbench)分别对随机基与固定基运行 BLS 标量乘法基准,要求max_t绝对值不超过 5(ABS_MAX_T),确保私钥操作不存在明显的时间侧信道;本地开发模式下跳过此项;
  2. VUF 公钥校验:将本地 VUF 公钥序列化为 JSON 后取出public_key字段与--expected-vuf-pubkey-on-startup比对;
  3. 派生 pepper 校验:使用硬编码的固定输入(fixed_issuer/fixed_sub/fixed_user_id/fixed_audience,常量定义于 service/src/main.rs)调用derive_pepper_and_account_address本地派生 pepper,与--expected-derived-pepper-on-startup比对,并将结果写入部署信息(deployment_information)便于可观测性。

VUF 密钥对的生成逻辑在 service/src/vuf_keypair.rs:

  • 若提供vuf_private_key_seed_hex,先 hex 解码,要求种子至少 32 字节,再用SHA3-512哈希后经scalar_from_uniform_be_bytes派生私钥标量;
  • 若直接提供vuf_private_key_hex,则直接反序列化为标量;
  • 公钥为G2Projective群元素,VUF 实现采用 BLS12-381 曲线(Bls12381G1Bls,见 keyless/pepper/common/src/vuf/bls12381_g1_bls.rs)。

这就是为什么脚本中的VUF_KEY_SEED_HEX(测试用全f种子)能对应到固定的期望公钥与派生 pepper——服务用启动自检保证"你手里的私钥种子派生出的确实是预期的密钥与 pepper"。

七、测试与验证

仓库为 Pepper Service 提供了较完整的单元与集成测试,集中在 service/src/tests:

  • pepper_request.rs:pepper 请求处理的核心逻辑测试;
  • request_handler.rs:HTTP 请求分发与响应构造测试;
  • jwk_fetcher.rs/federated_jwk.rs:JWK 拉取与联合发行者处理测试;
  • resource_fetcher.rs:链上资源(Groth16 VK / keyless 配置)缓存拉取测试。

运行方式:

cargo test -p aptos-keyless-pepper-service

本地联调时建议的完整验证路径:

  1. 终端 A:./start-pepper-service.sh启动服务(前台);
  2. 终端 B:./start-pepper-client.sh启动客户端,观察其依次完成"获取 VUF 公钥 → 生成 blinder/临时密钥 → 构造 nonce → 获取 JWT → 请求 pepper → 请求签名"的完整会话;
  3. 如需验证 Firestore 持久化:依次执行start-firestore-emulator.sh 8081start-pepper-service-with-firestore.shstart-pepper-client-with-firestore.sh,并可通过stop-firestore-emulator.sh 8081清理环境。

结语

本文以 keyless/pepper/README.md 为骨架,完整覆盖了 Pepper Service 的本地开发模式、Firestore Emulator 集成、全部启动参数与 HTTP 端点,并深入源码揭示了 VUF 密钥派生、启动自检与客户端交互流程。无论你是前端开发者(以 Rust Client 为 API 交互参考),还是后端/链上开发者(需要部署或扩展 Pepper Service),都可以直接依据上述命令与参数在本地复现整套环境,再对照 keyless/pepper/service/src 的源码继续深入。

【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 5:11:24

PyPDF安装:3条路线,5分钟装好 pypdf

PyPDF安装&#xff1a;3条路线&#xff0c;5分钟装好 pypdf 【免费下载链接】pypdf A pure-python PDF library capable of splitting, merging, cropping, and transforming the pages of PDF files 项目地址: https://gitcode.com/GitHub_Trending/py/pypdf pypdf 是一…

作者头像 李华
网站建设 2026/9/17 5:07:03

用爬虫追踪Steam硬件调查:Mac玩家与Apple Silicon趋势

1. 先把问题问对&#xff1a;什么叫"Mac玩家变多""Steam上的Mac玩家越来越多"这句话&#xff0c;我在群里、论坛里、评论区里都见过无数次&#xff0c;但每次看到我都会先反问一句&#xff1a;你说的是哪个数字&#xff1f;是 Steam 硬件调查里 macOS 那一…

作者头像 李华
网站建设 2026/9/17 5:03:14

内核模块编译报错 undefined symbol?modpost 符号解析排查指南

第一次在一台生产服务器上编自定义内核模块时&#xff0c;我撞上过这么一幕&#xff1a;gcc编译干净利落&#xff0c;一个警告都没有&#xff0c;可就在我以为马上要拿到.ko文件的时候&#xff0c;modpost阶段劈头盖脸甩出来一行ERROR: modpost: "my_symbol" [xxx.ko…

作者头像 李华