작성자: Cyimon ( @Cyimon ) · 상태: 초안 · 유형: 표준 트랙 (이더리움 요청 사항(ERC)) · 이더리움 개선 제안(EIP) : 8287 (PR) · 생성일: 2026년 6월 9일
설명: 이더리움 가상 머신(EVM) 용 대체 가능(fungible) 토큰 표준으로, 기본적으로 비공개입니다.
토론: ethresear.ch #25089 · 이더리움 매지션 #28702 · 구현: PERC20Labs/pERC20_
이전에 발표된 pERC20 프로토콜 설계( Ethereum Magicians #28702 / ethresear.ch #25089 )를 확장했습니다. 이번 개정의 주요 추가 사항은 ZIP-32 서브 계정을 통한 이더리움 요청 사항(ERC)-20 승인 지출 ( approve , allowance , transferFrom ) 기능입니다. 업데이트된 표준은 이더리움 요청 사항(ERC)-20 과 기능적으로 동일 하지만 바이트 호환성은 없습니다 (ABI가 다르고 공개 잔액이 없음).
| 이더리움 요청 사항(ERC) -20 | pERC20 | 층 |
|---|---|---|
name / symbol / decimals / totalSupply | 네, 대중의 견해는 같습니다. | 온체인 |
balanceOf | 예 — 소지자 전용 스캔 | 오프체인 |
transfer | 예 — 개인 파티 및 금액 | 온체인 |
approve / allowance / transferFrom | 새로운 기능 — ZIP-32 하위 계정을 통한 EOA 지출 승인; 온체인 = transfer (계약 지출자는 지원되지 않음) | 오프체인 |
mint / burn | 예 — 일반적인 확장 기능입니다. | 온체인 |
Transfer / Approval 이벤트 | 생략됨(개인정보 보호) | — |
다음은 최신 pERC20 표준인 프라이빗 토큰 표준 입니다.
추상적인
pERC20 이더리움 가상 머신(EVM)( European Virtual Machine)을 위한 기본적으로 대체 가능(fungible) 가능 토큰 표준으로 , 이더리움 요청 사항(ERC)-20 의 개인 정보 보호 버전입니다. 내부적으로는 지캐시(Zcash) 프로토콜 사양 의 Orchard 쉴드 풀 모델을 사용합니다. 이더리움 요청 사항(ERC)-20의 모든 메서드 표면을 유지하지만, 일부 메서드는 온체인에서 공개적으로 읽을 수 있는 것이 아니라 비공개 (보유자 전용, 오프체인)로 처리되며, transfer / approve / transferFrom 모두 온체인에서 동일한 transfer 작업으로 나타납니다. 아래의 pERC20 인터페이스를 참조하십시오.
동기 부여
이더리움의 공개 원장은 모든 이더리움 요청 사항(ERC)-20 잔액, 이체 및 할당량을 영구적으로 공개합니다. 결제, 급여, 트레져리 및 온체인 금융이 L1으로 이동함에 따라 사용자와 발행자는 공개 잔액에 대한 비공개 메시지 기능뿐만 아니라 개인 정보 보호를 위한 대체 가능(fungible) 토큰이 필요합니다.
개인정보 보호는 프로토콜 계층에서 점점 더 중요하게 다뤄지고 있습니다. 예를 들어, 이더리움 개선 제안(EIP)-8182 는 프로토콜에 내장된 보호 풀을 정의합니다. 사용자는 공개된 이더 이더리움(ETH) 이나 호환되는 이더리움 요청 사항(ERC)-20 토큰을 예치하고, 공유 풀 내에서 가치를 비공개로 이동시킨 후, 다시 공개 형태로 인출할 수 있습니다. 이 모델은 기존의 공개 자산을 보호하는 방식이지만 , 생성 시점부터 비공개인 토큰을 발행하는 방법을 정의하는 것은 아닙니다.
pERC20 후자의 공백을 메웁니다. 이는 기본적으로 대체 가능(fungible) 토큰(Fungible Token, FAT)을 위한 애플리케이션 계층 토큰 표준입니다. 이러한 토큰은 발행, 보유, 전송 및 사용이 approve / transferFrom 통해 처음부터 비공개 토큰으로 이루어지며, 공개 balanceOf 단계나 공유 보호 풀에 예치할 필요가 없습니다. pERC20은 이더리움 요청 사항(ERC)-20 의 비공개 버전(동일한 메서드 표면, 다른 개방성)을 명시하므로 발행자는 프로토콜 수준의 개인 정보 보호(예: 이더리움 개선 제안(EIP)-8182)가 병행 개발되는 동안에도 비공개 자산을 출시할 수 있습니다. 두 가지는 경쟁 관계가 아니라 상호 보완적입니다. 이더리움 개선 제안(EIP)-8182는 공개 자산을 비공개화하고, pERC20 비공개 자산 발행을 정의합니다.
사양
키워드 MUST , MUST NOT , SHOULD , MAY 는 RFC 2119에 따라 해석됩니다. 솔리디티 구문은 0.8.20 이상입니다.
기본 프로토콜
가치는 계좌 잔액이 아닌 보호된 노트에 저장됩니다. 노트 형식, 무효화 기능, 커밋먼트 트리, 노트 암호화 및 액션/번들 구조는 지캐시(Zcash) 프로토콜 사양 의 Orchard 보호 풀을 따르며, 여기서는 Groth16으로 검증된 자산별 이더리움 가상 머신(EVM) 계약으로 구현되었습니다. 아래에 반복되지 않는 필드 수준 형식은 참조 구현 섹션에서 표준으로 사용됩니다.
pERC20 인터페이스
이 섹션에서는 모든 pERC20 인터페이스를 한 곳에 나열하고 각 인터페이스가 이더리움 요청 사항(ERC)-20 표준 인터페이스에 해당하는지 여부를 표시합니다. 이더리움 요청 사항(ERC)-20 : yes = 이더리움 요청 사항(ERC)-20 표준; extension = 공통 확장(민트(Mint)/소각); no = pERC20 전용. 레이어 : on-chain = 컨트랙트 ABI; off-chain = 지갑/SDK(컨트랙트 방식 없음).
| pERC20 인터페이스 | 이더리움 요청 사항(ERC)-20 | 층 | 개방 상태 | 설명 |
|---|---|---|---|---|
name() / symbol() / decimals() | 예 | 온체인 | 공공의 | 이더리움 요청 사항(ERC)-20과 동일합니다. |
totalSupply() | 예 | 온체인 | 공공의 | 공용 카운터 ( mint - burn ) |
balanceOf(addr) | 예 | 오프체인 | 사적인 | 스캔 오차드 노트(보기 키 포함) - 홀더 전용 |
transfer(PrivacyCall) | 예 | 온체인 | 비공개 (파티 + 금액) | 과수원 액션 번들 |
approve(spender, N) | 예 | 오프체인 | 비공개 (관계 숨김) | ZIP-32 하위 계정; 자금 + 전달 키; 온체인에서 transfer(PrivacyCall) 으로 제출 |
allowance(owner, spender) | 예 | 오프체인 | 사적인 | 스캔 서브계정 잔액 |
transferFrom(from, to, amount) | 예 | 오프체인 | 비공개 (관계 숨김) | 지출자가 하위 계좌에서 돈을 지출합니다. 온체인에서는 이를 transfer(PrivacyCall) 로 제출합니다. |
mint(amount, PrivacyCall) | 확대 | 온체인 | 금액은 공개되지만 수령인은 비공개입니다. | 발행사 전용; 과수원 조치 + totalSupply 증가 |
burn(amount, PrivacyCall) | 확대 | 온체인 | 금액 공개; 버너 비공개 | 홀더 자신의 지폐를 소각합니다. 과수원 활동 + totalSupply 감소 |
issuer() | 아니요 | 온체인 | 공공의 | 토큰 발행자 주소 |
cmxFrozenRoot() / setFrozenRoot() | 아니요 | 온체인 | 공개 루트; 관리자 쓰기 | 규정 준수 동결 노트 루트 |
cmxRoot() / isValidAnchor() / isSpent() / treeSize() | 아니요 | 온체인 | 공공의 | 과수원 약속-나무 상태 |
이벤트
| pERC20 이벤트 | 이더리움 요청 사항(ERC)-20 | 층 | 설명 |
|---|---|---|---|
Transfer(from, to, value) | 예 | 오프체인(생략) | 발행되지 않음; 당사자 및 금액은 비공개입니다. |
Approval(owner, spender, value) | 예 | 오프체인(생략) | 발행되지 않음; 소유자 ↔ 지출자 링크(Chainlink) |
NoteAdded / NoteConfirmed | Transfer 대체합니다 | 온체인 | 음표별 관찰 가능성 |
Mint / Burn | 확대 | 온체인 | 공개 금액만 |
Perc20Created / FrozenRootUpdated / BundleExecuted | 아니요 | 온체인 | 배포, 규정 준수, 번들 메타데이터 |
온체인 내에서 구별이 불가능합니다. transfer , approve 의 자금 조달 단계, transferFrom 및 revoke-sweep은 모두 동일한 온체인 호출인 transfer(PrivacyCall) 입니다. 관찰자는 어떤 이더리움 요청 사항(ERC)-20 작업이 수행되는지 구분할 수 없습니다.
기본적으로 지원되지 않습니다. 이더리움 요청 사항(ERC)-20 토큰의 approve(contractAddress, amount) 메서드(컨트랙트가 transferFrom 자율적으로 호출하는 메서드)에는 기본적으로 대응하는 기능이 없습니다. 자금 지출에는 컨트랙트가 보유할 수 없는 개인 키가 필요하기 때문입니다. 자세한 내용은 이유를 참조하십시오.
계약 인터페이스
pERC20 하나의 온체인 ABI( IPERC20 , 위의 pERC20 인터페이스 참조)를 제공합니다. 해당 표에서 오프체인으로 표시된 메서드는 계약 진입점이 없으며, 동작은 아래의 메서드 의미론 에 명시되어 있습니다.
interface IPERC20 {struct PrivacyCall { bytes actions; uint256[3] bindingSig; }struct BundleAction {bytes32 cmx;bytes encCiphertext;bytes outCiphertext;bytes32 epk;bytes32 nfOld; // nullifier of the consumed (or dummy) input notebytes32 anchor; // historical root of the consumed (or dummy) input notebytes proof;uint256[8] pubFields;uint256[3] spendAuthSig;}// ERC-20-aligned public viewsfunction name() external view returns (string memory);function symbol() external view returns (string memory);function decimals() external view returns (uint8);function totalSupply() external view returns (uint256);function issuer() external view returns (address);// Value-changing operations (private parties; see Method Semantics)function transfer(PrivacyCall calldata call) external returns (bool success);function mint(uint256 amount, PrivacyCall calldata call) external;function burn(uint256 amount, PrivacyCall calldata call) external;// Compliancefunction cmxFrozenRoot() external view returns (uint256);function setFrozenRoot(uint256 newRoot) external; // onlyAdmin// Note state machine (Orchard commitment tree)function cmxRoot() external view returns (bytes32);function isValidAnchor(bytes32 root) external view returns (bool);function isSpent(bytes32 nf) external view returns (bool);function treeSize() external view returns (uint256);event Mint(address indexed issuer, uint256 amount);event Burn(uint256 amount);event FrozenRootUpdated(uint256 oldRoot, uint256 newRoot);event Perc20Created(address indexed pool, address indexed issuer,string name, string symbol, uint8 decimals);event NoteAdded(bytes32 indexed cmx, bytes encCiphertext, bytes outCiphertext,bytes32 epk, bytes32 nfOld, bytes32 cvNetX);event NoteConfirmed(bytes32 indexed cmx, bytes32 newRoot, uint256 position);event BundleExecuted(uint256 valueBalance, uint256 amount, bytes32 recipientMeta);}적합성:
-
transfer성공하면 반드시true반환해야 합니다. - 핵심 번들 실행 경로는 공개적으로 호출될 수 없어야 합니다(공급 불변 조건, 아래 참조).
- 구현 시 솔리디티 여러 계약(예:
IPERC20+ 검증자 기반)으로 분할할 수 있지만, 관찰 가능한 ABI 및 이벤트는 위의 통합 인터페이스와 일치해야 합니다. -
cmxRoot()는 최신 커밋먼트 트리 루트입니다.isValidAnchor(root)root활성화된 적이 있는 경우에만 true를 반환합니다.isSpent(nf)는 널라이저 집합을 보여줍니다.treeSize()는 삽입된 커밋먼트의 수입니다.
호출 형식
모든 값 변경 작업은 하나 이상의 Orchard 액션을 인코딩하는 PrivacyCall 제출합니다( 지캐시(Zcash) 프로토콜 사양 ).
-
actions=abi.encode(BundleAction[]). -
bindingSig= 값 보존을 증명하는 Schnorr 바인딩 서명[Rx, Ry, s].
각 BundleAction 은 이더리움 가상 머신(EVM) 검증에 맞게 조정된 Orchard 액션입니다. 하나의 출력 노트 커밋먼트( cmx )와 (실제 또는 더미) 입력에 대한 증명 자료가 포함됩니다. pubFields 반드시 다음 순서로 정렬되어야 합니다(Orchard 액션 기본 입력):
| 색인 | 필드 | 역할 |
|---|---|---|
[0] | anchor | 소비된 입력의 머클 루트 |
[1] | cv_net_x | 순 가치 약정 X (구속력 있는 서명) |
[2] | cv_net_y | 순 가치 약정 Y (구속력 있는 서명) |
[3] | nf_old | 소비된 입력의 널화 |
[4] | rk_x | 무작위로 생성된 지출 승인 키 X |
[5] | rk_y | 무작위로 생성된 지출 승인 키 Y |
[6] | cmx | 출력 노트 약정 |
[7] | rt_frozen | 규정 준수 동결 뿌리 결속 |
각 pubFields[i] 반드시 < Fr 이어야 합니다. 여기서 Fr 검증자가 사용하는 SNARK 곡선(참조 구현의 BN254)의 스칼라 필드 모듈러스입니다. 그렇지 않으면 revert( PubFieldOutOfRange )합니다. 구현은 회로의 PubHashAction() 과 일치하는 ActionPubHash (Poseidon sponge)를 통해 8개의 필드를 하나의 Groth16 공개 신호로 해시 해야 합니다.
calldata 필드에 바인딩합니다. 증명 공개 입력은 액션의 최상위 필드와 일치해야 합니다. 다음 중 하나라도 실패하면 구현은 되돌려야 합니다.
| 확인하다 | 돌아가는 것 |
|---|---|
pubFields[0] == anchor 및 isValidAnchor(anchor) | BadAnchor |
pubFields[3] == nfOld | 반드시 되돌려야 합니다(참조 구현: NullifierSpent ). |
pubFields[6] == cmx 및 cmx != 0 | InvalidProof / ZeroCommitment |
pubFields[7] == cmxFrozenRoot() | BadFrozenRoot |
spendAuthSig pubFields[4] , pubFields[5] 에 대해 (nfOld, cmx, epk, encCiphertext, outCiphertext) 를 통해 검증합니다. | BadSpendAuthSig |
pubFields ↔ calldata 동등성 검사가 없으면 유효한 증명을 다른 nfOld 또는 cmx 사용하여 다시 실행함으로써 널파이어 세트를 우회하거나 검증되지 않은 커밋먼트를 삽입할 수 있습니다.
encCiphertext 580바이트(Orchard 노트 평문 + 수신자 키 아래의 AEAD 태그)여야 합니다. outCiphertext 80바이트(OVK 아래의 발신자 자체 복구)여야 합니다. 노트 암호화 레이아웃을 변경하는 구현체는 이 이더리움 요청 사항(ERC) 의 별도 변형을 게시해야 합니다.
번들 수준의 bindingSig 모든 액션 무효화, 커밋먼트 및 연산의 valueBalance 에 대해 상태 변경 전에 반드시 검증되어야 합니다(인코딩에 대한 자세한 내용은 메서드 의미론을 참조하십시오).
암호화 및 키 유도는 지캐시(Zcash) 프로토콜 사양 의 Orchard 노트 형식을 따릅니다. 정확한 인코딩은 참조 구현 저장소에서 확인할 수 있습니다.
방법 의미론
name / symbol / decimals / totalSupply
이더리움 요청 사항(ERC)-20과 동일: 온체인에서 공개적으로 볼 수 있습니다.
transfer(PrivacyCall) → bool
입력된 Orchard 노트를 사용하고, valueBalance가 0이 아닌 값 보존 액션 번들( valueBalance == 0 )로 출력 노트를 생성합니다. 발신자, 수신자 및 금액은 반드시 비공개로 유지되어야 합니다. 성공 시 true 반환하고, NoteAdded / NoteConfirmed 이벤트를 발생시키며, Transfer(from,to,value) 발생시키지 않습니다.
mint(amount, PrivacyCall) / burn(amount, PrivacyCall)
transfer 와 동일한 과수원 활동 검증 경로를 사용하며, 총 totalSupply 회계 처리가 적용됩니다.
-
mint:totalSupply += amount(onlyIssuer);amount공개, recipient는 비공개. 민트(Mint)transfer과 동일한 앵커/널리파이어/지출 승인 경로를 사용해야 합니다(출력 전용 분기 없음). 회로는 소모된 입력을v = 0으로 제한하여 해당 동작이 순 유입을 나타내도록 해야 합니다. 계약은 지폐 가치를 직접 읽지 않습니다. -
burn:totalSupply -= amount; 모든 홀더 자신의 채권을 소각할 수 있습니다.amount공개되지만 소각자는 비공개입니다.
| 작업 | valueBalance 인코딩 |
|---|---|
transfer | 0 |
burn | 비트255 = 0, 하위 비츠(Bits) = 양 |
mint | 비트255 = 1, 하위 비츠(Bits) = 양 |
balanceOf (오프체인, 프라이빗)
홀더 만 NoteAdded 이벤트를 스캔하고, 보기 키를 사용하여 Orchard 노트를 시험 복호화하고, 사용된 널파이어를 제외하여 잔액을 계산할 수 있습니다. 온체인에는 balanceOf 없으며, 제3자의 잔액을 조회할 방법도 없습니다.
approve / allowance / transferFrom (오프체인 의미; 온체인 = transfer )
승인된 지출( approve / allowance / transferFrom )은 ZIP-32 계층적 계정을 기반으로 합니다. 각 EOA 지출자는 자체 지출 및 조회 키를 가진 전용 하위 계정( account_S )을 받으며, 이는 소유자의 기본 계정 및 다른 모든 지출자와 암호학적으로 격리됩니다. ZIP-32는 키 파생을 정의하며, 이 이더리움 요청 사항(ERC) 이더리움 요청 사항(ERC)-20 approve / transferFrom 키를 다음과 같이 매핑합니다.
-
approve(spender, N)— 소유자는 사용되지 않는 ZIP-32 하위 계정을 생성하고transfer(PrivacyCall)통해N을 해당 계정에 충전한 다음 해당 하위 계정의 지출 키를 EOA 지출자에게 전달합니다(오프체인에서 암호화됨). 온체인: 1회transfer. -
allowance(owner, spender)— 해당 하위 계정의 잔액을 하위 계정 보기 키로 스캔한 결과입니다. 온체인 매핑은 없습니다. -
transferFrom(owner, to, amount)— 스폰서가 서브계정에서 토픽에게 금액을to하고, 잔액은 서브계정으로 반환됩니다. 온체인: 1회transfer. -
approve(spender, 0)/ revoke — 소유자가transfer통해 하위 계정을 다시 회수합니다.
허용 한도는 온체인 카운터가 아닌 하위 계정의 실제 노트 잔액에 따라 적용됩니다. 지갑은 온체인 표시 없이, 어떤 보기 키로 노트를 복호화했는지에 따라 "자신 소유" 자산과 "허용" 자산을 구분합니다.
실행 요구사항
온체인 상태 머신은 Orchard 쉴드 풀( 지캐시(Zcash) 프로토콜 사양 )을 따릅니다. 구현 시 다음 사항을 반드시 준수해야 합니다.
- 널리파이어 세트를 유지하십시오. 동일한
nf두 번 사용해서는 안 됩니다. - 추가 전용 커밋 트리를 유지하며,
isValidAnchor통해 과거 루트를 조회할 수 있습니다. - Groth16 증명, spend-auth 및 바인딩 서명, 그리고 모든 pubFields 바인딩 검사(
pubFields[7]뿐만 아니라)를 검증합니다. - 중복되거나 커밋이 없는 경우를 거부합니다. 빈 액션 배열을 거부합니다. 호출당 액션 수를 제한합니다(
maxActions, 구성 가능한 유한한 양수 값). -
mint/burn/transfer통해서만 가치 변동을 공개합니다(공개적인 번들 진입점 없음). -
Perc20Created배포 시 한 번만 생성됩니다(공장 배포를 권장하지만 필수 사항은 아닙니다).
규정 준수. cmxFrozenRoot() 는 오프체인 블랙리스트 SMT의 루트입니다. 이 회로는 사용된 노트가 블랙리스트에 속하지 않음을 증명합니다. setFrozenRoot 는 admin 전용입니다. 초기 루트 0 블랙리스트가 비어 있음을 나타냅니다. 구현체는 업데이트 후 숏 유예 기간 동안 바로 이전 루트를 허용할 수 있으므로 진행 중인 증명이 중단되지 않습니다.
이론적 해석
- Orchard ZK-UTXO 모델입니다. 노트, 널파이어 및 커밋먼트 트리는 지캐시(Zcash) 프로토콜 사양을 따릅니다. 이 이더리움 요청 사항(ERC) 프라이빗 토큰 인터페이스와 이더리움 가상 머신(EVM) 상의 자산별 배포를 정의합니다.
- 개인용 이더리움 요청 사항(ERC)-20 토큰이며, 별도의 자산이 아닙니다. 동일한 메서드 표면을 가지며, 개인 정보 보호 정책에 따라 개방성(공개 보기 vs. 비공개 쿼리 vs. 구별할 수 없는 전송)이 달라지는 것이지 사용자 의도가 바뀌는 것은 아닙니다.
- 모든 이동에 대해 하나의 온체인 작업만 수행합니다.
transfer/approve/transferFrom통합하면 승인 메타데이터가 제거되어 이더리움 요청 사항(ERC)-20에서 불가피하게 누출이 발생합니다. - ZIP-32 하위 계정을 통한 승인된 지출. 각 EOA 지출자는 온체인
allowance매핑 대신 독립적인 계층적 계정을 받습니다. 자세한 내용은 방법론 의미론을 참조하십시오. -
approve(contract)없습니다. 계약에는 개인 키가 없으며, 지출 키를 온체인에 배치하면 모든 사람에게 노출됩니다. 프로그래밍 가능한 개인 지출(술어 기반 승인 노트, MPC 수탁)은 향후 개발 예정이며, 이 이더리움 요청 사항(ERC) 에는 포함되지 않습니다. - 지갑 동작은 온체인 ABI의 범위를 벗어납니다. 하위 계정 레이아웃, 암호화된 키 전달 및 노트 스캔은 지갑/SDK의 책임입니다. 참조 구현을 확인하십시오.
하위 호환성
pERC20 은 이더리움 요청 사항(ERC)-20 과 기능적으로는 동일 하지만 바이트 호환성은 없습니다 . 공개 balanceOf , 온체인 allowance , approve / transferFrom ABI, Transfer / Approval 이벤트 등이 지원되지 않습니다. 따라서 기존 이더리움 요청 사항(ERC)-20 인덱서 및 컴포저블 컨트랙트는 개인정보 보호를 고려한 지갑/SDK 없이는 pERC20을 사용할 수 없습니다.
선택적으로 공용 이더리움 요청 사항(ERC)-20 트윈으로 연결 bridgeOut 종료 시 개인 정보 보호를 종료할 수 있습니다. 이 제안에서는 필수 사항이 아닙니다.
테스트 케이스
참조 구현 저장소에는 다음이 포함됩니다.
- 파운드리 단위 테스트(
test/PERC20Test.t.sol): 생성자 가드, 민트(Mint)/소각/이체 회계, 공급 불변 조건. - 엔드투엔드 테스트(
test/PERC20E2E.t.sol,e2e/): 실제 Groth16 검증을 통해 배포된PERC20대상으로 민트(Mint), 전송, 소각,approve/transferFrom흐름을 모두 다룹니다.
참조 구현
암호
참조 구현: PERC20Labs/pERC20_ .
- 규범적 자산 계약:
contracts/ptoken/PERC20.sol(IPERC20). - 암호화 및 지갑 형식(키 파생,
perc1주소, 노트 암호화, 무효화, 패키징approve): 참조 라이브러리와 SDK가 동일한 저장소에 있습니다.
관련 표준 및 프로토콜
- 이더리움 개선 제안(EIP)-20 : 토큰 표준 —
pERC20이 매핑하는 공개 대체 가능(fungible) 토큰 인터페이스. - 지캐시(Zcash) 프로토콜 사양 : Orchard 쉴드 풀 — 노트 커밋먼트, 널파이어, 노트 암호화 및 액션 구조는 이더리움 가상 머신(EVM) Groth16 검증에 맞게 조정되었습니다.
- ZIP-32 : 보호된 계층적 결정론적 지갑 —
approve/transferFrom에서 지출자별 하위 계정에 사용되는 계층적 계정 파생.
보안 고려 사항
- 이중 지출 방지 : 널파이어 세트 + 올바른
nf파생. 각pubFields[i]< Fr작아야 합니다(그렇지 않으면nf + Fr다른isSpent키를 사용하여 증명을 재사용합니다).pubFields[0],[3],[6]은 각각anchor,nfOld,cmx와 같아야 합니다(그렇지 않으면 유효한 증명이 다른 calldata에 바인딩될 수 있습니다). - 공급 불변성 : 가치는
mint/burn/transfer통해서만 변경됩니다. 핵심 실행 경로는 공개적으로 호출될 수 없어야 합니다. - 값 보존 : 상태 변경 전에 바인딩 서명이 검증됩니다.
- 리플레이 방지 : sighash는
chainId, 계약 주소 및 모든nf/cmx바인딩합니다. - 하위 계정 지출 키 :
approve위해 전달되는 키는 반드시 암호화된 텍스트 형태로만 존재해야 하며, 계약 저장소에 저장되어서는 안 됩니다. - 규정 준수 권한 :
setFrozenRoot는 신뢰도가 높은 관리자 역할이므로 다중 서명/시간 잠금을 사용해야 합니다.
개인정보 보호 고려 사항
- 제출자의 EOA를 숨기려면 작업은 중계기를 통해 제출해야 합니다.
-
mint/burn및totalSupplyamount되지만, 이체량 및approve관계는 비공개입니다. -
approve/transferFrom온체인에서transfer과 구별할 수 없습니다(동일한transfer(PrivacyCall)선택기 사용).mint/burn공개 수량을 사용하는 별도의 기능입니다. - 시험 복호화는 수신에 대한 신뢰 경계입니다.
NoteAdded이벤트만으로는 지불이 증명되지 않습니다. 회로는encCiphertext가cmx와 일치하는지 확인하지 않습니다. -
setFrozenRoot사용하면 관리자가 오프체인 블랙리스트를 통해 식별된 노트를 동결할 수 있습니다. 이는 완전한 무신뢰성을 포기하는 대신 규정 준수를 위해 명시적으로 선택한 절충안입니다.
저작권
CC0 라이선스 를 통해 저작권 및 관련 권리를 포기합니다.
본 문서를 인용하실 때에는 다음과 같이 표기해 주십시오: Cyimon, “이더리움 요청 사항(ERC)-8287: 프라이빗 토큰 표준,” 이더리움 개선 제안 , 2026년 6월.




