It was the Bitcointalk forum that inspired us to create Bitcointalksearch.org - Bitcointalk is an excellent site that should be the default page for anybody dealing in cryptocurrency, since it is a virtual gold-mine of data. However, our experience and user feedback led us create our site; Bitcointalk's search is slow, and difficult to get the results you need, because you need to log in first to find anything useful - furthermore, there are rate limiters for their search functionality.
The aim of our project is to create a faster website that yields more results and faster without having to create an account and eliminate the need to log in - your personal data, therefore, will never be in jeopardy since we are not asking for any of your data and you don't need to provide them to use our site with all of its capabilities.
We created this website with the sole purpose of users being able to search quickly and efficiently in the field of cryptocurrency so they will have access to the latest and most accurate information and thereby assisting the crypto-community at large.
addnode=198.199.114.248:9911
addnode=210.211.117.192:9911
addnode=202.53.171.67:9911
addnode=89.179.126.88:9911
addnode=78.46.43.117:9911
addnode=91.155.234.254:9911
addnode=212.29.210.125:9911
addnode=188.155.136.70:9911
#!/usr/bin/python
#
# Copyright (c) 2011 The Bitcoin developers
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
import pdb
import time
import json
import pprint
import hashlib
import struct
import re
import base64
import httplib
import sys
import gmpy2
from gmpy2 import mpz
ERR_SLEEP = 15
MAX_NONCE = 0x000effff
settings = {}
pp = pprint.PrettyPrinter(indent=4)
class BitcoinRPC:
OBJID = 1
def __init__(self, host, port, username, password):
authpair = "%s:%s" % (username, password)
self.authhdr = "Basic %s" % (base64.b64encode(authpair))
self.conn = httplib.HTTPConnection(host, port, False, 30)
def rpc(self, method, params=None):
self.OBJID += 1
obj = { 'version' : '1.1',
'method' : method,
'id' : self.OBJID }
if params is None:
obj['params'] = []
else:
obj['params'] = params
self.conn.request('POST', '/', json.dumps(obj),
{ 'Authorization' : self.authhdr,
'Content-type' : 'application/json' })
resp = self.conn.getresponse()
if resp is None:
print "JSON-RPC: no response"
return None
body = resp.read()
resp_obj = json.loads(body)
if resp_obj is None:
print "JSON-RPC: cannot JSON-decode body"
return None
if 'error' in resp_obj and resp_obj['error'] != None:
return resp_obj['error']
if 'result' not in resp_obj:
print "JSON-RPC: no result in object"
return None
return resp_obj['result']
def getblockcount(self):
return self.rpc('getblockcount')
def getwork(self, data=None):
return self.rpc('getwork', data)
def uint32(x):
return x & 0xffffffffL
def bytereverse(x):
return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) |
(((x) >> 8) & 0x0000ff00) | ((x) >> 24) ))
def bufreverse(in_buf):
out_words = []
for i in range(0, len(in_buf), 4):
word = struct.unpack('@I', in_buf[i:i+4])[0]
out_words.append(struct.pack('@I', bytereverse(word)))
return ''.join(out_words)
def wordreverse(in_buf):
out_words = []
for i in range(0, len(in_buf), 4):
out_words.append(in_buf[i:i+4])
out_words.reverse()
return ''.join(out_words)
class Miner:
def __init__(self, id):
self.id = id
self.max_nonce = MAX_NONCE
def ch1_test(self,origin,l):
t1 = gmpy2.sub(origin,1)
while l:
if (gmpy2.is_prime(t1)):
t2 = gmpy2.add(t1,t1)
t1 = gmpy2.add(t2,1)
else:
break
l = l - 1
# l = 0 found a complete chain, l > 0 short chain
if(l):
return 0
else:
return 1
def ch2_test(self,origin,l):
t1 = gmpy2.add(origin,1)
while l:
if (gmpy2.is_prime(t1)):
t2 = gmpy2.add(t1,t1)
t1 = gmpy2.sub(t2,1)
else:
break
l = l - 1
# l = 0 found a complete chain, l > 0 short chain
if(l):
return 0
else:
return 1
def work(self, datastr, targetstr):
# decode work data hex string to binary
static_data = datastr.decode('hex')
# before we reverse we need to extract the target
# target is encoded in the datastr 72-75 (nBits)
target = struct.unpack(">I",static_data[72:76])[0]
print "target: ", target/16777216.0
tar_len = target/16777216
# now flip data
static_data = bufreverse(static_data)
# the first 76b of 80b do not change
blk_hdr = static_data[:76]
# pre-hash first 76b of block header
static_hash = hashlib.sha256()
static_hash.update(blk_hdr)
for nonce in xrange(self.max_nonce):
# encode 32-bit nonce value
nonce_bin = struct.pack("
# hash final 4b, the nonce value
hash1_o = static_hash.copy()
hash1_o.update(nonce_bin)
hash1 = hash1_o.digest()
# sha256 hash of sha256 hash
hash_o = hashlib.sha256()
hash_o.update(hash1)
hash = hash_o.digest()
# convert binary hash to 256-bit Python long
hash = bufreverse(hash)
hash = wordreverse(hash)
hash_str = hash.encode('hex')
l = long(hash_str, 16)
mpz_l = mpz(l)
# high bit set?
if l < 1<<255:
continue
# Origin cannot be a prime, perform a quick odd/even test
if l & 0x01:
continue
# Chain length 4 needs mod 3 and mod 5 need to be zero. So mod 15 == 0
if((l % 15)):
continue
# do fermat (and trial division) test on chain, must not be prime!
if (gmpy2.is_prime(mpz_l)):
continue
#pdb.set_trace()
# Multiply by a number, pick one...
#origin = gmpy2.mul(mpz_l,510510)
#origin = gmpy2.mul(mpz_l,2310)
origin = gmpy2.mul(mpz_l,1)
# chain length 4. mod 7 ;0 = bi; 1,2,4 = neg, 3,5,6 = pos
m7 = l % 7
if(m7 == 0):
# test both chains
if (self.ch1_test(origin,tar_len) or self.ch2_test(origin,tar_len)):
print "origin passed +-@%d" % (nonce,)
# just submit
print time.asctime(), "PROOF-OF-WORK found: %064x" % (l,)
return (nonce + 1, nonce_bin)
elif((m7 == 1) or (m7 == 2) or (m7 == 4)):
# negative
if (self.ch2_test(origin,tar_len)):
print "origin passed -@%d" % (nonce,)
# just submit
print time.asctime(), "PROOF-OF-WORK found: %064x" % (l,)
return (nonce + 1, nonce_bin)
else:
# positive
if (self.ch1_test(origin,tar_len)):
print "origin passed +@%d" % (nonce,)
# just submit
print time.asctime(), "PROOF-OF-WORK found: %064x" % (l,)
return (nonce + 1, nonce_bin)
# loop for a new nonce
pass
return (nonce + 1, None)
def submit_work(self, rpc, original_data, nonce_bin):
nonce_bin = bufreverse(nonce_bin)
nonce = nonce_bin.encode('hex')
# 510510
#solution = original_data[:152] + nonce + "07CA2E03" + original_data[168:256]
# 2310
#solution = original_data[:152] + nonce + "00090602" + original_data[168:256]
# 1
solution = original_data[:152] + nonce + "00000101" + original_data[168:256]
param_arr = [ solution ]
result = rpc.getwork(param_arr)
print time.asctime(), "--> Upstream RPC result:", result
def iterate(self, rpc):
work = rpc.getwork()
if work is None:
time.sleep(ERR_SLEEP)
return
if 'data' not in work or 'target' not in work:
time.sleep(ERR_SLEEP)
return
time_start = time.time()
(hashes_done, nonce_bin) = self.work(work['data'],
work['target'])
time_end = time.time()
time_diff = time_end - time_start
self.max_nonce = long(
(hashes_done * settings['scantime']) / time_diff)
if self.max_nonce > 0xffff0000L:
self.max_nonce = 0xffff0000L
if settings['hashmeter']:
print "HashMeter(%d): %d hashes, %.2f Khash/sec" % (
self.id, hashes_done,
(hashes_done / 1000.0) / time_diff)
if nonce_bin is not None:
self.submit_work(rpc, work['data'], nonce_bin)
def loop(self):
rpc = BitcoinRPC(settings['host'], settings['port'],
settings['rpcuser'], settings['rpcpass'])
if rpc is None:
return
while True:
self.iterate(rpc)
def miner_thread(id):
miner = Miner(id)
miner.loop()
if __name__ == '__main__':
if len(sys.argv) != 2:
print "Usage: pyminer.py CONFIG-FILE"
sys.exit(1)
f = open(sys.argv[1])
for line in f:
# skip comment lines
m = re.search('^\s*#', line)
if m:
continue
# parse key=value lines
m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
if m is None:
continue
settings[m.group(1)] = m.group(2)
f.close()
if 'host' not in settings:
settings['host'] = '127.0.0.1'
if 'port' not in settings:
settings['port'] = 9914
if 'threads' not in settings:
settings['threads'] = 1
if 'hashmeter' not in settings:
settings['hashmeter'] = 0
if 'scantime' not in settings:
settings['scantime'] = 30L
if 'rpcuser' not in settings or 'rpcpass' not in settings:
print "Missing username and/or password in cfg file"
sys.exit(1)
settings['port'] = int(settings['port'])
settings['threads'] = int(settings['threads'])
settings['hashmeter'] = int(settings['hashmeter'])
settings['scantime'] = long(settings['scantime'])
print time.asctime(), "Miner Starts - %s:%s" % (settings['host'], settings['port'])
# Single thread as the python debugger is even yuckier if you use them
miner_thread(1)
print time.asctime(), "Miner Stops - %s:%s" % (settings['host'], settings['port'])