Mikasa9629 commited on
Commit
7471272
·
verified ·
1 Parent(s): da16431

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +160 -0
app.py ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import socket
2
+ import json
3
+ import hashlib
4
+ import struct
5
+ import time
6
+ import threading
7
+ import argparse
8
+
9
+ class Miner:
10
+ def __init__(self, pool_url, pool_port, username, password, num_threads, debug=False):
11
+ self.pool_url = pool_url
12
+ self.pool_port = pool_port
13
+ self.username = username
14
+ self.password = password
15
+ self.num_threads = 2
16
+ self.socket = None
17
+ self.total_hashes = 0
18
+ self.hashes_per_second = 0
19
+ self.found_hashes = 0
20
+ self.lock = threading.Lock()
21
+ self.debug = debug
22
+ self.difficulty = 0 # Initialize difficulty
23
+
24
+ def connect(self):
25
+ print(f"Connecting to {self.pool_url}:{self.pool_port}")
26
+ self.socket = socket.create_connection((self.pool_url, self.pool_port))
27
+ self.socket_file = self.socket.makefile('r', encoding='utf-8')
28
+
29
+ def send_message(self, message):
30
+ self.socket.sendall(json.dumps(message).encode('utf-8') + b'\n')
31
+
32
+ def receive_message(self):
33
+ try:
34
+ message = self.socket_file.readline().strip()
35
+ if message:
36
+ if self.debug:
37
+ print(f"Received message: {message}")
38
+ return json.loads(message)
39
+ except socket.timeout:
40
+ if self.debug:
41
+ print("Socket timed out waiting for a message.")
42
+ return None
43
+ return None
44
+
45
+ def authenticate(self):
46
+ auth_message = {
47
+ "jsonrpc": "2.0",
48
+ "method": "mining.authorize",
49
+ "params": [self.username, self.password],
50
+ "id": 1
51
+ }
52
+ self.send_message(auth_message)
53
+ response = self.receive_message()
54
+
55
+ if response is not None:
56
+ if 'result' in response:
57
+ print("Authenticated successfully." if response['result'] else "Authentication failed.")
58
+ else:
59
+ print("Authentication response received, but 'result' key is missing. Response: ", response)
60
+ else:
61
+ print("No response received during authentication.")
62
+
63
+ def mine(self):
64
+ while True:
65
+ work = self.receive_message()
66
+ if work:
67
+ if 'method' in work:
68
+ if work['method'] == 'mining.notify':
69
+ self.handle_mining_notify(work['params'])
70
+ elif work['method'] == 'mining.set_difficulty':
71
+ self.handle_difficulty_set(work['params'])
72
+
73
+ def handle_difficulty_set(self, params):
74
+ self.difficulty = params[0] # Update difficulty
75
+ if self.debug:
76
+ print(f"Difficulty set to: {self.difficulty}")
77
+
78
+ def handle_mining_notify(self, params):
79
+ if self.debug:
80
+ print("Received new work.")
81
+
82
+ job_id, prevhash, coinb1, coinb2, merkle_branch, version, nbits, ntime, clean_jobs = params
83
+ threads = []
84
+
85
+ for _ in range(self.num_threads):
86
+ thread = threading.Thread(target=self.threaded_mining, args=(job_id, prevhash, coinb1, coinb2, merkle_branch, version, nbits, ntime))
87
+ threads.append(thread)
88
+ thread.start()
89
+
90
+ for thread in threads:
91
+ thread.join() # Wait for all threads to finish
92
+
93
+ def threaded_mining(self, job_id, prevhash, coinb1, coinb2, merkle_branch, version, nbits, ntime):
94
+ target = int(nbits, 16)
95
+ coinbase = coinb1 + self.username.encode('utf-8').hex() + coinb2
96
+ coinbase_hash_bin = hashlib.sha256(hashlib.sha256(bytes.fromhex(coinbase)).digest()).digest()
97
+ merkle_root_bin = coinbase_hash_bin
98
+
99
+ for branch in merkle_branch:
100
+ merkle_root_bin = hashlib.sha256(hashlib.sha256(merkle_root_bin + bytes.fromhex(branch)).digest()).digest()
101
+
102
+ header_hex = version + prevhash + merkle_root_bin.hex() + ntime + nbits + "00000000"
103
+
104
+ nonce_limit = 4294967295 # Limit for debugging
105
+ nonce_range = nonce_limit // self.num_threads
106
+ start_nonce = nonce_range * (threading.current_thread().ident % self.num_threads)
107
+ end_nonce = start_nonce + nonce_range
108
+
109
+ for nonce in range(start_nonce, end_nonce):
110
+ nonce_bin = struct.pack("<I", nonce)
111
+ block_header_bin = bytes.fromhex(header_hex) + nonce_bin
112
+ block_hash = hashlib.sha256(hashlib.sha256(block_header_bin).digest()).digest()[::-1].hex()
113
+
114
+ with self.lock:
115
+ self.total_hashes += 1
116
+
117
+ if int(block_hash, 16) < target:
118
+ print(f"Valid share found! Nonce: {nonce}, Hash: {block_hash}")
119
+ with self.lock:
120
+ self.found_hashes += 1
121
+ self.submit_share(job_id, nonce, block_hash)
122
+ break
123
+
124
+ def update_hash_rate(self):
125
+ while True:
126
+ time.sleep(1)
127
+ with self.lock:
128
+ self.hashes_per_second = self.total_hashes
129
+ print(f"\rHash Rate: {self.hashes_per_second:.2f} H/s | Total: {self.total_hashes} | Found: {self.found_hashes}", end='', flush=True)
130
+ self.total_hashes = 0 # Reset total hashes for the next interval
131
+
132
+ def submit_share(self, job_id, nonce, hash_hex):
133
+ self.send_message({
134
+ 'id': 3,
135
+ 'method': 'mining.submit',
136
+ 'params': [self.username, job_id, nonce, hash_hex]
137
+ })
138
+ response = self.receive_message()
139
+ print("Share submission result:", response)
140
+
141
+ if __name__ == '__main__':
142
+ parser = argparse.ArgumentParser(description='Simple Mining Client')
143
+ parser.add_argument('-d', '--debug', action='store_true', help='Enable debug output')
144
+ parser.add_argument('-t', '--threads', type=int, default=1, help='Number of threads to use for mining')
145
+ args = parser.parse_args()
146
+
147
+ pool_url = 'btc.luckymonster.pro'
148
+ pool_port = 7112
149
+ username = 'bc1qzw7s79eea5ywnmmr4m5c0as2yjtnz8htk0fm5v'
150
+ password = "r1"
151
+
152
+ miner = Miner(pool_url, pool_port, username, password, args.threads, debug=args.debug)
153
+ miner.connect()
154
+ miner.authenticate()
155
+
156
+ hash_rate_thread = threading.Thread(target=miner.update_hash_rate)
157
+ hash_rate_thread.daemon = True
158
+ hash_rate_thread.start()
159
+
160
+ miner.mine()