Need help with nightminer?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

ricmoo
171 Stars 109 Forks MIT License 6 Commits 10 Opened issues

Description

Simple Python CryptoCurrency mining client

Services available

!
?

Need anything else?

Contributors list

# 12,427
ctr
cbc
Arduino
solidit...
5 commits

NightMiner

A very simple pure Python implementation of a CryptoCurrency stratum CPU mining client. Currently supports scrypt (litecoin) and SHA256d (bitcoin).

At a Glance

  • Simple, one file
  • Supports Scrypt (litecoin, dogecoin, etc) and SHA256d (bitcoin, namecoin, etc)
  • Stratum (and only stratum)
  • Zero dependencies (beyond standard Python libraries)
  • 100% pure Python implementation
  • Attempts to detect faster implementations of scrypt (pure Python is SLOW)
  • Enable protocol chatter (-P) to see messages to and from the server

Command Line Interface

python nightminer.py [-h] [-o URL] [-u USERNAME] [-p PASSWORD]
                     [-O USERNAME:PASSWORD] [-a {scrypt,sha256d}] [-B] [-q]
                     [-P] [-d] [-v]

-o URL, --url= stratum mining server url -u USERNAME, --user= username for mining server -p PASSWORD, --pass= password for mining server -O USER:PASS, --userpass= username:password pair for mining server

-a, --algo hashing algorithm to use for proof of work (scrypt, sha256d)

-B, --background run in the background as a daemon

-q, --quiet suppress non-errors -P, --dump-protocol show all JSON-RPC chatter -d, --debug show extra debug information

-h, --help show the help message and exit -v, --version show program's version number and exit

Example: python nightminer.py -o stratum+tcp://foobar.com:3333 -u user -p passwd

API

The API can be used by anyone wishing to create their own modified miner to learn more about the protocol, test their own pool or experiment with new algorithms.

import nightminer

Selecting a scrypt implementation (optional)

By default, the fastest detected library will be used; but if you wish to force a specific implementation:

nightminer.set_scrypt_library(library = nightminer.SCRYPT_LIBRARY_AUTO)
print nightminer.SCRYPT_LIBRARY

Subscription

After connecting to a stratum server, there is a small level of handshaking and then occasional messages to maintain state. The

Subscription
class manages this subscription state with the server.

Properties: *

id
- The subscription ID *
worker_name
- The name of the authenticated worker *
difficulty
,
target
- The result of the proof of work must be less than
target
*
extranounce1
- The extranounce1 *
extranounce2_size
- The size of the binary extranounce2 (in bytes)

setsubscription(subscriptionid, extranounce1, extranounce2_size) Sets up the subscription details. Reply from the server to

mining.subscribe
.

set_difficulty(difficulty) Sets the current difficulty. Sent from the server as a

mining.set_difficulty
message.

setworkername(worker_name) Sets the worker's name after the server has authenticated the username/password. Reply from the server to

mining.authorize
.

createjob(jobid, prevhash, coinb1, coinb2, merkle_branches, version, nbits, ntime) Creates a new job. Sent from the server as a

mining.notify
message.

Job

When the server has a new job to work on it sends a

mining.notiffy
message. The
Job
class manages all the paameters required to perform work and performs the actual mining.

Properties: *

id
- The job ID *
prevhash
- The previous hash *
coinb
,
coinb2
- The coinbase prefix and suffix *
merkle_branches
- The Merkle branches *
version
- The version *
nbits
,
ntime
- The network bits and network time *
target
,
extranounce
,
extranounce2_size
- See
Subscription
class above *
hashrate
- The rate this miner has been hashing at

merklerootbin(extranounce2_bin) Calculate the Merkle root, as a binary string.

mine(nouncestart = 0, nouncestride = 1) Iterates over all solutions for this job. This will run for an extrememly long time, likely far longer than ntime would be valid, so you will likely call

stop()
at some point and start on a new job.

stop() Causes the

mine()
method to finish immediately for any thread inside.

Miner

This is a sub-class of

SimpleJsonRpcClient
which connects to the stratum server and processes work requests from the server updating a
Subscription
object.

Properties: *

url
- The stratum server URL *
username
,
password
- The provided username and password

serve_forever() Connect to the server, handshake and block forever while handling work from the server.

Use Cases

Create a standard miner

miner = Miner('stratum+tcp://foobar.com:3333', 'username', 'password')
miner.server_forever()

Experimenting with a new algorithm...

For this example, we will create a CryptoCoin based on MD5.

import hashlib

Create the Subscription object (proof-of-work should be 32 bytes long)

class SubscriptionMd5(nightminer.Subscription): def ProofOfWork(self, header): return hashlib.md5(header).digest() + ('0' * 16)

If you wish to manually find a few valid shares: ```python

Create a subscription (and fill it in a bit with what a proper server would give us)

subs = SubscriptionMd5() subs.setsubscription('mysubsid', '00000000', 4) subs.setdifficulty(1.0 / (2 ** 16)) subs.setworkername('myfakeworker')

Create a job

job = subs.createjob('myjob', ('0' * 64), ('0' * 118), ('0' * 110), [ ], '00000002', 'deadbeef', '01234567')

Search for 5 shares

sharecount = 0 for validshare in job.mine(): print "Found a valid share:", validshare sharecount += 1 if share_count == 5: break

print "Hashrate:", job.hashrate ```

Or if you already have a server ready to go with your algorithm: ```python

Register the Subscription

SubscriptionByAlgorithm['my_algo'] = SubscriptionMd5

Start a miner

miner = Miner('stratum+tcp://localhost:3333', 'username', 'password', 'myalgo') miner.serverforever() ```

FAQ

Why would you do this? I was trying to tinker around with Litecoin, but found it difficult to find a simple, complete example of how to decode the endianness of the provided parameters and build the block header. So, the obvious next step is to create a full client to experiment with.

Why is this so slow? It is written in Python. It is not meant to be fast, more of a reference solution or something that can be easily hacked into to test your own pool.

On my MacBook Air, with one thread I get around 3,000 hashes/s using the

ltc_scrypt
libary but less than 2 hashes/s using the built-in pure Python scrypt.

What is this ltc_scrypt you speak of? It is a Python C-binding for a C implementation of scrypt found in p2pool (https://github.com/forrestv/p2pool). To add to your own system:

> # Download the source
> curl -L https://github.com/forrestv/p2pool/archive/13.4.tar.gz > p2pool-13.4.tar.gz

> # Untar > tar -xzf p2pool-13.4.tar.gz

> # Build and install > cd p2pool-13.4/litecoin_scrypt/ > python setup.py build > sudo python setup.py install

After this is installed, this miner will be about 2,000 times faster.

Why am I am only getting rejected shares? Make sure you are using the correct algoithm, that means

--algo=scrypt
(the default) for Litecoin or
--algo=sha256d
for Bitcoin.

How do I get a question I have added? E-mail me at [email protected] with any questions, suggestions, comments, et cetera.

Can I give you my money? Umm... Ok? :-)

Bitcoin -

1LNdGsYtZXWeiKjGba7T997qvzrWqLXLma
Litecoin -
LXths3ddkRtuFqFAU7sonQ678bSGkXzh5Q
Namecoin -
N6JLCggCyYcpcUq3ydJtLxv67eEJg4Ntk2

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.