Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 37 additions & 7 deletions simpleCoin/miner.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from flask import Flask, request
from multiprocessing import Process, Pipe
import ecdsa
import pprint

from miner_config import MINER_ADDRESS, MINER_NODE_URL, PEER_NODES

Expand Down Expand Up @@ -63,24 +64,29 @@ def create_genesis_block():
discarded and your transaction goes back as if it was never
processed"""
NODE_PENDING_TRANSACTIONS = []

start_time = time.time()

def proof_of_work(last_proof, blockchain):
# Creates a variable that we will use to find our next proof of work
incrementer = last_proof + 1
# Keep incrementing the incrementer until it's equal to a number divisible by 7919
# and the proof of work of the previous block in the chain
start_time = time.time()
# start_time = time.time()
print(int((time.time()-start_time) % 60))
while not (incrementer % 7919 == 0 and incrementer % last_proof == 0):
# print('work')
incrementer += 1
# Check if any node found the solution every 60 seconds
if int((time.time()-start_time) % 60) == 0:
# print('check')

# If any other node got the proof, stop searching
new_blockchain = consensus(blockchain)
if new_blockchain:
# (False: another node got proof first, new blockchain)
return False, new_blockchain
# Once that number is found, we can return it as a proof of our work
print(incrementer)
return incrementer, blockchain


Expand Down Expand Up @@ -143,7 +149,8 @@ def find_new_chains():
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
# print(block)
# Convert the JSON object to a Python dictionary
block = json.loads(block)
# Verify other node block is correct
Expand Down Expand Up @@ -191,9 +198,9 @@ def get_blocks():
chain_to_send_json = []
for block in chain_to_send:
block = {
"index": str(block.index),
"timestamp": str(block.timestamp),
"data": str(block.data),
"index": block.index,
"timestamp": block.timestamp,
"data": block.data,
"hash": block.hash
}
chain_to_send_json.append(block)
Expand All @@ -203,6 +210,30 @@ def get_blocks():
return chain_to_send


@node.route('/balance', methods=['GET'])
def get_balance():
address = request.args.get("address")
global BLOCKCHAIN
chain_to_send = BLOCKCHAIN
transaction_history = []
c_counter = 0
d_counter = 0
for block in chain_to_send:
y = block.data
transaction_history.append(y["transactions"])
for x in transaction_history:
if x is not None:
for y in x:
# print(y['to'])
if y['to'] == address:
c_counter = c_counter + y['amount']
if y['from'] == address:
d_counter = d_counter + int(y['amount'])

balance = c_counter - d_counter
return str(balance)


@node.route('/txion', methods=['GET', 'POST'])
def transaction():
"""Each transaction sent to this node gets validated and submitted.
Expand Down Expand Up @@ -247,7 +278,6 @@ def validate_signature(public_key, signature, message):
except:
return False


