|
|
@@ -0,0 +1,153 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+from web3 import Web3
|
|
|
+import random
|
|
|
+import time
|
|
|
+import os
|
|
|
+
|
|
|
+# Monad 测试网 RPC URL
|
|
|
+provider_url = "https://testnet-rpc.monad.xyz"
|
|
|
+w3 = Web3(Web3.HTTPProvider(provider_url))
|
|
|
+
|
|
|
+# 合约地址、合约方法哈希值及描述
|
|
|
+contract_data = [
|
|
|
+ {
|
|
|
+ "address": "0x2c9c959516e9aaedb2c748224a41249202ca8be7",
|
|
|
+ "data_hash": "0xd5575982",
|
|
|
+ "description": "Magmastaking"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "address": "0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701",
|
|
|
+ "data_hash": "0xd5575982",
|
|
|
+ "description": "ApeBond"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "address": "0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701",
|
|
|
+ "data_hash": "0xd0e30db0",
|
|
|
+ "description": "OctoSwap - WMON"
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+# 读取私钥文件
|
|
|
+file_path = os.path.join(os.path.dirname(__file__), 'AccountList.txt')
|
|
|
+
|
|
|
+
|
|
|
+def get_random_amount():
|
|
|
+ # 生成随机交易金额 0.00000000****(最后4位随机数)
|
|
|
+ random_tail = random.randint(1000, 9999)
|
|
|
+ return Web3.to_wei(f"0.0000000000{random_tail}", "ether")
|
|
|
+
|
|
|
+
|
|
|
+def get_random_contract_data():
|
|
|
+ # 随机获取合约地址、合约方法哈希值及描述
|
|
|
+ if not contract_data:
|
|
|
+ print("The contract data array is empty, the contract cannot be selected, and the program exits.")
|
|
|
+ exit(1)
|
|
|
+ return random.choice(contract_data)
|
|
|
+
|
|
|
+
|
|
|
+def check_wallet_balance(balance, minimum_balance):
|
|
|
+ # 如果钱包余额小于等于最小余额
|
|
|
+ if balance <= Web3.to_wei(minimum_balance, "ether"):
|
|
|
+ print("The wallet balance is invalid.")
|
|
|
+ exit(1)
|
|
|
+
|
|
|
+
|
|
|
+async def execute_contract(account, minimum_balance):
|
|
|
+ try:
|
|
|
+ # 随机选择一个合约地址、合约方法哈希值及描述
|
|
|
+ contract_info = get_random_contract_data()
|
|
|
+ address = contract_info["address"]
|
|
|
+ data_hash = contract_info["data_hash"]
|
|
|
+ description = contract_info["description"]
|
|
|
+ print(f"Selected contract: {description}")
|
|
|
+ print(f"Selected contract address: {address}")
|
|
|
+ print(f"Selected contract dataHash: {data_hash}")
|
|
|
+
|
|
|
+ # 检查原生代币余额
|
|
|
+ balance = w3.eth.get_balance(account.address)
|
|
|
+ before_balance = Web3.from_wei(balance, "ether")
|
|
|
+ print(f"Native balance: {before_balance}")
|
|
|
+
|
|
|
+ # 检查钱包余额,不能小于 0.2
|
|
|
+ check_wallet_balance(balance, minimum_balance)
|
|
|
+
|
|
|
+ # 质押金额
|
|
|
+ amount_to_stake = get_random_amount()
|
|
|
+ print(f"Amount to contract: {Web3.from_wei(amount_to_stake, 'ether')}")
|
|
|
+
|
|
|
+ if balance < amount_to_stake:
|
|
|
+ raise Exception("Insufficient balance for contract execution.")
|
|
|
+
|
|
|
+ # 构建交易
|
|
|
+ nonce = w3.eth.get_transaction_count(account.address)
|
|
|
+ tx = {
|
|
|
+ "to": Web3.to_checksum_address(address),
|
|
|
+ "value": amount_to_stake,
|
|
|
+ "data": data_hash,
|
|
|
+ "gas": 100000,
|
|
|
+ "gasPrice": Web3.to_wei(50, "gwei"),
|
|
|
+ "nonce": nonce,
|
|
|
+ "chainId": w3.eth.chain_id
|
|
|
+ }
|
|
|
+
|
|
|
+ # 签名并发送交易
|
|
|
+ signed_tx = w3.eth.account.sign_transaction(tx, account.key)
|
|
|
+ tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction)
|
|
|
+ print(f"Contract Execution hash: {tx_hash.hex()}")
|
|
|
+
|
|
|
+ # 等待交易确认
|
|
|
+ receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
|
|
|
+ execute_status = receipt["status"]
|
|
|
+ if execute_status == 1:
|
|
|
+ print("Contract Execution status: seccessful")
|
|
|
+ elif execute_status == 0:
|
|
|
+ print("Contract Execution status: failed")
|
|
|
+ else:
|
|
|
+ print("Contract Execution status: unknown")
|
|
|
+
|
|
|
+ # 检查交易后的余额
|
|
|
+ balance_staking = w3.eth.get_balance(account.address)
|
|
|
+ after_balance = Web3.from_wei(balance_staking, "ether")
|
|
|
+ print(f"Native balance after transaction: {after_balance}")
|
|
|
+ print(f"The cost of this transaction: {float(before_balance) - float(after_balance)}")
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ print(f"Error executing contract: {e}")
|
|
|
+
|
|
|
+
|
|
|
+async def run_multiple_staking(private_keys):
|
|
|
+ last_times = 100
|
|
|
+ min_delay = 10
|
|
|
+ max_delay = 20
|
|
|
+ minimum_balance = 4
|
|
|
+
|
|
|
+ for private_key in private_keys:
|
|
|
+ account = w3.eth.account.from_key(private_key.strip())
|
|
|
+ print(f"Processing wallet with address: {account.address}")
|
|
|
+
|
|
|
+ for i in range(last_times):
|
|
|
+ if last_times > 1:
|
|
|
+ print(f"Starting Contract attempt {i + 1}")
|
|
|
+ await execute_contract(account, minimum_balance)
|
|
|
+ print(f"Completed Contract attempt {i + 1}")
|
|
|
+ if i < last_times - 1:
|
|
|
+ delay = random.uniform(min_delay, max_delay)
|
|
|
+ print(f"Waiting for {delay} seconds...")
|
|
|
+ print('------------------------------------------------------------')
|
|
|
+ time.sleep(random.uniform(min_delay, max_delay))
|
|
|
+
|
|
|
+
|
|
|
+async def main():
|
|
|
+ try:
|
|
|
+ with open(file_path, 'r') as file:
|
|
|
+ private_keys = [line.strip() for line in file if line.strip()]
|
|
|
+ await run_multiple_staking(private_keys)
|
|
|
+ except Exception as err:
|
|
|
+ print(f'读取文件时发生错误: {err}')
|
|
|
+ exit(1)
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ import asyncio
|
|
|
+
|
|
|
+ asyncio.run(main())
|