diff --git a/check_coin.py b/check_coin.py index 1837346..d4444fc 100644 --- a/check_coin.py +++ b/check_coin.py @@ -1,84 +1,51 @@ -import get_difficulty -import socket +import send_command +from rsa import PublicKey, encrypt +import time +import os import json -from rsa import * -import hashlib -import base64 -import sqlite3 import config +import hashlib import re -import os -import time +import base64 def check_coin(obj, data): """ - - {"address":, "hash":, "starter":} + + {"address":, "hash":, "starter":starter} """ - check = sqlite3.connect("db.db").cursor() - check.execute("SELECT * FROM coins WHERE hash=?", [data['hash']]) - if check.fetchall(): - print "Coin already exists" + check = config.db.find("coins", {"hash":data['hash']}) + if check: + print "Coin already exists." return - node = sqlite3.connect("nodes.db").cursor() - c = node.execute("SELECT public FROM data WHERE address=?", [data['address']]) - c = c.fetchall() - check.execute("SELECT level FROM difficulty") - difficulty = check.fetchall()[0][0] - if c: - c = c[0] + check_addr = config.nodes.find("nodes", {"address":data['address']}) + difficulty = config.db.find("coins", "all") + if not difficulty: + difficulty = [] + difficulty = len(difficulty)/50500 + 7 + if difficulty < 7: + difficulty = 7 + + if check_addr: + c = check_addr[0] if len(data['hash']) == 128: if hashlib.sha512(str(data['starter'])).hexdigest() == data['hash'] and data['hash'].startswith("1"*int(difficulty)): - if c[0].startswith("PublicKey(") and c[0].endswith(")"): - key = re.findall("([0-9]*)", c[0]) - key = filter(None, key) - key = PublicKey(int(key[0]), int(key[1])) + key = re.findall("([0-9]*)", c['public']) + key = filter(None, key) + key = PublicKey(int(key[0]), int(key[1])) data['plain'] = data['starter'] data['starter'] = base64.b64encode(encrypt(str(data['starter']), key)) obj.send(json.dumps({"response":"Coin Confirmed!"})) - try: - out = sqlite3.connect("db.db").cursor() - out.execute("SELECT * FROM coins") - data['difficulty'] = len(out.fetchall())/205000 + 7 - except TypeError: - data['difficulty'] = 7 - send_confirm(data) + while os.path.exists("db.lock"): + time.sleep(0.1) + open("db.lock", 'w').close() + config.db.insert("coins", {"starter":data['starter'], "hash":data['hash'], "address":data['address'], "difficulty":difficulty}) + config.db.save() + os.remove("db.lock") else: - obj.send(json.dumps({"response":"Invalid Coin!"})) - - -def send_confirm(data): - nodes = sqlite3.connect("nodes.db").cursor() - nodes = nodes.execute("SELECT ip, port FROM data WHERE relay=1 AND version=?", [config.version]) - nodes = nodes.fetchall() - for x in nodes: - s = socket.socket() - try: - s.settimeout(120) - s.connect((x[0], x[1])) - except: - continue + print "Invalid Coin!" else: - data['cmd'] = "confirm_coin" - s.send(json.dumps(data)) - s.close() - -def confirm_coin(obj, data): - db_ = sqlite3.connect("db.db") - db = db_.cursor() - check = sqlite3.connect("db.db").cursor() - check.execute("SELECT level FROM difficulty") - difficulty = check.fetchall()[0][0] - db.execute("SELECT * FROM coins WHERE hash=?", [data['hash']]) - if data['hash'].startswith("1"*int(difficulty)) and len(data['hash']) == 128 and not db.fetchall() and hashlib.sha512(data['plain']).hexdigest() == data['hash']: - while os.path.exists("db.lock"): - time.sleep(0.1) - open("db.lock", 'w') - db_.execute("UPDATE difficulty SET level=? WHERE level=?", [data['difficulty'], difficulty]) - db_.execute("INSERT INTO coins (starter, hash, address) VALUES (?, ?, ?)", [data['starter'], data['hash'], data['address']]) - db_.commit() - os.remove("db.lock") + print "Hash not long enough" else: - return - + print "Addr invalid." + diff --git a/coin_count.py b/coin_count.py new file mode 100644 index 0000000..3c48cc0 --- /dev/null +++ b/coin_count.py @@ -0,0 +1,29 @@ +import config +import json +import send_command +import get_db + +def coin_count(obj, data): + coins = config.db.find("coins", "all") + if coins: + obj.send(json.dumps({"coins":len(coins)})) + else: + obj.send(json.dumps({"coins":0})) + +def send(): + coins = config.db.find("coins", "all") + if coins: + coins = len(coins) + else: + coins = 0 + out = send_command.send({"cmd":"coin_count"}, out=True) + try: + out = json.loads(out) + except ValueError: + send() + else: + print out + if out['coins'] > coins: + get_db.send() + + diff --git a/config.py b/config.py index 134331e..0b9e413 100644 --- a/config.py +++ b/config.py @@ -1,7 +1,10 @@ -import sqlite3 +import landerdb -relay = 0 #1 is on 0 is off If 1 you must portforward port 6565 -brokers = [{0:"zcoin.zapto.org", 1:6564}, {0:"192.111.130.31", 1:6565}]#, {0:"162.209.89.34", 1:6565}] -port = 6565 +relay = 0 +brokers = [{"ip":"zcoin.zapto.org", "port":6564}] +version = "0.2.0" host = "0.0.0.0" -version = "0.1.6" +port = 6565 +nodes = landerdb.Connect("nodes.db") +wallet = landerdb.Connect("wallet.db") +db = landerdb.Connect("db.db") diff --git a/get_db.py b/get_db.py index f6e1cde..8838246 100644 --- a/get_db.py +++ b/get_db.py @@ -2,90 +2,56 @@ import json import config import random -import sqlite3 -import base64 -import hashlib -import register, get_nodes -import time import os +import time def get_db(obj, data): - db = sqlite3.connect("db.db").cursor() - db.execute("CREATE TABLE IF NOT EXISTS difficulty (level INT default 7)") - db.execute("CREATE TABLE IF NOT EXISTS coins (hash TEXT, address TEXT, starter TEXT)") - db.execute("CREATE TABLE IF NOT EXISTS transactions (to_ TEXT, from_ TEXT, hash TEXT)") - try: - db.execute("SELECT * FROM coins") - except sqlite3.DatabaseError: - return with open("db.db", 'rb') as file: while True: - x = file.read(100) - if not x: + data = file.read(100) + if not data: break - md5sum = hashlib.md5(x).hexdigest() - out = base64.b64encode(x) - x = json.dumps({"md5sum":md5sum, "data":out}) - obj.send(x) + obj.send(data) -def get_db_send(): - node = sqlite3.connect("nodes.db") - cmd = {"cmd":"get_db"} - try: - nodes = node.execute("SELECT ip, port FROM data WHERE relay=? AND version=?", [True, config.version]) - except sqlite3.OperationalError: - get_nodes.get_nodes_send(True) - get_db_send() - register.register_send() - return - if not nodes: - return - nodes = nodes.fetchall() - if not nodes: +def send(god=False): + if god: nodes = config.brokers - random.shuffle(nodes) + else: + nodes = config.nodes.find("nodes", {"relay":1}) + random.shuffle(nodes) for x in nodes: - s = socket.socket() try: - s.settimeout(120) - s.connect((x[0], x[1])) + s.connect((x['ip'], x['port'])) except: s.close() continue else: - s.send(json.dumps(cmd)) - out = "" - current = "" - no = False - while True: + s.send(json.dumps({"cmd":"get_version"})) + data = s.recv(1024) + if data == config.version: + s.close() + s = socket.socket() try: - data = s.recv(1) + s.connect((x['ip'], x['port'])) except: - no = True - break - if data: - current = current + data - if data != "}": - continue - try: - data = json.loads(current) - except ValueError: - break - else: - current = "" - check = base64.b64decode(data['data']) - if hashlib.md5(check).hexdigest() == data['md5sum']: - out = out + check - else: - break + s.close() + continue else: + s.send(json.dumps({"cmd":"get_db"})) + out = "" + while True: + data = s.recv(1024) + if not data: + break + out = out + data + while os.path.exists("db.lock"): + time.sleep(0.1) + open("db.lock", 'w').close() + with open("db.db", 'wb') as file: + file.write(out) + os.remove("db.lock") break - if not no: - while os.path.exists("db.lock"): - time.sleep(0.1) - open("db.lock", 'w') - with open("db.db", 'wb') as file: - file.write(out) - os.remove("db.lock") - break + else: + s.close() + diff --git a/get_difficulty.py b/get_difficulty.py index b2cb54a..afcc19b 100644 --- a/get_difficulty.py +++ b/get_difficulty.py @@ -1,50 +1,12 @@ -import socket -import json -import sqlite3 import config +import json def get_difficulty(obj, data): - node = sqlite3.connect("nodes.db") - nodes = node.execute("SELECT ip, port FROM data WHERE relay=1 AND version=?", [config.version]) - nodes = nodes.fetchall() - difficulties = [] - for x in nodes: - s = socket.socket() - try: - s.settimeout(120) - s.connect((x[0], x[1])) - except: - s.close() - continue - else: - s.send(json.dumps({"cmd":"get_raw_difficulty"})) - data = s.recv(1024) - if not data: - s.close() - continue - try: - data = int(data) - except: - continue - else: - difficulties.append(data) - out = 0 - for x in difficulties: - out += x - try: - out = out/len(difficulties) - if out < 7: - out = 7 - except ZeroDivisionError: - out = 7 - try: # Without this it will raise an error when check_coin is called. - obj.send(json.dumps({"difficulty":out})) - except: - pass - return {"difficulty":out} + diff = config.db.find("coins", "all") + if not diff: + diff = [] + diff = len(diff)/50500 + 7 + if diff < 7: + diff = 7 + obj.send(json.dumps({"difficulty":diff})) -def get_raw_difficulty(obj, data): - db = sqlite3.connect("db.db") - check = db.execute("SELECT level FROM difficulty") - check = check.fetchall()[0] - obj.send(str(check[0])) diff --git a/get_nodes.py b/get_nodes.py index fde3888..5b2b591 100644 --- a/get_nodes.py +++ b/get_nodes.py @@ -2,88 +2,56 @@ import json import config import random -import sqlite3 -import base64 -import hashlib -import register, get_db import os import time def get_nodes(obj, data): - n = sqlite3.connect("nodes.db").cursor() - try: - n.execute("SELECT * FROM data") - except sqlite3.DatabaseError: - return with open("nodes.db", 'rb') as file: while True: - x = file.read(100) - if not x: + data = file.read(100) + if not data: break - md5sum = hashlib.md5(x).hexdigest() - out = base64.b64encode(x) - x = json.dumps({"md5sum":md5sum, "data":out}) - obj.send(x) + obj.send(data) -def get_nodes_send(god=False): - node = sqlite3.connect("nodes.db") - cmd = {"cmd":"get_nodes"} +def send(god=False): if god: nodes = config.brokers else: - try: - nodes = node.execute("SELECT ip, port FROM data WHERE relay=?", [True]) - except sqlite3.OperationalError: - get_nodes_send(True) - get_db.get_db_send() - register.register_send() - return - nodes = nodes.fetchall() - if not nodes: - return - random.shuffle(nodes) + nodes = config.nodes.find("nodes", {"relay":1}) + random.shuffle(nodes) for x in nodes: - s = socket.socket() try: - s.settimeout(120) - s.connect((x[0], x[1])) + s.connect((x['ip'], x['port'])) except: s.close() continue else: - s.send(json.dumps(cmd)) - out = "" - current = "" - no = False - while True: + s.send(json.dumps({"cmd":"get_version"})) + data = s.recv(1024) + if data == config.version: + s.close() + s = socket.socket() try: - data = s.recv(1) + s.connect((x['ip'], x['port'])) except: - no = True - break - if data: - current = current + data - if data != "}": - continue - try: - data = json.loads(current) - except ValueError: - break - else: - current = "" - check = base64.b64decode(data['data']) - if hashlib.md5(check).hexdigest() == data['md5sum']: - out = out + check - else: - break + s.close() + continue else: + s.send(json.dumps({"cmd":"get_nodes"})) + out = "" + while True: + data = s.recv(1024) + if not data: + break + out = out + data + while os.path.exists("nodes.lock"): + time.sleep(0.1) + open("nodes.lock", 'w').close() + with open("nodes.db", 'wb') as file: + file.write(out) + os.remove("nodes.lock") break - if not no: - while os.path.exists("nodes.lock"): - time.sleep(0.1) - open("nodes.lock", 'w') - with open("nodes.db", 'wb') as file: - file.write(out) - os.remove("nodes.lock") - break + else: + s.close() + diff --git a/get_version.py b/get_version.py index f3b49bf..08c6c8b 100644 --- a/get_version.py +++ b/get_version.py @@ -1,29 +1,4 @@ import config -import sys -import socket -import json - -def get_version_send(): - nodes = config.brokers - for x in nodes: - s = socket.socket() - try: - s.settimeout(120) - s.connect((x[0], x[1])) - except: - s.close() - continue - else: - s.send(json.dumps({"cmd":"get_version"})) - data = s.recv(1024) - try: - data = json.loads(data) - except ValueError: - s.close() - continue - else: - return data def get_version(obj, data): - obj.send(json.dumps({"version":config.version})) - + obj.send(config.version) diff --git a/landerdb.py b/landerdb.py new file mode 100644 index 0000000..01554fc --- /dev/null +++ b/landerdb.py @@ -0,0 +1,61 @@ +import json +import os + +__version__ = "1.0.0" + +class Connect: + + def __init__(self, db_file): + self.db = db_file + self.json_data = {} + # allows find to be called multiple times, without + # re-reading from disk unless a change has occured + self.stale = True + if not os.path.exists(self.db): + self.save() + + def _load(self): + if self.stale: + with open(self.db, 'rb') as fp: + try: + self.json_data = json.load(fp) + except: + with open(self.db, 'wb') as file: + file.write(json.dumps(self.json_data)) + self._load() + def save(self): + with open(self.db, 'wb') as fp: + json.dump(self.json_data, fp) + self.stale = True + + def insert(self, collection, data): + self._load() + if collection not in self.json_data: + self.json_data[collection] = [] + self.json_data[collection].append(data) + + def remove(self, collection, data): + self._load() + if collection not in self.json_data: + return False + self.json_data[collection].remove(data) #Will only delete one entry + + def find(self, collection, data): + self._load() + if collection not in self.json_data: + return False + output = [] + for x in self.json_data[collection]: + if data != "all": + for y in data: + try: + if data[y] == x[y]: + output.append(x) + except KeyError: + continue + else: + output.append(x) + return output + + + diff --git a/miner.py b/miner.py index 5336a85..c8b7ce3 100644 --- a/miner.py +++ b/miner.py @@ -1,71 +1,24 @@ -import socket -import hashlib -import json +import send_command +import config import random import string -import sqlite3 -import threading - -def check_difficulty(): - db = sqlite3.connect("nodes.db") - find = db.execute("SELECT ip, port FROM data WHERE relay=?", [True]) - find = find.fetchall() - random.shuffle(find) - for x in find: - s = socket.socket() - try: - s.settimeout(1) - s.connect(x) - except: - s.close() - continue - else: - s.send(json.dumps({"cmd":"get_raw_difficulty"})) - data = s.recv(1024) - if data: - s.close() - return {"difficulty":int(data)} - - -def check_coin(data): - node = sqlite3.connect("nodes.db") - node = node.execute("SELECT ip, port FROM data WHERE relay=?", [True]) - node = node.fetchall() - random.shuffle(node) - for x in node: - s = socket.socket() - try: - s.settimeout(120) - s.connect((x[0], x[1])) - except: - s.close() - continue - else: - data['cmd'] = "check_coin" - print data - s.send(json.dumps(data)) - s.close() +import json +from hashlib import sha512 def mine(): + starter = ''.join([random.choice(string.uppercase+string.lowercase+string.digits) for x in range(5)]) + diff = send_command.send({"cmd":"get_difficulty"}, out=True) + diff = json.loads(diff)['difficulty'] + on = 0 + print starter + print diff while True: - check = check_difficulty() - starter = ''.join([random.choice(string.uppercase+string.lowercase+string.digits) for x in range(5)]) - on = 0 - print check - while True: -# print starter+str(on) - c = hashlib.sha512(starter+str(on)).hexdigest() - startswith = "1"*check['difficulty'] - if c.startswith(startswith): - print c - wall = sqlite3.connect("wallet.db") - address = wall.execute("SELECT address FROM data") - address = address.fetchall()[0][0] - check_coin({"starter":starter+str(on), "hash":c, "address":address}) - break - else: - on += 1 + check = starter + str(on) + #print check + if sha512(check).hexdigest().startswith("1"*diff): + send_command.send({"cmd":"check_coin", "address":raw_input("Address: "), "starter":starter+str(on), "hash":sha512(check).hexdigest()}) + else: + on += 1 + -for x in range(15): - threading.Thread(target=mine).start() -#mine() +mine() diff --git a/register.py b/register.py index 6a58e8c..2f5a5a8 100644 --- a/register.py +++ b/register.py @@ -1,53 +1,44 @@ -import json import socket +import json import config -import random -import sqlite3 -import get_nodes, get_db import os import time def register(obj, data): while os.path.exists("nodes.lock"): time.sleep(0.1) - open("nodes.lock", 'w') - check = sqlite3.connect("nodes.db") - c = check.execute("SELECT * FROM data WHERE address=?", [data['address']]) - if c.fetchall(): - check.execute("UPDATE data SET relay=?, ip=?, port=?, public=?, version=? WHERE address=?", [data['relay'], data['ip'], data['port'], data['address'], data['public'], data['version']]) - else: - check.execute("INSERT INTO data (address, ip, port, relay, public, version) VALUES (?, ?, ?, ?, ?, ?)", [data['address'], data['ip'], data['port'], data['relay'], data['public'], data['version']]) - check.commit() + open("nodes.lock",'w').close() + stuff = config.nodes.find("nodes", {"address":data['address']}) + if stuff: + for x in stuff: + config.nodes.remove("nodes", x) + config.nodes.save() + config.nodes.insert("nodes", data) + config.nodes.save() os.remove("nodes.lock") -def register_send(god=False): - node = sqlite3.connect("nodes.db") - wallet = sqlite3.connect("wallet.db") - data = wallet.execute("SELECT address, public FROM data") - data = data.fetchall()[0] - cmd = {"cmd":"register", "address":data[0], "public":data[1], "port":config.port, "relay":config.relay, "version":config.version} - try: - nodes = node.execute("SELECT ip, port FROM data WHERE relay=?", [True]) - except sqlite3.OperationalError: - get_nodes.get_nodes_send(True) - get_db.get_db_send() - register_send() - return - nodes = nodes.fetchall() - if god: - nodes = config.brokers - if not nodes: - return - random.shuffle(nodes) +def send(): + nodes = config.nodes.find("nodes", {"relay":1}) for x in nodes: s = socket.socket() try: - s.settimeout(120) - s.connect((x[0], x[1])) + s.connect((x['ip'], x['port'])) except: - s.close() continue else: - s.send(json.dumps(cmd)) - s.close() - + s.send(json.dumps({"cmd":"get_version"})) + data = s.recv(1024) + s.close() + if data == config.version: + s = socket.socket() + try: + s.connect((x['ip'], x['port'])) + except: + continue + else: + data = config.wallet.find("data", "all")[0] + s.send(json.dumps({"cmd":"register", "relay":config.relay, "public":data['public'], "address":data['address'], "port":config.port})) + s.close() + break + else: + s.close() diff --git a/send_coin.py b/send_coin.py index 04afad8..cf04ba5 100644 --- a/send_coin.py +++ b/send_coin.py @@ -1,102 +1,79 @@ -import socket -import sqlite3 +import config import json from rsa import * import base64 import re import hashlib -import config import os import time +import send_command +import hashlib +import uuid + +def send(address, amount): -def send_coin_send(address, amount): """ - - send as - + {"cmd":"send_coin", "for":
, "hash":, "starter":} - + """ - amount = int(amount) - db = sqlite3.connect("db.db").cursor() - wallet = sqlite3.connect('wallet.db') - nodes = sqlite3.connect('nodes.db').cursor() - nodes.execute("SELECT public FROM data WHERE address=?", [address]) - check = nodes.fetchall() - nodes.execute('SELECT ip, port FROM data WHERE relay=1') - node = nodes.fetchall() - if check[0][0]: - my_key = wallet.execute('SELECT private, address FROM data') - my_key = my_key.fetchall()[0] - my_address = my_key[1] - my_key = my_key[0] - key = check[0][0] - - if key.startswith('PublicKey(') and key.endswith(')'): - key = re.findall("([0-9]*)", key) - key = filter(None, key) - try: - for x in key: - int(x) - except: - return "Address has an invalid PublicKey" - key = PublicKey(int(key[0]), int(key[1])) - - my_key = re.findall("([0-9]*)", my_key) - my_key = filter(None, my_key) - my_key = PrivateKey(int(my_key[0]), int(my_key[1]), int(my_key[2]), int(my_key[3]), int(my_key[4])) - check_coins = db.execute('SELECT starter, hash FROM coins WHERE address=?', [my_address]) - check_coins = check_coins.fetchall() - if len(check_coins) < amount: - return 'You have insufficient funds.' - check_coins = check_coins[:amount] - for x in check_coins: - starter, hash_ = x[0], x[1] - starter = base64.b64encode(encrypt(decrypt(base64.b64decode(starter), my_key), key)) - out = {'cmd': 'send_coin', - 'for': address, - 'starter': starter, - 'hash': hash_} - if not send_coin_do(out): - continue - else: - return "You have invalid coins" - return "Coins sent successfully!" - else: - return "Invalid Key" + amount = int(amount) + check = config.nodes.find("nodes", {"address":address}) + if not check: + print "Address does not exist" else: - return "Address does not exist" - - -def send_coin_do(out): - node = sqlite3.connect('nodes.db').cursor() - to_send = json.dumps(out) - node.execute('SELECT ip, port FROM data WHERE relay=1') - nodes = node.fetchall() - if not nodes: - return - for x in nodes: - s = socket.socket() - try: - s.settimeout(120) - s.connect((x[0], x[1])) - except: - s.close() - continue - else: - s.send(to_send) - - s.close() + check = check[0] + my_key = config.wallet.find("data", "all")[0] + my_address = my_key['address'] + my_key = my_key['private'] + key = check['public'] + key = re.findall("([0-9]*)", key) + key = filter(None, key) + key = PublicKey(int(key[0]), int(key[1])) + my_key = re.findall("([0-9]*)", my_key) + my_key = filter(None, my_key) + my_key = PrivateKey(int(my_key[0]), int(my_key[1]), int(my_key[2]), int(my_key[3]), int(my_key[4])) + cc = config.db.find("coins", {"address":my_address}) + if len(cc) < amount: + print "You have insufficient funds." + return + cc = cc[:amount] + transactionid = uuid.uuid4().hex + for x in cc: + starter, hash_ = x['starter'], x['hash'] + starter = base64.b64encode(encrypt(decrypt(base64.b64decode(starter), my_key), key)) + out_s = {'cmd': 'send_coin', + 'for': address, + "transid":transactionid, + 'starter': starter, + 'hash': hash_, + "from":my_address, + "amount_sent":amount, + "plain":x['starter'], + "difficulty":x['difficulty'], + } + print out_s + send_command.send(out_s) + print "Coins sent!" def send_coin(obj, data): - + if not config.db.find("transactions", {"transid":data['transid']}): + config.db.insert("transactions", {"to":data['for'], "from":data['from'], "amount":data['amount_sent'], "transid":data['transid']}) + while os.path.exists("db.lock"): + time.sleep(0.1) + open("db.lock", 'w').close() + config.db.save() + os.remove("db.lock") while os.path.exists("db.lock"): time.sleep(0.1) - open("db.lock", 'w') - db = sqlite3.connect('db.db') - db.execute('UPDATE coins SET address=?, starter=? WHERE hash=?', [data['for'], data['starter'], data['hash']]) - db.execute("INSERT INTO transactions (to_, from_, hash) VALUES (?, ?, ?)", [data['for'], data['starter'], data['hash']]) - db.commit() + open("db.lock", 'w').close() + check = config.db.find("coins", {"hash":data['hash']}) + for x in check: + config.db.remove("coins", x) + config.db.save() + config.db.insert("coins",{"for":data['for'], "starter":data['starter'], "hash":data['hash']}) + config.db.save() os.remove("db.lock") + diff --git a/send_command.py b/send_command.py new file mode 100644 index 0000000..15a45d9 --- /dev/null +++ b/send_command.py @@ -0,0 +1,43 @@ +import socket +import json +import config +import random + +def send(cmd, out=False, god=False): + if god: + nodes = config.brokers + else: + nodes = config.nodes.find("nodes", {"relay":1}) + random.shuffle(nodes) + for x in nodes: + s = socket.socket() + try: + s.connect((x['ip'], x['port'])) + except: + s.close() + continue + else: + s.send(json.dumps({"cmd":"get_version"})) + data = s.recv(1024) + if data == config.version: + s.close() + s = socket.socket() + try: + s.connect((x['ip'], x['port'])) + except: + s.close() + continue + else: + s.send(json.dumps(cmd)) + out = "" + while True: + data = s.recv(1024) + if not data: + break + out = out + data + s.close() + if out: + return out + else: + s.close() + diff --git a/shell.py b/shell.py index dc703c2..2d8ebf2 100644 --- a/shell.py +++ b/shell.py @@ -1,94 +1,70 @@ +import config import cmd -import sqlite3 import send_coin -import get_nodes -import get_db -import urllib +import threading -class zCoinShell(cmd.Cmd): +class zc(cmd.Cmd): prompt = "zShell$ " - intro = "\nWelcome to the zCoin Shell for help type 'help'" - def do_coins(self, line): - coins = sqlite3.connect("db.db").cursor() - coins.execute("SELECT * FROM coins WHERE address=?", [self.addr()]) + intro = "Welcome to the zCoin shell, type `help` to get started." + def do_send(self, line): + line = line.split() try: - print "You have "+str(len(coins.fetchall())) + " coins." - except sqlite3.DatabaseError: - self.do_fixdb(None) - self.do_coins(None) - - def do_transactions(self, line): - coins = sqlite3.connect("db.db").cursor() - coins.execute("SELECT to_, from_, hash FROM transactions WHERE to_=?", [line]) - for x in coins.fetchall(): - print "\nTo: "+x[0] - print "Coin: "+x[2] + to = line[0] + amount = line[1] + except: + self.do_help() + else: + print "Coins are being sent" + threading.Thread(target=send_coin.send, args=(to, amount)).start() def do_totalcoins(self, line): - coins = sqlite3.connect("db.db").cursor() - coins.execute("SELECT * FROM coins") - try: - print "There are "+str(len(coins.fetchall()))+" coins in existence." - except sqlite3.DatabaseError: - self.do_fixdb(None) - self.do_totalcoins(None) - def do_fixdb(self, line): - print "Fixing your broken databases..." - get_nodes.get_nodes_send(True) - get_db.get_db_send() - print "Fixed!" - def do_update(self, line): - data = { - "check_coin.py":"https://raw.github.com/Max00355/zCoin/master/check_coin.py", - "config.py":"https://raw.github.com/Max00355/zCoin/master/config.py", - "get_db.py":"https://raw.github.com/Max00355/zCoin/master/get_db.py", - "get_nodes.py":"https://raw.github.com/Max00355/zCoin/master/get_nodes.py", - "get_difficulty.py":"https://raw.github.com/Max00355/zCoin/master/get_difficulty.py", - "get_version.py":"https://raw.github.com/Max00355/zCoin/master/get_version.py", - "register.py":"https://raw.github.com/Max00355/zCoin/master/register.py", - "send_coin.py":"https://raw.github.com/Max00355/zCoin/master/send_coin.py", - "zcoin.py":"https://raw.github.com/Max00355/zCoin/master/zcoin.py", - "shell.py":"https://raw.github.com/Max00355/zCoin/master/shell.py", - "miner.py":"https://raw.github.com/Max00355/zCoin/master/miner.py", - } - for x in data: - print "Updating "+x - with open(x, 'wb') as file: - file.write(urllib.urlopen(data[x]).read()) - print "Done! Restart your zCoin node please." + coin = config.db.find("coins", "all") + if not coin: + coin = 0 + else: + coin = len(coin) + print "Ther are "+str(coin)+" coins in existence." - def do_send(self, line): - line = line.split() - to = line[0] - amount = line[1] - print send_coin.send_coin_send(line[0], line[1]) - def do_addr(self, line): - print "Your zCoin address is: "+self.addr() - def do_exit(self, line): - print "Bye!" + def do_coins(self, line): + addr = config.wallet.find("data", "all")[0] + addr = addr['address'] + coins = config.db.find("coins", {"address":addr}) + if not coins: + coins = 0 + else: + coins = len(coins) + print "You have "+str(coins)+" coins." + + def do_transactions(self, line): + line = line.split() + if not line: + self.do_help() + else: + data = config.db.find("transactions", {"from":line}) + if not data: + print "No transactions have been made from this address." + else: + for x in data: + a = """ + ID: {0} + To: {1} + Amount: {2} + + """.format(x['transid'], x['to'], x['amount']) + print a - exit() - def addr(self): - wallet = sqlite3.connect("wallet.db").cursor() - wallet.execute("SELECT address FROM data") - return wallet.fetchall()[0][0] - - def do_help(self, line): print """ + + Welcome to the zCoin shell - zCoin Commands - - addr - Displays your zCoin address. - coins - Shows the amount of zCoins that you currently have. - totalcoins - Shows the amount of total zCoins on the network. - fixdb - If you are receiving any type of error about Sqlite3 run this command. - update - Updates your zCoin files. It is suggested that you run these every startup. - send
- Allows you to transfer coins to another wallet. - exit - Closes the zCoin shell + send - Send coins to an address + coins - Shows the amount of coins you currently own + totalcoins - Shows total coins on the network + transactions - Shows transactions made from an address + update - Updates the source code """ if __name__ == "__main__": - zCoinShell().cmdloop() - + zc().cmdloop() diff --git a/zcoin.py b/zcoin.py index c4fbeaa..3118cb5 100644 --- a/zcoin.py +++ b/zcoin.py @@ -1,136 +1,99 @@ +import config import socket -import json -from rsa import * -import random -import get_nodes import get_db +import get_version +import get_nodes +import coin_count +import string import register -import sqlite3 -import config -import time +import rsa +import random import thread -import string +import json +import time import get_difficulty import check_coin import send_coin -import get_version -import sys class zCoin: def __init__(self): self.cmds = { - "register":register.register, - "get_nodes":get_nodes.get_nodes, - "get_db":get_db.get_db, - "get_difficulty":get_difficulty.get_difficulty, - "get_raw_difficulty":get_difficulty.get_raw_difficulty, - "check_coin":check_coin.check_coin, - "confirm_coin":check_coin.confirm_coin, - "send_coin":send_coin.send_coin, - "get_version":get_version.get_version, - } + "get_db":get_db.get_db, + "get_nodes":get_nodes.get_nodes, + "get_version":get_version.get_version, + "coin_count":coin_count.coin_count, + "register":register.register, + "get_difficulty":get_difficulty.get_difficulty, + "check_coin":check_coin.check_coin, + "send_coin":send_coin.send_coin, + } - def first_run(self): + def firstrun(self): print "Generating address..." - pub, priv = newkeys(1024) + pub, priv = rsa.newkeys(1024) address = "Z"+''.join([random.choice(string.uppercase+string.lowercase+string.digits) for x in range(50)]) - print "Your address is "+address - wallet = sqlite3.connect("wallet.db") - db = sqlite3.connect("db.db") - nodes = sqlite3.connect("nodes.db") - nodes.execute("CREATE TABLE IF NOT EXISTS data (address TEXT, relay INT, port INT, public TEXT, ip TEXT, version TEXT)") - db.execute("CREATE TABLE IF NOT EXISTS difficulty (level INT)") - db.execute("CREATE TABLE IF NOT EXISTS coins (starter TEXT, address TEXT, hash TEXT)") - db.execute("CREATE TABLE IF NOT EXISTS transactions (to_ TEXT, from_ TEXT, hash TEXT)") - db.execute("INSERT INTO difficulty (level) VALUES (7)") - db.commit() - wallet.execute("CREATE TABLE data (public TEXT, private TEXT, address TEXT)") - wallet.execute("INSERT INTO data (public, private, address) VALUES (?, ?, ?)", [str(pub), str(priv), address]) - wallet.commit() - print "Registering with broker node..." - register.register_send(True) - print "Retrieving nodes db..." - get_nodes.get_nodes_send(True) - print "Retrieving coins db..." - get_db.get_db_send() - print "Syncing with network..." - register.register_send() + print "Your address is: "+address + print "Getting nodes..." + get_nodes.send(True) + check = config.nodes.find("nodes", "all") + if not check: + print "It looks like you are the first node on this network." + ip = raw_input("What is your IP address? ") + config.nodes.insert("nodes", {"public":str(pub), "address":address, "ip":ip, "relay":config.relay, "port":config.port}) + config.nodes.save() + config.db.insert("difficulty", {"difficulty":7}) + config.db.save() + config.wallet.insert("data", {"public":str(pub), "address":address, "private":str(priv)}) + config.wallet.save() + print "Registering..." + register.send() + print "Getting coins db..." + get_db.send() print "Done!" + def relay(self): + get_nodes.send() + register.send() + get_db.send() + sock = socket.socket() + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind((config.host, config.port)) + sock.listen(5) + while True: + obj, conn = sock.accept() + thread.start_new_thread(self.handle, (obj, conn[0])) def handle(self, obj, ip): data = obj.recv(10240) if data: try: data = json.loads(data) - except ValueError: + except: + obj.close() return else: - print data - data['ip'] = ip if "cmd" in data: - if data['cmd'] in self.cmds: + if data['cmd'] in self.cmds: + data['ip'] = ip + print data self.cmds[data['cmd']](obj, data) - obj.close() - - def relay(self): - print "zCoin has started as a relay node" - nodes = sqlite3.connect("nodes.db") - cur = nodes.cursor() - cur.execute("SELECT * FROM data") - if not cur.fetchall(): #This must mean that it is the first node, thus it is a god node. - wallet = sqlite3.connect("wallet.db").cursor() - print "\nIt seems as though you are trying to run as the first God node in the network." - ip = raw_input("\nJust to be safe, give me the IP address of this node: ") - port = config.port - relay = 1 - wallet.execute("SELECT address, public FROM data") - out = wallet.fetchall() - address = out[0][0] - public = out[0][1] - nodes.execute("INSERT INTO data (address, ip, port, public, relay, version) VALUES (?, ?, ?, ?, ?, ?)", [address, ip, port, public, relay, config.version]) - nodes.commit() - print "All good" - - get_nodes.get_nodes_send() - get_db.get_db_send() - sock = socket.socket() - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.bind((config.host, config.port)) - sock.listen(5) - while True: - obj, conn = sock.accept() - thread.start_new_thread(self.handle, (obj, conn[0])) + obj.close() - def non_relay(self): + def normal(self): + register.send() while True: - get_nodes.get_nodes_send() - get_db.get_db_send() + coin_count.send() + get_nodes.send() time.sleep(60) - if __name__ == "__main__": - if len(sys.argv) > 1: - if sys.argv[1] == "-fixdb": - get_nodes.get_nodes_send(god=True) - get_db.get_db_send() - update = False - try: - check = get_version.get_version_send() - if check['version'] != config.version: - print "Your version of zCoin is out of date. Please download the latest verion of zCoin from Github." - update = True - except: - print "Couldn't get current zCoin version from any of the brokers, they all must be down. I suggest you restart your client in a bit to check again." - if not update: - wallet = sqlite3.connect("wallet.db").cursor() - try: - wallet.execute("SELECT * FROM data") - except: - zCoin().first_run() - if config.relay: - register.register_send() - zCoin().relay() - else: - print "zCoin has started as a normal node." - register.register_send() - zCoin().non_relay() + zc = zCoin() + check = config.nodes.find("nodes", "all") + if not check: + zc.firstrun() + if config.relay: + print "zCoin started as a relay node." + zc.relay() + else: + print "zCoin started as a normal node." + zc.normal() +