构建一个每天处理 200 万次扫描、成本为 $0 的 Honeypot 扫描器

发布: (2026年2月1日 GMT+8 06:23)
8 分钟阅读
原文: Dev.to

抱歉,我需要您提供要翻译的具体文本内容。请粘贴您想要翻译的文章正文,我会按照要求保留来源链接并进行翻译。

问题:蜜罐代币

蜜罐代币是一种诈骗智能合约,允许你 购买 代币,却阻止你 出售。骗子利用 Solidity 中 tx.originmsg.sender 的差异:

// Malicious code example
function transfer(address to, uint256 amount) public returns (bool) {
    require(tx.origin == msg.sender, "No DEX sells allowed");
    // Transfer logic...
}
  • 直接购买tx.origin == msg.sender
  • 通过 Uniswap 出售tx.origin != msg.sender

交易会被回滚,资金将永远被锁住。

架构概览

┌─────────────────┐
│   Next.js 16    │  Frontend (Cloudflare Pages)
│   React 19      │
└────────┬────────┘


┌─────────────────┐
│ Cloudflare      │  Edge API (300+ locations)
│ Workers         │  - Input validation
│                 │  - Pattern detection
│                 │  - Response caching
└────────┬────────┘


┌─────────────────┐
│ Cloudflare KV   │  Global cache (24 h TTL)
│                 │  95 % hit rate
└────────┬────────┘


┌─────────────────┐
│ Etherscan API   │  Source‑code retrieval
│ (6 keys)        │  Rotation for rate limits
└─────────────────┘

为什么选择 Cloudflare Workers + KV?

  1. 边缘计算 = 稳定的延迟
    Workers 在全球 300 多个边缘位置运行。无论你在东京还是伦敦,都能获得约 2 秒的响应时间——没有冷启动,也没有地区瓶颈。

  2. KV 缓存 = 巨大的成本节约
    智能合约在部署后不可变,这使得激进的缓存安全可靠:

// Check cache first
const cached = await env.HONEYPOT_CACHE.get(address);
if (cached) {
  return JSON.parse(cached);
}

// Fetch from Etherscan
const sourceCode = await fetchFromEtherscan(address);

// Cache for 24 h
await env.HONEYPOT_CACHE.put(
  address,
  JSON.stringify(result),
  { expirationTtl: 86400 }
);

95 % 缓存命中率 下,我们得到:

  • 每日 10 万次 Worker 请求(免费层)
  • 每日 10 万次 KV 读取(免费层)

≈ 200 万次潜在扫描/天$0 / 月

  1. 内置 DDoS 防护
    Cloudflare 的边缘网络会自动缓解 DDoS 攻击。当有人尝试对 API 进行刷请求时,我甚至没有注意到,直到查看日志才发现。

检测算法

基于模式的静态分析

13 个正则表达式模式用于识别蜜罐技术:

const patterns = [
  // Core ERC20 abuse
  /function\s+balanceOf[^}]*tx\.origin/,
  /function\s+allowance[^}]*tx\.origin/,
  /function\s+transfer[^}]*tx\.origin/,

  // Hidden helpers
  /function\s+_taxPayer[^}]*tx\.origin/,
  /function\s+_isSuper[^}]*tx\.origin/,

  // Auth bypasses
  /require\s*\([^)]*tx\.origin/,
  /if\s*\([^)]*tx\.origin[^)]*==|!=/,
  /assert\s*\([^)]*tx\.origin/,
  /\[tx\.origin\]/,

  // Transfer blocks
  /_isSuper\s*\(\s*recipient\s*\)/,
  /_canTransfer[^}]*return\s+false/,
  /require\s*\([^)]*_whitelisted\[.*\]\s*&&\s*_whitelisted\[/,
  /if\s*\([^)]*isPair\[.*\][^}]*\)\s*{\s*taxAmount\s*=.*\*\s*9[5-9]/
];

置信度评分

const patternCount = patterns.filter(p => p.test(sourceCode)).length;

if (patternCount >= 2) {
  return { isHoneypot: true, confidence: 95 };
} else if (patternCount === 1) {
  return { isHoneypot: false, confidence: 50, warning: "Suspicious" };
} else {
  return { isHoneypot: false, confidence: 100 };
}

为什么阈值设为 2?

  • 真正的蜜罐通常显示 3‑7 个模式。
  • 合法合约很少出现 > 1 个模式。
  • 这可以在保持 ≈ 98 % 敏感度的同时最小化误报。

实现细节

输入验证

使用 keccak256 进行 EIP‑55 校验和验证:

import { keccak256 } from '@noble/hashes/sha3';
import { bytesToHex } from '@noble/hashes/utils';

function isValidChecksum(address: string): boolean {
  const addr = address.slice(2).toLowerCase();
  const hash = bytesToHex(keccak256(addr));

  for (let i = 0; i = 8 && addr[i] !== addr[i].toUpperCase()) return false;
    if (hashChar  controller.abort(), 10_000);
}

带超时的获取

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10_000);

try {
  const response = await fetch(url, { signal: controller.signal });
  // Process response…
} catch (error) {
  if (error.name === 'AbortError') {
    throw new Error('Request timeout');
  }
  throw error;
} finally {
  clearTimeout(timeoutId);
}

代码清理

在模式匹配之前,去除注释并规范化空白字符:

