v.1.1
- 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:
parent
76cfa95202
commit
daf5ab6549
|
@ -7,24 +7,36 @@ from datetime import datetime
|
|||
from flask import Flask, jsonify, request, render_template, flash, redirect, url_for
|
||||
|
||||
class Block:
|
||||
def __init__(self, index, timestamp, data, previous_hash):
|
||||
def __init__(self, index, timestamp, data, previous_hash, nonce=0):
|
||||
self.index = index
|
||||
self.timestamp = timestamp
|
||||
self.data = data
|
||||
self.previous_hash = previous_hash
|
||||
self.nonce = nonce
|
||||
self.hash = self.calculate_hash()
|
||||
|
||||
def calculate_hash(self):
|
||||
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:
|
||||
def __init__(self):
|
||||
self.chain = []
|
||||
self.difficulty = 4
|
||||
self.load_chain()
|
||||
|
||||
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):
|
||||
return self.chain[-1]
|
||||
|
@ -70,10 +82,13 @@ class Blockchain:
|
|||
if current_block.previous_hash != previous_block.hash:
|
||||
return False
|
||||
|
||||
if current_block.hash[:self.difficulty] != '0' * self.difficulty:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = 'lesecretkey'
|
||||
app.secret_key = 'lesecretkey'
|
||||
blockchain = Blockchain()
|
||||
CONNECTED_NODES = []
|
||||
|
||||
|
@ -87,10 +102,11 @@ def upload_image():
|
|||
image_data = base64.b64encode(file.read()).decode('utf-8')
|
||||
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.mine_block(blockchain.difficulty)
|
||||
blockchain.add_block(block)
|
||||
|
||||
if blockchain.is_chain_valid():
|
||||
flash('Image uploaded successfully', 'success')
|
||||
flash('Image uploaded successfully.', 'success')
|
||||
else:
|
||||
flash('Corrupted blocks detected. Image upload failed.', 'danger')
|
||||
blockchain.chain.pop()
|
||||
|
|
|
@ -3,6 +3,17 @@
|
|||
<head>
|
||||
<title>Memechain</title>
|
||||
<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>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
@ -19,23 +30,35 @@
|
|||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<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 style="margin-top: 40px;" class="row">
|
||||
<div class="col-md-6">
|
||||
<h2>New Block</h2>
|
||||
<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>
|
||||
<button type="submit" class="btn btn-primary">Upload</button>
|
||||
</form>
|
||||
<hr>
|
||||
<h2>Connected Nodes</h2>
|
||||
<form action="/register_node" method="post">
|
||||
<div class="form-group">
|
||||
<label for="node_url">Node URL:</label>
|
||||
<input type="text" class="form-control" id="node_url" name="node_url" required>
|
||||
<div class="col-md-6">
|
||||
<h2>Connected Nodes</h2>
|
||||
<form action="/register_node" method="post">
|
||||
<div class="form-group">
|
||||
<label for="node_url">Node URL:</label>
|
||||
<input type="text" class="form-control" id="node_url" name="node_url" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Connect Node</button>
|
||||
</form>
|
||||
<ul id="node-list" class="list-group mt-3"></ul>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Connect Node</button>
|
||||
</form>
|
||||
<ul id="node-list" class="list-group mt-3"></ul>
|
||||
</div>
|
||||
<hr>
|
||||
<a href="/sync_chain" class="btn btn-primary">Sync Blockchain</a>
|
||||
<hr>
|
||||
|
@ -64,7 +87,6 @@
|
|||
blockchainDiv.appendChild(blockDiv);
|
||||
});
|
||||
});
|
||||
|
||||
fetch('/nodes')
|
||||
.then(response => response.json())
|
||||
.then(nodes => {
|
||||
|
@ -75,7 +97,10 @@
|
|||
listItem.classList.add('list-group-item');
|
||||
nodeList.appendChild(listItem);
|
||||
});
|
||||
});
|
||||
});
|
||||
$('form').on('submit', function() {
|
||||
$('.loading').show();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue