You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Web3单交易中完成买卖以检测蜜罐代币?

单次交易完成代币买卖检测蜜罐方案及优化检测方法

一、单交易内完成买入+卖出的可行性与实现方案

完全可以通过Web3实现,核心是将买入、授权、卖出操作打包进同一笔交易,两种常用方案如下:

方式1:Multicall批量调用(无需自定义合约)

利用Multicall合约将多个操作合并,步骤为授权Router花费代币→买入代币→卖出代币,适合快速验证:

from web3 import Web3
import time

# 初始化配置
web3 = Web3(Web3.HTTPProvider("YOUR_BSC_RPC_URL"))
pan_router = web3.eth.contract(address=panRouterContractAddress, abi=panabi)
# BSC官方Multicall地址
multicall_addr = web3.toChecksumAddress("0x1Ee38d535d541c55C9dae27B12edf090C608E6Fb")
multicall_contract = web3.eth.contract(address=multicall_addr, abi=MULTICALL_ABI)
wbnb_addr = web3.toChecksumAddress("0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c")
sender_addr = web3.toChecksumAddress("YOUR_WALLET_ADDRESS")
private_key = "YOUR_PRIVATE_KEY"

def buy_sell_single_tx(token, wbnb_amount):
    token_addr = web3.toChecksumAddress(token)
    nonce = web3.eth.get_transaction_count(sender_addr)
    
    # 1. 授权Router无限额度使用代币(避免重复授权)
    approve_data = pan_router.encodeABI(
        fn_name="approve",
        args=[panRouterContractAddress, web3.toWei(2**256 - 1, 'wei')]
    )
    
    # 2. 买入代币:swapExactETHForTokens
    buy_data = pan_router.encodeABI(
        fn_name="swapExactETHForTokens",
        args=[
            0,
            [wbnb_addr, token_addr],
            sender_addr,
            int(time.time()) + 10000
        ]
    )
    
    # 3. 估算买入所得代币数量,设置卖出参数
    buy_amount_out = pan_router.functions.getAmountsOut(
        web3.toWei(wbnb_amount, 'ether'),
        [wbnb_addr, token_addr]
    ).call()[1]
    # 留1%滑点,避免因价格波动交易失败
    min_eth_out = int(buy_amount_out * 0.99)
    
    sell_data = pan_router.encodeABI(
        fn_name="swapExactTokensForETH",
        args=[
            buy_amount_out,
            min_eth_out,
            [token_addr, wbnb_addr],
            sender_addr,
            int(time.time()) + 10000
        ]
    )
    
    # 打包三个操作进Multicall
    calls = [
        (panRouterContractAddress, approve_data),
        (panRouterContractAddress, buy_data),
        (panRouterContractAddress, sell_data)
    ]
    
    # 构建Multicall交易
    multicall_txn = multicall_contract.functions.aggregate(calls).buildTransaction({
        'from': sender_addr,
        'value': web3.toWei(wbnb_amount, 'ether'),
        'gasPrice': web3.toWei('5', 'gwei'),
        'nonce': nonce,
        'gas': web3.eth.estimate_gas({
            'from': sender_addr,
            'to': multicall_addr,
            'data': multicall_contract.encodeABI(fn_name="aggregate", args=[calls]),
            'value': web3.toWei(wbnb_amount, 'ether')
        }) + 150000  # 预留额外gas
    })
    
    # 签名并发送
    signed_txn = web3.eth.account.sign_transaction(multicall_txn, private_key=private_key)
    tx_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
    return web3.toHex(tx_hash)

方式2:自定义封装合约(更可靠)

编写Solidity合约封装完整逻辑,避免批量调用的参数错误,还能规避部分蜜罐的合约检测:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IUniswapV2Router02 {
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts);
}

interface IERC20 {
    function balanceOf(address account) external view returns (uint);
    function approve(address spender, uint amount) external returns (bool);
}

contract HoneypotChecker {
    IUniswapV2Router02 public immutable router;
    address public constant WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;

    constructor(address _router) {
        router = IUniswapV2Router02(_router);
    }

    function check(address token) external payable returns (bool) {
        // 买入代币
        address[] memory path = new address[](2);
        path[0] = WBNB;
        path[1] = token;
        router.swapExactETHForTokens{value: msg.value}(0, path, address(this), block.timestamp + 10000);

        uint256 tokenBal = IERC20(token).balanceOf(address(this));
        require(tokenBal > 0, "No tokens received");

        // 授权并卖出
        IERC20(token).approve(address(router), tokenBal);
        path[0] = token;
        path[1] = WBNB;
        router.swapExactTokensForETH(tokenBal, 0, path, msg.sender, block.timestamp + 10000);

        return true; // 执行到此处则非蜜罐
    }

    receive() external payable {}
}

Web3调用示例:

def check_with_contract(token, wbnb_amount):
    checker_addr = web3.toChecksumAddress("YOUR_CHECKER_CONTRACT_ADDRESS")
    checker_contract = web3.eth.contract(address=checker_addr, abi=CHECKER_ABI)
    
    nonce = web3.eth.get_transaction_count(sender_addr)
    txn = checker_contract.functions.check(
        web3.toChecksumAddress(token)
    ).buildTransaction({
        'from': sender_addr,
        'value': web3.toWei(wbnb_amount, 'ether'),
        'gasPrice': web3.toWei('5', 'gwei'),
        'nonce': nonce,
        'gas': web3.eth.estimate_gas(txn) + 200000
    })
    
    signed_txn = web3.eth.account.sign_transaction(txn, private_key=private_key)
    tx_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
    return web3.toHex(tx_hash)

二、更优的蜜罐检测方法

除了单交易实测,这些手段更高效且成本更低:

  • 静态合约分析:直接解析代币合约代码,重点检查:
    • transfer/transferFrom函数是否限制普通地址转出(如白名单判断)
    • 是否存在卖出时收取超过50%的手续费、或直接销毁代币的逻辑
    • 是否有隐藏的_beforeTokenTransfer钩子,拦截转出操作
  • 链下模拟交易:用web3.eth.call()模拟卖出操作,无需真实上链,比如调用swapExactTokensForETH的模拟请求,看是否返回错误
  • 流动性与交易历史检查:
    • 通过Factory合约查询LP代币流向,确认是否被锁定到黑洞地址
    • 查看代币交易记录,若只有项目方地址能转出,大概率是蜜罐

三、注意事项

  • 实测时用极小金额(如0.0001 BNB),避免不必要损失
  • 部分蜜罐会检测调用者是否为合约,此时优先用EOA地址的Multicall方案
  • 模拟交易时要确保参数完整(如授权状态、滑点设置)

内容的提问来源于stack exchange,提问作者Soma Juice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:18:39