function sanitizeCode(code: string): string {
  return code
    .replace(/\/\*[\s\S]*?\*\//g, '') // Block comments
    .replace(/\/\/.*/g, '')            // Line comments
    .replace(/\s+/g, ' ')             // Collapse whitespace
    .trim();
}

最后思考

通过利用 edge computingglobal KV cachinglightweight static‑analysis engine,HoneypotScan 能够安全地以零成本每天处理 数百万次扫描。同样的模式可以适用于任何需要在大规模下运行且没有预算的 on‑chain security‑checking service

安全特性

CORS 白名单

const ALLOWED_ORIGINS = [
  'https://honeypotscan.pages.dev',
  'https://www.honeypotscan.com',
  'http://localhost:3000',
];

function handleCORS(request: Request): Response | null {
  const origin = request.headers.get('Origin');
  if (origin && !ALLOWED_ORIGINS.includes(origin)) {
    return new Response('Forbidden', { status: 403 });
  }
  return null;
}

内容安全策略

const CSP = [
  "default-src 'self'",
  "script-src 'self' 'unsafe-inline' 'unsafe-eval'",
  "style-src 'self' 'unsafe-inline'",
  "connect-src 'self' https://honeypotscan-api.teycircoder4.workers.dev",
  "frame-ancestors 'none'",
].join('; ');

response.headers.set('Content-Security-Policy', CSP);

限流

简单的内存限流(每分钟重置一次):

const rateLimits = new Map();

function checkRateLimit(ip: string): boolean {
  const count = rateLimits.get(ip) || 0;
  if (count >= 30) return false;

  rateLimits.set(ip, count + 1);
  return true;
}

前端功能

通过 URL 哈希分享结果

function shareResult(result: ScanResult) {
  const encoded = btoa(JSON.stringify(result));
  const url = `${window.location.origin}#result=${encoded}`;
  navigator.clipboard.writeText(url);
}

// On page load
const hash = window.location.hash;
if (hash.startsWith('#result=')) {
  const encoded = hash.slice(8);
  const result = JSON.parse(atob(encoded));
  displayResult(result);
}

本地扫描历史

Last 10 scans stored in localStorage:

function saveToHistory(result: ScanResult) {
  const history = JSON.parse(localStorage.getItem('scanHistory') || '[]');
  history.unshift(result);
  history.splice(10); // Keep only last 10
  localStorage.setItem('scanHistory', JSON.stringify(history));
}

导出为 JSON

function exportResult(result: ScanResult) {
  const data = {
    scanner: 'HoneypotScan',
    version: '1.0',
    scannedAt: new Date().toISOString(),
    result,
  };

  const blob = new Blob([JSON.stringify(data, null, 2)], {
    type: 'application/json',
  });

  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `honeypot-scan-${result.address}.json`;
  a.click();
}

性能优化

并行模式匹配

const matches = await Promise.all(
  patterns.map(async (pattern) => ({
    pattern: pattern.name,
    matched: pattern.regex.test(sourceCode),
  }))
);

缓存命中时提前退出

// Check cache before any processing
const cached = await env.HONEYPOT_CACHE.get(address);
if (cached) {
  return new Response(cached, {
    headers: { 'Content-Type': 'application/json' },
  });
}

懒加载组件

const ScanHistory = dynamic(() => import('./ScanHistory'), {
  ssr: false,
  loading: () => ,
});

部署

Cloudflare Workers

# Install Wrangler CLI
npm install -g wrangler

# Login to Cloudflare
wrangler login

# Deploy
wrangler deploy

环境变量

# wrangler.toml
name = "honeypotscan-api"
main = "src/worker.ts"
compatibility_date = "2024-01-01"

[[kv_namespaces]]
binding = "HONEYPOT_CACHE"
id = "your-kv-namespace-id"

[vars]
ETHERSCAN_API_KEY_1 = "your-key-1"
ETHERSCAN_API_KEY_2 = "your-key-2"
# ... more keys

Cloudflare Pages

# Build Next.js app
npm run build

# Deploy to Pages
npx wrangler pages deploy out

经验教训

有效的做法

  • KV caching is magic – 95 % 命中率 = 大幅成本节约
  • Edge computing eliminates latency issues – 全球一致的约 2 秒响应时间
  • Pattern‑based detection is fast – 正则匹配耗时 < 100 毫秒
  • Immutable contracts = aggressive caching – 无需缓存失效

注意事项

  • KV eventual consistency – 写入约 60 秒后在全球传播
  • 10 ms CPU limit – 必须优化正则模式
  • No WebSocket support – 无法进行实时更新
  • Cold start on first deploy – 全球传播约 30 秒

若重新来过,我会

  • 添加 WebAssembly 以加速模式匹配
  • 实现机器学习用于新颖模式检测
  • 构建反馈循环以随时间改进模式
  • 增加对更多链的支持(BSC、Avalanche 等)

结果

  • 平均响应时间 2 秒
  • 缓存命中率 95 %
  • $0 /月 基础设施成本
  • 免费层每日扫描容量 200 万次
  • 灵敏度 98 %,特异度 97 %

亲自尝试

整个技术栈都是开源的。欢迎随意分叉、修改,或将其作为您自己的边缘计算项目的参考。

Source:

结论

Cloudflare Workers + KV 适用于:

  • 读取频繁、写入较少的工作负载
  • 全球低延迟需求
  • 需要免费起步并可随时扩展的项目
  • 不可变数据(积极缓存)

对于 HoneypotScan 来说,它是理想的架构:快速、免费且高度可扩展。

有问题吗?在评论区留下吧! 👇

Back to Blog

相关文章

阅读更多 »