# EVM Transaction Preflight — ChainEvidence (`kieugiathinhphat/chainevidence-evm-transaction-preflight`) Actor

Inspect unsigned Base transactions before execution. ChainEvidence decodes calldata, simulates calls, detects proxies and privileged control, verifies contract source, and returns deterministic evidence with coverage and block provenance—without SAFE/SCAM labels or private keys.

- **URL**: https://apify.com/kieugiathinhphat/chainevidence-evm-transaction-preflight.md
- **Developed by:** [Kiều Gia Thịnh Phát](https://apify.com/kieugiathinhphat) (community)
- **Categories:** Developer tools
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 evm transaction preflights

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## ChainEvidence

> Evidence-first EVM transaction preflight for AI agents and developers.

ChainEvidence inspects an **unsigned Base transaction before execution** and returns deterministic, machine-readable evidence: decoded intent, basic simulation, contract verification, proxy/implementation facts, privilege signals, findings, coverage, and exact block provenance.

It deliberately does **not** label a transaction `SAFE`, `SCAM`, or `MALICIOUS`, and it does not emit a global risk score. The caller gets facts, confidence, and uncertainty so it can apply its own policy.

### What ChainEvidence checks

- calldata intent and known function selectors;
- unlimited ERC-20-style approvals and `setApprovalForAll`;
- basic `eth_call` simulation and gas estimation;
- target bytecode and contract status;
- verified source metadata through Etherscan V2 when available;
- ERC-1967, ERC-1167, beacon, and legacy ZeppelinOS proxy evidence;
- implementation and admin addresses when deterministically recoverable;
- readable `owner()` evidence;
- deterministic CE-001..CE-012 findings;
- coverage limits and exact state/block provenance.

Supported networks in v0.1: **Base Mainnet (8453)** and **Base Sepolia (84532)**.

### Run on Apify

The Apify Actor accepts one unsigned transaction and returns one evidence report.

Example input:

```json
{
  "chain": "base",
  "from": "0x0000000000000000000000000000000000000001",
  "to": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
  "data": "0x095ea7b3000000000000000000000000111111125421ca6dc452d289314280a0f8842a65ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  "value": "0",
  "blockTag": "latest"
}
```

Example evidence excerpt:

```json
{
  "schemaVersion": "chainevidence/0.1",
  "analysisVersion": "0.1.0-alpha.15",
  "intent": {
    "decoded": true,
    "signature": "approve(address,uint256)",
    "category": "TOKEN_APPROVAL"
  },
  "simulation": {
    "executed": true,
    "reverted": false
  },
  "target": {
    "sourceVerification": {
      "status": "VERIFIED",
      "provider": "etherscan",
      "contractName": "FiatTokenProxy"
    },
    "proxy": {
      "detected": true,
      "type": "ZEPPELINOS"
    }
  },
  "findings": [
    {
      "id": "CE-001",
      "kind": "MAX_UINT256_APPROVAL",
      "attention": "WARNING"
    }
  ],
  "coverage": {
    "calldataDecode": "FULL",
    "proxyDetection": "FULL",
    "sourceVerification": "FULL",
    "executionSimulation": "BASIC"
  },
  "provenance": {
    "chainId": 8453,
    "requestedBlockTag": "latest",
    "blockNumber": 0,
    "verificationSources": ["etherscan"]
  }
}
```

The example intentionally truncates fields. The dataset item contains the complete evidence report for that run.

### Why evidence-first?

A transaction simulation is an observation against a specific blockchain state, not a guarantee of future execution. A verified contract can still have privileged or upgradeable behavior. A single score can hide those distinctions.

ChainEvidence therefore records **what was observed, where it came from, how confident the engine is, and what it could not establish**.

### Report structure

Each report contains:

- `request` — normalized unsigned transaction request;
- `intent` — selector/signature/category and decoded arguments when supported;
- `simulation` — state-specific basic execution observation;
- `target` — bytecode, verification, proxy, implementation, and ownership evidence;
- `findings` — deterministic CE rules with evidence references;
- `coverage` — explicit FULL/PARTIAL/NOT\_AVAILABLE analysis coverage;
- `provenance` — chain, effective state block, block hash, provider class, and ruleset version.

Unknown selectors remain unknown instead of being guessed.

### Security and privacy boundary

ChainEvidence never asks for or accepts:

- private keys;
- seed phrases;
- wallet passwords;
- signed transactions;
- arbitrary user-supplied RPC URLs.

It does **not** sign or broadcast transactions. The engine performs read-only blockchain/RPC and verification lookups.

For pre-sign transaction analysis, ChainEvidence does not silently send private unsigned calldata to arbitrary public fallback RPC providers.

### Current limitations

- selector coverage is intentionally small in v0.1;
- simulation is basic and state-specific;
- no internal call tree yet;
- no complete asset-change model yet;
- privilege analysis is partial;
- verified-source availability depends on explorer coverage;
- `approve(address,uint256)` is shared by ERC-20 and ERC-721, so calldata alone does not establish the token standard.

These limits are surfaced in `coverage` rather than hidden behind a verdict.

### Local CLI

Requirements: Node.js 22+.

```bash
npm install
npm run build
npm test
```

Analyze a request file:

```bash
npm run cli -- --input fixtures/requests/unlimited-approval.example.json
```

For live local use, configure your own RPC and optional Etherscan key:

```bash
export BASE_RPC_URL="https://your-provider.example"
export ETHERSCAN_API_KEY="..."
```

A historical mined-transaction probe is also available with `--tx-hash`. Historical mode anchors reads to the mined block; it is **not** an exact intra-block pre-transaction replay.

### Deterministic design

The core v0.1 engine does not require an LLM. Findings are produced from decoded calldata, RPC observations, bytecode/storage patterns, verification metadata, and explicit rules.

This makes reports reproducible and suitable for AI agents, policy engines, developer tooling, and security automation that need evidence rather than a black-box verdict.

# Actor input Schema

## `chain` (type: `string`):

Base network to analyze.

## `from` (type: `string`):

Unsigned transaction sender address.

## `to` (type: `string`):

Transaction target address.

## `data` (type: `string`):

0x-prefixed unsigned transaction calldata.

## `value` (type: `string`):

Decimal wei amount or 0x-prefixed RPC quantity.

## `blockTag` (type: `string`):

latest analyzes the current confirmed state and records the exact effective block in provenance. pending analyzes the current pending state when supported by the RPC.

## `options` (type: `object`):

Optional analysis controls. Keep both checks enabled for the full preflight report.

## Actor input object example

```json
{
  "chain": "base",
  "data": "0x",
  "value": "0",
  "blockTag": "latest",
  "options": {
    "includeContractEvidence": true,
    "includeSimulation": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("kieugiathinhphat/chainevidence-evm-transaction-preflight").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("kieugiathinhphat/chainevidence-evm-transaction-preflight").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call kieugiathinhphat/chainevidence-evm-transaction-preflight --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kieugiathinhphat/chainevidence-evm-transaction-preflight"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/6SIbsdfiwuUlq0LT5/builds/QAIrS2ZrrBUO0fN7f/openapi.json
