Created
November 19, 2013 17:53
-
-
Save anonymous/7549461 to your computer and use it in GitHub Desktop.
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
import socket, json, random, time, struct | |
from binascii import hexlify, unhexlify | |
from hashlib import sha256 | |
def uint256_from_compact(c): | |
nbytes = (c >> 24) & 0xFF | |
v = (c & 0xFFFFFFL) << (8 * (nbytes - 3)) | |
return v | |
class JsonRPC2: | |
def __init__(self, host, port, timeout = 5): | |
self.conn = socket.create_connection((host, port), timeout) | |
self.id = 0 | |
self.handleNotification = None | |
def _write(self, message): | |
self.id += 1; | |
message['id'] = self.id; | |
print "==> "+json.dumps(message)+"\n" | |
self.conn.sendall(json.dumps(message)+"\n") | |
return self.id; | |
def write(self, message, cb = None): | |
ids = self._write(message) | |
data = self.conn.recv(3024) | |
print "<== "+data | |
for r in data.split("\n"): | |
try: | |
m = json.loads(r) | |
except: | |
m = None | |
if m != None and m['id'] == ids and cb != None: | |
cb(m) | |
for r in data.split("\n"): | |
try: | |
m = json.loads(r) | |
except: | |
m = None | |
if m != None and m['id'] != ids and self.handleNotification != None: | |
self.handleNotification(m) | |
def close(self): | |
self.conn.close() | |
class Miner: | |
def __init__(self): | |
self.extranonce1 = ""; | |
self.extranonce2 = 23343; | |
self.extranonce2_size = 4; | |
self.authorized = False; | |
self.difficulty = 1; | |
self.job = None | |
self.workerData = None | |
def open(self, host, port): | |
self.sock = JsonRPC2(host, port) | |
self.sock.handleNotification = self.handleMiningNotification | |
self.sock.write({"method": "mining.subscribe", "params": ["JSMiner"]}, self.handleMiningSubscribe) | |
def authorize(self, name, password): | |
self.sock.write({"method": "mining.authorize", "params": [name, password]}, self.handleMiningAuthorize) | |
def handleMiningNotification(self, m): | |
if m['method'] == "mining.set_difficulty": | |
self.difficulty = int(m['params'][0]) | |
print "Difficulty: "+str(self.difficulty) | |
if m['method'] == "mining.notify": | |
self.job = { | |
"job_id": m['params'][0], | |
"prevhash": unhexlify(m['params'][1].encode("ascii")), | |
"coinb1": unhexlify(m['params'][2].encode("ascii")), | |
"coinb2": unhexlify(m['params'][3].encode("ascii")), | |
"merkle_branch": [unhexlify(branch.encode("ascii")) for branch in m['params'][4]][::-1], | |
"version": unhexlify(m['params'][5].encode("ascii")), | |
"nbits": unhexlify(m['params'][6].encode("ascii")), | |
"ntime": struct.unpack(">I", unhexlify(m["params"][7].encode("ascii")))[0] - int(time.time()), | |
"clean_jobs": m['params'][8] | |
}; | |
def refreshWorkerData(self): | |
coinbase = self.job["coinb1"] + self.extranonce1 + self.extranonce2 + self.job["coinb2"] | |
merkle = sha256(sha256(coinbase).digest()).digest() | |
for branch in self.job["merkle_branch"]: merkle = sha256(sha256(merkle + branch).digest()).digest() | |
merkle = hexlify(struct.pack("<8I", *struct.unpack(">8I", merkle))) | |
nbits = hexlify(self.job['nbits']) | |
# Version, nonce e time in (int) | |
hashPrev = hexlify(self.job['prevhash']) | |
hashPrevA = [hashPrev[i:i+8] for i in range(0, len(hashPrev), 8)] | |
hashPrev = "".join(hashPrevA[::-1]) | |
print "RealPrevHash: "+hashPrev | |
hashPrevA = [hashPrev[i:i+2] for i in range(0, len(hashPrev), 2)] | |
hashPrev = "".join(hashPrevA[::-1]) | |
print "MinerPrevHash: "+hashPrev | |
#hashMerkleA = [merkle[i:i+2] for i in range(0, len(merkle), 2)] | |
#hashMerkle = "".join(hashMerkleA[::-1]) | |
#print "MinerMerkleHash: "+hashMerkle | |
print "HashMerkle: "+merkle | |
hashNBitsA = [nbits[i:i+2] for i in range(0, len(nbits), 2)] | |
hashNBits = "".join(hashNBitsA[::-1]) | |
print "MinerHashNBits: "+hashNBits | |
s = uint256_from_compact(int(hexlify(self.job['nbits']), 16)) | |
s = str(hex(s)[2:-1]) | |
while len(s) < 64: | |
s = "0"+s | |
self.workerData = { | |
"version": struct.unpack(">I", self.job['version'])[0], | |
"hashPrevBlock": hashPrev, | |
"hashMerkleRoot": merkle, | |
"time": self.job['ntime'] + int(time.time()), | |
"target": s, | |
"nbits": hashNBits | |
} | |
print self.workerData | |
def handleMiningAuthorize(self, m): | |
self.authorized = m['result'] | |
print "Authorized: "+str(self.authorized) | |
def handleMiningSubscribe(self, m): | |
self.extranonce1 = unhexlify(m['result'][1].encode('ascii')) | |
self.extranonce2_size = int(m['result'][2]) | |
self.extranonce2 = unhexlify((("%%0%dx" % (2 * self.extranonce2_size)) % random.randint(0,100000)).encode("ascii")) | |
print "Extranonce1: "+hexlify(self.extranonce1) | |
print "Extranonce2_size: "+str(self.extranonce2_size) | |
print "Extranonce2: "+hexlify(self.extranonce2) | |
def close(self): | |
self.sock.close() | |
if __name__ == "__main__": | |
m = Miner() | |
m.open('mine.pool-x.eu',9000) | |
m.authorize('manzati93.1','x') | |
m.refreshWorkerData() | |
m.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment