怎么创建链上抢币机器人的脚本?夹子代码全部开源分享

fffmCQ.jpg

抢币机器人,我们也可以称之为:抢跑交易。这类机器人通常有两个类型,第一种是抢中心化交易所的机器人。当币安或者火币有新币上线的时候,这种机器人会按照设定好的价格快速买入。由于使用的是机器人,比人工速度快,买入的价格低,进而获利较大。

不过今天我们分享的是第二种机器人:链上抢币机器人,也叫夹子。这种机器人,会在开盘的前几个区块买入代币,从而用低价获得大量代币。而在代币价格上涨时,又卖出,实现低买高卖的目的。

这种链上夹子机器人,大多以抢跑区块的方式实现,可以最大限度的降低自己的损失,从而获利。具体怎么实现呢?今天就给大家分享一下这类机器人的合约源码。

怎么创建链上抢币机器人的脚本?夹子代码全部开源分享

一、抢跑原理

链上机器人通过调高gas或其他方法将自己的交易安插在其他交易之前,来攫取价值。什么意思?在用户的交易被矿工打包进坊区块链之前,大部分交易会汇集到交易内存池中,矿工在这里寻找费用高的交易优先打包出块,实现利益最大化。通常来说,gas费越高的交易,越容易被打包。这种时候,机器人就会通过调高自己的Gas费来实现抢跑,进而达到提前交易的目的。

二、实现路径

在了解了原理之后,接下来就要进行实践了。我们以机器人抢跑购买NFT为例,整个过程共分为三个步骤:

  • 搭建本地测试链,请提前安装好 foundry
  • 用remix进行NFT合约的部署和铸造
  • 通过etherjs脚本监听mempool并进行抢跑

1、启动测试链

在安装好 foundry 之后,在命令行输入 anvil –chain-id 1234 -b 10 搭建本地测试链,chain-id 为 1234,每 10 秒产出一个区块。搭建成功后,它会在显示一些测试账户的地址和私钥,每个账户有 10000 ETH。你可以使用它们进行测试。

当然,如果你不想用本地测试链,完全可以使用币安测试链、火币测试链进行测试,这都无关紧要。主要是有这么一个链。

2. 将Remix连接到测试链: 打开 Remix 的部署页面,打开左上角的Environment下拉菜单,选Foundry Provider即可将 Remix 连接到测试链。

怎么创建链上抢币机器人的脚本?夹子代码全部开源分享

3. 部署NFT合约: 在 Remix 上部署一个简单的 freemint(免费铸造)NFT合约。它有一个mint(),用于免费铸造NFT。

// SPDX-License-Identifier: MIT
// By 0xAA
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

// 我们尝试frontrun一笔Free mint交易
contract FreeMint is ERC721 {
    uint256 public totalSupply;

    // 构造函数,初始化NFT合集的名称、代号
    constructor() ERC721("Free Mint NFT", "FreeMint"){}

    // 铸造函数
    function mint() external {
        _mint(msg.sender, totalSupply); // mint
        totalSupply++;
    }
}

4. 部署ethers.js抢跑脚本: 简单来说,frontrun.js脚本监听了测试链mempool中的未决交易,筛选出调用了mint()的交易,然后复制它并调高gas进行抢跑。

// provider.on("pending", listener)
import { ethers, utils } from "ethers";

// 1. 创建provider
var url = "https://127.0.0.1:8545";
const provider = new ethers.providers.WebSocketProvider(url);
let network = provider.getNetwork()
network.then(res => console.log(`[${(new Date).toLocaleTimeString()}] 连接到 chain ID ${res.chainId}`));

// 2. 创建interface对象,用于解码交易详情。
const iface = new utils.Interface([
    "function mint() external",
])

// 3. 创建钱包,用于发送抢跑交易
const privateKey = '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a'
const wallet = new ethers.Wallet(privateKey, provider)

const main = async () => {
    // 4. 监听pending的mint交易,获取交易详情,然后解码。
    console.log("\n4. 监听pending交易,获取txHash,并输出交易详情。")
    provider.on("pending", async (txHash) => {
        if (txHash) {
            // 获取tx详情
            let tx = await provider.getTransaction(txHash);
            if (tx) {
                // filter pendingTx.data
                if (tx.data.indexOf(iface.getSighash("mint")) !== -1 && tx.from != wallet.address ) {
                    // 打印txHash
                    console.log(`\n[${(new Date).toLocaleTimeString()}] 监听Pending交易: ${txHash} \r`);

                    // 打印解码的交易详情
                    let parsedTx = iface.parseTransaction(tx)
                    console.log("pending交易详情解码:")
                    console.log(parsedTx);
                    // Input data解码
                    console.log("raw transaction")
                    console.log(tx);

                    // 构建抢跑tx
                    const txFrontrun = {
                        to: tx.to,
                        value: tx.value,
                        maxPriorityFeePerGas: tx.maxPriorityFeePerGas * 1.2,
                        maxFeePerGas: tx.maxFeePerGas * 1.2,
                        gasLimit: tx.gasLimit * 2,
                        data: tx.data
                    }
                    // 发送抢跑交易
                    var txResponse = await wallet.sendTransaction(txFrontrun)
                    console.log(`正在frontrun交易`)
                    await txResponse.wait()
                    console.log(`frontrun 交易成功`)                
                }
            }
        }
    });

    provider._websocket.on("error", async () => {
        console.log(`Unable to connect to ${ep.subdomain} retrying in 3s...`);
        setTimeout(init, 3000);
      });

    provider._websocket.on("close", async (code) => {
        console.log(
            `Connection lost with code ${code}! Attempting reconnect in 3s...`
        );
        provider._websocket.terminate();
        setTimeout(init, 3000);
    });    
};

main()

5. 调用mint()函数: 在 Remix 的部署页面调用 Freemint 合约的mint() 函数,进行 NFT 铸造。

6. 脚本监听到交易并进行抢跑 我们可以在终端看到 frontrun.js 脚本成功监听到了交易,并进行了抢跑。如果你调用 NFT 合约的 ownerOf() 函数查看 tokenId 为 0 的持有者是抢跑脚本中的钱包地址,证明抢跑成功!

怎么创建链上抢币机器人的脚本?夹子代码全部开源分享

三、预防措施

现在,我们已经理解了链上抢跑机器人的实现方法和路径,那么,如果说我们自己遇到了这种机器人,应该如何预防呢?一般来说,我们没法消除它,但是可以通过减少交易顺序或时间的重要性,减少被抢先交易的收益。比如说使用暗池,用户发出的交易将不进入公开的mempool,而是直接到矿工手里。

最后,如果您开发这种夹子机器人,可以联系我,电报:@dapp165,微信:btc6540

声明:该文观点仅代表作者本人,与炒币网无关。炒币网系信息发布平台,仅提供信息存储空间服务。对所包含内容的准确性、可靠性或者完整性不提供任何明示或暗示的保证,并不对文章观点负责。 提示:投资有风险,入市须谨慎。本资讯仅供参阅,不作为投资理财建议。

发表评论

登录后才能评论