- PoW checks implemented
- Networking implemented, two instances of Memechain can now be connected to each other and share one blockchain.
- Minor front-end changes
This commit is contained in:
f.strw 2024-06-15 15:37:41 +03:00
parent 76cfa95202
commit daf5ab6549
2 changed files with 63 additions and 22 deletions

View file

@ -7,24 +7,36 @@ from datetime import datetime
from flask import Flask, jsonify, request, render_template, flash, redirect, url_for from flask import Flask, jsonify, request, render_template, flash, redirect, url_for
class Block: class Block:
def __init__(self, index, timestamp, data, previous_hash): def __init__(self, index, timestamp, data, previous_hash, nonce=0):
self.index = index self.index = index
self.timestamp = timestamp self.timestamp = timestamp
self.data = data self.data = data
self.previous_hash = previous_hash self.previous_hash = previous_hash
self.nonce = nonce
self.hash = self.calculate_hash() self.hash = self.calculate_hash()
def calculate_hash(self): def calculate_hash(self):
data_string = json.dumps(self.data, sort_keys=True) data_string = json.dumps(self.data, sort_keys=True)
return hashlib.sha256((str(self.index) + self.timestamp + data_string + self.previous_hash).encode()).hexdigest() hash_data = str(self.index) + self.timestamp + data_string + self.previous_hash + str(self.nonce)
return hashlib.sha256(hash_data.encode()).hexdigest()
def mine_block(self, difficulty):
target = '0' * difficulty
while self.hash[:difficulty] != target:
self.nonce += 1
self.hash = self.calculate_hash()
print(f"Mining block {self.index}: Nonce = {self.nonce}, Hash = {self.hash}")
print(f"Block {self.index} mined successfully!")
class Blockchain: class Blockchain:
def __init__(self): def __init__(self):
self.chain = [] self.chain = []
self.difficulty = 4
self.load_chain() self.load_chain()
def create_genesis_block(self): def create_genesis_block(self):
return Block(0, "00-00-0000", "Genesis Block", "0") return Block(0, "0000-00-00 00:00:00", "Genesis Block", "0")
def get_latest_block(self): def get_latest_block(self):
return self.chain[-1] return self.chain[-1]
@ -70,10 +82,13 @@ class Blockchain:
if current_block.previous_hash != previous_block.hash: if current_block.previous_hash != previous_block.hash:
return False return False
if current_block.hash[:self.difficulty] != '0' * self.difficulty:
return False
return True return True
app = Flask(__name__) app = Flask(__name__)
app.secret_key = 'lesecretkey' app.secret_key = 'lesecretkey'
blockchain = Blockchain() blockchain = Blockchain()
CONNECTED_NODES = [] CONNECTED_NODES = []
@ -87,10 +102,11 @@ def upload_image():
image_data = base64.b64encode(file.read()).decode('utf-8') image_data = base64.b64encode(file.read()).decode('utf-8')
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
block = Block(len(blockchain.chain), current_time, image_data, blockchain.get_latest_block().hash) block = Block(len(blockchain.chain), current_time, image_data, blockchain.get_latest_block().hash)
block.mine_block(blockchain.difficulty)
blockchain.add_block(block) blockchain.add_block(block)
if blockchain.is_chain_valid(): if blockchain.is_chain_valid():
flash('Image uploaded successfully', 'success') flash('Image uploaded successfully.', 'success')
else: else:
flash('Corrupted blocks detected. Image upload failed.', 'danger') flash('Corrupted blocks detected. Image upload failed.', 'danger')
blockchain.chain.pop() blockchain.chain.pop()

View file

@ -3,6 +3,17 @@
<head> <head>
<title>Memechain</title> <title>Memechain</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<style>
.loading {
display: none;
text-align: center;
margin-top: 20px;
}
.loading .spinner-border {
width: 100%;
height: 100%;
}
</style>
</head> </head>
<body> <body>
<div class="container"> <div class="container">
@ -19,23 +30,35 @@
{% endif %} {% endif %}
{% endwith %} {% endwith %}
<form action="/upload" method="post" enctype="multipart/form-data"> <div style="margin-top: 40px;" class="row">
<div class="form-group"> <div class="col-md-6">
<label for="image">Select Image:</label> <h2>New Block</h2>
<input type="file" class="form-control-file" id="image" name="image" accept="image/*" required> <form id="upload-form" action="/upload" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="image">Select Image:</label>
<input type="file" class="form-control-file" id="image" name="image" accept="image/*" required>
</div>
<button type="submit" class="btn btn-primary" id="upload-btn">Upload</button>
<div class="loading">
<div class="spinner-border" role="status">
<img style="height: 64px; width: 64px;" src="https://media.tenor.com/I6kN-6X7nhAAAAAi/loading-buffering.gif">
</div>
<p>Mining block...</p>
</div>
</form>
</div> </div>
<button type="submit" class="btn btn-primary">Upload</button> <div class="col-md-6">
</form> <h2>Connected Nodes</h2>
<hr> <form action="/register_node" method="post">
<h2>Connected Nodes</h2> <div class="form-group">
<form action="/register_node" method="post"> <label for="node_url">Node URL:</label>
<div class="form-group"> <input type="text" class="form-control" id="node_url" name="node_url" required>
<label for="node_url">Node URL:</label> </div>
<input type="text" class="form-control" id="node_url" name="node_url" required> <button type="submit" class="btn btn-primary">Connect Node</button>
</form>
<ul id="node-list" class="list-group mt-3"></ul>
</div> </div>
<button type="submit" class="btn btn-primary">Connect Node</button> </div>
</form>
<ul id="node-list" class="list-group mt-3"></ul>
<hr> <hr>
<a href="/sync_chain" class="btn btn-primary">Sync Blockchain</a> <a href="/sync_chain" class="btn btn-primary">Sync Blockchain</a>
<hr> <hr>
@ -64,7 +87,6 @@
blockchainDiv.appendChild(blockDiv); blockchainDiv.appendChild(blockDiv);
}); });
}); });
fetch('/nodes') fetch('/nodes')
.then(response => response.json()) .then(response => response.json())
.then(nodes => { .then(nodes => {
@ -75,7 +97,10 @@
listItem.classList.add('list-group-item'); listItem.classList.add('list-group-item');
nodeList.appendChild(listItem); nodeList.appendChild(listItem);
}); });
}); });
$('form').on('submit', function() {
$('.loading').show();
});
</script> </script>
</body> </body>
</html> </html>