币安链预售抢购机器人,支持pinksale、dxsale(附代码)

环境准备 :

安装 nodejs,vscode

使用方法 :

  1. 安装npm 依赖
  2. 重命名.env.example文件为.env文件,并按照要求添加相应参数(具体要求下面会写)
  3. 执行 node sniper-bot.js

.env配置文件

# 节点 默认BSC主网 测试网:https://data-seed-prebsc-1-s1.binance.org:8545
node=https://bsc-dataseed.binance.org/
# 预售地址(复制PinkSale或DxSale的预售地址,注意不是Token合约地址)
presaleContractAddress=0xA926e7C0F6afA20569f7425bB3E93017C813****
# 购买bnb数量
buyingBnbAmount=2

# 助记词和私钥二选一,助记词优先级高于私钥,若助记词为空,则读取私钥。私钥支持多个钱包,使用英文逗号隔开,助记词暂时不支持多个钱包
# 助记词
mnemonic="civil planet ......"
# 私钥(支持多个私钥,使用英文逗号隔开)
senderPrivateKey=

# 热度高的项目建议使用200-2000
gasPrice=25
# 机器人延时启动
hours=0
mins=0
secs=0

代码:

sniper-bot.js

// const fs = require('fs');
const Cronr = require('cronr');
const Web3 = require('web3');
const dotenv = require("dotenv")
const chalk = require("chalk")

const projectData = require("./utils").projectData


dotenv.config()
// var logsDir = __dirname + '/logs/';
// // 创建日志输出路径
// if (!fs.existsSync(logsDir)) {
//     fs.mkdirSync(logsDir);
// }

// ======================== 读取配置 ========================
var node = process.env.node || 'https://bsc-dataseed.binance.org/';
var chainId = 56;
var gasLimit = process.env.gasLimit || 500000; // in gwei
var gasPrice = process.env.gasPrice || 10; // in gwei
gasPrice = gasPrice * 1000000000;
var cronTime = '*/100 * * * * * *'; // every 10 milliseconds 每10毫秒

var hours = process.env.hours || 0
var mins = process.env.mins || 0
var secs = process.env.secs || 5

var delaySecs = parseInt(hours) * 3600 + parseInt(mins) * 60 + parseInt(secs) // 延迟的秒数
var botInitialDelay = delaySecs * 1000; // 机器人延时启动毫秒

const presaleContractAddress = process.env.presaleContractAddress // 预售地址
const buyingBnbAmount = process.env.buyingBnbAmount // 购买的bnb数量

const mnemonic = process.env.mnemonic || "" // 助记词
let senderPrivateKey = process.env.senderPrivateKey || "" // 私钥


if (mnemonic) {
    console.log(chalk.blue("检测到使用助记词方式导入钱包"))
    projectData.utils.getPrivateKey(mnemonic).then(res => {
        senderPrivateKey = res
    })
} else {
    console.log(chalk.blue("检测到使用私钥方式导入钱包"))
}

// ======================== 读取配置 ========================

var web3 = new Web3(new Web3.providers.HttpProvider(node));


