EAS 데이터 조회하기
마루 EAS에서 attestation을 읽는 방법을 안내합니다. 정식 surface인 Solidity 컨트랙트 호출, 역방향 조회용 EAS Indexer, JS/TS SDK 세 가지 경로를 다룹니다.
마루의 EAS는 Solidity 컨트랙트 preinstall이므로, 다른 컨트랙트와 동일하게 JSON-RPC로 attestation을 읽습니다. Indexer는 역방향 조회("주소 X가 스키마 Y로 받은 모든 attestation")를 노출하는 별도의 preinstall입니다. 스택에 맞는 경로를 선택하세요. 단일 조회는 컨트랙트 호출, 역방향 조회는 Indexer, JS 우선 API가 필요하면 eas-sdk를 사용합니다.
사전 요구사항
- 마루 테스트넷 RPC URL
- EAS / EAS Indexer 주소 (preinstall 또는 EAS 프리컴파일
getParams()로 해결)
EAS / Indexer 주소 해결
두 가지 옵션이 있습니다. 정식 preinstall 주소를 하드코딩하는 방법(
EAS = 0x1000…0007, Indexer = 0x1000…0008)은 알려진 네트워크에 적합합니다. 또는 EAS 프리컴파일의 getParams()를 호출하면 어떤 마루 네트워크에서든 수정 없이 동일한 코드로 동작합니다.import { createPublicClient, http } from "viem";
import { iEasAbi as easPrecompileAbi } from "@maroo-chain/contracts/abi/precompiles/eas/IEas";
const publicClient = createPublicClient({ transport: http(process.env.MAROO_RPC_URL) });
const EAS_PRECOMPILE = "0x1000000000000000000000000000000000000009";
const { eas: EAS, indexer: INDEXER } = await publicClient.readContract({
address: EAS_PRECOMPILE,
abi: easPrecompileAbi,
functionName: "getParams",
}); 방법 1 — 직접 컨트랙트 호출 (viem / ethers)
프론트엔드 dApp과 대부분의 백엔드 코드가 사용하는 기본 경로입니다. EAS 컨트랙트에
getAttestation(uid)을 호출하면 전체 Attestation struct (schema, recipient, attester, time, expirationTime, revocationTime, refUID, data)를 반환합니다.import { parseAbi } from "viem";
const easAbi = parseAbi([
"struct Attestation { bytes32 uid; bytes32 schema; uint64 time; uint64 expirationTime; uint64 revocationTime; bytes32 refUID; address recipient; address attester; bool revocable; bytes data; }",
"function getAttestation(bytes32 uid) view returns (Attestation)",
]);
const attestation = await publicClient.readContract({
address: EAS,
abi: easAbi,
functionName: "getAttestation",
args: [uid],
});
// attestation.recipient, attestation.revocationTime, attestation.expirationTime, ... 방법 2 — Indexer를 통한 역방향 조회
"사용자 X가 스키마 Y로 attest를 받았는가?" — 이때 사용하는 것이 Indexer입니다. 사용할 두 메서드는 다음과 같습니다.
각 UID를 방법 1에 넣어 실제 attestation을 가져옵니다.
getReceivedAttestationUIDCount(recipient, schemaUid)→ 저렴한 존재 확인getReceivedAttestationUIDs(recipient, schemaUid, start, length, reverseOrder)→ 페이지네이션 목록
각 UID를 방법 1에 넣어 실제 attestation을 가져옵니다.
const indexerAbi = parseAbi([
"function getReceivedAttestationUIDCount(address recipient, bytes32 schemaUID) view returns (uint256)",
"function getReceivedAttestationUIDs(address recipient, bytes32 schemaUID, uint256 start, uint256 length, bool reverseOrder) view returns (bytes32[])",
]);
// 1) 카운트 확인
const count = await publicClient.readContract({
address: INDEXER,
abi: indexerAbi,
functionName: "getReceivedAttestationUIDCount",
args: [recipient, schemaUid],
});
// 2) 가장 최근 5개
const uids = await publicClient.readContract({
address: INDEXER,
abi: indexerAbi,
functionName: "getReceivedAttestationUIDs",
args: [recipient, schemaUid, 0n, 5n, true /* reverseOrder */],
}); 참고: Indexer에는 누군가
indexAttestation(uid)로 인덱싱한 attestation만 나타납니다(누구나 호출할 수 있으며, 스키마의 resolver가 attest 시점에 인덱싱하기도 합니다). 일반 attest는 인덱싱되기 전까지 여기에 나타나지 않으며, Indexer를 통해서만 attestation을 찾는 PCL의 EAS_POLICY는 그 발신자를 EasNoAttestationReceived로 거절합니다. Indexer는 인덱싱 여부만 추적하고 유효성은 추적하지 않으므로, 가져온 뒤에는 폐기되거나 만료된 attestation을 걸러냅니다. EAS_POLICY도 가장 최근에 인덱싱된 attestation에 대해 getAttestation으로 같은 revocation/expiration 검사를 실행합니다. 방법 3 — eas-sdk (JS)
스택에서 이미 공식
@ethereum-attestation-service/eas-sdk를 쓰고 있다면 마루 EAS 주소를 가리키게 한 뒤 평소처럼 사용합니다. SDK는 getAttestation과 스키마 레지스트리 호출을 래핑합니다.const { EAS: EasSdk } = require("@ethereum-attestation-service/eas-sdk");
async function main() {
const eas = new EasSdk(EAS); // EAS: 위에서 프리컴파일의 getParams가 반환한 주소
await eas.connect(provider);
const attestation = await eas.getAttestation(uid);
console.log(attestation);
}
main().catch((err) => {
console.error(err);
process.exit(1);
}); 참고: eas-sdk는 Indexer 바인딩을 제공하지 않으므로, 역방향 조회는 방법 2처럼 viem/ethers로 Indexer를 직접 호출합니다.
방법 4 — 쉘 임시 조회용 cast
쉘에서 값을 즉석으로 확인하고 싶을 때 사용합니다.
# attestation 하나 가져오기
cast call $EAS "getAttestation(bytes32)" $ATTESTATION_UID --rpc-url $MAROO_RPC_URL
# 사용자가 스키마 하의 보유 attestation 카운트
cast call $INDEXER \
"getReceivedAttestationUIDCount(address,bytes32)(uint256)" \
$RECIPIENT $SCHEMA_UID --rpc-url $MAROO_RPC_URL 마무리
네 가지 경로 모두 동일한 온체인 상태를 읽습니다. 앱 코드에는 viem/ethers를, 이미 의존하고 있다면 eas-sdk를, 역방향 조회에는 Indexer를, 일회성 쉘 확인에는
cast를 사용합니다.