
过去半个月我几乎每天都会在链上过一遍新合约、新池子和异动交易。很多人看到别人说“抓到了金狗”第一反应是打听具体地址但说实话单纯拿到一个地址意义不大因为不知道筛选逻辑、不会验证真伪反而容易变成接盘的人。我更建议把方法沉淀下来链上筛选、热度验证、风险过滤然后才是技术层面的自动化扫描。这篇文章我会完整复盘这半个月用到的链上追踪思路附带一套可运行的 Python 扫描脚本供对链上数据分析和 Web3 开发感兴趣的读者参考。先说清楚本文只讨论链上数据处理与工程技术不构成任何投资建议也不存在所谓的“财富密码”。链上代币风险极高尤其新合约往往伴随貔貅盘、恶意授权和流动性抽走等不确定因素任何人都要先学会保护自己再讨论收益。把这层风险意识放在最前面比记住任何脚本都重要。1. 背景与核心概念1.1 什么是“金狗”以及链上追踪的本质在加密社区里“金狗”通常指早期市值极低、随后价格大幅上涨的代币。这个词带有不小的运气成分和情绪色彩但从技术角度看我们可以把它还原成几个可量化的链上特征合约创建时间短、持有人快速增长、交易量快速放大、流动性池被添加、链上转账频繁等。这些数据不是秘密因为区块链本身就是公开账本。任何地址的转账记录、任何合约的创建时间、任何池子的流动性变化都可以通过节点或区块浏览器查询到。所谓“链上追踪”本质就是把分散在区块中的事件日志、交易记录、合约状态抓取下来再按自己的逻辑过滤和打分。1.2 为什么链上监控比交易所上币信息更早一个代币的生命周期通常从链上开始先有合约部署然后创建流动性池出现第一批链上买卖最后才可能被交易所收录。如果只盯着交易所数据看到的热门币往往已经经历了早期阶段。链上事件则不同。流动性池子刚建立、部署者开始转移代币、第一批持有人地址出现这些事件在交易上链后几秒甚至几毫秒内就能被监控脚本捕捉到。这也是很多开发者研究早期代币时选择链上数据作为主要信号源的原因。链上监控做的是“比别人更早看到状态变化”而不是预测某个代币会上涨。1.3 这篇文章适合谁想入门链上数据分析但不知道从哪下手的开发者。已经会用区块浏览器但希望用脚本自动扫描和分析数据的工程师。对 Web3.py 感兴趣想做一个真实链上数据抓取小项目的读者。以及所有想在参与链上代币之前先学会用数据做基础判断的人。如果你只是想要一个“必涨清单”那这篇文章帮不到你如果你想建立一套可复用的链上筛选与验证框架下面的内容应该能提供不少思路。2. 环境准备与工具链2.1 基础运行环境本文示例使用 Python 编写主要依赖 Web3.py 库。版本需要根据你的项目实际情况调整本文以常见环境为例重点演示配置思路。建议环境如下操作系统Windows 10/11、Ubuntu 20.04、macOS 均可 Python3.9 及以上 Web3.py6.x 或 7.x 均可 节点服务支持以太坊 JSON-RPC 的公共节点或自建节点如果还没有 Python 环境建议先安装 Anaconda 或直接从 Python 官网下载安装包。创建独立虚拟环境可以避免依赖冲突这一步在真实项目中很值得做python -m venv venv source venv/bin/activate # Windows 下执行 venv\Scripts\activate2.2 数据源与工具清单做链上追踪不需要太多复杂系统核心是一个能访问链上数据的 RPC 节点以及一些用于交叉验证的平台。工具类型常见选择作用RPC 节点公共节点、云节点、自建节点读取区块、交易、合约状态、事件日志区块浏览器Etherscan 等手动查看合约源码、交易流向、持有人分布DEX 数据平台DexScreener、GeckoTerminal 等查看代币价格、流动性池、交易对变化数据分析平台Dune 等编写 SQL 做历史数据分析和统计自定义脚本Web3.py / ethers.js自动抓取链上数据并按规则过滤RPC 节点是整个链路的地基。公共节点方便但并发请求容易触发限流自建节点数据完整但需要同步成本。对于小范围扫描先用公共节点跑通逻辑后续再考虑多节点负载均衡。2.3 工程目录结构本文实战案例会创建一个最小化项目目录结构如下golddog_scanner/ ├── .env # 存放 RPC 地址等敏感配置 ├── requirements.txt # Python 依赖 └── scanner.py # 扫描脚本真实项目中还需要加入日志模块、数据库存储、告警通知等但先跑通最小闭环是更务实的第一步。3. 我常用的五个链上初筛信号3.1 新合约与新增流动性池新合约是最基础的信号。一个地址在链上第一次创建合约意味着新的项目出现了。但新合约太多真正关键的是合约是否创建了流动性池。流动性池可以理解为代币是否具备了“可交易”的基础条件。没有池子的代币合约再新也无法在 DEX 上买卖。所以“新合约 新池子”组合出现的瞬间往往是监控价值最高的节点。3.2 持有人数量裂变持有人数量是判断早期热度的重要指标。如果部署者把代币一次性转移给上百个地址且这些地址之间没有明显的批量创建规律可能意味着项目方在做空投或市场分发。反过来如果持有人列表里大量地址来自同一个创建者可能存在“刷量”嫌疑。在链上识别持有人分布并不难解析 Transfer 事件统计每个目标地址的余额变化。更复杂的是判断这些地址是否独立这需要聚类分析比如查看这些地址是否在同一笔交易中被批量转账。3.3 交易量快速放大交易量是另一个有效信号。一个新合约如果长时间没有交易说明市场关注度极低如果突然在某个区块高度前后出现密集交易大概率是有资金进场或者有社区开始关注。但交易量也可能被刷出来。通过自买自卖制造繁荣假象是很多风险项目的常规操作。因此交易量需要与持有人分散度、池子深度一起看不能单看一个指标。3.4 合约所有权与安全权限合约代码是否开源、是否存在 owner 权限、owner 能否增发代币或修改交易费率这些都是基础风控点。很多新合约通过隐藏函数实现黑名单、暂停转账、增发等能力普通用户很难从交易记录中直接察觉。用代码层面可以做部分探测读取合约代码、确认是否开源、调用常见敏感函数接口。更完善的做法是把合约字节码提交给安全审计工具分析但这已经超出“抓数据”的范畴属于安全审计领域。3.5 链上数据与社区信息交叉验证链上数据可以告诉我们“发生了什么”但很难告诉我们“为什么发生”。这时候需要结合项目官网、官方社群、代码仓库等信息做交叉验证。我半个月来的体感是链上信号负责发现社区信息负责排雷。一个完全没有任何公开资料的代币链上数据再漂亮风险也可能极高。交叉验证不是让你去追热点而是帮你过滤掉明显不合理的信号。4. 完整实战用 Python 扫描新合约下面进入核心部分用 Web3.py 实现一个最简单的链上扫描器完成以下流程获取最新区块号 - 遍历区块内交易 - 找到创建合约的交易 - 获取合约地址 - 读取代币名称和符号 - 输出结果这个脚本虽然简单但已经覆盖了链上数据抓取的核心链路你可以在此基础上扩展出池子监控、持有人统计和告警通知。4.1 创建项目结构先创建项目目录和虚拟环境mkdir golddog_scanner cd golddog_scanner python -m venv venv source venv/bin/activate # Windows 下执行 venv\Scripts\activate接着创建requirements.txtweb36.0.0 python-dotenv1.0.0 requests2.31.0安装依赖pip install -r requirements.txt4.2 配置 RPC 地址创建.env文件填入可用的 RPC 地址。示例中不写死具体服务商你需要根据自己使用的节点服务来填写RPC_URLhttps://your-rpc-endpoint BLOCK_RANGE20BLOCK_RANGE表示每次扫描多少区块。区块范围越大扫描时间越长也越容易触发 RPC 限流建议先用小范围测试。4.3 编写扫描脚本创建scanner.py完整代码如下import os import sys import time from datetime import datetime, timezone from dotenv import load_dotenv from web3 import Web3 load_dotenv() RPC_URL os.getenv(RPC_URL) BLOCK_RANGE int(os.getenv(BLOCK_RANGE, 20)) w3 Web3(Web3.HTTPProvider(RPC_URL)) # 最小 ERC20 接口只需读取常用的元数据 TOKEN_ABI [ { constant: True, inputs: [], name: name, outputs: [{name: , type: string}], type: function, }, { constant: True, inputs: [], name: symbol, outputs: [{name: , type: string}], type: function, }, { constant: True, inputs: [], name: decimals, outputs: [{name: , type: uint8}], type: function, }, ] def get_token_meta(address: str): 尝试读取代币名称、符号和小数位数失败返回 None try: contract w3.eth.contract( addressWeb3.to_checksum_address(address), abiTOKEN_ABI ) name contract.functions.name().call() symbol contract.functions.symbol().call() decimals contract.functions.decimals().call() return name, symbol, decimals except Exception: return None def scan_block(block_number: int): 扫描单个区块找出所有新创建的合约地址并返回代币信息 block w3.eth.get_block(block_number, full_transactionsTrue) hits [] for tx in block.transactions: # 创建合约的交易to 字段为 None if tx.get(to) is not None: continue try: receipt w3.eth.get_transaction_receipt(tx[hash]) except Exception: continue contract_address receipt.get(contractAddress) if not contract_address: continue meta get_token_meta(contract_address) if meta is None: continue ts datetime.fromtimestamp( block[timestamp], tztimezone.utc ).strftime(%Y-%m-%d %H:%M:%S) hits.append({ block: block_number, tx_hash: tx[hash].hex(), deployer: tx[from], contract: contract_address, name: meta[0], symbol: meta[1], decimals: meta[2], time: ts, }) return hits def main(): if not w3.is_connected(): print(RPC 连接失败请检查 .env 中的 RPC_URL) sys.exit(1) latest w3.eth.block_number start latest - BLOCK_RANGE 1 print(f当前区块: {latest}扫描范围: {start} ~ {latest}) total 0 for number in range(start, latest 1): try: hits scan_block(number) except Exception as err: print(f区块 {number} 扫描异常: {err}) continue for hit in hits: total 1 print( * 60) print(f时间: {hit[time]}) print(f代币名称: {hit[name]} ({hit[symbol]})) print(f合约地址: {hit[contract]}) print(f部署地址: {hit[deployer]}) print(f所在区块: {hit[block]}) print(f交易哈希: {hit[tx_hash]}) time.sleep(0.2) print(f\n扫描完成共发现 {total} 个可读取元数据的新合约。) if __name__ __main__: main()这段脚本的完整逻辑是先连接 RPC遍历指定区块范围内的每一笔交易筛选出“to 字段为空”的合约创建交易然后通过 receipt 拿到合约地址最后尝试读取代币名称、符号和小数位数。如果一个合约连这三个基础方法都不可读通常说明它不符合标准 ERC20 结构需要额外注意。4.4 运行与预期输出在.env中配置好 RPC 后运行python scanner.py预期输出类似当前区块: 20123456扫描范围: 20123437 ~ 20123456 时间: 2025-01-15 08:32:11 代币名称: Test Token (TT) 合约地址: 0x1234... 部署地址: 0xabcd... 所在区块: 20123440 交易哈希: 0xdeadbeef... ... 扫描完成共发现 3 个可读取元数据的新合约。注意公共 RPC 节点对大量eth_getBlockByNumber和eth_getTransactionReceipt请求非常敏感很容易出现超时或 429 限流。如果遇到这种情况可以调小BLOCK_RANGE或者在每次请求之间加更长的 sleep 时间。4.5 把脚本扩展为持续监控实际使用中手动运行一次脚本意义有限我们通常希望它持续轮询新区块。可以加一层while True循环每隔一段时间扫描一次最新区块def loop_forever(interval: int 30): last_block w3.eth.block_number while True: latest w3.eth.block_number if latest last_block: for number in range(last_block 1, latest 1): hits scan_block(number) for hit in hits: # 这里可以接数据库、钉钉/飞书机器人、Telegram Bot 等 print(发现新合约:, hit) last_block latest time.sleep(interval)这个版本会在每次新出块后自动扫描真正做到“链上事件驱动”。你可以把输出部分替换为写入数据库或发送告警通知。5. 进阶从“发现”到“交叉验证”扫描到新合约只是第一步能不能从潜在目标中过滤出更值得关注的信号取决于后续验证。以下是我在半个月里反复使用的几个验证维度。5.1 解析 Transfer 事件统计持有人增长代币持有人数量可以用 Transfer 事件的接收地址集合近似估算。思路如下从合约部署区块开始解析 Transfer 事件记录所有to地址去重后得到近似持有人数量。如果某个新合约在短时间内出现几十甚至上百个不同接收地址说明分发正在发生。下面是一个读取 Transfer 事件数量的核心片段TRANSFER_EVENT_ABI { anonymous: False, inputs: [ {indexed: True, name: from, type: address}, {indexed: True, name: to, type: address}, {indexed: False, name: value, type: uint256}, ], name: Transfer, type: event, } def count_transfer_events(token_address: str, from_block: int, to_block: int None): if to_block is None: to_block w3.eth.block_number contract w3.eth.contract( addressWeb3.to_checksum_address(token_address), abi[TRANSFER_EVENT_ABI] ) logs contract.events.Transfer().get_logs( from_blockfrom_block, to_blockto_block ) return len(logs)通过get_logs可以拿到指定范围内的全部事件。如果需要统计持有人的完整地址集合只需要遍历 logs 里的args.to并放入 set 即可。5.2 检查部署者与初始转账部署者地址是新合约最关键的关联方。通过查看部署者的历史交易可以判断这个地址是否属于批量部署工具或者是同一个项目方连续部署过多份合约。建议把部署者地址在区块浏览器中打开重点看三件事部署了多少个合约。代币创建后是否立即转出了大部分 supply。部署者地址是否与池子创建地址高度重合。如果同一个部署者在一个月内创建了大量内容相似的代币合约这属于典型的批量生产模式应当格外警惕。5.3 高权重验证清单我这里整理了一份日常使用的检查清单不一定完整但很实用验证项关注点合约是否开源不开源的合约风险显著提高是否存在 owner/管理员地址有权限地址需要重点监控是否创建了流动性池没有池子就没有实际交易渠道池子创建后是否立即移除流动性属于高风险行为持有人拓扑是否过于集中前 10 名持有比例过高是风险信号是否有公开社区和代码仓库完全匿名且无公开资料需谨慎代码是否有隐藏增发/黑名单函数需要专业工具进一步审计把这套清单做成自动化的评分系统就是个人链上筛选框架的雏形。每个指标赋一个权重最后生成综合评分可以有效减少情绪化决策。6. 常见问题与排查思路这半个月里我也遇到了不少工程上的坑最常见的有下面几类。问题现象常见原因解决思路RPC 连接失败节点地址错误、网络不可达、服务商限制检查 .env 配置换一个稳定节点测试请求频繁被限流公共节点对并发量有限制降低扫描频率增加 sleep或使用私有节点扫描区块速度很慢每个区块一笔笔获取 receipt串行请求太多缩小 BLOCK_RANGE使用异步 Web3 或批量请求合约元数据读不出来合约不是标准 ERC20或调用方法名不匹配不要硬读记录地址后转人工分析事件日志解析失败ABI 与链上事件签名不一致确认事件定义、indexed 字段和 topic 对应关系时区显示混乱区块时间戳是 Unix 时间戳直接本地格式化导致偏差统一用 UTC 时间并在展示层转换如果你也想做链上监控我的建议是先跑通最小脚本再叠加信号先学会控制回撤再谈寻找机会。链上数据的迷人之处在于每个地址都留下了痕迹但能不能从中读出有效信息取决于你的数据工程能力。7. 最佳实践与工程建议7.1 基础设施层面不要把所有请求都打到一个公共节点。更好的做法是维护一个 RPC 节点池在请求失败时自动切换。另一方面扫描程序不能只存在内存里需要把关键数据落库比如使用 SQLite 或 PostgreSQL 保存每次扫描到的合约地址和事件日志方便回溯分析。另外告警推送要设计成可配置的。最开始可以只打印日志跑通后再接入钉钉、飞书或 Telegram Bot避免在开发阶段被通知轰炸。7.2 数据处理层面链上原始数据非常“脏”。新合约可能伪造 name 和 symbolTransfer 事件里的 value 也可能因为 decimals 不同而误导判断。建议所有数据统一转换为标准单位后再做比较。同时保留原始值方便排查问题。解析合约时要注意异常处理。一个恶意合约可能在name()调用中抛异常甚至故意返回超大字符串阻塞你的脚本。所有外部调用都应该包 try-except并设置合理的超时时间。7.3 安全与风险控制这是最重要的一条。脚本中永远不要保存私钥或助记词任何需要签名的操作都要单独放在隔离环境里。使用第三方节点时不要在请求参数中带敏感信息如果后续做监控机器人机器人只负责“观察和提醒”不要负责“自动下单”更不要碰链上资产。从风险控制角度看链上代币天然存在极高不确定性。即使所有链上信号都正常也不能保证项目不会跑路。一定要把仓位控制在自己能接受的损失范围内并且充分理解“本金归零”的可能性。8. 总结与下一步这半个月的链上追踪经历让我意识到真正重要的不是抓到某个具体代币而是沉淀出一套稳定的数据流水线扫描合约、解析事件、统计持有人、交叉验证、记录结果。把这些环节自动化之后每天只需要花很少时间查看异常信号即可。如果你也想做链上监控我的建议是先跑通最小脚本再叠加信号先学会控制回撤再谈寻找机会。链上数据的迷人之处在于每个地址都留下了痕迹但能不能从中读出有效信息取决于你的数据工程能力。下一步可以继续研究事件日志过滤、LP 池子监控、持有人聚类分析以及把多个链上的数据统一接入同一套监控体系。先从一个简单的 Python 脚本开始把流程跑顺再逐步扩展成真正属于自己的链上数据监控系统。