EAS 프리컴파일

component identity

EAS 프리컴파일은 표준 EAS 모듈 주소인 SchemaRegistry, EAS, Indexer를 반환합니다. 실패는 IPrecompile의 공유 타입 지정 오류 인터페이스를 따르며, 초기화되지 않은 상태에서만 평문 문자열 revert가 발생합니다.

0x1000000000000000000000000000000000000009의 EAS 프리컴파일은 얇은 디스커버리 surface입니다. getParams() view 메서드 하나만 노출하며, 이 체인의 표준 schemaRegistry, eas, indexer 주소를 반환합니다. 실제 attestation API인 발급, 조회, 폐지는 이 프리컴파일이 아니라 EAS 컨트랙트 preinstall에 있습니다. 최신 인터페이스에서 IEas는 IPrecompile을 상속하므로, 인자 형태 실패는 공유 타입 지정 오류 집합의 오류로 반환됩니다.

Solidity 인터페이스

IEas.sol 그대로입니다. IEas는 IPrecompile을 상속하므로 자체 오류 타입을 선언하지 않습니다.
import {IPrecompile} from "../common/interfaces/IPrecompile.sol";

address constant EAS_PRECOMPILED_ADDRESS =
    0x1000000000000000000000000000000000000009;

struct EasParams {
    address schemaRegistry;
    address eas;
    address indexer;
}

interface IEas is IPrecompile {
    function getParams() external view returns (EasParams memory params);
}

이 프리컴파일이 존재하는 이유

EAS 컨트랙트, 스키마 레지스트리, 인덱서 모두 genesis에 배포된 preinstall입니다. 주소가 안정적이지만 툴체인이 다루는 모든 체인에서 동일하지는 않으므로, dApp이 이를 하드코딩하면 배포마다 깨집니다. getParams()는 런타임에 세 주소를 함께 반환하므로, 동일한 코드 경로가 별도 분기 없이 testnet과 mainnet에서 동작합니다.

오류 인터페이스 — 공유 IPrecompile과 단일 평문 revert

메서드와 맞지 않는 calldata(예: 오래된 ABI의 알 수 없는 selector)는 UnknownMethod가 아니라 공유 오류 집합의 ABISetupFailed(string reason)로 revert되며, 사유는 no method with id: 0x…입니다. selector 뒤에 붙은 바이트는 무시되므로, 여분의 ABI 인코딩 값이 있어도 InvalidNumberOfArgs는 발생하지 않습니다. 내부 모듈 조회 실패는 QueryFailed(string queryMethod, string reason)로 반환됩니다. 타입 지정 오류가 없는 실패가 하나 있습니다. 프리컴파일의 easKeeper 참조가 시작 시점에 연결되지 않으면, 호출은 평문 이유 "eas keeper is not initialized"로 revert됩니다. 이 이유는 Solidity Error(string) 형태로 ABI 인코딩되므로, decodeErrorResult는 이를 errorName: "Error"로 반환하고 이유는 args[0]에 담깁니다. IPrecompile 전체 목록은 precompile-shared-errors에서 확인할 수 있습니다.
import { decodeErrorResult } from "viem";

const iPrecompileErrorsAbi = [
  { type: "error", name: "InvalidNumberOfArgs",
    inputs: [{ name: "expected", type: "uint256" }, { name: "got", type: "uint256" }] },
  { type: "error", name: "ABISetupFailed", inputs: [{ name: "reason", type: "string" }] },
  { type: "error", name: "QueryFailed",
    inputs: [{ name: "queryMethod", type: "string" }, { name: "reason", type: "string" }] },
] as const;

// decodeErrorResult는 Solidity Error(string)도 알고 있으므로, 평문 이유
// (예: "eas keeper is not initialized")는 errorName "Error"로 디코드됩니다.
// 이 ABI에 없는 revert이면 예외를 던집니다.
function decodeEasRevert(errData: `0x${string}`) {
  return decodeErrorResult({ abi: iPrecompileErrorsAbi, data: errData });
}

사용법 — 주소 해석 후 EAS 컨트랙트 직접 호출

getParams()를 시작 시점에 한 번 호출하고 주소를 캐시합니다. 스키마 등록, attestation 발급, attestation 조회, 폐지 등 그 외의 모든 작업은 표준 ABI로 EAS 컨트랙트 또는 SchemaRegistry preinstall을 직접 호출합니다.
import { createPublicClient, http } from "viem";

const EAS_PRECOMPILE = "0x1000000000000000000000000000000000000009" as const;
const easPrecompileAbi = [{
  type: "function", name: "getParams", stateMutability: "view",
  inputs: [],
  outputs: [{ type: "tuple", components: [
    { name: "schemaRegistry", type: "address" },
    { name: "eas",            type: "address" },
    { name: "indexer",        type: "address" },
  ]}],
}] as const;

const publicClient = createPublicClient({ transport: http("https://rpc-testnet.maroo.io") });
const { schemaRegistry, eas, indexer } = await publicClient.readContract({
  address: EAS_PRECOMPILE,
  abi: easPrecompileAbi,
  functionName: "getParams",
});

// 반환된 `eas`, `indexer`, `schemaRegistry`를 @ethereum-attestation-service/eas-sdk
// 또는 원하는 ABI에 넘겨 실제 attestation 흐름을 진행합니다.
console.log({ schemaRegistry, eas, indexer });

참고

ESC
검색어를 입력하세요