getContractABI
Retrieve the Application Binary Interface (ABI) for verified smart contracts on EVM chains like Ethereum, Polygon, Arbitrum, Base, and Optimism. This tool fetches ABIs from Etherscan with Sourcify fallback, enabling interaction with contract functions and data.
Instructions
컨트랙트 ABI를 조회합니다 (Etherscan → Sourcify 폴백, verified contract 필요)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | 컨트랙트 주소 (0x...) | |
| chain | No | 체인 (ethereum, polygon, arbitrum, base, optimism) | ethereum |
Implementation Reference
- src/tools/getContractABI.ts:28-82 (handler)The handler function performs the logic for fetching the contract ABI, including validation, cache checking, RPC code verification, and fetching from Etherscan/Sourcify.
async function handler(args: z.infer<typeof inputSchema>): Promise<ToolResult<ContractABIData>> { const { address, chain } = args; if (!isSupportedChain(chain)) { return makeError(`Unsupported chain: ${chain}`, "CHAIN_NOT_SUPPORTED"); } if (!isAddress(address)) { return makeError(`Invalid address: ${address}`, "INVALID_INPUT"); } const cacheKey = `contractabi:${chain}:${address.toLowerCase()}`; const cached = cache.get<ContractABIData>(cacheKey); if (cached.hit) return makeSuccess(chain as SupportedChain, cached.data, true); const client = getClient(chain as SupportedChain); // 컨트랙트 여부 확인 let isContract = false; try { const code = await client.getCode({ address: address as `0x${string}` }); isContract = !!code && code !== "0x"; } catch { // RPC 실패 시 무시, ABI 조회 시도는 계속 } if (!isContract) { return makeError(`Address is not a contract: ${address}`, "ABI_NOT_FOUND"); } // ABI 조회 (Etherscan → Sourcify) const abiResult = await getABI(address, chain as SupportedChain); if (!abiResult) { return makeError(`ABI not found for ${address} on ${chain}. Contract may not be verified.`, "ABI_NOT_FOUND"); } const abi = abiResult.abi as Array<{ type?: string }>; const functionCount = abi.filter((item) => item.type === "function").length; const eventCount = abi.filter((item) => item.type === "event").length; const data: ContractABIData = { address, chain, abi: abiResult.abi, source: abiResult.source, contractName: abiResult.contractName, isContract: true, functionCount, eventCount, }; cache.set(cacheKey, data, ABI_CACHE_TTL); return makeSuccess(chain as SupportedChain, data, false); } - src/tools/getContractABI.ts:23-26 (schema)The Zod schema defines the input parameters for the getContractABI tool, ensuring the address and chain are properly formatted.
const inputSchema = z.object({ address: z.string().describe("컨트랙트 주소 (0x...)"), chain: z.string().default("ethereum").describe("체인 (ethereum, polygon, arbitrum, base, optimism)"), }); - src/tools/getContractABI.ts:84-94 (registration)The register function defines the tool with the MCP server using the handler and input schema.
export function register(server: McpServer) { server.tool( "getContractABI", "컨트랙트 ABI를 조회합니다 (Etherscan → Sourcify 폴백, verified contract 필요)", inputSchema.shape, async (args) => { const result = await handler(args as z.infer<typeof inputSchema>); return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] }; }, ); }