From 60fdb6328368b11b53fdb3d68b5b7b1db39816c7 Mon Sep 17 00:00:00 2001 From: nfl Date: Sat, 25 Feb 2023 04:34:34 +0100 Subject: [PATCH] mvp --- .env | 3 ++ README.md | 41 +++++++++++++++++++++++- main.py | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 ++ watchdog.sh | 47 ++++++++++++++++++++++++++++ 5 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 .env create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 watchdog.sh diff --git a/.env b/.env new file mode 100644 index 0000000..00eb11d --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +RPC_ENDPOINT=https://mainnet.infura.io/v3/your_project_id +PRIV_KEY=your_private_key +RCVING_ADDR=recipient_address diff --git a/README.md b/README.md index 67ef946..5235a99 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,41 @@ # autosweep -This script periodically attempts to sweep funds from compromised seed phrase wallets. +autosweep is a Python script that automatically sweeps the balance of an Ethereum account to a specified recipient address at regular intervals. The script uses the web3 library to interact with an Ethereum node and send transactions. + +Usage +To use autosweep, follow these steps: + +1- Clone the repository: + +`git clone https://github.com/cpte-org/autosweep.git` + +2- Install the required Python libraries: + +`pip install -r requirements.txt` + +3- Create a file named .env in the root directory of the repository with the following contents: + +` +RPC_ENDPOINT= +PRIV_KEY= +RCVING_ADDR= +` +Replace your_project_id, your_private_key, and recipient_address with your own values. +Note: Example Ethereum RPC endpoint is infura. + + +4- Run the script using the following command: + +`./watchdog.sh` + +This script starts the main.py script and monitors its output. If the script stops producing output or encounters an error, the watchdog.sh script restarts it. + +Files + +- watchdog.sh +This is a Bash script that monitors the main.py script and restarts it if necessary. It also sets the path to the Python script, the log file path, and the maximum idle time. + +- main.py +This is the Python script that monitors the Ethereum account balance and sends a transaction to the recipient address when the balance exceeds a specified threshold. It uses the web3 library to interact with the Ethereum network and the dotenv library to read the environment variables from the .env file. The script is configured to run every 20 seconds, but this can be changed by modifying the time.sleep() statement at the end of the script. + +License +This project is licensed under the chat-GPT v3.5 License. diff --git a/main.py b/main.py new file mode 100644 index 0000000..aab486d --- /dev/null +++ b/main.py @@ -0,0 +1,81 @@ +import time +import datetime +import os +import logging +from dotenv import load_dotenv +from web3 import Web3, HTTPProvider +from web3.middleware import geth_poa_middleware +from eth_account import Account + +load_dotenv() # take environment variables from .env. + +# Ethereum network endpoint and project ID +rpc_endpoint = os.environ.get('RPC_ENDPOINT') +w3 = Web3(HTTPProvider(rpc_endpoint)) +w3.middleware_onion.inject(geth_poa_middleware, layer=0) + +# Account private key and recipient address +private_key = os.environ.get('PRIV_KEY') +recipient_address = w3.toChecksumAddress(os.environ.get('RCVING_ADDR')) + +# Gas price and limit for the transaction +gas_price = w3.eth.gas_price +gas_limit = 21000 + +# Configure logging to a file +logging.basicConfig(filename='./sweeper.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + +def sweep_account_balance(): + # Get the current account balance + account = Account.privateKeyToAccount(private_key) + balance = w3.eth.get_balance(account.address) + + # Calculate the transaction fee and amount to send (full balance minus transaction fee) + transaction_fee = gas_price * gas_limit + eth_to_send = balance - transaction_fee + + # Send the transaction to the recipient address + if eth_to_send > 0: + message = f"Sending {w3.fromWei(eth_to_send, 'ether')} ETH to {recipient_address}..." + print(message) + logging.info(message) + # Build and sign the transaction + transaction = { + 'to': recipient_address, + 'value': eth_to_send, + 'gas': gas_limit, + 'gasPrice': gas_price, + 'nonce': w3.eth.getTransactionCount(account.address), + } + signed_tx = account.signTransaction(transaction) + + # Send the signed transaction + tx_hash = w3.eth.sendRawTransaction(signed_tx.rawTransaction) + message = f"Transaction sent with hash: {tx_hash.hex()}." + print(message) + logging.info(message) + + # Wait for confirmation and retrieve the transaction receipt + message = "Waiting for transaction confirmation..." + print(message) + logging.info(message) + tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash) + message = f"Transaction confirmed with status: {tx_receipt.status}." + print(message) + logging.info(message) + message = f"Transaction hash: {tx_receipt.transactionHash.hex()}." + print(message) + logging.info(message) + else: + message = f"Account balance is {w3.fromWei(balance, 'ether')} ETH, which is not enough to cover the transaction fee." + print(message) + logging.info(message) + +# Sweep the account balance every 20 seconds +while True: + sweep_account_balance() + ct = datetime.datetime.now() + message = "Sweeping account balance at {}".format(ct) + print(message) + logging.info(message) + time.sleep(20) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..313f3d5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +web3==5.31.3 +python-dotenv==0.21.1 diff --git a/watchdog.sh b/watchdog.sh new file mode 100644 index 0000000..952f835 --- /dev/null +++ b/watchdog.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Set the path to the Python script +PYTHON_SCRIPT=/home/Zcash/main.py + +# Set the log file path +LOG_FILE=/home/Zcash/sweeper.log + +# Set the maximum idle time in seconds +MAX_IDLE_TIME=300 + +# Define a function to check if the Python script is running and producing output +function check_python_script { + if ! pgrep -f "$PYTHON_SCRIPT" > /dev/null ; then + echo "Python script is not running. Restarting..." + echo "---------------------------" >> $LOG_FILE + echo "$(date '+%Y-%m-%d %H:%M:%S') - Python script is not running. Restarting..." >> $LOG_FILE + # Start the Python script in the background + nohup python $PYTHON_SCRIPT >> $LOG_FILE & + return + fi + + # Get the modification time of the log file + LOG_MOD_TIME=$(stat -c %Y $LOG_FILE) + + # Get the current time + CURRENT_TIME=$(date +%s) + + # Calculate the idle time + IDLE_TIME=$(($CURRENT_TIME - $LOG_MOD_TIME)) + + # Check if the idle time is greater than the maximum allowed + if [ $IDLE_TIME -gt $MAX_IDLE_TIME ]; then + echo "Python script is not producing output. Restarting..." + echo "---------------------------" >> $LOG_FILE + echo "$(date '+%Y-%m-%d %H:%M:%S') - Python script is not producing output. Restarting..." >> $LOG_FILE + # Kill the existing Python script process and start a new one in the background + pkill -f "$PYTHON_SCRIPT" + nohup python $PYTHON_SCRIPT >> $LOG_FILE & + fi +} + +# Run the function in a loop +while true; do + check_python_script + sleep 30 # check every 30 seconds +done