diff --git a/simpleCoin/miner.py b/simpleCoin/miner.py index 16c9252..e36107e 100644 --- a/simpleCoin/miner.py +++ b/simpleCoin/miner.py @@ -51,7 +51,7 @@ def create_genesis_block(): return Block(0, time.time(), { "proof-of-work": 9, "transactions": None}, - "0") + "0") # Node's blockchain copy @@ -74,7 +74,7 @@ def proof_of_work(last_proof, blockchain): while not (incrementer % 7919 == 0 and incrementer % last_proof == 0): incrementer += 1 # Check if any node found the solution every 60 seconds - if int((time.time()-start_time) % 60) == 0: + if int((time.time() - start_time) % 60) == 0: # If any other node got the proof, stop searching new_blockchain = consensus(blockchain) if new_blockchain: @@ -108,7 +108,8 @@ def mine(a, blockchain, node_pending_transactions): # Once we find a valid proof of work, we know we can mine a block so # ...we reward the miner by adding a transaction # First we load all pending transactions sent to the node server - NODE_PENDING_TRANSACTIONS = requests.get(url = MINER_NODE_URL + '/txion', params = {'update':MINER_ADDRESS}).content + NODE_PENDING_TRANSACTIONS = requests.get(url=MINER_NODE_URL + '/txion', + params={'update': MINER_ADDRESS}).content NODE_PENDING_TRANSACTIONS = json.loads(NODE_PENDING_TRANSACTIONS) # Then we add the mining reward NODE_PENDING_TRANSACTIONS.append({ @@ -130,20 +131,21 @@ def mine(a, blockchain, node_pending_transactions): BLOCKCHAIN.append(mined_block) # Let the client know this node mined a block print(json.dumps({ - "index": new_block_index, - "timestamp": str(new_block_timestamp), - "data": new_block_data, - "hash": last_block_hash + "index": new_block_index, + "timestamp": str(new_block_timestamp), + "data": new_block_data, + "hash": last_block_hash }) + "\n") a.send(BLOCKCHAIN) - requests.get(url = MINER_NODE_URL + '/blocks', params = {'update':MINER_ADDRESS}) + requests.get(url=MINER_NODE_URL + '/blocks', params={'update': MINER_ADDRESS}) + def find_new_chains(): # Get the blockchains of every other node other_chains = [] for node_url in PEER_NODES: # Get their chains using a GET request - block = requests.get(url = node_url + "/blocks").content + block = requests.get(url=node_url + "/blocks").content # Convert the JSON object to a Python dictionary block = json.loads(block) # Verify other node block is correct @@ -222,6 +224,15 @@ def transaction(): print("TO: {0}".format(new_txion['to'])) print("AMOUNT: {0}\n".format(new_txion['amount'])) # Then we let the client know it worked out + # my code----------------------------------------------------------- + f = open("transactions_share.txt", "w") + # f = open(r"C:\transactions_share.txt", "w") + print("New transaction", file=f) + print("FROM: {0}".format(new_txion['from']), file=f) + print("TO: {0}".format(new_txion['to']), file=f) + print("AMOUNT: {0}\n".format(new_txion['amount']), file=f) + f.close() + # my code------------------------------------------------------------ return "Transaction submission successful\n" else: return "Transaction submission failed. Wrong signature\n" diff --git a/simpleCoin/wallet.py b/simpleCoin/wallet.py index 7eeb992..2ba6e58 100644 --- a/simpleCoin/wallet.py +++ b/simpleCoin/wallet.py @@ -17,20 +17,101 @@ transaction with same timestamp was added, they should remove it from the node_pending_transactions list to avoid it get processed more than 1 time. """ - +import sqlite3 import requests import time import base64 import ecdsa +import smtplib +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +from email.mime.base import MIMEBase +from email import encoders +import os.path +from datetime import datetime + + +# my code------------------------------------------------------------------------------------------------------------- +def acc_check(): + login_check = input("Do you have an account?(y/n): ") + if login_check.lower() == 'y': + login() + elif login_check.lower() == 'n': + reg_check = input("Do you want to register?(y/n): ") + if reg_check.lower() == 'y': + reg() + else: + print("Goodbye") + end() + else: + print("Invalid input") + end() + +def reg(): + with sqlite3.connect("accounts.db") as db: + cursor = db.cursor() + # create table + cursor.execute(''' + CREATE TABLE IF NOT EXISTS user( + email VARCHAR(50) PRIMARY KEY, + firstname VARCHAR(20) NOT NULL, + surname VARCHAR(20) NOT NULL, + password VARCHAR(20) NOT NULL); + ''') + # insert values to table from user input + u_email = input('Please Enter Your Email: ') + u_fname = input('Please Enter Your First Name: ') + u_lname = input('Please Enter Your Last Name: ') + u_password = input('Please Enter Your Password: ') + cursor.execute(""" + INSERT INTO user(email, firstname, surname, password) + VALUES (?,?,?,?) + """, (u_email, u_fname, u_lname, u_password)) + db.commit() + print("Data entered successfully") + db.close() + print("Please Login Your Account") + login() + +def login(): + email = input("Enter Your Email: ") + password = input("Enter Your password: ") + with sqlite3.connect("accounts.db") as db: + cursor = db.cursor() + find_user = ("SELECT * FROM user WHERE email = ? AND password = ?") + cursor.execute(find_user, [(email), (password)]) + results = cursor.fetchall() + + if results: + for i in results: + print("Welcome " + i[2]) + wallet() # connect with main program here + + else: + print("Email and password not recognised") + again = input("Do you want to try again?(y/n): ") + if again.lower() == "n": + print("Goodbye") + end() + elif again.lower() == "y": + login() + else: + end() + + +# my code------------------------------------------------------------------------------------------------------------- def wallet(): response = None - while response not in ["1", "2", "3"]: + while response not in ["1", "2", "3", "4", "5"]: response = input("""What do you want to do? 1. Generate new wallet 2. Send coins to another wallet - 3. Check transactions\n""") + 3. Check transactions + 4. Check transactions history (enhanced) + 5. Exit program\n""") + if response == "1": # Generate new wallet print("""=========================================\n @@ -48,6 +129,10 @@ def wallet(): response = input("y/n\n") if response.lower() == "y": send_transaction(addr_from, private_key, addr_to, amount) + elif response == "4": + trans_improved() + elif response == "5": + end() else: # Will always occur when response == 3. check_transactions() @@ -77,16 +162,124 @@ def send_transaction(addr_from, private_key, addr_to, amount): res = requests.post(url, json=payload, headers=headers) print(res.text) + # my program ------------------------------------------------------------- + with sqlite3.connect("translog.db") as db2: + cursor2 = db2.cursor() + # create table + cursor2.execute(''' + CREATE TABLE IF NOT EXISTS transactions( + private_k VARCHAR(250) NOT NUll, + sender_k VARCHAR(250) NOT NULL, + receiver_k VARCHAR(250) NOT NULL, + c_amount INTEGER NOT NULL, + dNt TEXT NOT NULL); + ''') + # insert values to table from user input + + pri_key = private_key + pub_key = addr_from + r_pub_k = addr_to + c_amount = amount + dt_for = datetime.now().strftime("%B %d, %Y %I:%M%p") + cursor2.execute(""" + INSERT INTO transactions(private_k, sender_k, receiver_k, c_amount, dNt) + VALUES (?,?,?,?,?) + """, (pri_key, pub_key, r_pub_k, c_amount, dt_for)) + db2.commit() + # print("Data entered successfully") + + # my code ------------------------------------------------------------- + # my code---------------------------------------------------------------- + share_m = input("Do you want to share this transfer details with email?\n(y/n): ") + if share_m.lower() == 'y': + share_with_m() + elif share_m.lower() == 'n': + wallet() + else: + print("Invalid input") + print("Auto cancelled") + wallet() + # my code---------------------------------------------------------------- + else: print("Wrong address or key length! Verify and try again.") +# my code------------------------------------------------------------ +def share_with_m(): + r_mail = input("Enter the receiver mail address: ") + email = 'simplecoinproject@gmail.com' # Your email + password = '123Abc321!' # Your email account password + send_to_email = r_mail # Who you are sending the message to + subject = 'SimpleCoin Transaction Alert' # The subject line + message = '' # The message in the email + file_location = r'C:\Users\hp\Downloads\SimpleCoin-master\SimpleCoin-master\simpleCoin\transactions_share.txt' + #file_location = r'C:\Users\hp\Downloads\SimpleCoin-master enhanced (KND)\SimpleCoin-master\simpleCoin\transactions_share.txt' + + with open(file_location) as f: + message = f.read() + + msg = MIMEMultipart() + msg['From'] = email + msg['To'] = send_to_email + msg['Subject'] = subject + + # Attach the message to the MIMEMultipart object + msg.attach(MIMEText(message, 'plain')) + + # Setup the attachment + filename = os.path.basename(file_location) + attachment = open(file_location, "rb") + part = MIMEBase('application', 'octet-stream') + part.set_payload(attachment.read()) + encoders.encode_base64(part) + part.add_header('Content-Disposition', "attachment; filename= %s" % filename) + + server = smtplib.SMTP('smtp.gmail.com', 587) + server.starttls() + server.login(email, password) + text = msg.as_string() # You now need to convert the MIMEMultipart object to a string to send + server.sendmail(email, send_to_email, text) + server.quit() + print("Sent Successfully!!!!") + wallet() + + +# my code------------------------------------------------------------ +def trans_improved(): + pri_k = input("Enter your private key: ") + with sqlite3.connect("translog.db") as db2: + cursor2 = db2.cursor() + + cursor2.execute("SELECT * FROM transactions WHERE private_k = '%s'" % pri_k) + data1 = cursor2.fetchall() + if len(data1) == 0: + print("DATA IS NOT FOUND") + else: + for row in data1: + # pri_key = row[0] + pub_key = row[1] + r_pub_k = row[2] + c_amount = row[3] + dt_for = row[4] + # print(pri_key) + print('') + print("Date and Time: ", dt_for) + print("From:", pub_key) + print("To:", r_pub_k) + print("Amount: ", c_amount) + print('') + print('-----------------------------------------------------------------') + wallet() +# my code------------------------------------------------------------ + def check_transactions(): """Retrieve the entire blockchain. With this you can check your wallets balance. If the blockchain is to long, it may take some time to load. """ res = requests.get('http://localhost:5000/blocks') print(res.text) + wallet() def generate_ECDSA_keys(): @@ -97,17 +290,19 @@ def generate_ECDSA_keys(): private_key: str public_ley: base64 (to make it shorter) """ - sk = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) #this is your sign (private key) - private_key = sk.to_string().hex() #convert your private key to hex - vk = sk.get_verifying_key() #this is your verification key (public key) + sk = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) # this is your sign (private key) + private_key = sk.to_string().hex() # convert your private key to hex + vk = sk.get_verifying_key() # this is your verification key (public key) public_key = vk.to_string().hex() - #we are going to encode the public key to make it shorter + # we are going to encode the public key to make it shorter public_key = base64.b64encode(bytes.fromhex(public_key)) filename = input("Write the name of your new address: ") + ".txt" with open(filename, "w") as f: f.write("Private key: {0}\nWallet address / Public key: {1}".format(private_key, public_key.decode())) print("Your new address and private key are now in the file {0}".format(filename)) + wallet() + def sign_ECDSA_msg(private_key): """Sign the message to be sent @@ -125,6 +320,11 @@ def sign_ECDSA_msg(private_key): return signature, message +def end(): + print("This program is closed.") + exit() + + if __name__ == '__main__': print(""" =========================================\n SIMPLE COIN v1.0.0 - BLOCKCHAIN SYSTEM\n @@ -132,5 +332,5 @@ def sign_ECDSA_msg(private_key): You can find more help at: https://github.com/cosme12/SimpleCoin\n Make sure you are using the latest version or you may end in a parallel chain.\n\n\n""") - wallet() + acc_check() input("Press ENTER to exit...")