마지막 업데이트:
zkAPI는 계정에 연결된 API 키 대신 선불 잔액과 영지식 증명을 사용하여 AI 추론을 포함한 종량제 애플리케이션 프로그래밍 인터페이스(API) 사용료를 비공개로 지불하기 위한 프로토콜입니다. Ethereum Foundation과 Open Anonymity Project는 2026년 10월 1일 Ethereum Mainnet에서 이를 공식 발표했습니다. 실제 구현체는 Davide Crapis와 Vitalik Buterin이 Ethereum Research에 게시한 “ZK API 사용 크레딧(ZK API usage credits)” 설계를 바탕으로 Open Anonymity Project와 Ethereum Foundation이 공동으로 구축했습니다.[1][2]
zkAPI는 결제 승인을 API 요청 내용과 분리하도록 설계되었습니다. 런타임 키(runtime-key) 모드에서 로컬 클라이언트는 개인 잔액이 사용량을 충당할 수 있음을 증명한 후, 지출 한도가 제한된 단기 API 키를 획득합니다. 이 키는 사용자의 기기에 보관되며, 요청은 해당 기기에서 서비스 제공자에게 직접 전달됩니다.[1][3]
“ZK API 사용 크레딧” 설계는 Davide Crapis와 Vitalik Buterin에 의해 Ethereum Research에 발표되었습니다. Open Anonymity Project는 Ethereum Foundation의 dAI Team과 협력하여 실제 시스템을 위한 클라이언트, 서버 및 컨트랙트를 개발했습니다.[1][2]
Ethereum Foundation은 2026년 10월 1일 zkAPI를 발표하며 Ethereum Mainnet에서 가동 중이라고 설명했습니다. 출시 자료에는 ETH, USDC 또는 기타 자산의 예치에 대해 설명되어 있었으며, USDC 크레딧을 보유한 메인넷 금고(vault)와 함께 Sepolia 테스트넷 배포 및 브라우저 기반 프라이빗 AI 채팅 서비스인 OA Chat이 확인되었습니다.[1][2]
이후의 v2 프로토콜 문서에서는 네이티브 ETH 구현에 대해 설명합니다. 현재 SDK와 금고는 네이티브 ETH를 지원하며, 금액은 정수 단위의 gwei로 표시됩니다. 이러한 차이는 v2 구현의 문서화된 범위를 반영하는 것이며, 초기 출시 자료에서 언급된 모든 자산에 대한 설명으로 해석되어서는 안 됩니다.[3][4]
사용자는 Ethereum 금고에 자금을 예치합니다. 예치는 개인 잔액을 나타내는 노트를 생성합니다. 요청을 승인하기 위해 사용자의 로컬 소프트웨어는 노트를 공개하거나 요청을 원래 예치와 공개적으로 연결하지 않고도 해당 노트가 유효하며 충분한 자금이 있음을 보여주는 증명을 생성합니다. 일방향 널리파이어(nullifier)는 동일한 개인 상태가 두 번 소비되는 것을 방지합니다. 유효한 소비는 상태를 소진시키며, 이를 재사용하려는 시도는 중복된 널리파이어를 생성하게 됩니다.[1][2]
런타임 키 모드에서 애플리케이션은 평소 사용하던 API 인터페이스를 그대로 유지하면서 사용자 기기의 클라이언트와 통신합니다. 클라이언트는 프롬프트나 신원 정보를 보내지 않고 zkAPI 서버에 결제 증명을 보냅니다. 증명을 확인한 후 서버는 달러 금액으로 한도가 정해진 단기 API 키를 발급합니다. 키는 기기 메모리에 보관되며, 프롬프트는 기기에서 제공자에게 직접 전달됩니다.[1][3]
키가 만료되면 제공자는 서명된 영수증에 사용량을 기록합니다. 서버는 예약된 전체 한도를 청구하는 대신 실제 발생한 비용을 사용자의 개인 잔액에서 정산합니다. 한 번의 승인으로 한 세션의 요청들을 처리할 수 있습니다. v2에서는 각 요청마다 온체인에서 자금이 이동하지 않습니다. 사용량에 따라 개인 잔액이 감소하며, 사용되지 않은 용량은 그대로 유지됩니다.[1][3]
런타임 키 모드는 각 당사자가 관찰할 수 있는 정보를 분리합니다. 결제 서버는 유효한 결제가 존재한다는 사실과 세션당 총 청구 금액은 알 수 있지만, 프롬프트 내용은 알 수 없습니다. 제공자는 프롬프트와 응답은 볼 수 있지만, 키와 연결된 청구 신원은 알 수 없습니다. 이더리움은 예치, 종료 및 출금 내역은 노출하지만, 해당 잔액이 무엇을 위해 지불되었는지는 노출하지 않습니다.[1][2]
대안인 프록시(proxy) 모드는 zkAPI 서버를 통해 요청을 중계합니다. 런타임 키 모드와 달리 중계 서버는 요청 트래픽을 볼 수 있습니다. 로컬 클라이언트는 localhost를 통해 표준 OpenAI 호환 및 Ollama API를 노출하여, 호환되는 애플리케이션, 에디터 및 채팅 클라이언트가 평소의 API 인터페이스를 변경하지 않고도 연결할 수 있도록 합니다.[1][2]
zkAPI v2에서 지갑은 비밀값을 샘플링하고 이로부터 등록 커밋먼트(commitment)를 도출합니다. 예치는 깊이 32의 Merkle tree에 리프(leaf)를 삽입하며, 이 리프는 노트 ID, 비밀값 기반 등록 정보, 예치 금액 및 만료 시간을 결합합니다. 사용자의 개인 잔액은 잔액, 블라인딩 값(blinding value), 그리고 노트 리프를 결합한 커밋먼트로 표현됩니다. 커밋먼트를 해당 리프에 결합함으로써 서명된 잔액이 다른 활성 노트로 이전되는 것을 방지합니다.[3][5]
각 요청에 대해 지갑은 개인 상태 커밋먼트를 재랜덤화하고 Groth16 증명을 생성합니다. 이 증명은 활성 트리 루트의 멤버십을 입증하고, 노트의 초기 또는 서버 서명 상태를 검증하며, 잔액이 요구되는 지급 능력 한도를 충족하는지, 노트가 만료되지 않았는지 확인하고, 승인을 요청 ID 및 페이로드 해시에 결합합니다. 서버는 승인을 수락하기 전에 정확한 페이로드와 요청 컨텍스트의 해시를 재계산합니다.[3]
프로토콜의 상태 앵커(state-anchor) 체인은 수락된 각 승인을 새로운 서버 서명 상태에 연결합니다. 서버는 요금을 적용하고 개인 잔액과 커밋먼트를 업데이트한 후 새로운 상태 앵커에 서명합니다. 지갑은 다음 상태를 저장하기 전에 응답, 요금, 서명 및 커밋먼트 업데이트를 확인합니다. 정확한 재시도는 복구를 위해 영구적인 요청 기록을 사용하며, 요청을 변경해도 동일한 상태에 대해 새로운 소비 가능 널리파이어가 생성되지 않습니다.[3]
v2 회로는 BN254 곡선 상의 Groth16 증명, 커밋먼트 및 널리파이어를 위한 Poseidon 해싱, 서명된 상태를 위한 Baby-JubJub 상의 Schnorr 서명을 사용합니다. 요청 및 출금 회로는 노트 결합 상태 설계를 공유합니다. 프로토콜의 현재 회로 버전 이름은 zkapi-v2-note-bound-v1입니다.[3][6]
ZkApiVault 컨트랙트는 네이티브 ETH를 에스크로하고 예치 및 출금을 위한 노트 결합 증명을 검증합니다. 예치는 정수 gwei 단위를 사용하며 wei 단위로 정확히 예치된 금액을 전송해야 합니다. 컨트랙트는 노트를 Merkle tree에 삽입하고 만료 시간을 기록합니다. 만료 시간은 금고의 1일 버킷 단위로 올림됩니다. 증명 어댑터와 상태 및 승인 서명 키는 불변의 배포 파라미터입니다.[5][3]
인덱서는 Ethereum의 예치, 종료, 탈출(escape), 챌린지, 확정 및 만료 이벤트를 로컬 머클 트리에 미러링합니다. 이는 브라우저가 증명을 생성하는 데 사용하는 루트와 경로를 제공하며, 서버가 활성 상태를 추적하는 데 사용됩니다. 클라이언트는 트리 스냅샷을 가져와 로컬에서 경로를 재구성할 수 있으므로, 경로 요청 시 특정 노트 ID가 노출되는 것을 방지할 수 있습니다. 컨트랙트와 클라이언트는 제공된 경로에서 루트를 재계산하므로, 잘못되거나 오래된 경로는 증명 생성이나 트랜잭션 실패를 유발할 수 있습니다.[7]
사용자는 상호 출금을 통해 노트를 종료할 수 있으며, 이는 서버의 승인이 필요하고 남은 잔액을 선택한 목적지로 지급합니다. 예치금의 나머지 부분은 재고(treasury)로 귀속됩니다. 출금 목적지는 자금 조달 주소와 다를 수 있습니다. 종료 시 금고는 사용자에게 최종 잔액을 지급하고 재고에는 원래 예치금과 해당 잔액의 차액을 지급합니다.[3][5]
탈출 출금 경로는 사용자가 서버 승인 없이 출금을 시작할 수 있게 해줍니다. 이는 활성 트리에서 노트를 제거하고 대기 중인 지급액을 기록하며, 기본 24시간의 챌린지 기간을 거칩니다. 기한 전에 챌린저는 원래의 요청 증명과 일치하는 널리파이어를 사용하여 해당 노트가 이미 사용 승인을 받았음을 보여줄 수 있습니다. 챌린지에 성공하면 지급이 취소되고 노트가 활성 트리로 복구됩니다. 성공적인 챌린지가 없으면 기한 후에 누구나 출금을 확정할 수 있습니다. 종료되지 않고 만료된 활성 노트는 재고로 청구될 수 있습니다.[3][5]
따라서 사용자는 zkAPI 서버의 지속적인 운영에 의존하지 않고도 온체인에서 종료 및 출금을 할 수 있습니다. 브라우저 SDK는 개인 노트 상태, 증명 생성, 트랜잭션 저널, 영수증 복구 및 정산을 관리하며, 호스트는 결제 인터페이스와 EIP-1193 지갑 제공자를 공급합니다. 이 프로젝트에는 Rust 런타임 및 증명 라이브러리, Solidity 금고 컨트랙트, 서버 및 인덱서 라이브러리, 인덱서 및 챌린지 서비스, 그리고 운영자 CLI가 포함되어 있습니다.[4][2]