contract_analyze
Analyze Hedera smart contracts to assess risks, examine activity patterns, evaluate gas usage, and classify contract functionality for security and performance insights.
Instructions
Deep analysis of a Hedera smart contract including activity patterns, caller distribution, gas usage, risk assessment, and functional classification. Costs 1 HBAR.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| api_key | Yes | Your HederaIntel API key | |
| contract_id | Yes | Hedera contract ID to analyze (e.g. 0.0.123456) |
Implementation Reference
- src/modules/contract/tools.js:363-511 (handler)The handler function for the `contract_analyze` tool, which fetches contract data, analyzes activities, gas usage, success rates, and performs a risk assessment.
// --- contract_analyze --- if (name === "contract_analyze") { const payment = chargeForTool("contract_analyze", args.api_key); const base = getMirrorNodeBase(); // Fetch contract info const contractRes = await axios.get(`${base}/api/v1/contracts/${args.contract_id}`); const contract = contractRes.data; // Fetch recent results (up to 100) const resultsRes = await axios.get( `${base}/api/v1/contracts/${args.contract_id}/results?limit=100&order=desc` ).catch(() => ({ data: { results: [] } })); const results = resultsRes.data.results || []; // Fetch contract logs const logsRes = await axios.get( `${base}/api/v1/contracts/${args.contract_id}/results/logs?limit=50&order=desc` ).catch(() => ({ data: { logs: [] } })); const logs = logsRes.data.logs || []; // Fetch state const stateRes = await axios.get( `${base}/api/v1/contracts/${args.contract_id}/state?limit=25` ).catch(() => ({ data: { state: [] } })); const stateEntries = stateRes.data.state || []; // Contract age const createdAt = contract.created_timestamp ? new Date(parseFloat(contract.created_timestamp) * 1000) : null; const ageDays = createdAt ? Math.floor((Date.now() - createdAt.getTime()) / (1000 * 60 * 60 * 24)) : null; // Caller analysis const callerCounts = {}; for (const r of results) { if (r.from) callerCounts[r.from] = (callerCounts[r.from] || 0) + 1; } const topCallers = Object.entries(callerCounts) .sort((a, b) => b[1] - a[1]) .slice(0, 5) .map(([account, count]) => ({ account, call_count: count })); // Gas analysis const gasUsed = results.map(r => parseInt(r.gas_used || 0)).filter(g => g > 0); const avgGas = gasUsed.length > 0 ? Math.round(gasUsed.reduce((a, b) => a + b, 0) / gasUsed.length) : 0; const maxGas = gasUsed.length > 0 ? Math.max(...gasUsed) : 0; const minGas = gasUsed.length > 0 ? Math.min(...gasUsed) : 0; // Success/failure rate // Mirror node contract results: status field is "0x1" (success) or "0x0" (fail) // result field may contain revert reason strings for failures const successCount = results.filter(r => r.status === "0x1" || r.result === "SUCCESS" || (!r.status && !r.error_message) ).length; const failCount = results.filter(r => r.status === "0x0" || (r.error_message && r.error_message.length > 0) ).length; // Activity trend - group by day const dayActivity = {}; for (const r of results) { if (r.timestamp) { const day = new Date(parseFloat(r.timestamp) * 1000).toISOString().slice(0, 10); dayActivity[day] = (dayActivity[day] || 0) + 1; } } const activityByDay = Object.entries(dayActivity) .sort((a, b) => b[0].localeCompare(a[0])) .slice(0, 7) .map(([date, count]) => ({ date, calls: count })); // Function signature analysis from call data const functionCalls = {}; for (const r of results) { if (r.function_parameters && r.function_parameters.length >= 10) { const sig = r.function_parameters.slice(0, 10); functionCalls[sig] = (functionCalls[sig] || 0) + 1; } } const topFunctions = Object.entries(functionCalls) .sort((a, b) => b[1] - a[1]) .slice(0, 5) .map(([selector, count]) => ({ selector, call_count: count })); // Risk assessment const riskSignals = []; let riskScore = 0; if (!contract.admin_key) { riskSignals.push("No admin key - contract is immutable (good for decentralization)"); } if (contract.deleted) { riskScore += 50; riskSignals.push("Contract has been DELETED"); } if (failCount > 0 && failCount > successCount && results.length > 5) { riskScore += 20; riskSignals.push("High failure rate - more failed calls than successful ones"); } if (ageDays !== null && ageDays < 7) { riskScore += 15; riskSignals.push("Very new contract - deployed less than 7 days ago"); } if (topCallers.length === 1 && results.length > 10) { riskScore += 10; riskSignals.push("Single caller dominates all interactions"); } if (stateEntries.length === 0 && results.length > 0) { riskSignals.push("No readable state entries - contract may use non-standard storage"); } if (riskSignals.length === 0) riskSignals.push("No significant risk signals detected"); const riskLevel = riskScore >= 40 ? "HIGH" : riskScore >= 15 ? "MEDIUM" : "LOW"; // Contract classification guess let classification = "Unknown"; const logTopics = logs.map(l => (l.topics || [])[0]).filter(Boolean); const uniqueTopics = [...new Set(logTopics)]; if (uniqueTopics.some(t => t.startsWith("0xddf252ad"))) classification = "ERC20 / HTS Token"; else if (uniqueTopics.some(t => t.startsWith("0xc3d58168"))) classification = "ERC1155 Multi-Token"; else if (uniqueTopics.some(t => t.startsWith("0x17307eab"))) classification = "ERC721 NFT"; else if (results.length > 50) classification = "High-activity contract (DEX, lending, or staking likely)"; else if (results.length > 0) classification = "General purpose smart contract"; return { contract_id: args.contract_id, evm_address: contract.evm_address || null, created_at: createdAt ? createdAt.toISOString() : null, age_days: ageDays, deleted: contract.deleted || false, hbar_balance: contract.balance?.balance ? (contract.balance.balance / 100000000).toFixed(4) + " HBAR" : "0.0000 HBAR", classification, activity: { total_calls_sampled: results.length, successful_calls: successCount, failed_calls: failCount, success_rate: results.length > 0 ? ((successCount / results.length) * 100).toFixed(1) + "%" : "unknown", unique_callers: Object.keys(callerCounts).length, recent_logs: logs.length, state_entries: stateEntries.length, }, gas_analysis: { avg_gas_used: avgGas, max_gas_used: maxGas, min_gas_used: minGas, }, top_callers: topCallers, top_function_selectors: topFunctions, activity_last_7_days: activityByDay, risk_assessment: { score: riskScore, level: riskLevel, signals: riskSignals, }, payment, timestamp: new Date().toISOString(), }; } - The definition and input schema for the `contract_analyze` tool.
{ name: "contract_analyze", description: "Deep analysis of a Hedera smart contract including activity patterns, caller distribution, gas usage, risk assessment, and functional classification. Costs 1.5 HBAR.", inputSchema: { type: "object", properties: { contract_id: { type: "string", description: "Hedera contract ID to analyze (e.g. 0.0.123456)" }, api_key: { type: "string", description: "Your HederaIntel API key" }, }, required: ["contract_id", "api_key"], }, },