目录
- [貔貅币 (Honeypot Token) 识别与防御](#貔貅币 (Honeypot Token) 识别与防御)
-
- [1. 什么是貔貅币](#1. 什么是貔貅币)
- [2. 受害者视角:一次典型的"上当流程"](#2. 受害者视角:一次典型的"上当流程")
- [3. 合约层面的常见实现手法](#3. 合约层面的常见实现手法)
-
- [3.1 卖出直接 revert](#3.1 卖出直接 revert)
- [3.2 黑名单 / 白名单](#3.2 黑名单 / 白名单)
- [3.3 极端高税 (Fee on Transfer)](#3.3 极端高税 (Fee on Transfer))
- [3.4 可升级的 transfer 逻辑 (代理合约 / 可改税率)](#3.4 可升级的 transfer 逻辑 (代理合约 / 可改税率))
- [3.5 余额 rebase / 隐性扣减](#3.5 余额 rebase / 隐性扣减)
- [3.6 假转账 (Fake Transfer Event)](#3.6 假转账 (Fake Transfer Event))
- [4. 如何识别 (人工排查清单)](#4. 如何识别 (人工排查清单))
- [5. 自动化检测方案](#5. 自动化检测方案)
-
- [5.1 基于 eth_call 的"模拟交易" (最有效)](#5.1 基于 eth_call 的"模拟交易" (最有效))
- [5.2 静态分析 (字节码 / 源码)](#5.2 静态分析 (字节码 / 源码))
- [5.3 行为指标 (链上数据)](#5.3 行为指标 (链上数据))
- [5.4 综合分层方案 (推荐)](#5.4 综合分层方案 (推荐))
- [6. 面向普通用户的现成检测工具](#6. 面向普通用户的现成检测工具)
- [7. remix 貔貅币实践测试](#7. remix 貔貅币实践测试)
-
- [1 环境准备](#1 环境准备)
- [2 部署合约](#2 部署合约)
- [3 初始状态验证(陷阱关闭)](#3 初始状态验证(陷阱关闭))
- [4 激活貔貅陷阱](#4 激活貔貅陷阱)
- [5 验证陷阱效果](#5 验证陷阱效果)
- [8. 给安全平台的实践建议](#8. 给安全平台的实践建议)
- [9. 参考资料](#9. 参考资料)
- [10. 一句话总结](#10. 一句话总结)
貔貅币 (Honeypot Token) 识别与防御
面向新人和安全研究者。读完应该能回答: 什么是貔貅币?它怎么骗人的?我作为用户怎么避坑?我作为安全平台怎么自动检测它?
1. 什么是貔貅币
貔貅 (pí xiū) 是中国神话里的一种神兽,传说"只进不出"。在加密货币圈,貔貅币 (Honeypot Token / Pixiu Token) 借用了这个意象:
你能买进,但你卖不出去。
具体表现:
- 用户在 PancakeSwap / Uniswap 上看到某个新 token 价格暴涨,FOMO 买入
- 钱包里也确实显示有余额
- 想卖的时候,要么交易直接 revert,要么卖出后到手金额接近 0
- 项目方 / 部署者却可以正常卖出(甚至砸盘跑路)
这是 Web3 里最经典也最高发的诈骗手法之一,主要出现在 BSC、ETH 等支持任意 ERC-20 / BEP-20 部署的链上。
2. 受害者视角:一次典型的"上当流程"
1. Telegram / X / 小红书看到推荐 → "百倍币 $SCAM 已上线 Pancake"
2. 链上看 K 线: 一直涨,持有人数持续增长 (其实是机器人地址)
3. 用 BNB swap → SCAM, 钱包确实到账
4. 想卖出锁利润 → MetaMask 弹 "Transaction will likely fail"
5. 强行提高 gas / 滑点 → 交易上链但只到账 0.0001 BNB (99% 被扣)
6. 几小时后 LP 被项目方撤掉 → 池子归零,币变成纯空气
这一整套流程在合约层面是完全合法的代码行为,没有"漏洞",只是规则对用户极度不利。
3. 合约层面的常见实现手法
貔貅币的核心都是在 transfer / _transfer 函数里对"非白名单地址"或"卖出方向"做特殊限制。常见招数:
3.1 卖出直接 revert
最粗暴的一种。检测到 to == pair(向池子转账即卖出)时直接抛错:
solidity
function _transfer(address from, address to, uint256 amount) internal override {
if (to == uniswapV2Pair && from != owner) {
revert("Anti-bot"); // 任何人卖都失败
}
super._transfer(from, to, amount);
}
变种:用 require(from == owner || to != pair)、或者通过一个 canSell mapping 控制。
3.2 黑名单 / 白名单
只有白名单地址(开发者自己 + 给网红的地址)能卖:
solidity
mapping(address => bool) private _blacklist;
function _transfer(address from, address to, uint256 amount) internal override {
require(!_blacklist[from], "Blacklisted");
...
}
变种:默认所有人黑名单,只白名单几个地址;或者根据"买入时间窗口"动态拉黑。
3.3 极端高税 (Fee on Transfer)
允许卖,但对卖出方向收 99% 税:
solidity
uint256 public sellTax = 99;
function _transfer(address from, address to, uint256 amount) internal override {
uint256 fee = 0;
if (to == uniswapV2Pair) {
fee = amount * sellTax / 100; // 99% 给 owner / 销毁
}
super._transfer(from, address(this), fee);
super._transfer(from, to, amount - fee);
}
用户卖 1000 SCAM,实际只到账等价 10 SCAM 的 BNB ------ 体感和"卖不出去"一样。
3.4 可升级的 transfer 逻辑 (代理合约 / 可改税率)
合约用 proxy / setTaxRate(uint) 函数,初始 0% 税,等流量上来 owner 调成 99%。初期审计看不出问题,因为代码确实没毒,但 owner 有钥匙。
3.5 余额 rebase / 隐性扣减
balanceOf(user) 返回的数字看着没变,但内部记账已经把余额清零;或者每个区块自动减少非白名单地址的余额。
3.6 假转账 (Fake Transfer Event)
transfer 函数只 emit 了 Event 但没真的改 storage,让区块浏览器看着像有币,实际链上余额是 0。比较少见但出现过。
4. 如何识别 (人工排查清单)
给散户的快速 checklist:
| 检查项 | 怎么看 | 危险信号 |
|---|---|---|
| 合约是否开源 | BscScan / Etherscan 的 Contract 标签 | 未开源 = 直接 pass |
| 是否有 proxy / 可升级 | 看是否是 EIP-1967 proxy | owner 可随时改逻辑 |
| owner 权限 | owner() 是否已 renounce 到 0x000... |
未 renounce 风险高 |
| 税率函数 | 是否有 setTax, setFee, setBlacklist 等 owner-only 函数 |
有 = 风险 |
| LP 是否锁仓 | LP token 是否在 PinkLock / Unicrypt | 未锁 = rug 风险 |
| 持仓集中度 | Top 10 holders 占比 | 单地址 > 5% 警惕 |
| 真实交易模拟 | 用工具试着 sell 1 wei | revert / 高税立刻露馅 |
| 历史交易 | 是否只有买没有卖 / 卖的全是同一个地址 | 典型貔貅特征 |
5. 自动化检测方案
5.1 基于 eth_call 的"模拟交易" (最有效)
核心思想:不真的花钱,模拟一次完整的"买 → 卖"交易,看链上节点返回什么。
伪代码:
python
def is_honeypot(token_address, router, weth):
# 1. 用一个有钱的"测试地址"在 fork 上模拟
state = fork_chain_at_latest_block()
# 2. 模拟用 0.01 ETH 买入
buy_tx = router.swapExactETHForTokens(
amountOutMin=0,
path=[weth, token_address],
to=test_address,
deadline=...,
)
buy_result = state.call(buy_tx, value=0.01 ether)
if buy_result.reverted:
return "BUY_FAILED" # 也是异常,但不是貔貅
tokens_received = buy_result.amount_out
# 3. 模拟把买到的 token 全部卖出
sell_tx = router.swapExactTokensForETHSupportingFeeOnTransferTokens(
amountIn=tokens_received,
amountOutMin=0,
path=[token_address, weth],
to=test_address,
deadline=...,
)
sell_result = state.call(sell_tx)
if sell_result.reverted:
return "HONEYPOT_CANNOT_SELL" # 经典貔貅
eth_back = sell_result.amount_out
tax = 1 - eth_back / 0.01
if tax > 0.5:
return f"HIGH_TAX:{tax:.0%}" # 高税貔貅
return "OK"
技术栈:
- Anvil / Hardhat fork:本地 fork 主网,免费、快、可重置 state
- Tenderly Simulation API:托管方案,按调用收费
- eth_call 直接 batch :在 RPC 层用 state override 一次性模拟两步交易(Phalcon 系列工具的做法)
5.2 静态分析 (字节码 / 源码)
对没开源的合约,反编译字节码扫描可疑模式:
- 是否存在仅 owner 可调用的
setBlacklist/setTaxselector _transfer中是否有针对pair地址的特殊分支- 是否使用 proxy delegate call (升级风险)
工具:
- Slither (有源码时)
- GoPlus Token Security API --- 直接返回 honeypot / buy_tax / sell_tax / can_take_back_ownership 等字段
- Honeypot.is --- 单链查询,免费
5.3 行为指标 (链上数据)
即使合约没明显貔貅代码,也可以通过链上行为打分:
- Sell:Buy 比例:正常 token 1:1 ~ 1:2,貔貅币常见 0:N
- 唯一卖家数 / 唯一买家数:貔貅币卖家高度集中(只有 owner 在卖)
- 首次交易后的 LP 变化:LP 是否被快速抽走
- deployer 与早期持有者的关系:地址聚类、资金来源同一 CEX 提币
这些指标可以从 Hive 数仓里跑出来 (链上交易表 → token 维度聚合)。
5.4 综合分层方案 (推荐)
Layer 1 GoPlus / Honeypot.is API ← 几毫秒,覆盖已知 token
↓ 未命中
Layer 2 自建 Anvil fork 模拟买卖 ← 几秒,覆盖新 token
↓ 模拟通过
Layer 3 行为指标打分 + 持续监控 ← 离线,发现"延迟貔貅"(后期改税)
↓ 异常
Layer 4 静态分析 + 人工 review ← 处理 proxy / 加密 logic 等深水区
每一层都有 false positive,组合使用能压到很低。
6. 面向普通用户的现成检测工具
不是每个人都需要自建检测服务。对散户来说,下面这几个工具在交易前花 30 秒查一下,能挡掉 90% 以上的貔貅币:
| 工具 | 链支持 | 核心能力 | 适合场景 |
|---|---|---|---|
| Honeypot.is | ETH / BSC / Base 等 | 专门检测代币是否为貔貅币的利器,直接给出"能买能卖"的结论 + 买卖税率 | 输入合约地址做最快速的 yes/no 判断 |
| DEXTools / Dexscreener | 全链 | 看 K 线时右侧通常集成了安全检测分数 (如 GoPlus Security),自动标出合约高危风险 (蜜罐 / 高税 / 可改税 / 黑名单等) | 边看 K 线边顺手做风控 |
| Token Sniffer | ETH / BSC 为主 | 输入地址后从"合约是否开源"、"是否存在冒牌代币 (clone scam)"、"流动性是否锁定"、"持仓集中度"等维度做百分制打分 | 想要一个综合评分,而不只是单一布尔结论 |
| GoPlus Security | 全链最广 | 上面几家很多分数其实都在调用 GoPlus 的底层 API,可以直接用网页版或免费 API | 想拿原始字段自己做二次判断 |
实战建议:
- 不要只信一家。Honeypot.is 说没事 + Token Sniffer 评分 > 80,再考虑下手
- 注意"现在不是貔貅 ≠ 永远不是貔貅"。可改税 / 可升级 (proxy) 的合约今天 0% 税,明天可能就是 99%
- 移动端可以装 Pocket Universe / Wallet Guard 这类钱包插件,在签名前再做一次实时模拟
7. remix 貔貅币实践测试
本节将通过一个简单的 Solidity 合约示例,在 Remix IDE 中演示貔貅币的核心机制是如何运作的。我们将分步展示:
- 部署一个"可切换"的貔貅合约:合约拥有一个开关,项目方可以随时开启或关闭"貔貅模式"。
- 模拟正常交易阶段:在开关关闭时,代币表现正常,允许任意转账,以吸引用户买入。
- 开启陷阱:项目方开启开关,激活貔貅机制。
- 观察效果:普通用户将无法转账或卖出代币,而项目方(合约所有者)仍可自由操作。
这个实践将帮助你直观理解第 3 节中提到的"黑名单/白名单"和"可升级逻辑"等手法的底层实现。
1 环境准备
* 打开 [Remix IDE](https://remix.ethereum.org/)。
* 在文件资源管理器中,新建一个 `.sol` 文件(例如 `HoneypotTest.sol`),并粘贴下方提供的合约代码。
* 在左侧插件面板激活 "Solidity compiler" 插件,选择编译器版本为 `0.8.20` 或更高,然后点击 `Compile HoneypotTest.sol`。
- HoneypotTest.sql
java
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract HoneypotTest is ERC20 {
address public owner;
// The Honeypot switch: when true, normal users cannot transfer/sell tokens
bool public isHoneypotActivated = false;
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_;
}
constructor() ERC20("Honeypot Test Token", "HTT") {
owner = msg.sender;
// Mint 1 million tokens to the owner
_mint(msg.sender, 1000000 * 10 ** decimals());
}
// Owner can turn on the honeypot trap at any time
function activateTrap(bool _status) external onlyOwner {
isHoneypotActivated = _status;
}
// Overriding the internal standard transfer logic
function _update(address from, address to, uint256 value) internal override {
// If the trap is active, ONLY the owner can move tokens.
// Anyone else attempting to transfer (or sell on a DEX) will be blocked.
if (isHoneypotActivated) {
require(from == owner || to == owner, "Honeypot Activated: You cannot sell or transfer!");
}
super._update(from, to, value);
}
}
2 部署合约
* 切换到 "Deploy & run transactions" 插件。
* 在 `ENVIRONMENT` 下拉菜单中选择 `Remix VM (Shanghai)` 或任何测试环境(如 JavaScript VM)。
* 确保 `CONTRACT` 下拉菜单中选中了 `HoneypotTest`。
* 点击 `Deploy`。部署成功后,合约地址会出现在 "Deployed Contracts" 区域。
3 初始状态验证(陷阱关闭)
* 合约部署后,`isHoneypotActivated` 默认为 `false`,即陷阱未激活。
* 此时,合约所有者(部署账户)可以将代币转账给任何其他账户(例如 `Account 2`),接收方也可以自由地将代币转给第三方(例如 `Account 3`)。这模拟了项目方在早期"撒币"营造正常交易假象的阶段。
在貔貅开关开启前,代币必须表现得像正常代币一样,才能骗取散户信任。
如下项目方转账0x5B38Da6a701c568545dCfcB03FcB875f56beddC4到一个普通账户:0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2

普通账户0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2 正常转给另一个账户0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db

4 激活貔貅陷阱
* 在 "Deployed Contracts" 区域,找到 `activateTrap` 函数。
* 在输入框中填入 `true`,然后点击 `activateTrap` 按钮(确保使用合约所有者账户操作)。
* 交易成功后,调用 `isHoneypotActivated` 函数查看,其值应变为 `true`。
项目方设置activateTrap,貔貅机制开启

5 验证陷阱效果
* 现在,让普通用户账户(例如 `Account 2`)尝试向另一个账户(例如 `Account 3`)转账。
* 你会看到交易失败,并返回错误信息:`"Honeypot Activated: You cannot sell or transfer!"`。这模拟了用户在 DEX 上尝试卖出时遭遇的失败。
* **关键对比**:此时,合约所有者(`Account`)再次尝试转账,交易**仍然会成功**。这证明了陷阱只针对普通用户。
0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2 给另一个账户0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db再次尝试转账,则报错

项目方则正常转帐:

- 关闭陷阱(可选) :
- 项目方可以随时调用
activateTrap(false)来关闭陷阱,使代币恢复"正常"。这模拟了某些可升级合约或可修改参数合约的风险------安全状态是暂时的。
- 项目方可以随时调用
8. 给安全平台的实践建议
如果在做一个面向用户的"代币安全扫描"服务,最小可用版本 (MVP):
- 接入 GoPlus Token Security API,覆盖主流链上的已收录 token
- 自建一个 Anvil fork + 模拟买卖 服务,处理新 token / GoPlus 没收录的
- 把结果按风险等级返回:
SAFE/WARNING/HONEYPOT/UNVERIFIED - 重点字段必须返回:
is_honeypot: boolbuy_tax,sell_tax: floatcan_modify_tax: bool (owner 是否能改税)is_proxy: boolowner_renounced: boollp_locked: bool + 解锁时间
- 对 proxy / 可升级 token,每个区块持续监测,owner 改税 → 立刻告警
9. 参考资料
- GoPlus Security Docs: https://docs.gopluslabs.io/
- Honeypot.is: https://honeypot.is/
- BlockSec Phalcon: https://phalcon.blocksec.com/
- "Detecting Honeypots in Smart Contracts" --- 学术论文 (Torres et al., 2019)
- SlowMist 慢雾 --- 历年 rug / honeypot 案例库
10. 一句话总结
貔貅币不是合约漏洞,而是合约规则本身就是陷阱。防御核心是"在花钱之前先模拟一次完整的买卖闭环"。