EAS_POLICY
트랜잭션 발신자가 지정된 스키마의 유효한 EAS attestation을 보유하도록 요구하는 템플릿입니다. KYC/KYB 강제 게이트로 사용합니다.
발신자가 특정 EAS 스키마로 발행된 유효한 (만료되지 않고 폐기되지 않은) attestation을 보유했는지를 트랜잭션 게이트의 기준으로 삼습니다. KYC, KYB, 자격 증명, 자격 기반 게이트를 구현하는 표준 프리미티브입니다. 체인의 x/eas 모듈이 EAS 및 Indexer 컨트랙트를 view 호출로 읽어 attestation을 해결하며, 이는 PCL이 정책을 평가하는 모든 지점(실행 전, 실행 중의 PCL preCall / postCall 훅과 정책 인식 Privacy 프리컴파일, 실행 후)에서 이루어집니다.
Solidity struct + ABI
IPcl.sol에서:struct EasPolicy {
address easContract; // 쿼리할 EAS 배포
address indexContract; // EAS Indexer (O(1) 역방향 조회 제공)
bytes32 schemaUid; // 발신자가 attestation을 가져야 할 스키마
} ABI 튜플 약칭:
(address easContract, address indexContract, bytes32 schemaUid).PolicySet.policy용 인코딩:import {
EasPolicy, PolicySet, LogicalPolicy, ForEachPolicy, LogicalQuantifier, ForEachQuantifier,
ForEachSubject, VolumePolicy, VolumeUnitPolicy, PeriodicVolumePolicy, UnitPeriodicVolumePolicy,
ContractPolicyConfig, GlobalPolicyConfig, DenylistPolicy
} from "@maroo-chain/contracts/precompiles/pcl/IPcl.sol";
EasPolicy memory ep = EasPolicy({
easContract: 0x1000000000000000000000000000000000000007, // EAS preinstall
indexContract: 0x1000000000000000000000000000000000000008, // EAS Indexer preinstall
schemaUid: 0x5f3a2b0e1d5c9a7f6e3b4a1d2c8f7b6a5e4d3c2b1a0f9e8d7c6b5a4938271605 // KYC 스키마 UID
});
bytes memory policyBytes = abi.encode(ep);
// PolicySet.templateId = "EAS_POLICY" easContract와 indexContract는 일반적으로 마루 정식 preinstall 주소 — 하드코딩 대신 배포 시 EAS 프리컴파일의 getParams()로 해결 가능합니다.정책 평가 방식
PCL은 평가하는 각 트랜잭션의 발신자를 다음과 같이 검사합니다.
1. EAS Indexer(
2. Indexer에 등록된 것이 없으면 거절합니다:
3. 그 attestation을 EAS 컨트랙트에서 가져와 검증합니다:
- 조회 실패? →
- 폐기됨? →
- 만료됨 (
4. 그 밖에는 통과합니다. 가장 최근에 인덱싱된 attestation 하나만 검사하므로, 그것이 폐기되었거나 만료되었다면 더 오래된 유효한 attestation이 있어도 통과하지 못합니다. 새 attestation을 발급해 인덱싱해야 합니다.
1. EAS Indexer(
indexContract)에서 발신자가 schemaUid로 받은 attestation 중 가장 최근에 인덱싱된 것을 조회합니다. 인덱싱된 attestation만 인정됩니다. 일반 EAS attest만으로는 인덱싱되지 않으므로, 스키마의 resolver가 attestation을 만들 때 인덱싱하지 않는다면 attest한 뒤 Indexer의 indexAttestation(uid)를 호출해야 합니다(누구나 호출할 수 있으며, isAttestationIndexed(uid)로 확인합니다).2. Indexer에 등록된 것이 없으면 거절합니다:
EasNoAttestationReceived(sender).3. 그 attestation을 EAS 컨트랙트에서 가져와 검증합니다:
- 조회 실패? →
EasAttestationLookupFailed(sender)- 폐기됨? →
EasAttestationRevoked(sender)- 만료됨 (
expirationTime != 0 && expirationTime <= now)? → EasAttestationExpired(sender)4. 그 밖에는 통과합니다. 가장 최근에 인덱싱된 attestation 하나만 검사하므로, 그것이 폐기되었거나 만료되었다면 더 오래된 유효한 attestation이 있어도 통과하지 못합니다. 새 attestation을 발급해 인덱싱해야 합니다.
거절 시 발생하는 ReasonCode
EasNoAttestationReceived(address sender)— 발신자가 이 스키마로 받은 attestation이 EAS Indexer에 없습니다. 발급된 적이 없거나, 발급되었지만 인덱싱되지 않은 경우입니다.EasAttestationRevoked(address sender)— attestation을 받은 적이 있지만 이후 폐기되었습니다.EasAttestationExpired(address sender)— attestation을 받은 적이 있지만 이미 만료되었습니다.EasAttestationLookupFailed(address sender)— 인덱서가 알려 준 attestation을easContract에서 읽지 못했습니다. 정책에 올바른 EAS 컨트랙트가 지정되었는지 확인합니다.
EasAttestationRequired(address sender)도 같은 오류 집합에 선언되어 있지만, EAS_POLICY는 이 오류를 발생시키지 않습니다.지갑 UX: 적절한 KYC/KYB 온보딩 파트너로 사용자를 라우팅합니다. 새 attestation이 발급되고 EAS Indexer에 인덱싱되면 같은 트랜잭션이 성공합니다.
주요 활용 사례
- KYC 게이트: 전역 수준(
GlobalPolicyConfig)에서 "KYC 인증 계정만 규제 경로를 사용"하도록 강제합니다. - 상위 등급 기능: DeFi 풀 접근에 기관 KYB 스키마를 요구하는
ContractPolicyConfig로 사용합니다. - 계층 모델:
EAS_POLICY와VOLUME_POLICY상한을 정량자가Or인LOGICAL_POLICY하나로 묶어, 인증된 발신자는 통과시키고 미인증 발신자에게는 상한을 적용합니다. 단순 yes/no 게이트보다 일반적으로 더 유용합니다. 테스트넷의 전역 정책도 이렇게 구성되어 있어, attestation이 없으면 트랜잭션당 200만 OKRW로 제한됩니다.