async function initBot() {
    if (presaleContractAddress === '' || presaleContractAddress == null || presaleContractAddress.length !== 42 || await web3.eth.getCode(presaleContractAddress) === '0x') {
        return console.error('预售地址没填写或填写错误,预售地址必须是合约地址');
    } else if (buyingBnbAmount === '' || buyingBnbAmount == null) {
        return console.error('购买BNB的数量填写错误');
    } else if (senderPrivateKey === '' || senderPrivateKey == null) {
        return console.error('私钥填写错误');
    }

    var privateKeys = [];
    if (senderPrivateKey.indexOf(',') > -1) {
        privateKeys = senderPrivateKey.split(',');
    } else {
        privateKeys.push(senderPrivateKey);
    }

    var addressesUsedToSendTransactions = ''; // 钱包地址
    var firstIteration = true;
    for (var i = 0, len = privateKeys.length; i < len; i+=1) {
        if (privateKeys[i].length !== 66) {
            return console.error('需要传入一个或多个钱包私钥,多个钱包私钥请使用,作为分隔符');
        }

        if (firstIteration) {
            firstIteration = false;
            addressesUsedToSendTransactions += web3.eth.accounts.privateKeyToAccount(privateKeys[i]).address;
        } else {
            addressesUsedToSendTransactions += ', ' + web3.eth.accounts.privateKeyToAccount(privateKeys[i]).address;
        }
    }

    var senderAddress = web3.eth.accounts.privateKeyToAccount(privateKeys[0]).address;
    web3.eth.getBalance(senderAddress).then(r => {
        const balance = r / 1000000000000000000
        console.log("====================================================")
        console.log(`预售地址:`, chalk.green(presaleContractAddress))
        console.log(`钱包地址:`, chalk.green(addressesUsedToSendTransactions));
        console.log(`钱包余额:`, chalk.green(`${balance} BNB`))
        console.log(`购买数量:`, chalk.green(`${buyingBnbAmount} BNB`))
        console.log(`Gas limit: ${gasLimit}`);
        console.log(`Gas price: ${(gasPrice / 1000000000) + ' Gwei'}`);
        console.log(`矿工费: < ${(gasLimit * (gasPrice / 1000000000)) / 1000000000} BNB (Gax used x Gas price)`)
        console.log("====================================================")
        if (parseFloat(buyingBnbAmount) > balance) {
            console.log(chalk.red("钱包余额不足,已自动退出"))
            process.exit()
        }
    })


    if (botInitialDelay > 0) {
        console.log(`${hours}小时${mins}分钟${secs}秒后启动机器人 (${botInitialDelay / 1000}秒)`)
        console.log("等待中......")
    } else {
        console.log('启动成功... ¯\\_(*o*)_/¯');
    }


    setTimeout(function () {
        var executeBuy = true;
        const job = new Cronr(cronTime, function() {
            // projectData.utils.consoleLog('Cronjob iteration.');
            if (executeBuy) {
                executeBuy = false;

                var counter = 0;
                return recursiveTransactionsLoop(counter);

                function recursiveTransactionsLoop(counter) {
                    var senderAddress = web3.eth.accounts.privateKeyToAccount(privateKeys[counter]).address;

                    web3.eth.estimateGas({to: presaleContractAddress, from: senderAddress, value: web3.utils.toHex(web3.utils.toWei(buyingBnbAmount, 'ether'))}, function(gasEstimateError, gasAmount) {
                        if (!gasEstimateError) {
                            projectData.utils.consoleLog('Transaction estimation successful: ' + gasAmount);

                            var txParams = {
                                gas: web3.utils.toHex(gasLimit),
                                gasPrice: web3.utils.toHex(gasPrice),
                                chainId: chainId,
                                value: web3.utils.toHex(web3.utils.toWei(buyingBnbAmount, 'ether')),
                                to: presaleContractAddress
                            };

                            web3.eth.accounts.signTransaction(txParams, privateKeys[counter], function (signTransactionErr, signedTx) {
                                if (!signTransactionErr) {
                                    web3.eth.sendSignedTransaction(signedTx.rawTransaction, function (sendSignedTransactionErr, transactionHash) {
                                        if (!sendSignedTransactionErr) {
                                            if (counter === privateKeys.length - 1) {
                                                if (privateKeys.length === 1) {
                                                    projectData.utils.consoleLog(`first and only transaction sent success. Transaction hash: ${transactionHash}. https://www.bscscan.com/tx/${transactionHash}`);
                                                } else {
                                                    projectData.utils.consoleLog(`Completed last transaction. Transaction hash: ${transactionHash}. https://www.bscscan.com/tx/${transactionHash}`);
                                                }
                                            } else {
                                                projectData.utils.consoleLog('Completed transaction. Transaction hash: ' + transactionHash);
                                                counter+=1;
                                                return recursiveTransactionsLoop(counter);
                                            }
                                        } else {
                                            executeBuy = true;
                                            if (sendSignedTransactionErr.message) {
                                                projectData.utils.consoleLog('sendSignedTransaction failed, most likely signed with low gas limit.. Message: ' + sendSignedTransactionErr.message);
                                            } else {
                                                projectData.utils.consoleLog('sendSignedTransaction failed, most likely signed with low gas limit.. Message: ' + sendSignedTransactionErr.toString());
                                            }

                                            if (counter !== privateKeys.length - 1) {
                                                counter+=1;
                                                return recursiveTransactionsLoop(counter);
                                            }
                                        }
                                    })
                                        .on("receipt", () => {
                                            console.log(chalk.green(`Transaction confirmed.`))
                                        })
                                        .on("error", (err) => {
                                            console.log("Error during transaction execution. Details will follow.")
                                            console.log(err)
                                        })
                                } else {
                                    executeBuy = true;
                                    if (signTransactionErr.message) {
                                        projectData.utils.consoleLog('signTransaction failed, most likely signed with low gas limit. Message: ' + signTransactionErr.message);
                                    } else {
                                        projectData.utils.consoleLog('signTransaction failed, most likely signed with low gas limit. Message: ' + signTransactionErr.toString());
                                    }

                                    if (counter !== privateKeys.length - 1) {
                                        counter+=1;
                                        return recursiveTransactionsLoop(counter);
                                    }
                                }
                            });
                        } else {
                            executeBuy = true;
                            if (gasEstimateError.message) {
                                projectData.utils.consoleLog('estimateGas failed. Error message: ' + gasEstimateError.message);
                            } else {
                                projectData.utils.consoleLog('estimateGas failed. Error message: ' + gasEstimateError.toString());
                            }

                            if (counter !== privateKeys.length - 1) {
                                counter+=1;
                                return recursiveTransactionsLoop(counter);
                            }
                        }
                    });
                }
            }
        }, {});
        job.start();
    }, botInitialDelay);
}
initBot();

utils.js 

const fs = require('fs');
const bip39 = require("bip39")
const HdWallet = require("ethereum-hdwallet")

var logsDir = __dirname + '/logs/';
var logsPath = logsDir + 'sniper-bot-' + new Date().toISOString().slice(0,10) + '.txt';
const projectData = {
    utils: {
        createLog: function(content) {
            if (fs.existsSync(logsPath)) {
                content = '\r\n' + new Date().toLocaleTimeString() + ': ' + content;
                console.log(content);
            }
            fs.appendFile(logsPath, content, function (err) {
                if (err) throw err;
            });
        },
        consoleLog: function (content) {
            content = '\r' + new Date().toLocaleTimeString() + ': ' + content;
            console.log(content);
        },
        propertyExists: function(object, key) {
            return object ? hasOwnProperty.call(object, key) : false;
        },
        async getPrivateKey(mnemonic) {
            // 助记词转私钥
            const seed = await bip39.mnemonicToSeed(mnemonic)
            const hdwallet = HdWallet.fromSeed(seed)
            const key = hdwallet.derive("m/44'/60'/0'/0/0")
            return "0x" + key.getPrivateKey().toString("hex")
        }
    }
};
module.exports = {
    projectData,
}

猜你喜欢

转载自blog.csdn.net/bareape/article/details/124590655