Skip to content

Instantly share code, notes, and snippets.

Created November 19, 2013 17:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/7549461 to your computer and use it in GitHub Desktop.
Save anonymous/7549461 to your computer and use it in GitHub Desktop.
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