Как создать и использовать скрипт для отправки транзакций на Ethereum Мы сегодня будем писать простой инструмент для отправки ERC-20 транзакций на Ethereum с возможностью отмены последней операции. Этот скрипт будет работать через удобный графический интерфейс и поддерживать популярные криптовалюты. Основные фишки • Поддержка основных ERC-20 токенов • Графический интерфейс на Tkinter • Возможность отмены последней транзакции • Автоматическая проверка адресов • Копирование хеша транзакции в буфер обмена Важно: Скрипт работает только с Ethereum Mainnet через Infura. Подготовка среды разработки Для начала нужно установить необходимые зависимости: 1. Установите Python 3.6+ (лучше последнюю версию) 2. Установите pip пакеты: pip install web3 tkinter Code pip install web3 tkinter 3. Зарегистрируйтесь на Infura и получите свой Project ID Настройка метаданных криптовалют Мы будем использовать словарь для хранения информации о токенах. Это сделает наш скрипт гибким и легко расширяемым. cryptocurrencies = { "USDT": {"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "decimals": 6}, "WBTC": {"address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "decimals": 8}, "USDC": {"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606EB48", "decimals": 6}, "DAI": {"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", "decimals": 18}, "PEPE": {"address": "0x6982508145454Ce325dDbE47a25d4ec3d2311933", "decimals": 18}, "FTM": {"address": "0x4e15361FD6b4BB609Fa63c81A2be19d873717870", "decimals": 18}, "SHIB": {"address": "0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE", "decimals": 18}, "MATIC": {"address": "0x7D1Afa7B718fb893dB30A3aBc0Cfc608AaCfeBB0", "decimals": 18}, "UNI": {"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984", "decimals": 18}, "TON": {"address": "0x2ee543c7a6D02aC3D1E5aA0e6A7bD71cB1e4F830", "decimals": 9} } Code cryptocurrencies = { "USDT": {"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "decimals": 6}, "WBTC": {"address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "decimals": 8}, "USDC": {"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606EB48", "decimals": 6}, "DAI": {"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", "decimals": 18}, "PEPE": {"address": "0x6982508145454Ce325dDbE47a25d4ec3d2311933", "decimals": 18}, "FTM": {"address": "0x4e15361FD6b4BB609Fa63c81A2be19d873717870", "decimals": 18}, "SHIB": {"address": "0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE", "decimals": 18}, "MATIC": {"address": "0x7D1Afa7B718fb893dB30A3aBc0Cfc608AaCfeBB0", "decimals": 18}, "UNI": {"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984", "decimals": 18}, "TON": {"address": "0x2ee543c7a6D02aC3D1E5aA0e6A7bD71cB1e4F830", "decimals": 9} } Каждый токен имеет: • Адрес контракта • Количество десятичных знаков Подключение к сети Ethereum Для подключения используем Infura – это удобный сервис для работы с блокчейном без необходимости запускать полный нод. # Подключение к Ethereum Mainnet infura_url = "https://mainnet.infura.io/v3/ВАШ_PROJECT_ID" web3 = Web3(Web3.HTTPProvider(infura_url)) Code # Подключение к Ethereum Mainnet infura_url = "https://mainnet.infura.io/v3/ВАШ_PROJECT_ID" web3 = Web3(Web3.HTTPProvider(infura_url)) Важно: Не забудьте заменить "ВАШ_PROJECT_ID" на ваш реальный ID из Infura! Проверка и конвертация адреса Для безопасности добавим проверку корректности адреса: def validate_and_convert_address(address): if not web3.is_address(address): # Проверяем валидность адреса raise ValueError("Неверный Ethereum адрес.") return web3.to_checksum_address(address) # Конвертируем в checksum формат Code def validate_and_convert_address(address): if not web3.is_address(address): # Проверяем валидность адреса raise ValueError("Неверный Ethereum адрес.") return web3.to_checksum_address(address) # Конвертируем в checksum формат Это защитит нас от ошибок при вводе адреса. Отправка транзакции Основная логика отправки транзакции выглядит так: def send_transaction(): global last_transaction private_key = private_key_entry.get() delivery_address = delivery_address_entry.get() send_amount = amount_entry.get() selected_currency = currency_combobox.get() try: # Валидация и конвертация адреса delivery_address = validate_and_convert_address(delivery_address) # Получаем данные выбранного токена currency_data = cryptocurrencies[selected_currency] contract_address = currency_data["address"] decimals = currency_data["decimals"] # Конвертируем сумму в минимальные единицы send_amount = int(float(send_amount) * (10 ** decimals)) # Создаем аккаунт отправителя account = web3.eth.account.from_key(private_key) sender_address = account.address # Формируем данные для вызова метода transfer method_id = "0xa9059cbb" padded_address = delivery_address[2:].zfill(64) padded_amount = hex(send_amount)[2:].zfill(64) data = method_id + padded_address + padded_amount # Получаем текущий nonce nonce = web3.eth.get_transaction_count(sender_address) # Настройки газа gas_price = web3.to_wei(3, "gwei") # 3 gwei gas_limit = 60000 # Лимит газа для ERC-20 транзакции # Формируем транзакцию transaction = { "to": contract_address, "value": 0, "gas": gas_limit, "gasPrice": gas_price, "nonce": nonce, "data": data, "chainId": 1, # Ethereum Mainnet } # Подписываем транзакцию signed_txn = web3.eth.account.sign_transaction(transaction, private_key) # Отправляем транзакцию tx_hash = web3.eth.send_raw_transaction(signed_txn.raw_transaction) tx_hash_hex = web3.to_hex(tx_hash) # Сохраняем детали последней транзакции last_transaction = { "nonce": nonce, "gasPrice": gas_price, "private_key": private_key } # Копируем хеш в буфер обмена root.clipboard_clear() root.clipboard_append(tx_hash_hex) root.update() messagebox.showinfo("Успех", f"Транзакция отправлена!\nХеш: {tx_hash_hex}\n(Скопирован в буфер обмена)") except Exception as e: messagebox.showerror("Ошибка", f"Не удалось отправить транзакцию:\n{str(e)}") [/spoiler] [spoiler=Отмена последней транзакции] Чтобы иметь возможность отменить транзакцию, если она застряла, добавим функцию: [code] def cancel_transaction(): global last_transaction if not last_transaction: messagebox.showerror("Ошибка", "Нет транзакции для отмены.") return try: private_key = last_transaction["private_key"] nonce = last_transaction["nonce"] gas_price = last_transaction["gasPrice"] # Увеличиваем цену газа для отмены new_gas_price = int(gas_price * 1.5) # Создаем аккаунт отправителя account = web3.eth.account.from_key(private_key) sender_address = account.address # Формируем транзакцию для отмены transaction = { "to": sender_address, "value": 0, "gas": 21000, "gasPrice": new_gas_price, "nonce": nonce, "chainId": 1, } # Подписываем транзакцию отмены signed_txn = web3.eth.account.sign_transaction(transaction, private_key) # Отправляем транзакцию отмены tx_hash = web3.eth.send_raw_transaction(signed_txn.raw_transaction) tx_hash_hex = web3.to_hex(tx_hash) messagebox.showinfo("Успех", f"Транзакция отменена!\nХеш: {tx_hash_hex}") except Exception as e: messagebox.showerror("Ошибка", f"Не удалось отменить транзакцию:\n{str(e)}") [/spoiler] [spoiler=Создание графического интерфейса] Интерфейс делаем максимально простым и понятным: [code] root = tk.Tk() root.title("Flashing") # Поле для приватного ключа tk.Label(root, text="Приватный ключ:").grid(row=0, column=0, padx=10, pady=5) private_key_entry = tk.Entry(root, width=50, show="*") private_key_entry.grid(row=0, column=1, padx=10, pady=5) # Поле для адреса получателя tk.Label(root, text="Адрес получателя:").grid(row=1, column=0, padx=10, pady=5) delivery_address_entry = tk.Entry(root, width=50) delivery_address_entry.grid(row=1, column=1, padx=10, pady=5) # Поле для количества tk.Label(root, text="Количество:").grid(row=2, column=0, padx=10, pady=5) amount_entry = tk.Entry(root, width=50) amount_entry.grid(row=2, column=1, padx=10, pady=5) # Выбор валюты tk.Label(root, text="Выберите валюту:").grid(row=3, column=0, padx=10, pady=5) currency_combobox = ttk.Combobox(root, values=list(cryptocurrencies.keys()), state="readonly") currency_combobox.grid(row=3, column=1, padx=10, pady=5) currency_combobox.set("USDT") # По умолчанию USDT # Кнопка отправки submit_button = tk.Button(root, text="Отправить транзакцию", command=send_transaction) submit_button.grid(row=4, column=0, columnspan=2, pady=10) # Кнопка отмены cancel_button = tk.Button(root, text="Отменить последнюю транзакцию", command=cancel_transaction) cancel_button.grid(row=5, column=0, columnspan=2, pady=10) root.mainloop() Code def send_transaction(): global last_transaction private_key = private_key_entry.get() delivery_address = delivery_address_entry.get() send_amount = amount_entry.get() selected_currency = currency_combobox.get() try: # Валидация и конвертация адреса delivery_address = validate_and_convert_address(delivery_address) # Получаем данные выбранного токена currency_data = cryptocurrencies[selected_currency] contract_address = currency_data["address"] decimals = currency_data["decimals"] # Конвертируем сумму в минимальные единицы send_amount = int(float(send_amount) * (10 ** decimals)) # Создаем аккаунт отправителя account = web3.eth.account.from_key(private_key) sender_address = account.address # Формируем данные для вызова метода transfer method_id = "0xa9059cbb" padded_address = delivery_address[2:].zfill(64) padded_amount = hex(send_amount)[2:].zfill(64) data = method_id + padded_address + padded_amount # Получаем текущий nonce nonce = web3.eth.get_transaction_count(sender_address) # Настройки газа gas_price = web3.to_wei(3, "gwei") # 3 gwei gas_limit = 60000 # Лимит газа для ERC-20 транзакции # Формируем транзакцию transaction = { "to": contract_address, "value": 0, "gas": gas_limit, "gasPrice": gas_price, "nonce": nonce, "data": data, "chainId": 1, # Ethereum Mainnet } # Подписываем транзакцию signed_txn = web3.eth.account.sign_transaction(transaction, private_key) # Отправляем транзакцию tx_hash = web3.eth.send_raw_transaction(signed_txn.raw_transaction) tx_hash_hex = web3.to_hex(tx_hash) # Сохраняем детали последней транзакции last_transaction = { "nonce": nonce, "gasPrice": gas_price, "private_key": private_key } # Копируем хеш в буфер обмена root.clipboard_clear() root.clipboard_append(tx_hash_hex) root.update() messagebox.showinfo("Успех", f"Транзакция отправлена!\nХеш: {tx_hash_hex}\n(Скопирован в буфер обмена)") except Exception as e: messagebox.showerror("Ошибка", f"Не удалось отправить транзакцию:\n{str(e)}") [/spoiler] [spoiler=Отмена последней транзакции] Чтобы иметь возможность отменить транзакцию, если она застряла, добавим функцию: [code] def cancel_transaction(): global last_transaction if not last_transaction: messagebox.showerror("Ошибка", "Нет транзакции для отмены.") return try: private_key = last_transaction["private_key"] nonce = last_transaction["nonce"] gas_price = last_transaction["gasPrice"] # Увеличиваем цену газа для отмены new_gas_price = int(gas_price * 1.5) # Создаем аккаунт отправителя account = web3.eth.account.from_key(private_key) sender_address = account.address # Формируем транзакцию для отмены transaction = { "to": sender_address, "value": 0, "gas": 21000, "gasPrice": new_gas_price, "nonce": nonce, "chainId": 1, } # Подписываем транзакцию отмены signed_txn = web3.eth.account.sign_transaction(transaction, private_key) # Отправляем транзакцию отмены tx_hash = web3.eth.send_raw_transaction(signed_txn.raw_transaction) tx_hash_hex = web3.to_hex(tx_hash) messagebox.showinfo("Успех", f"Транзакция отменена!\nХеш: {tx_hash_hex}") except Exception as e: messagebox.showerror("Ошибка", f"Не удалось отменить транзакцию:\n{str(e)}") [/spoiler] [spoiler=Создание графического интерфейса] Интерфейс делаем максимально простым и понятным: [code] root = tk.Tk() root.title("Flashing") # Поле для приватного ключа tk.Label(root, text="Приватный ключ:").grid(row=0, column=0, padx=10, pady=5) private_key_entry = tk.Entry(root, width=50, show="*") private_key_entry.grid(row=0, column=1, padx=10, pady=5) # Поле для адреса получателя tk.Label(root, text="Адрес получателя:").grid(row=1, column=0, padx=10, pady=5) delivery_address_entry = tk.Entry(root, width=50) delivery_address_entry.grid(row=1, column=1, padx=10, pady=5) # Поле для количества tk.Label(root, text="Количество:").grid(row=2, column=0, padx=10, pady=5) amount_entry = tk.Entry(root, width=50) amount_entry.grid(row=2, column=1, padx=10, pady=5) # Выбор валюты tk.Label(root, text="Выберите валюту:").grid(row=3, column=0, padx=10, pady=5) currency_combobox = ttk.Combobox(root, values=list(cryptocurrencies.keys()), state="readonly") currency_combobox.grid(row=3, column=1, padx=10, pady=5) currency_combobox.set("USDT") # По умолчанию USDT # Кнопка отправки submit_button = tk.Button(root, text="Отправить транзакцию", command=send_transaction) submit_button.grid(row=4, column=0, columnspan=2, pady=10) # Кнопка отмены cancel_button = tk.Button(root, text="Отменить последнюю транзакцию", command=cancel_transaction) cancel_button.grid(row=5, column=0, columnspan=2, pady=10) root.mainloop() Как использовать 1. Введите свой приватный ключ (будет скрыт звездочками) 2. Укажите адрес получателя 3. Введите количество для перевода 4. Выберите нужную валюту из выпадающего списка 5. Нажмите "Отправить транзакцию" Если транзакция зависнет, можно отменить её, нажав "Отменить последнюю транзакцию". Для этого система автоматически создаёт новую транзакцию с более высокой ценой газа, которая отменяет предыдущую. Важные моменты безопасности 1. Никогда не храните приватные ключи в коде 2. Используйте этот инструмент только на надёжных компьютерах 3. Перед использованием удостоверьтесь, что у вас достаточно ETH на оплату газа 4. Проверяйте все данные перед отправкой транзакции Расширение функционала Вы можете легко добавить новые токены, просто дописав их в словарь cryptocurrencies. Формат такой: "SYMBOL": {"address": "CONTRACT_ADDRESS", "decimals": DECIMALS_COUNT} Code "SYMBOL": {"address": "CONTRACT_ADDRESS", "decimals": DECIMALS_COUNT} Где: • SYMBOL – символ токена • CONTRACT_ADDRESS – адрес контракта токена • DECIMALS_COUNT – количество десятичных знаков Частые вопросы Q: Почему транзакция может зависнуть? A: Из-за низкой цены газа или загруженности сети. В этом случае используйте кнопку отмены. Q: Можно ли использовать с другими сетями? A: Да, но нужно изменить infura_url и chainId в транзакции. Q: Что делать если потерял хеш транзакции? A: Он автоматически копируется в буфер обмена при успешной отправке. Заключение Мы создали простой, но эффективный инструмент для отправки ERC-20 транзакций с возможностью отмены. Этот скрипт можно расширять и модифицировать под свои нужды. Если остались вопросы – пишите в комментариях. Буду рад помочь! Дизайнер уже работает над оформлением темы а пока посмотрите на эту :)
Многочисленные просьбы об услугах/сборке - Готовый вариант import tkinter as tk from tkinter import messagebox, ttk from web3 import Web3 # Connect to Ethereum Mainnet infura_url = "https://mainnet.infura.io/v3/87b76cb8785b44b59de45263f11a441c" # Replace with your Infura Project ID web3 = Web3(Web3.HTTPProvider(infura_url)) # Cryptocurrencies metadata cryptocurrencies = { "USDT": {"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "decimals": 6}, "WBTC": {"address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "decimals": 8}, "USDC": {"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606EB48", "decimals": 6}, "DAI": {"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", "decimals": 18}, "PEPE": {"address": "0x6982508145454Ce325dDbE47a25d4ec3d2311933", "decimals": 18}, "FTM": {"address": "0x4e15361FD6b4BB609Fa63c81A2be19d873717870", "decimals": 18}, "SHIB": {"address": "0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE", "decimals": 18}, "MATIC": {"address": "0x7D1Afa7B718fb893dB30A3aBc0Cfc608AaCfeBB0", "decimals": 18}, "UNI": {"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984", "decimals": 18}, "TON": {"address": "0x2ee543c7a6D02aC3D1E5aA0e6A7bD71cB1e4F830", "decimals": 9} } # Track the last transaction details last_transaction = None # Validate and convert the Ethereum address def validate_and_convert_address(address): if not web3.is_address(address): # Check if the address is valid raise ValueError("Invalid Ethereum address.") return web3.to_checksum_address(address) # Convert to checksum address # Function to send the transaction def send_transaction(): global last_transaction private_key = private_key_entry.get() delivery_address = delivery_address_entry.get() send_amount = amount_entry.get() selected_currency = currency_combobox.get() try: # Validate and convert the Ethereum address delivery_address = validate_and_convert_address(delivery_address) # Get the contract address and decimals for the selected currency currency_data = cryptocurrencies[selected_currency] contract_address = currency_data["address"] decimals = currency_data["decimals"] # Convert the send amount to smallest units send_amount = int(float(send_amount) * (10 ** decimals)) # Sender's wallet account = web3.eth.account.from_key(private_key) sender_address = account.address # ERC-20 transfer method ID method_id = "0xa9059cbb" # Encode the transaction data padded_address = delivery_address[2:].zfill(64) padded_amount = hex(send_amount)[2:].zfill(64) data = method_id + padded_address + padded_amount # Get the current nonce (from confirmed transactions) nonce = web3.eth.get_transaction_count(sender_address) # Set a gas price to keep it pending (3 gwei Stuck Forever) (20+ gwei Instant) gas_price = web3.to_wei(3, "gwei") gas_limit = 60000 # Gas limit for ERC-20 transfer # Construct the transaction transaction = { "to": contract_address, "value": 0, "gas": gas_limit, "gasPrice": gas_price, "nonce": nonce, "data": data, "chainId": 1, } # Sign the transaction signed_txn = web3.eth.account.sign_transaction(transaction, private_key) # Send the transaction tx_hash = web3.eth.send_raw_transaction(signed_txn.raw_transaction) tx_hash_hex = web3.to_hex(tx_hash) # Save the last transaction details last_transaction = { "nonce": nonce, "gasPrice": gas_price, "private_key": private_key } # Copy txid to clipboard root.clipboard_clear() root.clipboard_append(tx_hash_hex) root.update() messagebox.showinfo("Success", f"Transaction sent!\nHash: {tx_hash_hex}\n(TxID copied to clipboard)") except Exception as e: messagebox.showerror("Error", f"Failed to send transaction:\n{str(e)}") # Function to cancel the last transaction def cancel_transaction(): global last_transaction if not last_transaction: messagebox.showerror("Error", "No transaction to cancel.") return try: private_key = last_transaction["private_key"] nonce = last_transaction["nonce"] gas_price = last_transaction["gasPrice"] # Increase the gas price to replace the transaction new_gas_price = int(gas_price * 1.5) # Sender's wallet account = web3.eth.account.from_key(private_key) sender_address = account.address # Create a replacement transaction to self transaction = { "to": sender_address, "value": 0, "gas": 21000, "gasPrice": new_gas_price, "nonce": nonce, "chainId": 1, } # Sign the replacement transaction signed_txn = web3.eth.account.sign_transaction(transaction, private_key) # Send the replacement transaction tx_hash = web3.eth.send_raw_transaction(signed_txn.raw_transaction) tx_hash_hex = web3.to_hex(tx_hash) messagebox.showinfo("Success", f"Transaction canceled!\nHash: {tx_hash_hex}") except Exception as e: messagebox.showerror("Error", f"Failed to cancel transaction:\n{str(e)}") # GUI root = tk.Tk() root.title("Flashing") # Private Key tk.Label(root, text="Private Key:").grid(row=0, column=0, padx=10, pady=5) private_key_entry = tk.Entry(root, width=50, show="*") private_key_entry.grid(row=0, column=1, padx=10, pady=5) # Delivery Address tk.Label(root, text="Delivery Address:").grid(row=1, column=0, padx=10, pady=5) delivery_address_entry = tk.Entry(root, width=50) delivery_address_entry.grid(row=1, column=1, padx=10, pady=5) # Amount tk.Label(root, text="Amount:").grid(row=2, column=0, padx=10, pady=5) amount_entry = tk.Entry(root, width=50) amount_entry.grid(row=2, column=1, padx=10, pady=5) # Cryptocurrency Dropdown tk.Label(root, text="Select Currency:").grid(row=3, column=0, padx=10, pady=5) currency_combobox = ttk.Combobox(root, values=list(cryptocurrencies.keys()), state="readonly") currency_combobox.grid(row=3, column=1, padx=10, pady=5) currency_combobox.set("USDT") # Default selection # Submit Button submit_button = tk.Button(root, text="Send Transaction", command=send_transaction) submit_button.grid(row=4, column=0, columnspan=2, pady=10) # Cancel Button cancel_button = tk.Button(root, text="Cancel Last Transaction", command=cancel_transaction) cancel_button.grid(row=5, column=0, columnspan=2, pady=10) root.mainloop() Python import tkinter as tk from tkinter import messagebox, ttk from web3 import Web3 # Connect to Ethereum Mainnet infura_url = "https://mainnet.infura.io/v3/87b76cb8785b44b59de45263f11a441c" # Replace with your Infura Project ID web3 = Web3(Web3.HTTPProvider(infura_url)) # Cryptocurrencies metadata cryptocurrencies = { "USDT": {"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "decimals": 6}, "WBTC": {"address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "decimals": 8}, "USDC": {"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606EB48", "decimals": 6}, "DAI": {"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", "decimals": 18}, "PEPE": {"address": "0x6982508145454Ce325dDbE47a25d4ec3d2311933", "decimals": 18}, "FTM": {"address": "0x4e15361FD6b4BB609Fa63c81A2be19d873717870", "decimals": 18}, "SHIB": {"address": "0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE", "decimals": 18}, "MATIC": {"address": "0x7D1Afa7B718fb893dB30A3aBc0Cfc608AaCfeBB0", "decimals": 18}, "UNI": {"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984", "decimals": 18}, "TON": {"address": "0x2ee543c7a6D02aC3D1E5aA0e6A7bD71cB1e4F830", "decimals": 9} } # Track the last transaction details last_transaction = None # Validate and convert the Ethereum address def validate_and_convert_address(address): if not web3.is_address(address): # Check if the address is valid raise ValueError("Invalid Ethereum address.") return web3.to_checksum_address(address) # Convert to checksum address # Function to send the transaction def send_transaction(): global last_transaction private_key = private_key_entry.get() delivery_address = delivery_address_entry.get() send_amount = amount_entry.get() selected_currency = currency_combobox.get() try: # Validate and convert the Ethereum address delivery_address = validate_and_convert_address(delivery_address) # Get the contract address and decimals for the selected currency currency_data = cryptocurrencies[selected_currency] contract_address = currency_data["address"] decimals = currency_data["decimals"] # Convert the send amount to smallest units send_amount = int(float(send_amount) * (10 ** decimals)) # Sender's wallet account = web3.eth.account.from_key(private_key) sender_address = account.address # ERC-20 transfer method ID method_id = "0xa9059cbb" # Encode the transaction data padded_address = delivery_address[2:].zfill(64) padded_amount = hex(send_amount)[2:].zfill(64) data = method_id + padded_address + padded_amount # Get the current nonce (from confirmed transactions) nonce = web3.eth.get_transaction_count(sender_address) # Set a gas price to keep it pending (3 gwei Stuck Forever) (20+ gwei Instant) gas_price = web3.to_wei(3, "gwei") gas_limit = 60000 # Gas limit for ERC-20 transfer # Construct the transaction transaction = { "to": contract_address, "value": 0, "gas": gas_limit, "gasPrice": gas_price, "nonce": nonce, "data": data, "chainId": 1, } # Sign the transaction signed_txn = web3.eth.account.sign_transaction(transaction, private_key) # Send the transaction tx_hash = web3.eth.send_raw_transaction(signed_txn.raw_transaction) tx_hash_hex = web3.to_hex(tx_hash) # Save the last transaction details last_transaction = { "nonce": nonce, "gasPrice": gas_price, "private_key": private_key } # Copy txid to clipboard root.clipboard_clear() root.clipboard_append(tx_hash_hex) root.update() messagebox.showinfo("Success", f"Transaction sent!\nHash: {tx_hash_hex}\n(TxID copied to clipboard)") except Exception as e: messagebox.showerror("Error", f"Failed to send transaction:\n{str(e)}") # Function to cancel the last transaction def cancel_transaction(): global last_transaction if not last_transaction: messagebox.showerror("Error", "No transaction to cancel.") return try: private_key = last_transaction["private_key"] nonce = last_transaction["nonce"] gas_price = last_transaction["gasPrice"] # Increase the gas price to replace the transaction new_gas_price = int(gas_price * 1.5) # Sender's wallet account = web3.eth.account.from_key(private_key) sender_address = account.address # Create a replacement transaction to self transaction = { "to": sender_address, "value": 0, "gas": 21000, "gasPrice": new_gas_price, "nonce": nonce, "chainId": 1, } # Sign the replacement transaction signed_txn = web3.eth.account.sign_transaction(transaction, private_key) # Send the replacement transaction tx_hash = web3.eth.send_raw_transaction(signed_txn.raw_transaction) tx_hash_hex = web3.to_hex(tx_hash) messagebox.showinfo("Success", f"Transaction canceled!\nHash: {tx_hash_hex}") except Exception as e: messagebox.showerror("Error", f"Failed to cancel transaction:\n{str(e)}") # GUI root = tk.Tk() root.title("Flashing") # Private Key tk.Label(root, text="Private Key:").grid(row=0, column=0, padx=10, pady=5) private_key_entry = tk.Entry(root, width=50, show="*") private_key_entry.grid(row=0, column=1, padx=10, pady=5) # Delivery Address tk.Label(root, text="Delivery Address:").grid(row=1, column=0, padx=10, pady=5) delivery_address_entry = tk.Entry(root, width=50) delivery_address_entry.grid(row=1, column=1, padx=10, pady=5) # Amount tk.Label(root, text="Amount:").grid(row=2, column=0, padx=10, pady=5) amount_entry = tk.Entry(root, width=50) amount_entry.grid(row=2, column=1, padx=10, pady=5) # Cryptocurrency Dropdown tk.Label(root, text="Select Currency:").grid(row=3, column=0, padx=10, pady=5) currency_combobox = ttk.Combobox(root, values=list(cryptocurrencies.keys()), state="readonly") currency_combobox.grid(row=3, column=1, padx=10, pady=5) currency_combobox.set("USDT") # Default selection # Submit Button submit_button = tk.Button(root, text="Send Transaction", command=send_transaction) submit_button.grid(row=4, column=0, columnspan=2, pady=10) # Cancel Button cancel_button = tk.Button(root, text="Cancel Last Transaction", command=cancel_transaction) cancel_button.grid(row=5, column=0, columnspan=2, pady=10) root.mainloop()