Skip to main content
Glama
ACaiSec
by ACaiSec

contract_info

Retrieve comprehensive on-chain EVM contract information by analyzing contract addresses, executing view functions, and providing detailed contract insights.

Instructions

获取 EVM 合约的完整链上信息,包括调用所有无参数的 view 函数

Args:
    contract_address: EVM 合约地址 (0x开头的42位十六进制字符串)

Returns:
    合约的详细信息,包括基础信息和所有view函数的调用结果

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
contract_addressYes

Implementation Reference

  • The main handler function for the "contract_info" MCP tool, decorated with @mcp.tool() for registration. Includes input schema via type hints and docstring, validation, delegation to analyzer, and JSON output formatting.
    @mcp.tool()
    async def contract_info(contract_address: str):
        """
        获取 EVM 合约的完整链上信息,包括调用所有无参数的 view 函数
        
        Args:
            contract_address: EVM 合约地址 (0x开头的42位十六进制字符串)
        
        Returns:
            合约的详细信息,包括基础信息和所有view函数的调用结果
        """
        # 验证合约地址格式
        if not contract_address or not isinstance(contract_address, str):
            raise ValueError("合约地址不能为空且必须是字符串")
        
        if not contract_address.startswith("0x") or len(contract_address) != 42:
            raise ValueError("合约地址格式无效,必须是0x开头的42位十六进制字符串")
        
        try:
            print(f"🔍 开始分析合约: {contract_address}")
            
            # 执行合约分析
            result = await analyzer.analyze_contract(contract_address)
            
            # 格式化输出
            formatted_result = json.dumps(result, ensure_ascii=False, indent=2)
            
            print(f"✅ 合约分析完成: {contract_address}")
            
            return formatted_result
            
        except Exception as e:
            error_msg = f"合约分析失败: {str(e)}"
            print(f"❌ {error_msg}")
            
            error_response = {
                "status": "error",
                "error": error_msg,
                "contract_address": contract_address,
                "tool": "contract_info"
            }
            
            return json.dumps(error_response, ensure_ascii=False, indent=2)
  • Core helper method in ContractAnalyzer that performs the detailed contract analysis: initializes clients, validates address, fetches ABI, extracts and calls parameterless view functions, processes results, and returns structured data.
    async def analyze_contract(self, contract_address: str) -> Dict[str, Any]:
        """
        分析合约信息 - 主要业务逻辑
        
        Args:
            contract_address: 合约地址
            
        Returns:
            Dict: 分析结果
        """
        # 初始化检查
        if not await self.initialize():
            return {
                "status": "error",
                "error": "分析器初始化失败",
                "timestamp": datetime.now().isoformat()
            }
        
        # 步骤1: 验证地址格式
        if not is_valid_ethereum_address(contract_address):
            return {
                "status": "error",
                "error": f"无效的以太坊地址格式: {contract_address}",
                "timestamp": datetime.now().isoformat()
            }
        
        # 转换为校验和格式
        checksum_address = to_checksum_address(contract_address)
        
        # 步骤2: 检查是否为合约地址
        is_contract = await self.web3_client.is_contract_address(checksum_address)
        if not is_contract:
            return {
                "status": "error",
                "error": f"地址 {checksum_address} 不是合约地址",
                "timestamp": datetime.now().isoformat()
            }
        
        # 步骤3: 从 Etherscan 获取合约 ABI
        print(f"📡 正在获取合约 {checksum_address} 的 ABI...")
        abi = await self.etherscan_client.get_contract_abi(checksum_address)
        if not abi:
            return {
                "status": "error",
                "error": f"无法获取合约 ABI,可能合约未验证",
                "contract_address": checksum_address,
                "timestamp": datetime.now().isoformat()
            }
        
        # 步骤4: 筛选无参数的 view 函数
        view_functions = extract_view_functions(abi)
        if not view_functions:
            return {
                "status": "warning",
                "message": "合约中没有找到无参数的 view 函数",
                "contract_address": checksum_address,
                "total_functions": len([f for f in abi if f.get("type") == "function"]),
                "timestamp": datetime.now().isoformat()
            }
        
        print(f"🔍 找到 {len(view_functions)} 个无参数的 view 函数")
        
        # 步骤5: 创建合约实例
        contract = await self.web3_client.get_contract_instance(checksum_address, abi)
        if not contract:
            return {
                "status": "error",
                "error": "创建合约实例失败",
                "contract_address": checksum_address,
                "timestamp": datetime.now().isoformat()
            }
        
        # 步骤6: 批量调用 view 函数
        function_names = [func["name"] for func in view_functions]
        print(f"🚀 正在调用 {len(function_names)} 个函数...")
        
        call_results = await self.web3_client.batch_call_view_functions(
            contract, function_names
        )
        
        # 步骤7: 处理和格式化结果
        successful_calls = []
        failed_calls = []
        
        for i, result in enumerate(call_results):
            if result["status"] == "success":
                # 获取函数的输出类型信息
                func_info = view_functions[i]
                output_type = self._get_output_type(func_info)
                
                formatted_result = {
                    "function_name": result["function_name"],
                    "result": result["result"],
                    "type": output_type,
                    "status": "success"
                }
                
                # 格式化特殊类型的值
                if output_type.startswith("uint") and isinstance(result["result"], int):
                    if result["result"] > 10**15:  # 可能是 wei 值
                        formatted_result["formatted_value"] = self._format_large_number(result["result"])
                elif output_type == "address":
                    formatted_result["checksum_address"] = to_checksum_address(str(result["result"]))
                
                successful_calls.append(formatted_result)
            else:
                failed_calls.append({
                    "function_name": result["function_name"],
                    "error": result.get("error", "未知错误"),
                    "status": "failed"
                })
        
        # 获取额外的合约信息
        contract_name = await self.etherscan_client.get_contract_name(checksum_address)
        
        # 组装最终结果
        final_result = {
            "status": "success",
            "contract_address": checksum_address,
            "contract_name": contract_name,
            "analysis_summary": {
                "total_view_functions": len(view_functions),
                "successful_calls": len(successful_calls),
                "failed_calls": len(failed_calls)
            },
            "successful_functions": successful_calls,
            "failed_functions": failed_calls if failed_calls else None,
            "timestamp": datetime.now().isoformat()
        }
        
        print(f"✅ 分析完成: 成功调用 {len(successful_calls)} 个函数,失败 {len(failed_calls)} 个")
        
        return final_result
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It mentions calling '所有无参数的 view 函数' (all parameterless view functions), which implies read-only behavior, but doesn't explicitly state whether this is a read operation, what permissions are needed, potential rate limits, or error conditions. For a tool that interacts with blockchain contracts without annotation coverage, this leaves significant behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and appropriately sized. It starts with the core purpose, then has clear 'Args' and 'Returns' sections. Every sentence adds value: the purpose statement, parameter explanation, and return description. It could be slightly more concise by combining the purpose and returns, but overall it's efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, no output schema, and a single parameter with good description coverage, the description is moderately complete. It explains what the tool does and what it returns at a high level ('合约的详细信息,包括基础信息和所有view函数的调用结果' - detailed contract information including basic info and all view function call results). However, for a tool that presumably makes blockchain calls, it lacks details about network behavior, error handling, or response format specifics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description provides excellent parameter semantics beyond the schema. The schema only shows 'contract_address' as a string with 0% description coverage. The description adds: 'EVM 合约地址 (0x开头的42位十六进制字符串)' (EVM contract address - 42-character hexadecimal string starting with 0x), which gives crucial format and validation details. This fully compensates for the schema's lack of description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: '获取 EVM 合约的完整链上信息,包括调用所有无参数的 view 函数' (Get complete on-chain information for EVM contracts, including calling all parameterless view functions). It specifies the verb ('获取' - get), resource ('EVM 合约' - EVM contract), and scope ('完整链上信息' - complete on-chain information). However, it doesn't explicitly distinguish from its sibling 'contract_summary', which likely provides less detailed information.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context through '完整链上信息' (complete on-chain information) and '所有无参数的 view 函数' (all parameterless view functions), suggesting this is for comprehensive analysis rather than a summary. However, it doesn't explicitly state when to use this tool versus 'contract_summary' or provide any exclusion criteria. The guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ACaiSec/ContractInfoMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server