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