-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
173 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
RPC_ENDPOINT=https://mainnet.infura.io/v3/your_project_id | ||
PRIV_KEY=your_private_key | ||
RCVING_ADDR=recipient_address |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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=<your Ethereum RPC endpoint (e.g., https://mainnet.infura.io/v3/your-project-id)> | ||
PRIV_KEY=<your account private key> | ||
RCVING_ADDR=<the recipient address> | ||
` | ||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
web3==5.31.3 | ||
python-dotenv==0.21.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |