最后更新:
zkAPI 是一种协议,用于通过预付余额和零知识证明(而非关联账户的 API 密钥)私密地支付按量计费的应用程序编程接口 (API) 使用费(包括 AI 推理)。以太坊 基金会 和 Open Anonymity Project 于 2026 年 10 月 1 日宣布其在以太坊 主网 上线。该运行实现由 Open Anonymity Project 与以太坊基金会共同构建,基于 Davide Crapis 和 Vitalik Buterin 在 Ethereum Research 上发表的“ZK API 使用积分”设计。[1][2]
zkAPI 旨在将支付授权与 API 请求的内容分离。在其运行时密钥(runtime-key)模式下,本地客户端在证明隐私余额足以支付使用费后,会获得一个短期的、有支出上限的 API 密钥。该密钥保存在用户的设备上,请求直接从该设备发送到服务提供商。[1][3]
“ZK API 使用积分”设计由 Davide Crapis 和 Vitalik Buterin 在 Ethereum Research 上发表。Open Anonymity Project 与 以太坊基金会 的 dAI 团队 合作,为该运行系统开发了客户端、服务器和合约。[1][2]
以太坊基金会于 2026 年 10 月 1 日宣布 zkAPI,称其已在以太坊 主网 上线。发布材料描述了 ETH、USDC 或其他资产的存款,并确定了一个持有 USDC 积分的主网金库,同时还包括 Sepolia 测试部署和 OA Chat(一个基于浏览器的隐私 AI 聊天服务)。[1][2]
后来的 v2 协议文档描述了原生 ETH 的实现:当前的 SDK 和金库支持原生 ETH,金额以整 gwei 为单位。这一区别反映了 v2 实现的记录范围,不应被视为对初始发布材料中提到的每种资产的描述。[3][4]
用户将资金存入 以太坊 金库。存款会创建一个代表隐私余额的票据(note)。为了授权请求,用户的本地软件会生成一个证明,证明该票据有效且资金充足,而无需公开票据或将请求公开链接到原始存款。单向无效符(nullifier)可防止同一隐私状态被重复支出:有效的支出会消耗该状态,而尝试重复使用则会产生重复的无效符。[1][2]
在运行时密钥模式下,应用程序与用户设备上的客户端通信,同时继续使用其常用的 API 接口。客户端向 zkAPI 服务器发送支付证明,而不发送提示词(prompt)或身份信息。验证证明后,服务器会签发一个有美元金额上限的短期 API 密钥;该密钥保存在设备内存中,提示词直接从设备传输到提供商。[1][3]
当密钥过期时,提供商会在签名的收据中记录使用情况。服务器根据用户的隐私余额结算实际费用,而不是收取整个预留上限。一次授权可以覆盖一个会话的多个请求。在 v2 中,每个请求都不会在链上移动资金:使用会减少隐私余额,而未使用的容量仍可使用。[1][3]
运行时密钥模式划分了各方可以观察到的内容。支付服务器知道存在有效的支付以及每个会话收取的总美元金额,但不知道提示词内容。提供商可以看到提示词和响应,但不知道与密钥关联的计费身份。以太坊暴露了存款、关闭和提款操作,但不知道余额支付了什么内容。[1][2]
另一种代理模式通过 zkAPI 服务器转发请求。与运行时密钥模式不同,中继可以看到请求流量。本地客户端通过 localhost 暴露标准的 OpenAI 兼容接口和 Ollama API,允许兼容的应用程序、编辑器和聊天客户端在不更改其常用 API 接口的情况下进行连接。[1][2]
在 zkAPI v2 中,钱包采样一个秘密并从中派生出注册承诺。存款会在深度为 32 的 默克尔树 中插入一个叶子节点;该叶子绑定了票据 ID、秘密派生的注册、存款金额和到期时间。用户的隐私余额由一个结合了余额、盲化值和票据叶子的承诺表示。将承诺绑定到该叶子可以防止签名的余额被转移到另一个活动票据。[3][5]
对于每个请求,钱包会重新随机化其隐私状态承诺并生成一个 Groth16 证明。该证明确立了活动树根的成员身份,验证票据的初始或服务器签名状态,检查余额是否满足所需的偿付能力边界以及票据是否未过期,并将授权绑定到请求 ID 和有效载荷哈希。服务器在接受授权之前,会重新计算确切有效载荷和请求上下文的哈希。[3]
协议的状态锚点链将每个接受的授权链接到一个新鲜的服务器签名状态。服务器应用费用,更新隐私余额和承诺,并签署新的状态锚点。钱包在保存下一个状态之前,会验证响应、费用、签名和承诺更新。精确重试使用持久的请求记录进行恢复;更改请求不会为同一状态创建新的可支出无效符。[3]
v2 电路在 BN254 曲线上使用 Groth16 证明,使用 Poseidon 哈希处理承诺和无效符,并在 Baby-JubJub 上使用 Schnorr 签名处理签名状态。请求和提款电路共享票据绑定状态设计。协议当前的电路版本命名为 zkapi-v2-note-bound-v1。[3][6]
ZkApiVault 合约托管原生 ETH,并验证存款和提款的票据绑定证明。存款使用整 gwei 单位,且必须发送确切的以 wei 为单位的存款金额。合约将票据插入 默克尔树 并记录其到期时间;到期时间向上取整到金库的一天桶(one-day bucket)。其证明适配器以及状态和清算签名密钥是不可变的部署参数。[5][3]
索引器将来自 以太坊 的存款、关闭、逃逸、挑战、最终确定和到期事件镜像到本地默克尔树中。它提供浏览器用于构建证明以及服务器用于跟踪活动状态的根和路径。客户端可以检索树快照并在本地重建路径,从而避免在路径请求中泄露特定的票据 ID。合约和客户端根据提供的路径重新计算根,因此不正确或过时的路径会导致证明生成或交易失败。[7]
用户可以通过共同提款关闭票据,这需要服务器清算并将剩余余额支付给选定的目的地;存款的剩余部分进入国库。提款目的地可以与资金来源地址不同。关闭时,金库向用户支付最终余额,并向国库支付原始存款与该余额之间的差额。[3][5]
逃逸提款路径允许用户在没有服务器清算的情况下发起提款。它将票据从活动树中移除并记录一笔待处理的付款,受挑战期的限制(默认为 24 小时)。在截止日期之前,挑战者可以使用原始请求证明和匹配的无效符来证明该票据已经授权了使用。成功的挑战会取消付款并将票据恢复到活动树中;如果没有挑战成功,任何人都可以在截止日期后最终确定提款。过期且未关闭的活动票据可以被国库申领。[3][5]
因此,用户可以在不依赖 zkAPI 服务器持续运行的情况下在链上关闭和提款。浏览器 SDK 管理隐私票据状态、证明生成、交易日志、收据恢复和结算,而主机提供支付接口和 EIP-1193 钱包提供商。该项目还包括 Rust 运行时和证明库、Solidity 金库合约、服务器和索引器库、索引器和挑战服务以及运营商 CLI。[4][2]