def welcome_msg():
print(""" =========================================\n
SIMPLE COIN v1.0.0 - BLOCKCHAIN SYSTEM\n
Expand Down
3 changes: 2 additions & 1 deletion simpleCoin/miner_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
"""

# Write your generated adress here. All coins mined will go to this address
MINER_ADDRESS = "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi"
MINER_ADDRESS = "e5yWZy7lcTm6ulr0rMmXxBGaYg4Mb10a+50SJb59MQm434y8bkRttCi5+SPWF4DxN3EIUEj2a2fLu9SVWRMe0g=="

# Write your node url or ip. If you are running it localhost use default
MINER_NODE_URL = "http://localhost:5000"

# Store the url data of every other node in the network
# so that we can communicate with them
PEER_NODES = []
# PEER_NODES = ['http://3.96.192.248:5000']
146 changes: 146 additions & 0 deletions simpleCoin/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Python Flask App to create Blockchain

# For timestamp
import datetime

# Calculating the hash
# in order to add digital
# fingerprints to the blocks
import hashlib

# To store data
# in our blockchain
import json

# Flask is for creating the web
# app and jsonify is for
# displaying the blockchain
from flask import Flask, jsonify


class Blockchain:

# This function is created
# to create the very first
# block and set its hash to "0"
def __init__(self):
self.chain = []
self.create_block(proof=1, previous_hash='0')
print(self.chain)

# This function is created
# to add further blocks
# into the chain
def create_block(self, proof, previous_hash):
block = {'index': len(self.chain) + 1,
'timestamp': str(datetime.datetime.now()),
'proof': proof,
'previous_hash': previous_hash}
self.chain.append(block)
return block

# This function is created
# to display the previous block
def print_previous_block(self):
return self.chain[-1]

# This is the function for proof of work
# and used to successfully mine the block
def proof_of_work(self, previous_proof):
new_proof = 1
check_proof = False

while check_proof is False:
hash_operation = hashlib.sha256(
str(new_proof ** 2 - previous_proof ** 2).encode()).hexdigest()
if hash_operation[:5] == '00000':
check_proof = True
else:
new_proof += 1

return new_proof

def hash(self, block):
encoded_block = json.dumps(block, sort_keys=True).encode()
return hashlib.sha256(encoded_block).hexdigest()

def chain_valid(self, chain):
previous_block = chain[0]
block_index = 1

while block_index < len(chain):
block = chain[block_index]
if block['previous_hash'] != self.hash(previous_block):
return False

previous_proof = previous_block['proof']
proof = block['proof']
hash_operation = hashlib.sha256(
str(proof ** 2 - previous_proof ** 2).encode()).hexdigest()

if hash_operation[:5] != '00000':
return False
previous_block = block
block_index += 1

return True


# Creating the Web
# App using flask
app = Flask(__name__)

# Create the object
# of the class blockchain
blockchain = Blockchain()


# Mining a new block


@app.route('/mine_block', methods=['GET'])
def mine_block():
print('mining')
previous_block = blockchain.print_previous_block()
previous_proof = previous_block['proof']
proof = blockchain.proof_of_work(previous_proof)
previous_hash = blockchain.hash(previous_block)
block = blockchain.create_block(proof, previous_hash)

response = {'message': 'A block is MINED',
'index': block['index'],
'timestamp': block['timestamp'],
'proof': block['proof'],
'previous_hash': block['previous_hash']}

return jsonify(response), 200


# Display blockchain in json format


@app.route('/get_chain', methods=['GET'])
def display_chain():
response = {'chain': blockchain.chain,
'length': len(blockchain.chain)}
return jsonify(response), 200


# Check validity of blockchain


@app.route('/valid', methods=['GET'])
def valid():
valid = blockchain.chain_valid(blockchain.chain)

if valid:
response = {'message': 'The Blockchain is valid.'}
else:
response = {'message': 'The Blockchain is not valid.'}
return jsonify(response), 200


# Run the flask server locally
app.run(host='127.0.0.1', port=5000)

mine_block()
22 changes: 20 additions & 2 deletions simpleCoin/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@

def wallet():
response = None
while response not in ["1", "2", "3", "4"]:
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
4. Quit\n""")
4. Check Balance
5. Quit\n""")
if response == "1":
# Generate new wallet
print("""=========================================\n
Expand All @@ -55,6 +56,9 @@ def wallet():
elif response == "3": # Will always occur when response == 3.
check_transactions()
return wallet() # return to main menu
elif response == "4": # Will always occur when response == 4.
check_balance()
return wallet() # return to main menu
else:
quit()

Expand Down Expand Up @@ -100,6 +104,20 @@ def check_transactions():
print('Connection error. Make sure that you have run miner.py in another terminal.')


def check_balance():
"""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.
"""
try:
res = requests.get('http://localhost:5000/balance', params =
{'address':"rqH1SmqNBqnNojCin9fI4BdFHN/KsazIj/xasjZK6i1iFi03AApkKtQXzm61lUA6TMCvfbKg7+ylLkYvKZMfMg=="})
# print(str(res))
parsed = json.loads(res.text)
print('balance: ' + (json.dumps(parsed, indent=4, sort_keys=True)))
except requests.ConnectionError:
print('Connection error. Make sure that you have run miner.py in another terminal.')


def generate_ECDSA_keys():
"""This function takes care of creating your private and public (your address) keys.
It's very important you don't lose any of them or those wallets will be lost
Expand Down