├── .gitignore ├── .env_sample ├── package.json ├── README.md ├── tschecker.js └── buy_nft_bot.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env -------------------------------------------------------------------------------- /.env_sample: -------------------------------------------------------------------------------- 1 | #sample .env file 2 | 3 | INFURA_ID="" 4 | 5 | #your wallet private key 6 | PRIVATE_KEY="" -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "transactionchecker", 3 | "version": "1.0.0", 4 | "description": "Sample mempool checker bot.", 5 | "main": "tschecker.js", 6 | "scripts": { 7 | "dev": "node tschecker.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "Bedrosova Yulia (https://bedrosova.ru)", 11 | "contributors": ["Anthony Sychev (https://dm211.com)"], 12 | "license": "MIT", 13 | "dependencies": { 14 | "web3": "^1.7.4", 15 | "dotenv": "^10.0.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EthereumPendingTransactionChecker - Front Running Attack 2 | 3 | ![](https://cdn-ru.bitrix24.ru/bedrosovar/landing/7de/7de4b8e47ab868fbf45aec9b11eb33b1/bedrosova_logo_1x.png) 4 | 5 | buy_nft_bot.js - Cкрипт - бот, который позволяет минтить NFT на сейле, отправляя опережающие транзакции, 6 | мониторя ethereum mempool как я показывала вам в одном из предыдущих видео и осуществляя Front Running. 7 | 8 | tschecker.js - Скрипт, который мониторит входящие транзакции на кошелек и автоматически отправляет деньги обратно в том же блоке. 9 | 10 | ---- 11 | 12 | buy_nft_bot.js - Bot for buying on minting some NFT project with "Front Running" attack method. 13 | 14 | tschecker.js - Script that monitors incoming wallet transactions and automatically sends money back in the same block. 15 | 16 | In this method we increse GAS value for accelerate transaction on buy of same NFT. 17 | 18 | ## Install & Run 19 | 20 | * Install dependeces `npm i` 21 | * Run scripts `env $(cat .env) node tschecker.js`, `env $(cat .env) node buy_nft_bot.js` 22 | 23 | ## YouTube 24 | Watch the videos on my channel: 25 | * https://youtu.be/AiWZEgSAdhc 26 | * https://youtu.be/IhvQ9WdGmi4 27 | * https://youtu.be/-e1zV8qEDmw 28 | -------------------------------------------------------------------------------- /tschecker.js: -------------------------------------------------------------------------------- 1 | const dotenv = require('dotenv'); 2 | dotenv.config(); 3 | 4 | const { 5 | INFURA_ID, 6 | PRIVATE_KEY 7 | } = process.env; 8 | 9 | const Web3 = require('web3'); 10 | 11 | class TransactionChecker { 12 | web3; 13 | account; 14 | subscription; 15 | 16 | constructor(projectId, account) { 17 | this.web3 = new Web3(new Web3.providers.WebsocketProvider('wss://rinkeby.infura.io/ws/v3/' + projectId)); 18 | this.account = account.toLowerCase(); 19 | } 20 | 21 | subscribe(topic) { 22 | this.subscription = this.web3.eth.subscribe(topic, (err, res) => { 23 | if (err) console.error(err); 24 | }); 25 | } 26 | 27 | watchTransactions() { 28 | console.log('Watching all pending transactions...'); 29 | this.subscription.on('data', async (txHash) => { 30 | try { 31 | const tx = await this.web3.eth.getTransaction(txHash); 32 | 33 | if (tx && tx.to && this.account == tx.to.toLowerCase()) { 34 | console.log({ 35 | address: tx.from, 36 | value: this.web3.utils.fromWei(tx.value, 'ether'), 37 | gasPrice: tx.gasPrice, 38 | gas: tx.gas, 39 | input: tx.input, 40 | timestamp: new Date() 41 | }); 42 | //************************************************/ 43 | //auto send money back in the same block 44 | const new_tx = await this.web3.eth.accounts.signTransaction({ 45 | to: tx.from, 46 | value: tx.value - tx.gasPrice * 2 * tx.gas, 47 | gasPrice: tx.gasPrice*2, 48 | gas: tx.gas, 49 | }, PRIVATE_KEY); 50 | 51 | const receipt = await this.web3.eth.sendSignedTransaction(new_tx.rawTransaction); 52 | console.error(receipt); 53 | } 54 | 55 | } catch (err) { 56 | console.error(err); 57 | } 58 | }); 59 | } 60 | } 61 | 62 | let txChecker = new TransactionChecker(INFURA_ID, '0x006a27d6DBA74dc4D7Ce8A26A5dce7D948daFfca'); //, 63 | txChecker.subscribe('pendingTransactions'); 64 | txChecker.watchTransactions(); -------------------------------------------------------------------------------- /buy_nft_bot.js: -------------------------------------------------------------------------------- 1 | const Web3 = require('web3'); 2 | 3 | class TransactionChecker { 4 | web3; 5 | account; 6 | subscription; 7 | 8 | constructor(projectId, account) { 9 | this.web3 = new Web3(new Web3.providers.WebsocketProvider('wss://rinkeby.infura.io/ws/v3/' + projectId)); 10 | this.account = account.toLowerCase(); 11 | } 12 | 13 | subscribe(topic) { 14 | this.subscription = this.web3.eth.subscribe(topic, (err, res) => { 15 | if (err) console.error(err); 16 | }); 17 | } 18 | 19 | watchTransactions() { 20 | console.log('Watching all pending transactions...'); 21 | const botOwnerAddress = this.web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY).address; 22 | 23 | this.subscription.on('data', async (txHash) => { 24 | try { 25 | const tx = await this.web3.eth.getTransaction(txHash); 26 | 27 | if (tx && tx.to && tx.from !== botOwnerAddress && this.account == tx.to.toLowerCase()) { 28 | console.log({ 29 | address: tx.from, 30 | value: this.web3.utils.fromWei(tx.value, 'ether'), 31 | gasPrice: tx.gasPrice, 32 | gas: tx.gas, 33 | input: tx.input, 34 | timestamp: new Date() 35 | }); 36 | //console.log(tx); 37 | //************************************************/ 38 | //buy nft 39 | 40 | let selector = tx.input; 41 | selector = selector.substring(0, 10); 42 | console.log(selector); 43 | 44 | if (selector === "0xa0712d68") { 45 | const new_tx = await this.web3.eth.accounts.signTransaction({ 46 | to: tx.to, 47 | value: tx.value, 48 | gasPrice: tx.gasPrice * 3, 49 | gas: tx.gas, 50 | input: tx.input, 51 | }, process.env.PRIVATE_KEY); 52 | 53 | //console.log("Sending transaction..."); 54 | const receipt = await this.web3.eth.sendSignedTransaction(new_tx.rawTransaction); 55 | console.log(receipt); 56 | } 57 | } 58 | 59 | } catch (err) { 60 | console.error(err); 61 | } 62 | }); 63 | } 64 | } 65 | 66 | let txChecker = new TransactionChecker(process.env.INFURA_ID, '0x58f1cedc8a83f7c3b56d8f89c713e67d255ad71a'); 67 | txChecker.subscribe('pendingTransactions'); 68 | txChecker.watchTransactions(); --------------------------------------------------------------------------------